diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 6c79182fc5b..aa2627c0148 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -1020,7 +1020,7 @@ public void addParserResult(ParserResult pr, boolean focusPanel) { */ @Deprecated public void output(final String s) { - statusLine.show(s, 3000); + DefaultTaskExecutor.runInJavaFXThread(() -> statusLine.show(s, 3000)); } private void initActions() { diff --git a/src/main/java/org/jabref/gui/maintable/ColumnPreferences.java b/src/main/java/org/jabref/gui/maintable/ColumnPreferences.java index ead48b18a3d..7a6d88ac463 100644 --- a/src/main/java/org/jabref/gui/maintable/ColumnPreferences.java +++ b/src/main/java/org/jabref/gui/maintable/ColumnPreferences.java @@ -3,6 +3,8 @@ import java.util.List; import java.util.Map; +import javafx.scene.control.TableColumn.SortType; + import org.jabref.model.entry.BibtexSingleField; import org.jabref.model.entry.specialfields.SpecialField; @@ -16,8 +18,9 @@ public class ColumnPreferences { private final List specialFieldColumns; private final List extraFileColumns; private final Map columnWidths; + private final Map columnSortType; - public ColumnPreferences(boolean showFileColumn, boolean showUrlColumn, boolean preferDoiOverUrl, boolean showEprintColumn, List normalColumns, List specialFieldColumns, List extraFileColumns, Map columnWidths) { + public ColumnPreferences(boolean showFileColumn, boolean showUrlColumn, boolean preferDoiOverUrl, boolean showEprintColumn, List normalColumns, List specialFieldColumns, List extraFileColumns, Map columnWidths, Map columnSortType) { this.showFileColumn = showFileColumn; this.showUrlColumn = showUrlColumn; this.preferDoiOverUrl = preferDoiOverUrl; @@ -26,6 +29,7 @@ public ColumnPreferences(boolean showFileColumn, boolean showUrlColumn, boolean this.specialFieldColumns = specialFieldColumns; this.extraFileColumns = extraFileColumns; this.columnWidths = columnWidths; + this.columnSortType = columnSortType; } public boolean showFileColumn() { @@ -59,4 +63,8 @@ public List getNormalColumns() { public double getPrefColumnWidth(String columnName) { return columnWidths.getOrDefault(columnName, BibtexSingleField.DEFAULT_FIELD_LENGTH); } + + public Map getSortTypesForColumns() { + return columnSortType; + } } diff --git a/src/main/java/org/jabref/gui/maintable/MainTable.java b/src/main/java/org/jabref/gui/maintable/MainTable.java index 0c739e23b6a..62167d44da8 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTable.java +++ b/src/main/java/org/jabref/gui/maintable/MainTable.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.nio.file.Path; import java.util.List; +import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -13,6 +14,8 @@ import javafx.collections.ListChangeListener; import javafx.scene.control.ScrollPane; import javafx.scene.control.SelectionMode; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableColumn.SortType; import javafx.scene.control.TableRow; import javafx.scene.control.TableView; import javafx.scene.input.ClipboardContent; @@ -62,7 +65,6 @@ public class MainTable extends TableView { private final NewDroppedFileHandler fileHandler; private final CustomLocalDragboard localDragboard = GUIGlobals.localDragboard; - public MainTable(MainTableDataModel model, JabRefFrame frame, BasePanel panel, BibDatabaseContext database, MainTablePreferences preferences, ExternalFileTypes externalFileTypes, KeyBindingRepository keyBindingRepository) { @@ -73,14 +75,15 @@ public MainTable(MainTableDataModel model, JabRefFrame frame, this.undoManager = panel.getUndoManager(); fileHandler = new NewDroppedFileHandler(frame.getDialogService(), database, externalFileTypes, - Globals.prefs.getFilePreferences(), + Globals.prefs.getFilePreferences(), Globals.prefs.getImportFormatPreferences(), Globals.prefs.getUpdateFieldPreferences(), - Globals.getFileUpdateMonitor() + Globals.getFileUpdateMonitor() ); this.getColumns().addAll(new MainTableColumnFactory(database, preferences.getColumnPreferences(), externalFileTypes, panel.getUndoManager(), frame.getDialogService()).createColumns()); + new ViewModelTableRowFactory() .withOnMouseClickedEvent((entry, event) -> { if (event.getClickCount() == 2) { @@ -94,13 +97,20 @@ public MainTable(MainTableDataModel model, JabRefFrame frame, .setOnMouseDragEntered(this::handleOnDragEntered) .install(this); + for (Entry entries : preferences.getColumnPreferences().getSortTypesForColumns().entrySet()) { + Optional> column = this.getColumns().stream().filter(col -> entries.getKey().equals(col.getText())).findFirst(); + column.ifPresent(col -> { + col.setSortType(entries.getValue()); + this.getSortOrder().add(col); + }); + } + if (preferences.resizeColumnsToFit()) { this.setColumnResizePolicy(new SmartConstrainedResizePolicy()); } this.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); this.setItems(model.getEntriesFilteredAndSorted()); - // Enable sorting model.getEntriesFilteredAndSorted().comparatorProperty().bind(this.comparatorProperty()); @@ -115,12 +125,6 @@ public MainTable(MainTableDataModel model, JabRefFrame frame, // Store visual state new PersistenceVisualStateTable(this, Globals.prefs); - // TODO: enable DnD - //setDragEnabled(true); - //TransferHandler xfer = new EntryTableTransferHandler(this, frame, panel); - //setTransferHandler(xfer); - //pane.setTransferHandler(xfer); - // TODO: Float marked entries //model.updateMarkingState(Globals.prefs.getBoolean(JabRefPreferences.FLOAT_MARKED_ENTRIES)); @@ -348,84 +352,6 @@ public List getSelectedEntries() { .collect(Collectors.toList()); } - /** - * This method sets up what Comparators are used for the various table columns. - * The ComparatorChooser enables and disables such Comparators as the user clicks - * columns, but this is where the Comparators are defined. Also, the ComparatorChooser - * is initialized with the sort order defined in Preferences. - */ - private void setupComparatorChooser() { - // TODO: Proper sorting - - /* - // Set initial sort columns: - - // Default sort order: - String[] sortFields = new String[] { - Globals.prefs.get(JabRefPreferences.TABLE_PRIMARY_SORT_FIELD), - Globals.prefs.get(JabRefPreferences.TABLE_SECONDARY_SORT_FIELD), - Globals.prefs.get(JabRefPreferences.TABLE_TERTIARY_SORT_FIELD) - }; - boolean[] sortDirections = new boolean[] { - Globals.prefs.getBoolean(JabRefPreferences.TABLE_PRIMARY_SORT_DESCENDING), - Globals.prefs.getBoolean(JabRefPreferences.TABLE_SECONDARY_SORT_DESCENDING), - Globals.prefs.getBoolean(JabRefPreferences.TABLE_TERTIARY_SORT_DESCENDING) - }; // descending - - model.getSortedForUserDefinedTableColumnSorting().getReadWriteLock().writeLock().lock(); - try { - for (int i = 0; i < sortFields.length; i++) { - int index = -1; - - // TODO where is this prefix set? - // if (!sortFields[i].startsWith(MainTableFormat.ICON_COLUMN_PREFIX)) - if (sortFields[i].startsWith("iconcol:")) { - for (int j = 0; j < tableFormat.getColumnCount(); j++) { - if (sortFields[i].equals(tableFormat.getColumnName(j))) { - index = j; - break; - } - } - } else { - index = tableFormat.getColumnIndex(sortFields[i]); - } - if (index >= 0) { - comparatorChooser.appendComparator(index, 0, sortDirections[i]); - } - } - } finally { - model.getSortedForUserDefinedTableColumnSorting().getReadWriteLock().writeLock().unlock(); - } - - // Add action listener so we can remember the sort order: - comparatorChooser.addSortActionListener(e -> { - // Get the information about the current sort order: - List fields = getCurrentSortFields(); - List order = getCurrentSortOrder(); - // Update preferences: - int count = Math.min(fields.size(), order.size()); - if (count >= 1) { - Globals.prefs.put(JabRefPreferences.TABLE_PRIMARY_SORT_FIELD, fields.get(0)); - Globals.prefs.putBoolean(JabRefPreferences.TABLE_PRIMARY_SORT_DESCENDING, order.get(0)); - } - if (count >= 2) { - Globals.prefs.put(JabRefPreferences.TABLE_SECONDARY_SORT_FIELD, fields.get(1)); - Globals.prefs.putBoolean(JabRefPreferences.TABLE_SECONDARY_SORT_DESCENDING, order.get(1)); - } else { - Globals.prefs.put(JabRefPreferences.TABLE_SECONDARY_SORT_FIELD, ""); - Globals.prefs.putBoolean(JabRefPreferences.TABLE_SECONDARY_SORT_DESCENDING, false); - } - if (count >= 3) { - Globals.prefs.put(JabRefPreferences.TABLE_TERTIARY_SORT_FIELD, fields.get(2)); - Globals.prefs.putBoolean(JabRefPreferences.TABLE_TERTIARY_SORT_DESCENDING, order.get(2)); - } else { - Globals.prefs.put(JabRefPreferences.TABLE_TERTIARY_SORT_FIELD, ""); - Globals.prefs.putBoolean(JabRefPreferences.TABLE_TERTIARY_SORT_DESCENDING, false); - } - }); - */ - } - private Optional findEntry(BibEntry entry) { return model.getEntriesFilteredAndSorted() .stream() diff --git a/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java b/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java index fa771bc9a3b..ff343bc16c4 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java @@ -120,6 +120,7 @@ public MainTableColumnFactory(BibDatabaseContext database, ColumnPreferences pre new ValueTableCellFactory>() .withGraphic(this::createGroupColorRegion) .install(column); + column.setSortable(true); return column; } @@ -156,6 +157,7 @@ private Node createGroupColorRegion(BibEntryTableViewModel entry, List() .withText(text -> text) .install(column); + column.setSortable(true); column.setPrefWidth(preferences.getPrefColumnWidth(columnName)); columns.add(column); } @@ -199,6 +201,7 @@ private TableColumn column.setComparator(new RankingFieldComparator()); } + column.setSortable(true); return column; } @@ -374,7 +377,6 @@ private TableColumn> createExtraFileCol new ValueTableCellFactory>() .withGraphic(linkedFiles -> createFileIcon(linkedFiles.stream().filter(linkedFile -> linkedFile.getFileType().equalsIgnoreCase(externalFileTypeName)).collect(Collectors.toList()))) .install(column); - return column; } diff --git a/src/main/java/org/jabref/gui/maintable/NormalTableColumn.java b/src/main/java/org/jabref/gui/maintable/NormalTableColumn.java index 3407e291452..8405327047f 100644 --- a/src/main/java/org/jabref/gui/maintable/NormalTableColumn.java +++ b/src/main/java/org/jabref/gui/maintable/NormalTableColumn.java @@ -77,7 +77,7 @@ public ObservableValue getColumnValue(BibEntryTableViewModel entry) { return null; } - ObjectBinding[] dependencies = bibtexFields.stream().map(entry::getField).toArray(ObjectBinding[]::new); + ObjectBinding[] dependencies = bibtexFields.stream().map(entry::getField).toArray(ObjectBinding[]::new); return Bindings.createStringBinding(() -> computeText(entry), dependencies); } @@ -99,7 +99,7 @@ private String computeText(BibEntryTableViewModel entry) { result = toUnicode.format(MainTableNameFormatter.formatName(result)); } - if (result != null && !bibtexFields.contains(BibEntry.KEY_FIELD)) { + if ((result != null) && !bibtexFields.contains(BibEntry.KEY_FIELD)) { result = toUnicode.format(result).trim(); } return result; diff --git a/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java b/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java index 2b6e3708466..131e8b05c2e 100644 --- a/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java +++ b/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java @@ -1,10 +1,13 @@ package org.jabref.gui.maintable; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import javafx.collections.ListChangeListener; import javafx.scene.control.TableColumn; +import javafx.scene.control.TableColumn.SortType; import org.jabref.preferences.JabRefPreferences; @@ -16,12 +19,15 @@ public class PersistenceVisualStateTable { private final MainTable mainTable; private final JabRefPreferences preferences; + private final Map columnsSortOrder = new LinkedHashMap<>(); public PersistenceVisualStateTable(final MainTable mainTable, JabRefPreferences preferences) { this.mainTable = mainTable; this.preferences = preferences; mainTable.getColumns().addListener(this::onColumnsChanged); + mainTable.getColumns().forEach(col -> col.sortTypeProperty().addListener(obs -> updateColumnSortType(col.getText(), col.getSortType()))); + } private void onColumnsChanged(ListChangeListener.Change> change) { @@ -33,6 +39,12 @@ private void onColumnsChanged(ListChangeListener.Change listener = (event) -> { - boolean selected = event.getSource() == exportInSpecifiedOrder; - exportOrderPanel.setEnabled(selected); + EventHandler listener = (event) -> { + boolean selected = event.getSource() == exportInSpecifiedOrder; + exportOrderPanel.setEnabled(selected); }; exportInOriginalOrder.setOnAction(listener); @@ -52,9 +51,9 @@ public ExportSortingPrefsTab(JabRefPreferences prefs) { // create GUI builder.add(exportSortOrder, 1, 1); builder.add(new Separator(), 2, 1); - builder.add(exportInOriginalOrder, 1, 2); + builder.add(exportInOriginalOrder, 1, 2); builder.add(new Line(), 2, 3); - builder.add(exportInTableOrder, 1, 4); + builder.add(exportInTableOrder, 1, 4); builder.add(new Line(), 2, 5); builder.add(exportInSpecifiedOrder, 1, 6); builder.add(new Line(), 2, 7); @@ -64,6 +63,7 @@ public ExportSortingPrefsTab(JabRefPreferences prefs) { } + @Override public Node getBuilder() { return builder; } diff --git a/src/main/java/org/jabref/gui/preferences/TablePrefsTab.java b/src/main/java/org/jabref/gui/preferences/TablePrefsTab.java index 9069ac21e09..4ec10405351 100644 --- a/src/main/java/org/jabref/gui/preferences/TablePrefsTab.java +++ b/src/main/java/org/jabref/gui/preferences/TablePrefsTab.java @@ -1,24 +1,13 @@ package org.jabref.gui.preferences; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Objects; - -import javafx.collections.FXCollections; import javafx.scene.Node; import javafx.scene.control.CheckBox; -import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; -import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; -import org.jabref.Globals; import org.jabref.logic.l10n.Localization; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.InternalBibtexFields; import org.jabref.preferences.JabRefPreferences; class TablePrefsTab extends Pane implements PrefsTab { @@ -26,9 +15,6 @@ class TablePrefsTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; private final CheckBox autoResizeMode; - private final CheckBox priDesc; - private final CheckBox secDesc; - private final CheckBox terDesc; private final RadioButton namesAsIs; private final RadioButton namesFf; @@ -38,13 +24,6 @@ class TablePrefsTab extends Pane implements PrefsTab { private final RadioButton noAbbrNames; private final RadioButton lastNamesOnly; - private final TextField priField; - private final TextField secField; - private final TextField terField; - private final TextField numericFields; - private final ComboBox priSort; - private final ComboBox secSort; - private final ComboBox terSort; private final GridPane builder = new GridPane(); /** @@ -62,13 +41,6 @@ public TablePrefsTab(JabRefPreferences prefs) { * * http://sourceforge.net/tracker/index.php?func=detail&aid=1540646&group_id=92314&atid=600306 */ - List fieldNames = InternalBibtexFields.getAllPublicFieldNames(); - fieldNames.add(BibEntry.KEY_FIELD); - Collections.sort(fieldNames); - String[] allPlusKey = fieldNames.toArray(new String[fieldNames.size()]); - priSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); - secSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); - terSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); autoResizeMode = new CheckBox(Localization.lang("Fit table horizontally on screen")); namesAsIs = new RadioButton(Localization.lang("Show names unchanged")); @@ -79,36 +51,6 @@ public TablePrefsTab(JabRefPreferences prefs) { abbrNames = new RadioButton(Localization.lang("Abbreviate names")); lastNamesOnly = new RadioButton(Localization.lang("Show last names only")); - priField = new TextField(); - secField = new TextField(); - terField = new TextField(); - - numericFields = new TextField(); - - priSort.setValue(Localization.lang("")); - terSort.setValue(Localization.lang("= Abbreviate\ journal\ names\ of\ the\ selected\ entries\ (ISO\ abbreviation)=Abbreviate journal names of the selected entries (ISO abbreviation) Abbreviate\ journal\ names\ of\ the\ selected\ entries\ (MEDLINE\ abbreviation)=Abbreviate journal names of the selected entries (MEDLINE abbreviation) @@ -253,8 +251,6 @@ Default\ grouping\ field=Default grouping field Default\ pattern=Default pattern -Default\ sort\ criteria=Default sort criteria - Delete=Delete Delete\ custom\ format=Delete custom format @@ -1203,7 +1199,6 @@ Use\ IEEE\ LaTeX\ abbreviations=Use IEEE LaTeX abbreviations When\ opening\ file\ link,\ search\ for\ matching\ file\ if\ no\ link\ is\ defined=When opening file link, search for matching file if no link is defined Settings\ for\ %0=Settings for %0 -Sort\ the\ following\ fields\ as\ numeric\ fields=Sort the following fields as numeric fields Line\ %0\:\ Found\ corrupted\ BibTeX\ key.=Line %0: Found corrupted BibTeX key. Line\ %0\:\ Found\ corrupted\ BibTeX\ key\ (contains\ whitespaces).=Line %0: Found corrupted BibTeX key (contains whitespaces). Line\ %0\:\ Found\ corrupted\ BibTeX\ key\ (comma\ missing).=Line %0: Found corrupted BibTeX key (comma missing).