diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index dc6d3c14753..4af3c52fca1 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -558,47 +558,6 @@ public void update() { (BaseAction) () -> JabRefExecutorService.INSTANCE.execute(new DuplicateSearch(BasePanel.this))); */ - // TODO - //actions.put(Actions.MARK_ENTRIES, new MarkEntriesAction(frame, 0)); - - actions.put(Actions.UNMARK_ENTRIES, (BaseAction) () -> { - try { - List bes = mainTable.getSelectedEntries(); - if (bes.isEmpty()) { - output(Localization.lang("This operation requires one or more entries to be selected.")); - return; - } - NamedCompound ce = new NamedCompound(Localization.lang("Unmark entries")); - for (BibEntry be : bes) { - EntryMarker.unmarkEntry(be, false, bibDatabaseContext.getDatabase(), ce); - } - ce.end(); - getUndoManager().addEdit(ce); - markBaseChanged(); - String outputStr; - if (bes.size() == 1) { - outputStr = Localization.lang("Unmarked selected entry"); - } else { - outputStr = Localization.lang("Unmarked all %0 selected entries", Integer.toString(bes.size())); - } - output(outputStr); - } catch (Throwable ex) { - LOGGER.warn("Could not unmark", ex); - } - }); - - actions.put(Actions.UNMARK_ALL, (BaseAction) () -> { - NamedCompound ce = new NamedCompound(Localization.lang("Unmark all")); - - for (BibEntry be : bibDatabaseContext.getDatabase().getEntries()) { - EntryMarker.unmarkEntry(be, false, bibDatabaseContext.getDatabase(), ce); - } - ce.end(); - getUndoManager().addEdit(ce); - markBaseChanged(); - output(Localization.lang("Unmarked all entries")); - }); - // Note that we can't put the number of entries that have been reverted into the undoText as the concrete number cannot be injected actions.put(new SpecialFieldValueViewModel(SpecialField.RELEVANCE.getValues().get(0)).getCommand(), new SpecialFieldViewModel(SpecialField.RELEVANCE, undoManager).getSpecialFieldAction( diff --git a/src/main/java/org/jabref/gui/EntryMarker.java b/src/main/java/org/jabref/gui/EntryMarker.java deleted file mode 100644 index 8237304aced..00000000000 --- a/src/main/java/org/jabref/gui/EntryMarker.java +++ /dev/null @@ -1,199 +0,0 @@ -package org.jabref.gui; - -import java.util.Set; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.jabref.Globals; -import org.jabref.gui.undo.NamedCompound; -import org.jabref.gui.undo.UndoableFieldChange; -import org.jabref.model.database.BibDatabase; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.FieldName; -import org.jabref.preferences.JabRefPreferences; - -public class EntryMarker { - - public static final int MARK_COLOR_LEVELS = 6; - public static final int MAX_MARKING_LEVEL = MARK_COLOR_LEVELS - 1; - public static final int IMPORT_MARK_LEVEL = MARK_COLOR_LEVELS; - - private static final Pattern MARK_NUMBER_PATTERN = Pattern.compile(JabRefPreferences.getInstance().MARKING_WITH_NUMBER_PATTERN); - - private EntryMarker() { - } - - /** - * @param increment whether the given increment should be added to the current one. Currently never used in JabRef. Could be used to increase marking color ("Mark in specific color"). - */ - public static void markEntry(BibEntry be, int markIncrement, boolean increment, NamedCompound ce) { - int prevMarkLevel; - String newValue = null; - if (be.hasField(FieldName.MARKED_INTERNAL)) { - String markerString = be.getField(FieldName.MARKED_INTERNAL).get(); - int index = markerString.indexOf(Globals.prefs.getWrappedUsername()); - if (index >= 0) { - // Already marked 1 for this user. - prevMarkLevel = 1; - newValue = markerString.substring(0, index) - + markerString.substring(index + Globals.prefs.getWrappedUsername().length()) - + Globals.prefs.getWrappedUsername().substring(0, - Globals.prefs.getWrappedUsername().length() - 1) - + ":" + (increment ? Math.min(MAX_MARKING_LEVEL, prevMarkLevel + markIncrement) : markIncrement) - + "]"; - } else { - Matcher m = MARK_NUMBER_PATTERN.matcher(markerString); - if (m.find()) { - try { - prevMarkLevel = Integer.parseInt(m.group(1)); - newValue = markerString.substring(0, m.start(1)) + (increment ? Math.min(MAX_MARKING_LEVEL, prevMarkLevel + markIncrement) : markIncrement) + markerString.substring(m.end(1)); - } catch (NumberFormatException ex) { - // Do nothing. - } - } - } - } - if (newValue == null) { - newValue = Globals.prefs.getWrappedUsername().substring(0, Globals.prefs.getWrappedUsername().length() - 1) + ":" + markIncrement + "]"; - } - - ce.addEdit(new UndoableFieldChange(be, FieldName.MARKED_INTERNAL, - be.getField(FieldName.MARKED_INTERNAL).orElse(null), newValue)); - be.setField(FieldName.MARKED_INTERNAL, newValue); - } - - /** - * SIDE EFFECT: Unselects given entry - */ - public static void unmarkEntry(BibEntry be, boolean onlyMaxLevel, BibDatabase database, NamedCompound ce) { - if (be.hasField(FieldName.MARKED_INTERNAL)) { - String markerString = be.getField(FieldName.MARKED_INTERNAL).get(); - if ("0".equals(markerString)) { - if (!onlyMaxLevel) { - unmarkOldStyle(be, database, ce); - } - return; - } - String newValue = null; - int index = markerString.indexOf(Globals.prefs.getWrappedUsername()); - if (index >= 0) { - // Marked 1 for this user. - if (onlyMaxLevel) { - return; - } else { - newValue = markerString.substring(0, index) - + markerString.substring(index + Globals.prefs.getWrappedUsername().length()); - } - } else { - Matcher m = MARK_NUMBER_PATTERN.matcher(markerString); - if (m.find()) { - try { - int prevMarkLevel = Integer.parseInt(m.group(1)); - if (!onlyMaxLevel || (prevMarkLevel == MARK_COLOR_LEVELS)) { - if (prevMarkLevel > 1) { - newValue = markerString.substring(0, m.start(1)) + markerString.substring(m.end(1)); - } else { - String toRemove = Globals.prefs.getWrappedUsername().substring(0, - Globals.prefs.getWrappedUsername().length() - 1) + ":1]"; - index = markerString.indexOf(toRemove); - if (index >= 0) { - newValue = markerString.substring(0, index) + markerString.substring(index + toRemove.length()); - } - } - } else { - return; - } - } catch (NumberFormatException ex) { - // Do nothing. - } - } - } - - /*int piv = 0, hit; - StringBuffer sb = new StringBuffer(); - while ((hit = s.indexOf(G047749118118 - 1110lobals.prefs.WRAPPED_USERNAME, piv)) >= 0) { - if (hit > 0) - sb.append(s.substring(piv, hit)); - piv = hit + Globals.prefs.WRAPPED_USERNAME.length(); - } - if (piv < s.length() - 1) { - sb.append(s.substring(piv)); - } - String newVal = sb.length() > 0 ? sb.toString() : null;*/ - ce.addEdit(new UndoableFieldChange(be, FieldName.MARKED_INTERNAL, - be.getField(FieldName.MARKED_INTERNAL).get(), newValue)); - if (newValue == null) { - be.clearField(FieldName.MARKED_INTERNAL); - } else { - be.setField(FieldName.MARKED_INTERNAL, newValue); - } - } - } - - /** - * An entry is marked with a "0", not in the new style with user names. We - * want to unmark it as transparently as possible. Since this shouldn't - * happen too often, we do it by scanning the "owner" fields of the entire - * database, collecting all user names. We then mark the entry for all users - * except the current one. Thus only the user who unmarks will see that it - * is unmarked, and we get rid of the old-style marking. - * - * @param be - * @param ce - */ - private static void unmarkOldStyle(BibEntry be, BibDatabase database, NamedCompound ce) { - Set owners = new TreeSet<>(); - for (BibEntry entry : database.getEntries()) { - entry.getField(FieldName.OWNER).ifPresent(owners::add); - } - owners.remove(Globals.prefs.get(JabRefPreferences.DEFAULT_OWNER)); - StringBuilder sb = new StringBuilder(); - for (Object owner : owners) { - sb.append('['); - sb.append(owner); - sb.append(']'); - } - String newVal = sb.toString(); - if (newVal.isEmpty()) { - ce.addEdit(new UndoableFieldChange(be, FieldName.MARKED_INTERNAL, - be.getField(FieldName.MARKED_INTERNAL).orElse(null), null)); - be.clearField(FieldName.MARKED_INTERNAL); - } else { - ce.addEdit(new UndoableFieldChange(be, FieldName.MARKED_INTERNAL, - be.getField(FieldName.MARKED_INTERNAL).orElse(null), newVal)); - be.setField(FieldName.MARKED_INTERNAL, newVal); - } - } - - public static int isMarked(BibEntry be) { - if (!be.hasField(FieldName.MARKED_INTERNAL)) { - return 0; - } - String s = be.getField(FieldName.MARKED_INTERNAL).get(); - if ("0".equals(s)) { - return 1; - } - int index = s.indexOf(Globals.prefs.getWrappedUsername()); - if (index >= 0) { - return 1; - } - - Matcher m = MARK_NUMBER_PATTERN.matcher(s); - if (m.find()) { - try { - return Integer.parseInt(m.group(1)); - } catch (NumberFormatException ex) { - return 1; - } - } else { - return 0; - } - - } - - public static boolean shouldMarkEntries() { - return Globals.prefs.getBoolean(JabRefPreferences.MARK_IMPORTED_ENTRIES); - } -} diff --git a/src/main/java/org/jabref/gui/IconTheme.java b/src/main/java/org/jabref/gui/IconTheme.java index 61834e10096..7c1526701de 100644 --- a/src/main/java/org/jabref/gui/IconTheme.java +++ b/src/main/java/org/jabref/gui/IconTheme.java @@ -207,9 +207,7 @@ public enum JabRefIcons implements JabRefIcon { COMMENT(MaterialDesignIcon.COMMENT), REDO(MaterialDesignIcon.REDO), UNDO(MaterialDesignIcon.UNDO), - MARK_ENTRIES(MaterialDesignIcon.BOOKMARK), MARKER(MaterialDesignIcon.MARKER), - UNMARK_ENTRIES(MaterialDesignIcon.BOOKMARK_OUTLINE), REFRESH(MaterialDesignIcon.REFRESH), DELETE_ENTRY(MaterialDesignIcon.DELETE), SEARCH(MaterialDesignIcon.MAGNIFY), @@ -296,12 +294,11 @@ public enum JabRefIcons implements JabRefIcon { BLOG(MaterialDesignIcon.RSS), /* css: rss */ GLOBAL_SEARCH(MaterialDesignIcon.EARTH), /* css: earth */ DATE_PICKER(MaterialDesignIcon.CALENDAR), /* css: calendar */ - DEFAULT_GROUP_ICON(MaterialDesignIcon.LABEL_OUTLINE), /* css: label-outline */ + DEFAULT_GROUP_ICON_COLORED(MaterialDesignIcon.CHECKBOX_BLANK_CIRCLE), + DEFAULT_GROUP_ICON(MaterialDesignIcon.LABEL_OUTLINE), ALL_ENTRIES_GROUP_ICON(DefaultGroupsFactory.ALL_ENTRIES_GROUP_DEFAULT_ICON), IMPORT_EXPORT(MaterialDesignIcon.SWAP_VERTICAL), - CLOSE_JABREF(MaterialDesignIcon.GLASSDOOR), - // STILL MISSING: - GROUP_REGULAR(Color.RED, MaterialDesignIcon.SYNC); + CLOSE_JABREF(MaterialDesignIcon.GLASSDOOR); private final JabRefIcon icon; @@ -337,6 +334,11 @@ public JabRefIcon disabled() { return icon.disabled(); } + @Override + public JabRefIcon withColor(javafx.scene.paint.Color color) { + return icon.withColor(color); + } + private class InternalFileIcon implements JabRefIcon { private final ImageIcon imageIcon; @@ -364,6 +366,11 @@ public Node getGraphicNode() { public JabRefIcon disabled() { throw new NotImplementedException("Cannot create disabled version of a file-based icon"); } + + @Override + public JabRefIcon withColor(javafx.scene.paint.Color color) { + throw new NotImplementedException("Cannot create colored version of a file-based icon"); + } } public Button asButton() { diff --git a/src/main/java/org/jabref/gui/InternalMaterialDesignIcon.java b/src/main/java/org/jabref/gui/InternalMaterialDesignIcon.java index 837d4503e52..836957a6da0 100644 --- a/src/main/java/org/jabref/gui/InternalMaterialDesignIcon.java +++ b/src/main/java/org/jabref/gui/InternalMaterialDesignIcon.java @@ -71,6 +71,11 @@ public JabRefIcon disabled() { return new InternalMaterialDesignIcon(ColorUtil.toFX(IconTheme.DEFAULT_DISABLED_COLOR), icons); } + @Override + public JabRefIcon withColor(Color color) { + return new InternalMaterialDesignIcon(color, icons); + } + public String getCode() { return this.unicode; } diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index a67d16f978b..709b695e075 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -169,13 +169,6 @@ public class JabRefFrame extends BorderPane implements OutputPrinter { // Note: GeneralAction's constructor automatically gets translations // for the name and message strings. - private final AbstractAction mark = new GeneralAction(Actions.MARK_ENTRIES, Localization.menuTitle("Mark entries"), - Localization.lang("Mark entries"), Globals.getKeyPrefs().getKey(KeyBinding.MARK_ENTRIES), IconTheme.JabRefIcons.MARK_ENTRIES.getIcon()); - private final JMenu markSpecific = JabRefFrame.subMenu(Localization.menuTitle("Mark specific color")); - private final AbstractAction unmark = new GeneralAction(Actions.UNMARK_ENTRIES, - Localization.menuTitle("Unmark entries"), Localization.lang("Unmark entries"), - Globals.getKeyPrefs().getKey(KeyBinding.UNMARK_ENTRIES), IconTheme.JabRefIcons.UNMARK_ENTRIES.getIcon()); - private final AbstractAction unmarkAll = new GeneralAction(Actions.UNMARK_ALL, Localization.menuTitle("Unmark all")); private final AbstractAction toggleRelevance = new GeneralAction( new SpecialFieldValueViewModel(SpecialField.RELEVANCE.getValues().get(0)).getCommand(), new SpecialFieldValueViewModel(SpecialField.RELEVANCE.getValues().get(0)).getMenuString(), @@ -852,16 +845,7 @@ private MenuBar createMenu() { new SeparatorMenuItem() ); - /* - edit.add(mark); - for (int i = 0; i < EntryMarker.MAX_MARKING_LEVEL; i++) { - markSpecific.add(new MarkEntriesAction(this, i).getMenuItem()); - } - edit.add(markSpecific); - edit.add(unmark); - edit.add(unmarkAll); - edit.addSeparator(); - */ + /* TODO if (Globals.prefs.getBoolean(JabRefPreferences.SPECIALFIELDSENABLED)) { boolean menuitem = false; diff --git a/src/main/java/org/jabref/gui/JabRefIcon.java b/src/main/java/org/jabref/gui/JabRefIcon.java index 08d4fc56e48..f1353bdbbd6 100644 --- a/src/main/java/org/jabref/gui/JabRefIcon.java +++ b/src/main/java/org/jabref/gui/JabRefIcon.java @@ -3,6 +3,7 @@ import javax.swing.Icon; import javafx.scene.Node; +import javafx.scene.paint.Color; public interface JabRefIcon { Icon getIcon(); @@ -12,4 +13,6 @@ public interface JabRefIcon { Node getGraphicNode(); JabRefIcon disabled(); + + JabRefIcon withColor(Color color); } diff --git a/src/main/java/org/jabref/gui/actions/Actions.java b/src/main/java/org/jabref/gui/actions/Actions.java index 4fff5e60abe..628bd9f16fe 100644 --- a/src/main/java/org/jabref/gui/actions/Actions.java +++ b/src/main/java/org/jabref/gui/actions/Actions.java @@ -31,7 +31,6 @@ public enum Actions { EXPORT_TO_CLIPBOARD, MAKE_KEY, MANAGE_SELECTORS, - MARK_ENTRIES, MERGE_DATABASE, MERGE_ENTRIES, MERGE_WITH_FETCHED_ENTRY, @@ -59,8 +58,6 @@ public enum Actions { TOGGLE_PREVIEW, UNABBREVIATE, UNDO, - UNMARK_ALL, - UNMARK_ENTRIES, WRITE_XMP, PRINT_PREVIEW, togglePrinted, diff --git a/src/main/java/org/jabref/gui/groups/GroupMatcher.java b/src/main/java/org/jabref/gui/groups/GroupMatcher.java deleted file mode 100644 index 426a5f2bbf7..00000000000 --- a/src/main/java/org/jabref/gui/groups/GroupMatcher.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.jabref.gui.groups; - -import org.jabref.model.entry.BibEntry; - -import ca.odell.glazedlists.matchers.Matcher; - -/** - * Matcher for filtering or sorting the table according to whether entries - * are tagged as group matches. - */ -public class GroupMatcher implements Matcher { - - public static final GroupMatcher INSTANCE = new GroupMatcher(); - - @Override - public boolean matches(BibEntry entry) { - return entry.isGroupHit(); - } -} diff --git a/src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java b/src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java index 5afa8400a9e..6aae6aa51fa 100644 --- a/src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java @@ -182,13 +182,22 @@ public int hashCode() { public JabRefIcon getIcon() { Optional iconName = groupNode.getGroup().getIconName(); return iconName.flatMap(this::parseIcon) - .orElse(IconTheme.JabRefIcons.DEFAULT_GROUP_ICON); + .orElseGet(this::createDefaultIcon); + } + + private JabRefIcon createDefaultIcon() { + Optional color = groupNode.getGroup().getColor(); + if (color.isPresent()) { + return IconTheme.JabRefIcons.DEFAULT_GROUP_ICON_COLORED.withColor(color.get()); + } else { + return IconTheme.JabRefIcons.DEFAULT_GROUP_ICON_COLORED.withColor(Color.web("#8a8a8a")); + } } private Optional parseIcon(String iconCode) { return Enums.getIfPresent(MaterialDesignIcon.class, iconCode.toUpperCase(Locale.ENGLISH)) - .toJavaUtil() - .map(icon -> new InternalMaterialDesignIcon(getColor(), icon)); + .toJavaUtil() + .map(icon -> new InternalMaterialDesignIcon(getColor(), icon)); } public ObservableList getChildren() { diff --git a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java index 3f316ba5de0..e4425f8e171 100644 --- a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java @@ -56,7 +56,6 @@ import org.jabref.gui.BasePanelPreferences; import org.jabref.gui.DuplicateResolverDialog; import org.jabref.gui.DuplicateResolverDialog.DuplicateResolverResult; -import org.jabref.gui.EntryMarker; import org.jabref.gui.GUIGlobals; import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefDialog; @@ -809,19 +808,6 @@ private void addSelectedEntries(NamedCompound ce, final List selected) // Set owner/timestamp if options are enabled: UpdateField.setAutomaticFields(selected, Globals.prefs.getUpdateFieldPreferences()); - // Mark entries if we should - if (EntryMarker.shouldMarkEntries()) { - for (BibEntry entry : selected) { - EntryMarker.markEntry(entry, EntryMarker.IMPORT_MARK_LEVEL, false, new NamedCompound("")); - } - } - // Check if we should unmark entries before adding the new ones: - if (Globals.prefs.getBoolean(JabRefPreferences.UNMARK_ALL_ENTRIES_BEFORE_IMPORTING)) { - for (BibEntry entry : panel.getDatabase().getEntries()) { - EntryMarker.unmarkEntry(entry, true, panel.getDatabase(), ce); - } - } - for (BibEntry entry : selected) { // Remove settings to group/search hit status: entry.setSearchHit(false); diff --git a/src/main/java/org/jabref/gui/importer/ImportMenuItem.java b/src/main/java/org/jabref/gui/importer/ImportMenuItem.java index 1baeca12bf8..e1ded89acd3 100644 --- a/src/main/java/org/jabref/gui/importer/ImportMenuItem.java +++ b/src/main/java/org/jabref/gui/importer/ImportMenuItem.java @@ -16,9 +16,7 @@ import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; -import org.jabref.gui.EntryMarker; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.gui.worker.AbstractWorker; @@ -232,11 +230,7 @@ private ParserResult mergeImportResults(List> getSpecialField(Spe public ObservableValue> getLinkedFiles() { return EasyBind.map(getField(FieldName.FILE), FileFieldParser::parse); } + + public ObservableValue> getMatchedGroups(BibDatabaseContext database) { + SimpleObjectProperty> matchedGroups = new SimpleObjectProperty<>(Collections.emptyList()); + + Optional root = database.getMetaData() + .getGroups(); + if (root.isPresent()) { + List groups = root.get().getMatchingGroups(entry) + .stream() + .map(GroupTreeNode::getGroup) + .collect(Collectors.toList()); + groups.remove(root.get().getGroup()); + matchedGroups.setValue(groups); + } + + return matchedGroups; + } } diff --git a/src/main/java/org/jabref/gui/maintable/MainTable.java b/src/main/java/org/jabref/gui/maintable/MainTable.java index 1df86ee0b3c..def0218eb94 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTable.java +++ b/src/main/java/org/jabref/gui/maintable/MainTable.java @@ -2,7 +2,6 @@ import java.awt.Color; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -23,7 +22,6 @@ import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.ClipBoardManager; -import org.jabref.gui.EntryMarker; import org.jabref.gui.JabRefFrame; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.keyboard.KeyBinding; @@ -56,15 +54,11 @@ public class MainTable extends TableView { private static GeneralRenderer grayedOutRenderer; private static GeneralRenderer veryGrayedOutRenderer; - private static List markedRenderers; - private static IncompleteRenderer incRenderer; private static CompleteRenderer compRenderer; private static CompleteRenderer grayedOutNumberRenderer; private static CompleteRenderer veryGrayedOutNumberRenderer; - private static List markedNumberRenderers; - private final BasePanel panel; //private final boolean tableColorCodes; //private final boolean tableResolvedColorCodes; @@ -348,14 +342,7 @@ else if (score == -1) { else if (column == 0) { if (isComplete(row)) { MainTable.compRenderer.setNumber(row); - int marking = isMarked(row); - if (marking > 0) { - marking = Math.min(marking, EntryMarker.MARK_COLOR_LEVELS); - renderer = MainTable.markedNumberRenderers.get(marking - 1); - MainTable.markedNumberRenderers.get(marking - 1).setNumber(row); - } else { - renderer = MainTable.compRenderer; - } + renderer = MainTable.compRenderer; } else { // Return a renderer with red background if the entry is incomplete. MainTable.incRenderer.setNumber(row); @@ -372,13 +359,6 @@ else if (column == 0) { } } - // For MARKED feature: - int marking = isMarked(row); - if ((column != 0) && (marking > 0)) { - marking = Math.min(marking, EntryMarker.MARK_COLOR_LEVELS); - renderer = MainTable.markedRenderers.get(marking - 1); - } - return renderer; } */ @@ -537,15 +517,6 @@ private boolean isComplete(int row) { return true; } - private int isMarked(int row) { - Optional bibEntry = getBibEntry(row); - - if (bibEntry.isPresent()) { - return EntryMarker.isMarked(bibEntry.get()); - } - return 0; - } - private Optional getBibEntry(int row) { try { return Optional.of(model.getEntriesFiltered().get(row).getEntry()); @@ -589,16 +560,6 @@ public static void updateRenderers() { MainTable.veryGrayedOutRenderer = new GeneralRenderer(Globals.prefs.getColor(JabRefPreferences.VERY_GRAYED_OUT_BACKGROUND), Globals.prefs.getColor(JabRefPreferences.VERY_GRAYED_OUT_TEXT), MainTable.mixColors(Globals.prefs.getColor(JabRefPreferences.VERY_GRAYED_OUT_BACKGROUND), sel)); - - MainTable.markedRenderers = new ArrayList<>(EntryMarker.MARK_COLOR_LEVELS); - MainTable.markedNumberRenderers = new ArrayList<>(EntryMarker.MARK_COLOR_LEVELS); - for (int i = 0; i < EntryMarker.MARK_COLOR_LEVELS; i++) { - Color c = Globals.prefs.getColor(JabRefPreferences.MARKED_ENTRY_BACKGROUND + i); - MainTable.markedRenderers.add(new GeneralRenderer(c, Globals.prefs.getColor(JabRefPreferences.TABLE_TEXT), - MainTable.mixColors(Globals.prefs.getColor(JabRefPreferences.MARKED_ENTRY_BACKGROUND + i), sel))); - MainTable.markedNumberRenderers.add(new CompleteRenderer(c)); - } - } private static Color mixColors(Color one, Color two) { diff --git a/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java b/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java index 71ae07ed67d..603baac8352 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java @@ -13,7 +13,11 @@ import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.control.TableColumn; +import javafx.scene.control.Tooltip; import javafx.scene.input.MouseButton; +import javafx.scene.layout.BorderPane; +import javafx.scene.paint.Color; +import javafx.scene.shape.Rectangle; import org.jabref.Globals; import org.jabref.gui.DialogService; @@ -27,19 +31,23 @@ import org.jabref.gui.specialfields.SpecialFieldViewModel; import org.jabref.gui.util.OptionalValueTableCellFactory; import org.jabref.gui.util.ValueTableCellFactory; +import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; import org.jabref.model.entry.LinkedFile; import org.jabref.model.entry.specialfields.SpecialField; import org.jabref.model.entry.specialfields.SpecialFieldValue; +import org.jabref.model.groups.AbstractGroup; +import org.jabref.model.util.OptionalUtil; import org.controlsfx.control.Rating; import org.fxmisc.easybind.EasyBind; class MainTableColumnFactory { - private static final String STYLE_ICON = "column-icon"; + private static final String ICON_COLUMN = "column-icon"; + private static final String GROUP_COLUMN = "column-groups"; private final ColumnPreferences preferences; private final ExternalFileTypes externalFileTypes; @@ -60,6 +68,8 @@ public MainTableColumnFactory(BibDatabaseContext database, ColumnPreferences pre public List> createColumns() { List> columns = new ArrayList<>(); + columns.add(createGroupColumn()); + // Add column for linked files if (preferences.showFileColumn()) { columns.add(createFileColumn()); @@ -93,6 +103,38 @@ public MainTableColumnFactory(BibDatabaseContext database, ColumnPreferences pre return columns; } + private TableColumn createGroupColumn() { + TableColumn> column = new TableColumn<>(); + column.getStyleClass().add(GROUP_COLUMN); + setExactWidth(column, 20); + column.setCellValueFactory(cellData -> cellData.getValue().getMatchedGroups(database)); + new ValueTableCellFactory>() + .withGraphic(this::createGroupColorRegion) + .install(column); + return column; + } + + private Node createGroupColorRegion(BibEntryTableViewModel entry, List matchedGroups) { + Rectangle rectangle = new Rectangle(); + rectangle.setWidth(3); + rectangle.setHeight(20); + Color color = matchedGroups.stream() + .flatMap(group -> OptionalUtil.toStream(group.getColor())) + .findFirst() + .orElse(Color.TRANSPARENT); + rectangle.setFill(color); + + String matchedGroupsString = matchedGroups.stream() + .map(AbstractGroup::getName) + .collect(Collectors.joining(", ")); + Tooltip tooltip = new Tooltip(Localization.lang("Entry is contained in the following groups:") + "\n" + matchedGroupsString); + Tooltip.install(rectangle, tooltip); + + BorderPane container = new BorderPane(); + container.setLeft(rectangle); + return container; + } + private List> createNormalColumns() { List> columns = new ArrayList<>(); @@ -115,7 +157,7 @@ private TableColumn TableColumn> column = new TableColumn<>(); SpecialFieldViewModel specialFieldViewModel = new SpecialFieldViewModel(specialField, undoManager); column.setGraphic(specialFieldViewModel.getIcon().getGraphicNode()); - column.getStyleClass().add(STYLE_ICON); + column.getStyleClass().add(ICON_COLUMN); if (specialField == SpecialField.RANKING) { setExactWidth(column, GUIGlobals.WIDTH_ICON_COL_RANKING); new OptionalValueTableCellFactory() @@ -177,16 +219,16 @@ private Node createSpecialFieldIcon(Optional fieldVa }); } - private void setExactWidth(TableColumn column, int widthIconCol) { - column.setMinWidth(widthIconCol); - column.setPrefWidth(widthIconCol); - column.setMaxWidth(widthIconCol); + private void setExactWidth(TableColumn column, int width) { + column.setMinWidth(width); + column.setPrefWidth(width); + column.setMaxWidth(width); } private TableColumn> createFileColumn() { TableColumn> column = new TableColumn<>(); column.setGraphic(IconTheme.JabRefIcons.FILE.getGraphicNode()); - column.getStyleClass().add(STYLE_ICON); + column.getStyleClass().add(ICON_COLUMN); setExactWidth(column, GUIGlobals.WIDTH_ICON_COL); column.setCellValueFactory(cellData -> cellData.getValue().getLinkedFiles()); new ValueTableCellFactory>() @@ -227,7 +269,7 @@ private ContextMenu createFileMenu(BibEntryTableViewModel entry, List createIconColumn(JabRefIcon icon, String firstField, String secondField) { TableColumn column = new TableColumn<>(); column.setGraphic(icon.getGraphicNode()); - column.getStyleClass().add(STYLE_ICON); + column.getStyleClass().add(ICON_COLUMN); setExactWidth(column, GUIGlobals.WIDTH_ICON_COL); column.setCellValueFactory(cellData -> EasyBind.monadic(cellData.getValue().getField(firstField)).orElse(cellData.getValue().getField(secondField))); new ValueTableCellFactory() @@ -239,7 +281,7 @@ private TableColumn createIconColumn(JabRefIcon private TableColumn createIconColumn(JabRefIcon icon, String field) { TableColumn column = new TableColumn<>(); column.setGraphic(icon.getGraphicNode()); - column.getStyleClass().add(STYLE_ICON); + column.getStyleClass().add(ICON_COLUMN); setExactWidth(column, GUIGlobals.WIDTH_ICON_COL); column.setCellValueFactory(cellData -> cellData.getValue().getField(field)); new ValueTableCellFactory() @@ -259,7 +301,7 @@ private TableColumn> createExtraFileCol externalFileTypes.getExternalFileTypeByName(externalFileTypeName) .map(ExternalFileType::getIcon).orElse(IconTheme.JabRefIcons.FILE) .getGraphicNode()); - column.getStyleClass().add(STYLE_ICON); + column.getStyleClass().add(ICON_COLUMN); setExactWidth(column, GUIGlobals.WIDTH_ICON_COL); column.setCellValueFactory(cellData -> cellData.getValue().getLinkedFiles()); new ValueTableCellFactory>() diff --git a/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java b/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java index c00d5e4b4cf..f5c00bfe48a 100644 --- a/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java +++ b/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java @@ -61,13 +61,11 @@ import org.jabref.Globals; import org.jabref.gui.ClipBoardManager; import org.jabref.gui.DialogService; -import org.jabref.gui.EntryMarker; import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefDialog; import org.jabref.gui.JabRefFrame; import org.jabref.gui.OSXCompatibleToolbar; import org.jabref.gui.keyboard.KeyBinding; -import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.gui.util.component.OverlayPanel; @@ -478,15 +476,8 @@ private boolean parseWithFreeCiteAndAddEntries() { return false; } else { UpdateField.setAutomaticFields(importedEntries, false, false, Globals.prefs.getUpdateFieldPreferences()); - boolean markEntries = EntryMarker.shouldMarkEntries(); - for (BibEntry e : importedEntries) { - if (markEntries) { - EntryMarker.markEntry(entry, EntryMarker.IMPORT_MARK_LEVEL, false, new NamedCompound("")); - } - - frame.getCurrentBasePanel().insertEntry(e); - } + importedEntries.forEach(entry -> frame.getCurrentBasePanel().insertEntry(entry)); return true; } } diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index cd9046ea57b..3764acf1ca7 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -43,8 +43,6 @@ class GeneralTab extends JPanel implements PrefsTab { private final JCheckBox useTimeStamp; private final JCheckBox updateTimeStamp; private final JCheckBox overwriteTimeStamp; - private final JCheckBox markImportedEntries; - private final JCheckBox unmarkAllEntriesBeforeImporting; private final JTextField defOwnerField; private final JTextField timeStampFormat; @@ -87,8 +85,6 @@ public GeneralTab(JabRefPreferences prefs) { enforceLegalKeys = new JCheckBox(Localization.lang("Enforce legal characters in BibTeX keys")); confirmDelete = new JCheckBox(Localization.lang("Show confirmation dialog when deleting entries")); - markImportedEntries = new JCheckBox(Localization.lang("Mark entries imported into an existing library")); - unmarkAllEntriesBeforeImporting = new JCheckBox(Localization.lang("Unmark all entries before importing new entries into an existing library")); defOwnerField = new JTextField(); timeStampFormat = new JTextField(); timeStampField = new JTextField(); @@ -138,10 +134,6 @@ public GeneralTab(JabRefPreferences prefs) { builder.append(updateTimeStamp, 11); builder.nextLine(); - builder.append(markImportedEntries, 13); - builder.nextLine(); - builder.append(unmarkAllEntriesBeforeImporting, 13); - builder.nextLine(); builder.append(shouldCollectTelemetry, 13); builder.nextLine(); JLabel lab; @@ -180,8 +172,6 @@ public void setValues() { timeStampFormat.setText(prefs.get(JabRefPreferences.TIME_STAMP_FORMAT)); timeStampField.setText(prefs.get(JabRefPreferences.TIME_STAMP_FIELD)); inspectionWarnDupli.setSelected(prefs.getBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION)); - markImportedEntries.setSelected(prefs.getBoolean(JabRefPreferences.MARK_IMPORTED_ENTRIES)); - unmarkAllEntriesBeforeImporting.setSelected(prefs.getBoolean(JabRefPreferences.UNMARK_ALL_ENTRIES_BEFORE_IMPORTING)); if (Globals.prefs.getBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE)) { biblatexMode.setSelectedItem(BibDatabaseMode.BIBLATEX); } else { @@ -229,8 +219,6 @@ public void storeSettings() { // Update name of the time stamp field based on preferences InternalBibtexFields.updateTimeStampField(Globals.prefs.get(JabRefPreferences.TIME_STAMP_FIELD)); prefs.setDefaultEncoding((Charset) encodings.getSelectedItem()); - prefs.putBoolean(JabRefPreferences.MARK_IMPORTED_ENTRIES, markImportedEntries.isSelected()); - prefs.putBoolean(JabRefPreferences.UNMARK_ALL_ENTRIES_BEFORE_IMPORTING, unmarkAllEntriesBeforeImporting.isSelected()); prefs.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, biblatexMode.getSelectedItem() == BibDatabaseMode.BIBLATEX); if (!LANGUAGES.get(language.getSelectedItem()).equals(prefs.get(JabRefPreferences.LANGUAGE))) { diff --git a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java index 0ae9570d1c9..acbee5be563 100644 --- a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java @@ -32,7 +32,6 @@ class TablePrefsTab extends JPanel implements PrefsTab { private final JCheckBox priDesc; private final JCheckBox secDesc; private final JCheckBox terDesc; - private final JCheckBox floatMarked; private final JRadioButton namesAsIs; private final JRadioButton namesFf; @@ -86,8 +85,6 @@ public TablePrefsTab(JabRefPreferences prefs) { abbrNames = new JRadioButton(Localization.lang("Abbreviate names")); lastNamesOnly = new JRadioButton(Localization.lang("Show last names only")); - floatMarked = new JCheckBox(Localization.lang("Float marked entries")); - priField = new JTextField(10); secField = new JTextField(10); terField = new JTextField(10); @@ -181,9 +178,6 @@ public TablePrefsTab(JabRefPreferences prefs) { builder.append(builder2.getPanel()); builder.nextLine(); builder.append(pan); - builder.append(floatMarked); - builder.nextLine(); - builder.append(pan); builder2 = new DefaultFormBuilder(new FormLayout("left:pref, 8dlu, fill:pref", "")); builder2.append(Localization.lang("Sort the following fields as numeric fields") + ':'); builder2.append(numericFields); @@ -236,8 +230,6 @@ public void setValues() { secDesc.setSelected(prefs.getBoolean(JabRefPreferences.TABLE_SECONDARY_SORT_DESCENDING)); terDesc.setSelected(prefs.getBoolean(JabRefPreferences.TABLE_TERTIARY_SORT_DESCENDING)); - floatMarked.setSelected(prefs.getBoolean(JabRefPreferences.FLOAT_MARKED_ENTRIES)); - abbrNames.setEnabled(!namesNatbib.isSelected()); lastNamesOnly.setEnabled(!namesNatbib.isSelected()); noAbbrNames.setEnabled(!namesNatbib.isSelected()); @@ -273,9 +265,6 @@ public void storeSettings() { prefs.put(JabRefPreferences.TABLE_SECONDARY_SORT_FIELD, secField.getText().toLowerCase(Locale.ROOT).trim()); prefs.put(JabRefPreferences.TABLE_TERTIARY_SORT_FIELD, terField.getText().toLowerCase(Locale.ROOT).trim()); - prefs.putBoolean(JabRefPreferences.FLOAT_MARKED_ENTRIES, floatMarked.isSelected()); - // updatefont - String oldVal = prefs.get(JabRefPreferences.NUMERIC_FIELDS); String newVal = numericFields.getText().trim(); if (newVal.isEmpty()) { diff --git a/src/main/java/org/jabref/gui/util/comparator/IsMarkedComparator.java b/src/main/java/org/jabref/gui/util/comparator/IsMarkedComparator.java deleted file mode 100644 index de25fdf905b..00000000000 --- a/src/main/java/org/jabref/gui/util/comparator/IsMarkedComparator.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.jabref.gui.util.comparator; - -import java.util.Comparator; - -import org.jabref.gui.EntryMarker; -import org.jabref.model.entry.BibEntry; - -public class IsMarkedComparator implements Comparator { - - public static Comparator INSTANCE = new IsMarkedComparator(); - - @Override - public int compare(BibEntry e1, BibEntry e2) { - return -EntryMarker.isMarked(e1) + EntryMarker.isMarked(e2); - } - -} diff --git a/src/main/java/org/jabref/gui/worker/MarkEntriesAction.java b/src/main/java/org/jabref/gui/worker/MarkEntriesAction.java deleted file mode 100644 index 1fe16aace01..00000000000 --- a/src/main/java/org/jabref/gui/worker/MarkEntriesAction.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.jabref.gui.worker; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.List; - -import javax.swing.JMenuItem; - -import org.jabref.Globals; -import org.jabref.gui.BasePanel; -import org.jabref.gui.EntryMarker; -import org.jabref.gui.JabRefFrame; -import org.jabref.gui.undo.NamedCompound; -import org.jabref.logic.l10n.Localization; -import org.jabref.model.entry.BibEntry; -import org.jabref.preferences.JabRefPreferences; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MarkEntriesAction extends AbstractWorker implements ActionListener { - - private static final Logger LOGGER = LoggerFactory.getLogger(MarkEntriesAction.class); - private final JabRefFrame frame; - private final int level; - private final JMenuItem menuItem; - - private int besLength; - - public MarkEntriesAction(JabRefFrame frame, int level) { - this.frame = frame; - this.level = level; - - //menuItem = new JMenuItem(Globals.menuTitle("Mark entries").replace("&","")); - menuItem = new JMenuItem(Localization.lang("Level") + " " + level + " "); - menuItem.setMnemonic(String.valueOf(level + 1).charAt(0)); - menuItem.setBackground(Globals.prefs.getColor(JabRefPreferences.MARKED_ENTRY_BACKGROUND + this.level)); - menuItem.setOpaque(true); - menuItem.addActionListener(this); - } - - public JMenuItem getMenuItem() { - return menuItem; - } - - @Override - public void actionPerformed(ActionEvent actionEvent) { - try { - this.init(); - getWorker().run(); - getCallBack().update(); - } catch (Throwable t) { - LOGGER.warn("Problem marking entries", t); - } - } - - @Override - public void run() { - BasePanel panel = frame.getCurrentBasePanel(); - if (panel != null) { - List bes = panel.getSelectedEntries(); - - // used at update() to determine output string - besLength = bes.size(); - - if (!bes.isEmpty()) { - NamedCompound ce = new NamedCompound(Localization.lang("Mark entries")); - for (BibEntry be : bes) { - EntryMarker.markEntry(be, level + 1, false, ce); - } - ce.end(); - panel.getUndoManager().addEdit(ce); - } - } - } - - @Override - public void update() { - String outputStr; - switch (besLength) { - case 0: - outputStr = Localization.lang("This operation requires one or more entries to be selected."); - break; - case 1: - frame.getCurrentBasePanel().markBaseChanged(); - outputStr = Localization.lang("Marked selected entry"); - break; - default: - frame.getCurrentBasePanel().markBaseChanged(); - outputStr = Localization.lang("Marked all %0 selected entries", Integer.toString(besLength)); - break; - } - frame.output(outputStr); - } -} diff --git a/src/main/java/org/jabref/logic/importer/OpenDatabase.java b/src/main/java/org/jabref/logic/importer/OpenDatabase.java index 6b5b451eaca..f8c04f8d870 100644 --- a/src/main/java/org/jabref/logic/importer/OpenDatabase.java +++ b/src/main/java/org/jabref/logic/importer/OpenDatabase.java @@ -2,7 +2,7 @@ import java.io.File; import java.io.IOException; -import java.util.Collections; +import java.util.Arrays; import java.util.List; import org.jabref.logic.importer.fileformat.BibtexImporter; @@ -10,6 +10,7 @@ import org.jabref.logic.specialfields.SpecialFieldsUtils; import org.jabref.logic.util.io.FileBasedLock; import org.jabref.migrations.ConvertLegacyExplicitGroups; +import org.jabref.migrations.ConvertMarkingToGroups; import org.jabref.migrations.PostOpenMigration; import org.jabref.model.entry.BibEntry; import org.jabref.model.util.FileUpdateMonitor; @@ -86,7 +87,10 @@ public static ParserResult loadDatabase(File fileToOpen, ImportFormatPreferences } private static void performLoadDatabaseMigrations(ParserResult parserResult) { - List postOpenMigrations = Collections.singletonList(new ConvertLegacyExplicitGroups()); + List postOpenMigrations = Arrays.asList( + new ConvertLegacyExplicitGroups(), + new ConvertMarkingToGroups() + ); for (PostOpenMigration migration : postOpenMigrations) { migration.performMigration(parserResult); diff --git a/src/main/java/org/jabref/migrations/ConvertMarkingToGroups.java b/src/main/java/org/jabref/migrations/ConvertMarkingToGroups.java new file mode 100644 index 00000000000..aaf2b10a583 --- /dev/null +++ b/src/main/java/org/jabref/migrations/ConvertMarkingToGroups.java @@ -0,0 +1,92 @@ +package org.jabref.migrations; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javafx.collections.ObservableList; + +import org.jabref.logic.groups.DefaultGroupsFactory; +import org.jabref.logic.importer.ParserResult; +import org.jabref.logic.l10n.Localization; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FieldName; +import org.jabref.model.groups.ExplicitGroup; +import org.jabref.model.groups.GroupHierarchyType; +import org.jabref.model.groups.GroupTreeNode; + +import com.google.common.collect.Multimap; +import com.google.common.collect.MultimapBuilder; + +/** + * Converts legacy explicit groups, where the group contained a list of assigned entries, to the new format, + * where the entry stores a list of groups it belongs to. + */ +public class ConvertMarkingToGroups implements PostOpenMigration { + + private static final Pattern MARKING_PATTERN = Pattern.compile("\\[(.*):(\\d+)\\]"); + + @Override + public void performMigration(ParserResult parserResult) { + Objects.requireNonNull(parserResult); + + ObservableList entries = parserResult.getDatabase().getEntries(); + Multimap markings = getMarkingWithEntries(entries); + if (!markings.isEmpty()) { + GroupTreeNode markingRoot = GroupTreeNode.fromGroup( + new ExplicitGroup(Localization.lang("Markings"), GroupHierarchyType.INCLUDING, ',')); + + for (Map.Entry> marking : markings.asMap().entrySet()) { + String markingName = marking.getKey(); + Collection markingMatchedEntries = marking.getValue(); + + GroupTreeNode markingGroup = markingRoot.addSubgroup( + new ExplicitGroup(markingName, GroupHierarchyType.INCLUDING, ',')); + markingGroup.addEntriesToGroup(markingMatchedEntries); + } + + if (!parserResult.getMetaData().getGroups().isPresent()) { + parserResult.getMetaData().setGroups(GroupTreeNode.fromGroup(DefaultGroupsFactory.getAllEntriesGroup())); + } + GroupTreeNode root = parserResult.getMetaData().getGroups().get(); + root.addChild(markingRoot, 0); + parserResult.getMetaData().setGroups(root); + + clearMarkings(entries); + } + } + + /** + * Looks for markings (such as __markedentry = {[Nicolas:6]}) in the given list of entries. + */ + private Multimap getMarkingWithEntries(List entries) { + Multimap markings = MultimapBuilder.treeKeys().linkedListValues().build(); + + for (BibEntry entry : entries) { + Optional marking = entry.getField(FieldName.MARKED_INTERNAL); + if (!marking.isPresent()) { + continue; + } + + Matcher matcher = MARKING_PATTERN.matcher(marking.get()); + if (matcher.find()) { + String owner = matcher.group(1); + String number = matcher.group(2); + markings.put(owner + ":" + number, entry); + } else { + // Not in the expected format, so just add it to not loose information + markings.put(marking.get(), entry); + } + } + + return markings; + } + + private void clearMarkings(List entries) { + entries.forEach(entry -> entry.clearField(FieldName.MARKED_INTERNAL)); + } +} diff --git a/src/main/java/org/jabref/model/groups/GroupEntryChanger.java b/src/main/java/org/jabref/model/groups/GroupEntryChanger.java index fc8ff9c4a59..8bd75be26db 100644 --- a/src/main/java/org/jabref/model/groups/GroupEntryChanger.java +++ b/src/main/java/org/jabref/model/groups/GroupEntryChanger.java @@ -1,5 +1,6 @@ package org.jabref.model.groups; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -18,7 +19,7 @@ public interface GroupEntryChanger { * @return If this group or one or more entries was/were modified as a * result of this operation, a list of changes is returned. */ - List add(List entriesToAdd); + List add(Collection entriesToAdd); default List add(BibEntry entryToAdd) { return add(Collections.singletonList(entryToAdd)); diff --git a/src/main/java/org/jabref/model/groups/GroupTreeNode.java b/src/main/java/org/jabref/model/groups/GroupTreeNode.java index 0a3aec3e396..367b2ac1184 100644 --- a/src/main/java/org/jabref/model/groups/GroupTreeNode.java +++ b/src/main/java/org/jabref/model/groups/GroupTreeNode.java @@ -1,6 +1,7 @@ package org.jabref.model.groups; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -161,6 +162,16 @@ public List getContainingGroups(List entries, boolean r return groups; } + /** + * Determines all groups in the subtree starting at this node which contain the given entry. + */ + public List getMatchingGroups(BibEntry entry) { + return getMatchingGroups(Collections.singletonList(entry)); + } + + /** + * Determines all groups in the subtree starting at this node which contain at least one of the given entries. + */ public List getMatchingGroups(List entries) { List groups = new ArrayList<>(); @@ -286,7 +297,7 @@ public Optional getChildByPath(String pathToSource) { * If the group does not support explicit adding of entries (i.e., does not implement {@link GroupEntryChanger}), * then no action is performed. */ - public List addEntriesToGroup(List entries) { + public List addEntriesToGroup(Collection entries) { if (getGroup() instanceof GroupEntryChanger) { return ((GroupEntryChanger) getGroup()).add(entries); } else { diff --git a/src/main/java/org/jabref/model/groups/WordKeywordGroup.java b/src/main/java/org/jabref/model/groups/WordKeywordGroup.java index 7f13729b15a..46dcdf409ce 100644 --- a/src/main/java/org/jabref/model/groups/WordKeywordGroup.java +++ b/src/main/java/org/jabref/model/groups/WordKeywordGroup.java @@ -51,7 +51,7 @@ private static boolean containsCaseInsensitive(Set searchIn, String sear } @Override - public List add(List entriesToAdd) { + public List add(Collection entriesToAdd) { Objects.requireNonNull(entriesToAdd); List changes = new ArrayList<>(); diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 569f569941b..f8f918a41e3 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -222,7 +222,6 @@ public class JabRefPreferences implements PreferencesService { public static final String TABLE_TEXT = "tableText"; public static final String TABLE_OPT_FIELD_BACKGROUND = "tableOptFieldBackground"; public static final String TABLE_REQ_FIELD_BACKGROUND = "tableReqFieldBackground"; - public static final String MARKED_ENTRY_BACKGROUND = "markedEntryBackground"; public static final String TABLE_RESOLVED_FIELD_BACKGROUND = "tableResolvedFieldBackground"; public static final String TABLE_BACKGROUND = "tableBackground"; public static final String ICON_ENABLED_COLOR = "iconEnabledColor"; @@ -249,8 +248,6 @@ public class JabRefPreferences implements PreferencesService { public static final String OVERWRITE_TIME_STAMP = "overwriteTimeStamp"; public static final String WARN_ABOUT_DUPLICATES_IN_INSPECTION = "warnAboutDuplicatesInInspection"; - public static final String UNMARK_ALL_ENTRIES_BEFORE_IMPORTING = "unmarkAllEntriesBeforeImporting"; - public static final String MARK_IMPORTED_ENTRIES = "markImportedEntries"; public static final String GENERATE_KEYS_AFTER_INSPECTION = "generateKeysAfterInspection"; public static final String NON_WRAPPABLE_FIELDS = "nonWrappableFields"; public static final String RESOLVE_STRINGS_ALL_FIELDS = "resolveStringsAllFields"; @@ -278,7 +275,6 @@ public class JabRefPreferences implements PreferencesService { public static final String SHOW_FILE_LINKS_UPGRADE_WARNING = "showFileLinksUpgradeWarning"; public static final String SIDE_PANE_WIDTH = "sidePaneWidthFX"; public static final String LAST_USED_EXPORT = "lastUsedExport"; - public static final String FLOAT_MARKED_ENTRIES = "floatMarkedEntries"; public static final String CITE_COMMAND = "citeCommand"; public static final String GENERATE_KEYS_BEFORE_SAVING = "generateKeysBeforeSaving"; public static final String EMAIL_SUBJECT = "emailSubject"; @@ -425,7 +421,6 @@ public class JabRefPreferences implements PreferencesService { * HashMap that contains all preferences which are set by default */ public final Map defaults = new HashMap<>(); - public final String MARKING_WITH_NUMBER_PATTERN; // Object containing custom export formats: public final CustomExportList customExports; /** @@ -709,8 +704,6 @@ private JabRefPreferences() { defaults.put(RESOLVE_STRINGS_ALL_FIELDS, Boolean.FALSE); defaults.put(NON_WRAPPABLE_FIELDS, "pdf;ps;url;doi;file;isbn;issn"); defaults.put(GENERATE_KEYS_AFTER_INSPECTION, Boolean.TRUE); - defaults.put(MARK_IMPORTED_ENTRIES, Boolean.TRUE); - defaults.put(UNMARK_ALL_ENTRIES_BEFORE_IMPORTING, Boolean.TRUE); defaults.put(WARN_ABOUT_DUPLICATES_IN_INSPECTION, Boolean.TRUE); defaults.put(USE_TIME_STAMP, Boolean.FALSE); defaults.put(OVERWRITE_TIME_STAMP, Boolean.FALSE); @@ -729,7 +722,6 @@ private JabRefPreferences() { defaults.put(PERSONAL_JOURNAL_LIST, ""); defaults.put(EXTERNAL_JOURNAL_LISTS, ""); defaults.put(CITE_COMMAND, "\\cite"); // obsoleted by the app-specific ones (not any more?) - defaults.put(FLOAT_MARKED_ENTRIES, Boolean.TRUE); defaults.put(LAST_USED_EXPORT, ""); defaults.put(SIDE_PANE_WIDTH, 0.15); @@ -780,8 +772,6 @@ private JabRefPreferences() { customExports = new CustomExportList(new ExportComparator()); customImports = new CustomImportList(this); - MARKING_WITH_NUMBER_PATTERN = "\\[" + get(DEFAULT_OWNER).replaceAll("\\\\", "\\\\\\\\") + ":(\\d+)\\]"; - String defaultExpression = "**/.*[bibtexkey].*\\\\.[extension]"; defaults.put(AUTOLINK_REG_EXP_SEARCH_EXPRESSION_KEY, defaultExpression); defaults.put(AUTOLINK_USE_REG_EXP_SEARCH_KEY, Boolean.FALSE); diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 0c1e109c089..22ac6ea2d49 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2333,10 +2333,9 @@ Look\ up\ document\ identifier=Look up document identifier Next\ library=Next library Previous\ library=Previous library add\ group=add group +Entry\ is\ contained\ in\ the\ following\ groups\:=Entry is contained in the following groups\: Delete\ entries=Delete entries Keep\ entries=Keep entries Keep\ entry=Keep entry - - Ignore\ backup=Ignore backup -Restore\ from\ backup=Restore from backup \ No newline at end of file +Restore\ from\ backup=Restore from backup diff --git a/src/test/java/org/jabref/gui/keyboard/KeyBindingsDialogViewModelTest.java b/src/test/java/org/jabref/gui/keyboard/KeyBindingsDialogViewModelTest.java index 23f8d542bdc..7b423d42ae0 100644 --- a/src/test/java/org/jabref/gui/keyboard/KeyBindingsDialogViewModelTest.java +++ b/src/test/java/org/jabref/gui/keyboard/KeyBindingsDialogViewModelTest.java @@ -45,7 +45,7 @@ public void testInvalidKeyBindingIsNotSaved() { assertFalse(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.COPY, shortcutKeyEvent)); model.setNewBindingForCurrent(shortcutKeyEvent); KeyCombination combination = KeyCombination.keyCombination(keyBindingRepository.get(KeyBinding.COPY).get()); - assertFalse(keyBindingRepository.checkKeyCombinationEquality(combination, shortcutKeyEvent)); + assertFalse(KeyBindingRepository.checkKeyCombinationEquality(combination, shortcutKeyEvent)); model.saveKeyBindings(); assertFalse(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.COPY, shortcutKeyEvent)); } @@ -63,7 +63,7 @@ public void testSpecialKeysValidKeyBindingIsSaved() { KeyCombination combination = KeyCombination .keyCombination(keyBindingRepository.get(KeyBinding.IMPORT_INTO_NEW_DATABASE).get()); - assertTrue(keyBindingRepository.checkKeyCombinationEquality(combination, shortcutKeyEvent)); + assertTrue(KeyBindingRepository.checkKeyCombinationEquality(combination, shortcutKeyEvent)); model.saveKeyBindings(); @@ -90,9 +90,9 @@ public void testRandomNewKeyKeyBindingInRepository() { KeyCombination combination = KeyCombination.keyCombination(keyBindingRepository.get(KeyBinding.CLEANUP).get()); - assertTrue(keyBindingRepository.checkKeyCombinationEquality(combination, shortcutKeyEvent)); + assertTrue(KeyBindingRepository.checkKeyCombinationEquality(combination, shortcutKeyEvent)); - assertFalse(keyBindingRepository.checkKeyCombinationEquality(KeyCombination.valueOf(KeyBinding.CLEANUP.getDefaultKeyBinding()), shortcutKeyEvent)); + assertFalse(KeyBindingRepository.checkKeyCombinationEquality(KeyCombination.valueOf(KeyBinding.CLEANUP.getDefaultKeyBinding()), shortcutKeyEvent)); } @Test @@ -111,16 +111,16 @@ public void testSaveNewKeyBindingsToPreferences() { @Test public void testSaveNewSpecialKeysKeyBindingsToPreferences() { - setKeyBindingViewModel(KeyBinding.UNMARK_ENTRIES); + setKeyBindingViewModel(KeyBinding.ABBREVIATE); KeyEvent shortcutKeyEvent = new KeyEvent(KeyEvent.KEY_PRESSED, "F1", "F1", KeyCode.F1, true, false, false, false); - assertFalse(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.UNMARK_ENTRIES, shortcutKeyEvent)); + assertFalse(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.ABBREVIATE, shortcutKeyEvent)); model.setNewBindingForCurrent(shortcutKeyEvent); model.saveKeyBindings(); - assertTrue(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.UNMARK_ENTRIES, shortcutKeyEvent)); + assertTrue(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.ABBREVIATE, shortcutKeyEvent)); } @Test diff --git a/src/test/java/org/jabref/migrations/ConvertMarkingToGroupsTest.java b/src/test/java/org/jabref/migrations/ConvertMarkingToGroupsTest.java new file mode 100644 index 00000000000..bf05d02903b --- /dev/null +++ b/src/test/java/org/jabref/migrations/ConvertMarkingToGroupsTest.java @@ -0,0 +1,34 @@ +package org.jabref.migrations; + +import java.util.Collections; +import java.util.Optional; + +import org.jabref.logic.groups.DefaultGroupsFactory; +import org.jabref.logic.importer.ParserResult; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FieldName; +import org.jabref.model.groups.ExplicitGroup; +import org.jabref.model.groups.GroupHierarchyType; +import org.jabref.model.groups.GroupTreeNode; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ConvertMarkingToGroupsTest { + @Test + void performMigrationForSingleEntry() { + BibEntry entry = new BibEntry() + .withField(FieldName.MARKED_INTERNAL, "[Nicolas:6]"); + ParserResult parserResult = new ParserResult(Collections.singleton(entry)); + + new ConvertMarkingToGroups().performMigration(parserResult); + + GroupTreeNode rootExpected = GroupTreeNode.fromGroup(DefaultGroupsFactory.getAllEntriesGroup()); + GroupTreeNode markings = rootExpected.addSubgroup(new ExplicitGroup("Markings", GroupHierarchyType.INCLUDING, ',')); + markings.addSubgroup(new ExplicitGroup("Nicolas:6", GroupHierarchyType.INCLUDING, ',')); + + assertEquals(Optional.empty(), entry.getField(FieldName.MARKED_INTERNAL)); + assertEquals(Optional.of(rootExpected), parserResult.getMetaData().getGroups()); + } +} diff --git a/src/test/resources/testbib/complex.bib b/src/test/resources/testbib/complex.bib index 84a8899d40f..414e02a489e 100644 --- a/src/test/resources/testbib/complex.bib +++ b/src/test/resources/testbib/complex.bib @@ -301,8 +301,8 @@ @Comment{jabref-meta: @Comment{jabref-meta: grouping: 0 AllEntriesGroup:; -1 StaticGroup:StaticGroup\;0\;1\;\;\;A test static group\;; -1 KeywordGroup:DynamicGroup\;0\;author\;Churchill\;0\;0\;1\;\;\;\;; +1 StaticGroup:StaticGroup\;0\;1\;0x6d74baff\;\;A test static group\;; +1 KeywordGroup:DynamicGroup\;0\;author\;Churchill\;0\;0\;1\;0x5eba7dff\;\;\;; 1 AutomaticPersonsGroup:Automatic group (Authors)\;0\;author\;1\;\;\;Automatic group for all authors\;; }