diff --git a/src/main/java/org/jabref/collab/GroupChange.java b/src/main/java/org/jabref/collab/GroupChange.java index 1c9f8e0298b..7b6f398dee2 100644 --- a/src/main/java/org/jabref/collab/GroupChange.java +++ b/src/main/java/org/jabref/collab/GroupChange.java @@ -7,9 +7,9 @@ import org.jabref.gui.groups.GroupTreeNodeViewModel; import org.jabref.gui.groups.UndoableModifySubtree; import org.jabref.gui.undo.NamedCompound; +import org.jabref.logic.groups.DefaultGroupsFactory; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabase; -import org.jabref.model.groups.AllEntriesGroup; import org.jabref.model.groups.GroupTreeNode; class GroupChange extends Change { @@ -34,7 +34,7 @@ public boolean makeChange(BasePanel panel, BibDatabase secondary, NamedCompound root.removeAllChildren(); if (changedGroups == null) { // I think setting root to null is not possible - root.setGroup(new AllEntriesGroup(Localization.lang("All entries"))); + root.setGroup(DefaultGroupsFactory.getAllEntriesGroup()); } else { // change root group, even though it'll be AllEntries anyway root.setGroup(changedGroups.getGroup()); diff --git a/src/main/java/org/jabref/gui/IconTheme.java b/src/main/java/org/jabref/gui/IconTheme.java index 1771f288664..e1f99c82a3e 100644 --- a/src/main/java/org/jabref/gui/IconTheme.java +++ b/src/main/java/org/jabref/gui/IconTheme.java @@ -32,24 +32,22 @@ public class IconTheme { - public static Font FONT; - public static Font FONT_16; - public static javafx.scene.text.Font FX_FONT; - - /* Colors */ - // JabRef's default colors + /** + * JabRef's default color + */ public static final Color DEFAULT_COLOR = JabRefPreferences.getInstance().getColor(JabRefPreferences.ICON_ENABLED_COLOR); public static final Color DEFAULT_DISABLED_COLOR = JabRefPreferences.getInstance().getColor(JabRefPreferences.ICON_DISABLED_COLOR); + private static final String DEFAULT_ICON_PATH = "/images/external/red.png"; + private static final Log LOGGER = LogFactory.getLog(IconTheme.class); + private static final Map KEY_TO_ICON = readIconThemeFile( + IconTheme.class.getResource("/images/Icons.properties"), "/images/external/"); + public static Font FONT; // Christmas edition //public static final Color DEFAULT_COLOR = new Color(0x155115); //public static final Color DEFAULT_DISABLED_COLOR = new Color(0x990000); - - private static final Map KEY_TO_ICON = readIconThemeFile( - IconTheme.class.getResource("/images/Icons.properties"), "/images/external/"); - private static final String DEFAULT_ICON_PATH = "/images/external/red.png"; - - private static final Log LOGGER = LogFactory.getLog(IconTheme.class); + private static Font FONT_16; + private static javafx.scene.text.Font FX_FONT; static { try (InputStream stream = FontBasedIcon.class.getResourceAsStream("/fonts/materialdesignicons-webfont.ttf")) { @@ -63,6 +61,90 @@ public class IconTheme { } } + public static javafx.scene.paint.Color getDefaultColor() { + return javafx.scene.paint.Color.rgb(DEFAULT_COLOR.getRed(), DEFAULT_COLOR.getGreen(), DEFAULT_COLOR.getBlue(), DEFAULT_COLOR.getAlpha() / 255.0); + } + + /** + * Constructs an ImageIcon for the image representing the given function, in the resource + * file listing images. + * + * @param name The name of the icon, such as "open", "save", "saveAs" etc. + * @return The ImageIcon for the function. + */ + public static ImageIcon getImage(String name) { + return new ImageIcon(getIconUrl(name)); + } + + public static Image getJabRefImageFX() { + return getImageFX("jabrefIcon48"); + } + + /** + * Constructs an {@link Image} for the image representing the given function, in the resource + * file listing images. + * + * @param name The name of the icon, such as "open", "save", "saveAs" etc. + * @return The {@link Image} for the function. + */ + public static Image getImageFX(String name) { + return new Image(getIconUrl(name).toString()); + } + + /** + * Looks up the URL for the image representing the given function, in the resource + * file listing images. + * + * @param name The name of the icon, such as "open", "save", "saveAs" etc. + * @return The URL to the actual image to use. + */ + public static URL getIconUrl(String name) { + String key = Objects.requireNonNull(name, "icon name"); + if (!KEY_TO_ICON.containsKey(key)) { + LOGGER.warn("Could not find icon url by name " + name + ", so falling back on default icon " + + DEFAULT_ICON_PATH); + } + String path = KEY_TO_ICON.getOrDefault(key, DEFAULT_ICON_PATH); + return Objects.requireNonNull(IconTheme.class.getResource(path), "Path must not be null for key " + key); + } + + /** + * Read a typical java property url into a Map. Currently doesn't support escaping + * of the '=' character - it simply looks for the first '=' to determine where the key ends. + * Both the key and the value is trimmed for whitespace at the ends. + * + * @param url The URL to read information from. + * @param prefix A String to prefix to all values read. Can represent e.g. the directory where icon files are to be + * found. + * @return A Map containing all key-value pairs found. + */ + // FIXME: prefix can be removed?! + private static Map readIconThemeFile(URL url, String prefix) { + Objects.requireNonNull(url, "url"); + Objects.requireNonNull(prefix, "prefix"); + + Map result = new HashMap<>(); + + try (BufferedReader in = new BufferedReader( + new InputStreamReader(url.openStream(), StandardCharsets.ISO_8859_1))) { + String line; + while ((line = in.readLine()) != null) { + if (!line.contains("=")) { + continue; + } + + int index = line.indexOf('='); + String key = line.substring(0, index).trim(); + String value = prefix + line.substring(index + 1).trim(); + result.put(key, value); + } + } catch (IOException e) { + LOGGER.warn("Unable to read default icon theme.", e); + } + return result; + } + + public enum JabRefIcon { ADD("\uf416") /*css: mdi-plus-box*/, @@ -165,6 +247,8 @@ public enum JabRefIcon { BLOG("\uf46b"), /* css: rss */ GLOBAL_SEARCH("\uF1E7"), /* css: earth */ DATE_PICKER("\uF0ED;"), /* css: calendar */ + DEFAULT_GROUP_ICON("\uF316"), /* css: label-outline */ + ALL_ENTRIES_GROUP_ICON("\uF1B8"), /* css: database */ // STILL MISSING: GROUP_REGULAR("\uF4E6", Color.RED); @@ -259,85 +343,4 @@ public FontBasedIcon createWithNewColor(Color newColor) { } } - - - /** - * Constructs an ImageIcon for the image representing the given function, in the resource - * file listing images. - * - * @param name The name of the icon, such as "open", "save", "saveAs" etc. - * @return The ImageIcon for the function. - */ - public static ImageIcon getImage(String name) { - return new ImageIcon(getIconUrl(name)); - } - - public static Image getJabRefImageFX() { - return getImageFX("jabrefIcon48"); - } - - /** - * Constructs an {@link Image} for the image representing the given function, in the resource - * file listing images. - * - * @param name The name of the icon, such as "open", "save", "saveAs" etc. - * @return The {@link Image} for the function. - */ - public static Image getImageFX(String name) { - return new Image(getIconUrl(name).toString()); - } - - - /** - * Looks up the URL for the image representing the given function, in the resource - * file listing images. - * - * @param name The name of the icon, such as "open", "save", "saveAs" etc. - * @return The URL to the actual image to use. - */ - public static URL getIconUrl(String name) { - String key = Objects.requireNonNull(name, "icon name"); - if (!KEY_TO_ICON.containsKey(key)) { - LOGGER.warn("Could not find icon url by name " + name + ", so falling back on default icon " - + DEFAULT_ICON_PATH); - } - String path = KEY_TO_ICON.getOrDefault(key, DEFAULT_ICON_PATH); - return Objects.requireNonNull(IconTheme.class.getResource(path), "Path must not be null for key " + key); - } - - /** - * Read a typical java property url into a Map. Currently doesn't support escaping - * of the '=' character - it simply looks for the first '=' to determine where the key ends. - * Both the key and the value is trimmed for whitespace at the ends. - * - * @param url The URL to read information from. - * @param prefix A String to prefix to all values read. Can represent e.g. the directory - * where icon files are to be found. - * @return A Map containing all key-value pairs found. - */ - // FIXME: prefix can be removed?! - private static Map readIconThemeFile(URL url, String prefix) { - Objects.requireNonNull(url, "url"); - Objects.requireNonNull(prefix, "prefix"); - - Map result = new HashMap<>(); - - try (BufferedReader in = new BufferedReader( - new InputStreamReader(url.openStream(), StandardCharsets.ISO_8859_1))) { - String line; - while ((line = in.readLine()) != null) { - if (!line.contains("=")) { - continue; - } - - int index = line.indexOf('='); - String key = line.substring(0, index).trim(); - String value = prefix + line.substring(index + 1).trim(); - result.put(key, value); - } - } catch (IOException e) { - LOGGER.warn("Unable to read default icon theme.", e); - } - return result; - } } diff --git a/src/main/java/org/jabref/gui/Main.css b/src/main/java/org/jabref/gui/Main.css index d89d1b4d694..735592b4c0b 100644 --- a/src/main/java/org/jabref/gui/Main.css +++ b/src/main/java/org/jabref/gui/Main.css @@ -48,7 +48,6 @@ .icon { -fx-font-family: 'Material Design Icons'; -fx-font-size: 16.0; - -fx-fill : -fx-mid-text-color; } .tooltip { diff --git a/src/main/java/org/jabref/gui/groups/GroupDialog.java b/src/main/java/org/jabref/gui/groups/GroupDialog.java index e5713c36c45..471b5b27b31 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialog.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialog.java @@ -28,6 +28,8 @@ import javax.swing.SwingConstants; import javax.swing.event.CaretListener; +import javafx.scene.paint.Color; + import org.jabref.Globals; import org.jabref.JabRefGUI; import org.jabref.gui.Dialog; @@ -80,6 +82,10 @@ class GroupDialog extends JDialog implements Dialog { Localization.lang("Refine supergroup: When selected, view entries contained in both this group and its supergroup")); private final JRadioButton unionButton = new JRadioButton( Localization.lang("Include subgroups: When selected, view entries contained in this group or its subgroups")); + private final JTextField colorField = new JTextField(GroupDialog.TEXTFIELD_LENGTH); + private final JTextField descriptionField = new JTextField(GroupDialog.TEXTFIELD_LENGTH); + private final JTextField iconField = new JTextField(GroupDialog.TEXTFIELD_LENGTH); + // for KeywordGroup private final JTextField keywordGroupSearchField = new JTextField(GroupDialog.TEXTFIELD_LENGTH); private final TextField keywordGroupSearchTerm = new TextField(FieldName.KEYWORDS, "", false); @@ -209,7 +215,7 @@ public GroupDialog(JabRefFrame jabrefFrame, AbstractGroup editedGroup) { // create layout FormLayout layoutAll = new FormLayout( "right:pref, 4dlu, fill:600px, 4dlu, fill:pref", - "p, 3dlu, p, 3dlu, p, 0dlu, p, 0dlu, p, 0dlu, p, 3dlu, p, 3dlu, p, " + "p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 0dlu, p, 0dlu, p, 0dlu, p, 3dlu, p, 3dlu, p, " + "0dlu, p, 0dlu, p, 3dlu, p, 3dlu, " + "p, 3dlu, p, 3dlu, top:80dlu, 9dlu, p, 9dlu, p"); @@ -221,6 +227,18 @@ public GroupDialog(JabRefFrame jabrefFrame, AbstractGroup editedGroup) { builderAll.append(nameField); builderAll.nextLine(); builderAll.nextLine(); + builderAll.append(Localization.lang("Description")); + builderAll.append(descriptionField); + builderAll.nextLine(); + builderAll.nextLine(); + builderAll.append(Localization.lang("Color")); + builderAll.append(colorField); + builderAll.nextLine(); + builderAll.nextLine(); + builderAll.append(Localization.lang("Icon")); + builderAll.append(iconField); + builderAll.nextLine(); + builderAll.nextLine(); builderAll.append(explicitRadioButton, 5); builderAll.nextLine(); builderAll.nextLine(); @@ -339,6 +357,14 @@ public void actionPerformed(ActionEvent e) { autoGroupPersonsField.getText().trim()); } } + try { + resultingGroup.setColor(Color.valueOf(colorField.getText())); + } catch (IllegalArgumentException ex) { + // Ignore invalid color (we should probably notify the user instead...) + } + resultingGroup.setDescription(descriptionField.getText()); + resultingGroup.setIconCode(iconField.getText()); + dispose(); } catch (IllegalArgumentException exception) { jabrefFrame.showMessage(exception.getLocalizedMessage()); @@ -349,6 +375,9 @@ public void actionPerformed(ActionEvent e) { ItemListener itemListener = e -> updateComponents(); nameField.addCaretListener(caretListener); + colorField.addCaretListener(caretListener); + descriptionField.addCaretListener(caretListener); + iconField.addCaretListener(caretListener); keywordGroupSearchField.addCaretListener(caretListener); keywordGroupSearchTerm.addCaretListener(caretListener); keywordGroupCaseSensitive.addItemListener(itemListener); @@ -363,9 +392,13 @@ public void actionPerformed(ActionEvent e) { explicitRadioButton.setSelected(true); setContext(GroupHierarchyType.INDEPENDENT); } else { + nameField.setText(editedGroup.getName()); + colorField.setText(editedGroup.getColor().map(Color::toString).orElse("")); + descriptionField.setText(editedGroup.getDescription().orElse("")); + iconField.setText(editedGroup.getIconCode().orElse("")); + if (editedGroup.getClass() == WordKeywordGroup.class) { WordKeywordGroup group = (WordKeywordGroup) editedGroup; - nameField.setText(group.getName()); keywordGroupSearchField.setText(group.getSearchField()); keywordGroupSearchTerm.setText(group.getSearchExpression()); keywordGroupCaseSensitive.setSelected(group.isCaseSensitive()); @@ -374,7 +407,6 @@ public void actionPerformed(ActionEvent e) { setContext(editedGroup.getHierarchicalContext()); } else if (editedGroup.getClass() == RegexKeywordGroup.class) { RegexKeywordGroup group = (RegexKeywordGroup) editedGroup; - nameField.setText(group.getName()); keywordGroupSearchField.setText(group.getSearchField()); keywordGroupSearchTerm.setText(group.getSearchExpression()); keywordGroupCaseSensitive.setSelected(group.isCaseSensitive()); @@ -383,18 +415,15 @@ public void actionPerformed(ActionEvent e) { setContext(editedGroup.getHierarchicalContext()); } else if (editedGroup.getClass() == SearchGroup.class) { SearchGroup group = (SearchGroup) editedGroup; - nameField.setText(group.getName()); searchGroupSearchExpression.setText(group.getSearchExpression()); searchGroupCaseSensitive.setSelected(group.isCaseSensitive()); searchGroupRegExp.setSelected(group.isRegularExpression()); searchRadioButton.setSelected(true); setContext(editedGroup.getHierarchicalContext()); } else if (editedGroup.getClass() == ExplicitGroup.class) { - nameField.setText(editedGroup.getName()); explicitRadioButton.setSelected(true); setContext(editedGroup.getHierarchicalContext()); } else if (editedGroup.getClass() == AutomaticKeywordGroup.class) { - nameField.setText(editedGroup.getName()); autoRadioButton.setSelected(true); setContext(editedGroup.getHierarchicalContext()); diff --git a/src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java b/src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java index 578465c411c..ac32e641980 100644 --- a/src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java @@ -15,16 +15,17 @@ import javafx.beans.property.SimpleIntegerProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import javafx.scene.paint.Color; +import org.jabref.gui.IconTheme; import org.jabref.gui.StateManager; import org.jabref.gui.util.BindingsHelper; -import org.jabref.logic.l10n.Localization; +import org.jabref.logic.groups.DefaultGroupsFactory; import org.jabref.logic.layout.format.LatexToUnicodeFormatter; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.event.EntryEvent; import org.jabref.model.groups.AbstractGroup; -import org.jabref.model.groups.AllEntriesGroup; import org.jabref.model.groups.AutomaticGroup; import org.jabref.model.groups.GroupTreeNode; import org.jabref.model.strings.StringUtil; @@ -36,7 +37,6 @@ public class GroupNodeViewModel { private final String displayName; private final boolean isRoot; - private final String iconCode; private final ObservableList children; private final BibDatabaseContext databaseContext; private final GroupTreeNode groupNode; @@ -52,7 +52,6 @@ public GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager state LatexToUnicodeFormatter formatter = new LatexToUnicodeFormatter(); displayName = formatter.format(groupNode.getName()); isRoot = groupNode.isRoot(); - iconCode = ""; if (groupNode.getGroup() instanceof AutomaticGroup) { AutomaticGroup automaticGroup = (AutomaticGroup) groupNode.getGroup(); @@ -71,6 +70,8 @@ public GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager state hasChildren.bind(Bindings.isNotEmpty(children)); hits = new SimpleIntegerProperty(0); calculateNumberOfMatches(); + expandedProperty.set(groupNode.getGroup().isExpanded()); + expandedProperty.addListener((observable, oldValue, newValue) -> groupNode.getGroup().setExpanded(newValue)); // Register listener databaseContext.getDatabase().registerListener(this); @@ -90,7 +91,7 @@ private static Predicate distinctByKey(Function keyExtracto } static GroupNodeViewModel getAllEntriesGroup(BibDatabaseContext newDatabase, StateManager stateManager) { - return new GroupNodeViewModel(newDatabase, stateManager, new AllEntriesGroup(Localization.lang("All entries"))); + return new GroupNodeViewModel(newDatabase, stateManager, DefaultGroupsFactory.getAllEntriesGroup()); } private Stream createSubgroups(BibDatabaseContext databaseContext, StateManager stateManager, AutomaticGroup automaticGroup, BibEntry entry) { @@ -123,7 +124,7 @@ public boolean isRoot() { } public String getDescription() { - return "Some group named " + getDisplayName(); + return groupNode.getGroup().getDescription().orElse(""); } public SimpleIntegerProperty getHits() { @@ -146,7 +147,7 @@ public String toString() { return "GroupNodeViewModel{" + "displayName='" + displayName + '\'' + ", isRoot=" + isRoot + - ", iconCode='" + iconCode + '\'' + + ", iconCode='" + getIconCode() + '\'' + ", children=" + children + ", databaseContext=" + databaseContext + ", groupNode=" + groupNode + @@ -160,7 +161,7 @@ public int hashCode() { } public String getIconCode() { - return iconCode; + return groupNode.getGroup().getIconCode().orElse(IconTheme.JabRefIcon.DEFAULT_GROUP_ICON.getCode()); } public ObservableList getChildren() { @@ -200,4 +201,8 @@ void toggleExpansion() { boolean isMatchedBy(String searchString) { return StringUtil.isBlank(searchString) || getDisplayName().contains(searchString); } + + public Color getColor() { + return groupNode.getGroup().getColor().orElse(IconTheme.getDefaultColor()); + } } diff --git a/src/main/java/org/jabref/gui/groups/GroupSelector.java b/src/main/java/org/jabref/gui/groups/GroupSelector.java index ffb17c98e12..68a9223f167 100644 --- a/src/main/java/org/jabref/gui/groups/GroupSelector.java +++ b/src/main/java/org/jabref/gui/groups/GroupSelector.java @@ -57,6 +57,7 @@ import org.jabref.gui.maintable.MainTableDataModel; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.worker.AbstractWorker; +import org.jabref.logic.groups.DefaultGroupsFactory; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; import org.jabref.model.FieldChange; @@ -285,7 +286,7 @@ public void stateChanged(ChangeEvent event) { KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.CTRL_MASK)); - setGroups(GroupTreeNode.fromGroup(new AllEntriesGroup(Localization.lang("All entries")))); + setGroups(GroupTreeNode.fromGroup(DefaultGroupsFactory.getAllEntriesGroup())); JFXPanel groupsPane = new JFXPanel(); @@ -601,7 +602,7 @@ public void componentClosing() { private void setGroups(GroupTreeNode groupsRoot) { // We ignore the set group since this is handled via JavaFX - this.groupsRoot = new GroupTreeNodeViewModel(new GroupTreeNode(new AllEntriesGroup("DUMMY"))); + this.groupsRoot = new GroupTreeNodeViewModel(new GroupTreeNode(DefaultGroupsFactory.getAllEntriesGroup())); //this.groupsRoot = new GroupTreeNodeViewModel(groupsRoot); groupsTreeModel = new DefaultTreeModel(this.groupsRoot); this.groupsRoot.subscribeToDescendantChanged(groupsTreeModel::nodeStructureChanged); @@ -773,7 +774,7 @@ public void setActiveBasePanel(BasePanel panel) { setGroups(metaData.getGroups().get()); } else { GroupTreeNode newGroupsRoot = GroupTreeNode - .fromGroup(new AllEntriesGroup(Localization.lang("All entries"))); + .fromGroup(DefaultGroupsFactory.getAllEntriesGroup()); metaData.setGroups(newGroupsRoot); setGroups(newGroupsRoot); } diff --git a/src/main/java/org/jabref/gui/groups/GroupTree.css b/src/main/java/org/jabref/gui/groups/GroupTree.css index 284c08f7f68..2f88e2b1652 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTree.css +++ b/src/main/java/org/jabref/gui/groups/GroupTree.css @@ -101,9 +101,6 @@ } .tree-table-row-cell > .tree-table-cell > .icon { - -fx-font-family: 'MaterialDesignIcons'; - -fx-font-size: 16; - -fx-fill: #5e5f5e; -fx-translate-x: -5px; } diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeController.java b/src/main/java/org/jabref/gui/groups/GroupTreeController.java index a38f63a68d0..5500b9e3617 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeController.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeController.java @@ -75,7 +75,7 @@ public void initialize() { mainColumn.setCellValueFactory(cellData -> cellData.getValue().valueProperty()); mainColumn.setCellFactory(new ViewModelTreeTableCellFactory() .withText(GroupNodeViewModel::getDisplayName) - .withIcon(GroupNodeViewModel::getIconCode) + .withIcon(GroupNodeViewModel::getIconCode, GroupNodeViewModel::getColor) .withTooltip(GroupNodeViewModel::getDescription) ); diff --git a/src/main/java/org/jabref/gui/util/ViewModelTreeTableCellFactory.java b/src/main/java/org/jabref/gui/util/ViewModelTreeTableCellFactory.java index 294292481bd..1033a1c3502 100644 --- a/src/main/java/org/jabref/gui/util/ViewModelTreeTableCellFactory.java +++ b/src/main/java/org/jabref/gui/util/ViewModelTreeTableCellFactory.java @@ -6,6 +6,7 @@ import javafx.scene.control.TreeTableCell; import javafx.scene.control.TreeTableColumn; import javafx.scene.input.MouseEvent; +import javafx.scene.paint.Paint; import javafx.scene.text.Text; import javafx.util.Callback; @@ -32,10 +33,11 @@ public ViewModelTreeTableCellFactory withGraphic(Callback toGraph return this; } - public ViewModelTreeTableCellFactory withIcon(Callback toIcon) { + public ViewModelTreeTableCellFactory withIcon(Callback toIcon, Callback toColor) { this.toGraphic = viewModel -> { Text graphic = new Text(toIcon.call(viewModel)); graphic.getStyleClass().add("icon"); + graphic.setFill(toColor.call(viewModel)); return graphic; }; return this; diff --git a/src/main/java/org/jabref/logic/groups/DefaultGroupsFactory.java b/src/main/java/org/jabref/logic/groups/DefaultGroupsFactory.java new file mode 100644 index 00000000000..702f5053069 --- /dev/null +++ b/src/main/java/org/jabref/logic/groups/DefaultGroupsFactory.java @@ -0,0 +1,13 @@ +package org.jabref.logic.groups; + +import org.jabref.logic.l10n.Localization; +import org.jabref.model.groups.AllEntriesGroup; + +public class DefaultGroupsFactory { + + public static AllEntriesGroup getAllEntriesGroup() { + AllEntriesGroup group = new AllEntriesGroup(Localization.lang("All entries")); + group.setIconCode(org.jabref.gui.IconTheme.JabRefIcon.ALL_ENTRIES_GROUP_ICON.getCode()); + return group; + } +} diff --git a/src/main/java/org/jabref/logic/importer/util/GroupsParser.java b/src/main/java/org/jabref/logic/importer/util/GroupsParser.java index 3b2c91e8e33..c010d57e080 100644 --- a/src/main/java/org/jabref/logic/importer/util/GroupsParser.java +++ b/src/main/java/org/jabref/logic/importer/util/GroupsParser.java @@ -2,12 +2,12 @@ import java.util.List; +import org.jabref.logic.groups.DefaultGroupsFactory; import org.jabref.logic.importer.ParseException; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.MetadataSerializationConfiguration; import org.jabref.logic.util.strings.QuotedStringTokenizer; import org.jabref.model.groups.AbstractGroup; -import org.jabref.model.groups.AllEntriesGroup; import org.jabref.model.groups.ExplicitGroup; import org.jabref.model.groups.GroupHierarchyType; import org.jabref.model.groups.GroupTreeNode; @@ -148,7 +148,7 @@ private static AbstractGroup allEntriesGroupFromString(String s) { if (!s.startsWith(MetadataSerializationConfiguration.ALL_ENTRIES_GROUP_ID)) { throw new IllegalArgumentException("AllEntriesGroup cannot be created from \"" + s + "\"."); } - return new AllEntriesGroup(Localization.lang("All entries")); + return DefaultGroupsFactory.getAllEntriesGroup(); } /** diff --git a/src/main/java/org/jabref/model/groups/AbstractGroup.java b/src/main/java/org/jabref/model/groups/AbstractGroup.java index 07bd0ecf3f3..f8b5bd7ad56 100644 --- a/src/main/java/org/jabref/model/groups/AbstractGroup.java +++ b/src/main/java/org/jabref/model/groups/AbstractGroup.java @@ -2,6 +2,9 @@ import java.util.List; import java.util.Objects; +import java.util.Optional; + +import javafx.scene.paint.Color; import org.jabref.model.entry.BibEntry; import org.jabref.model.search.SearchMatcher; @@ -15,17 +18,52 @@ public abstract class AbstractGroup implements SearchMatcher { * The group's name. */ protected final String name; - /** * The hierarchical context of the group. */ protected final GroupHierarchyType context; + protected Optional color = Optional.empty(); + protected boolean isExpanded = true; + protected Optional description = Optional.empty(); + protected Optional iconCode = Optional.empty(); protected AbstractGroup(String name, GroupHierarchyType context) { this.name = name; this.context = Objects.requireNonNull(context); } + public Optional getColor() { + return color; + } + + public void setColor(Color color) { + this.color = Optional.of(color); + } + + public boolean isExpanded() { + return isExpanded; + } + + public void setExpanded(boolean expanded) { + isExpanded = expanded; + } + + public Optional getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = Optional.of(description); + } + + public Optional getIconCode() { + return iconCode; + } + + public void setIconCode(String iconCode) { + this.iconCode = Optional.of(iconCode); + } + /** * Returns the way this group relates to its sub- or supergroup. */ diff --git a/src/main/resources/l10n/JabRef_da.properties b/src/main/resources/l10n/JabRef_da.properties index 364c671539e..df5376df405 100644 --- a/src/main/resources/l10n/JabRef_da.properties +++ b/src/main/resources/l10n/JabRef_da.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_de.properties b/src/main/resources/l10n/JabRef_de.properties index 753a6021e99..64fae71d7e3 100644 --- a/src/main/resources/l10n/JabRef_de.properties +++ b/src/main/resources/l10n/JabRef_de.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons=Größe_für_große_Icons Size_of_small_icons=Größe_für_kleine_Icon Default_table_font_size=Standard_Tabellenschriftgröße Escape_underscores=Unterstriche_maskieren +Color= diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 3d1ce55bf67..5e41df8970d 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons=Size_of_large_icons Size_of_small_icons=Size_of_small_icons Default_table_font_size=Default_table_font_size Escape_underscores=Escape_underscores +Color=Color diff --git a/src/main/resources/l10n/JabRef_es.properties b/src/main/resources/l10n/JabRef_es.properties index 20fc17a8989..a9c14d6abcd 100644 --- a/src/main/resources/l10n/JabRef_es.properties +++ b/src/main/resources/l10n/JabRef_es.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_fa.properties b/src/main/resources/l10n/JabRef_fa.properties index 4bd1e8549b2..68d4720e7f1 100644 --- a/src/main/resources/l10n/JabRef_fa.properties +++ b/src/main/resources/l10n/JabRef_fa.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_fr.properties b/src/main/resources/l10n/JabRef_fr.properties index 6e352e031d4..e8341a93bdc 100644 --- a/src/main/resources/l10n/JabRef_fr.properties +++ b/src/main/resources/l10n/JabRef_fr.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons=Taille_des_grands_icones Size_of_small_icons=Taille_des_petits_icones Default_table_font_size=Taille_par_défaut_des_police_du_tableau Escape_underscores=Echapper_les_soulignements +Color= diff --git a/src/main/resources/l10n/JabRef_in.properties b/src/main/resources/l10n/JabRef_in.properties index f5ff714aab2..0584ec68936 100644 --- a/src/main/resources/l10n/JabRef_in.properties +++ b/src/main/resources/l10n/JabRef_in.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_it.properties b/src/main/resources/l10n/JabRef_it.properties index 3d3e431b169..cce3426abf6 100644 --- a/src/main/resources/l10n/JabRef_it.properties +++ b/src/main/resources/l10n/JabRef_it.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_ja.properties b/src/main/resources/l10n/JabRef_ja.properties index 7fba66f0e8e..fc5af5b0f0c 100644 --- a/src/main/resources/l10n/JabRef_ja.properties +++ b/src/main/resources/l10n/JabRef_ja.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_nl.properties b/src/main/resources/l10n/JabRef_nl.properties index 282b7b24bed..8d31c3e37e6 100644 --- a/src/main/resources/l10n/JabRef_nl.properties +++ b/src/main/resources/l10n/JabRef_nl.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_no.properties b/src/main/resources/l10n/JabRef_no.properties index 8f9f291140a..36889da582d 100644 --- a/src/main/resources/l10n/JabRef_no.properties +++ b/src/main/resources/l10n/JabRef_no.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_pt_BR.properties b/src/main/resources/l10n/JabRef_pt_BR.properties index 4b1fa023303..6bbb8360f3e 100644 --- a/src/main/resources/l10n/JabRef_pt_BR.properties +++ b/src/main/resources/l10n/JabRef_pt_BR.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_ru.properties b/src/main/resources/l10n/JabRef_ru.properties index 70343569f7a..66f64ebdaa0 100644 --- a/src/main/resources/l10n/JabRef_ru.properties +++ b/src/main/resources/l10n/JabRef_ru.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_sv.properties b/src/main/resources/l10n/JabRef_sv.properties index 998a93f4302..da0639a3a35 100644 --- a/src/main/resources/l10n/JabRef_sv.properties +++ b/src/main/resources/l10n/JabRef_sv.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores=Maskera_understreck +Color= diff --git a/src/main/resources/l10n/JabRef_tr.properties b/src/main/resources/l10n/JabRef_tr.properties index 61770323740..0b948828617 100644 --- a/src/main/resources/l10n/JabRef_tr.properties +++ b/src/main/resources/l10n/JabRef_tr.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_vi.properties b/src/main/resources/l10n/JabRef_vi.properties index 6f9601a172c..ab4690d2630 100644 --- a/src/main/resources/l10n/JabRef_vi.properties +++ b/src/main/resources/l10n/JabRef_vi.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color= diff --git a/src/main/resources/l10n/JabRef_zh.properties b/src/main/resources/l10n/JabRef_zh.properties index 44a84d5e503..3ebd3423d99 100644 --- a/src/main/resources/l10n/JabRef_zh.properties +++ b/src/main/resources/l10n/JabRef_zh.properties @@ -2356,3 +2356,4 @@ Size_of_large_icons= Size_of_small_icons= Default_table_font_size= Escape_underscores= +Color=