From 2999474ad2aac42cbb4aa27e01e46d2728ba9a32 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 26 Feb 2018 20:03:51 +0100 Subject: [PATCH 01/28] Reenable drag'n'drop support for tabs / libraries (#3688) * Use library for drag'n'drop support for tabs * Use DnDTab library --- build.gradle | 2 ++ external-libraries.txt | 5 +++++ src/main/java/org/jabref/gui/JabRefFrame.java | 9 ++++++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 78945e5674e..a208157e09a 100644 --- a/build.gradle +++ b/build.gradle @@ -131,6 +131,8 @@ dependencies { compile 'org.fxmisc.easybind:easybind:1.0.3' compile 'org.fxmisc.flowless:flowless:0.6' compile 'org.fxmisc.richtext:richtextfx:0.8.2' + compile 'com.sibvisions.external.jvxfx:dndtabpane:0.1' + // Cannot be updated to 9.*.* until Jabref works with Java 9 compile 'org.controlsfx:controlsfx:8.40.15-SNAPSHOT' diff --git a/external-libraries.txt b/external-libraries.txt index 5f654af0f8a..334acb76d3c 100644 --- a/external-libraries.txt +++ b/external-libraries.txt @@ -80,6 +80,11 @@ Project: Application Insights SDK for Java URL: https://github.com/Microsoft/ApplicationInsights-Java License: MIT +Id: com.sibvisions.external.jvxfx:DnDTabPane +Project: Drag'n'Drop TabPane +URL: https://github.com/sibvisions/javafx.DndTabPane +License: EPL-1.0 + Id: commons-cli:commons-cli Project: Apache Commons CLI URL: http://commons.apache.org/cli/ diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index a12403321ed..9fc82fc4d43 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -134,6 +134,8 @@ import org.jabref.preferences.SearchPreferences; import com.google.common.eventbus.Subscribe; +import org.eclipse.fx.ui.controls.tabpane.DndTabPane; +import org.eclipse.fx.ui.controls.tabpane.DndTabPaneFactory; import org.fxmisc.easybind.EasyBind; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -205,7 +207,7 @@ public class JabRefFrame extends BorderPane implements OutputPrinter { private final Stage mainStage; // The sidepane manager takes care of populating the sidepane. private SidePaneManager sidePaneManager; - private final TabPane tabbedPane = new TabPane(); + private TabPane tabbedPane; private PushToApplications pushApplications; private final CountingUndoManager undoManager = new CountingUndoManager(); private final DialogService dialogService; @@ -258,6 +260,9 @@ private void init() { sidePaneManager = new SidePaneManager(Globals.prefs, this); sidePane = sidePaneManager.getPane(); + Pane containerPane = DndTabPaneFactory.createDefaultDnDPane(DndTabPaneFactory.FeedbackType.MARKER, null); + tabbedPane = (DndTabPane) containerPane.getChildren().get(0); + initLayout(); initActions(); @@ -269,8 +274,6 @@ private void init() { // JabRefPreferences.SIZE_Y); //pw.displayWindowAtStoredLocation(); - tabbedPane.setBorder(null); - /* * The following state listener makes sure focus is registered with the * correct database when the user switches tabs. Without this, From 01bb49e49faa6214f2588b5cc1000b1c9ca4a71e Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 27 Feb 2018 16:38:50 +0100 Subject: [PATCH 02/28] Show empty group pane if no database is open (#3785) --- src/main/java/org/jabref/gui/JabRefFrame.java | 1 + .../org/jabref/gui/groups/GroupTreeViewModel.java | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 9fc82fc4d43..ac58cee18cd 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -281,6 +281,7 @@ private void init() { */ EasyBind.subscribe(tabbedPane.getSelectionModel().selectedItemProperty(), e -> { if (e == null) { + Globals.stateManager.activeDatabaseProperty().setValue(Optional.empty()); return; } diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java b/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java index a4e2889b9e7..0ad63a4c994 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java @@ -33,6 +33,8 @@ import org.jabref.model.groups.GroupTreeNode; import org.jabref.model.metadata.MetaData; +import org.fxmisc.easybind.EasyBind; + public class GroupTreeViewModel extends AbstractViewModel { private final ObjectProperty rootGroup = new SimpleObjectProperty<>(); @@ -53,9 +55,8 @@ public GroupTreeViewModel(StateManager stateManager, DialogService dialogService this.taskExecutor = Objects.requireNonNull(taskExecutor); // Register listener - stateManager.activeDatabaseProperty() - .addListener((observable, oldValue, newValue) -> onActiveDatabaseChanged(newValue)); - selectedGroups.addListener((observable, oldValue, newValue) -> onSelectedGroupChanged(newValue)); + EasyBind.subscribe(stateManager.activeDatabaseProperty(), this::onActiveDatabaseChanged); + EasyBind.subscribe(selectedGroups, this::onSelectedGroupChanged); // Set-up bindings filterPredicate @@ -122,8 +123,10 @@ private void onActiveDatabaseChanged(Optional newDatabase) { rootGroup.setValue(newRoot); this.selectedGroups.setAll( stateManager.getSelectedGroup(newDatabase.get()).stream() - .map(selectedGroup -> new GroupNodeViewModel(newDatabase.get(), stateManager, taskExecutor, selectedGroup)) - .collect(Collectors.toList())); + .map(selectedGroup -> new GroupNodeViewModel(newDatabase.get(), stateManager, taskExecutor, selectedGroup)) + .collect(Collectors.toList())); + } else { + rootGroup.setValue(GroupNodeViewModel.getAllEntriesGroup(new BibDatabaseContext(), stateManager, taskExecutor)); } currentDatabase = newDatabase; From fc3614011619921149b22d956a41761bb82ad18a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 27 Feb 2018 16:39:02 +0100 Subject: [PATCH 03/28] Allow side pane to be completely hidden (#3784) --- src/main/java/org/jabref/gui/JabRefFrame.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index ac58cee18cd..ab1d548af17 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -593,9 +593,19 @@ private void initLayout() { @Override public void changed(ObservableValue observable, Boolean oldValue, Boolean showing) { if (showing) { - splitPane.setDividerPositions(prefs.getDouble(JabRefPreferences.SIDE_PANE_WIDTH)); - EasyBind.subscribe(splitPane.getDividers().get(0).positionProperty(), - position -> prefs.putDouble(JabRefPreferences.SIDE_PANE_WIDTH, position.doubleValue())); + setDividerPosition(); + + EasyBind.subscribe(sidePane.visibleProperty(), visible -> { + if (visible) { + if (!splitPane.getItems().contains(sidePane)) { + splitPane.getItems().add(0, sidePane); + setDividerPosition(); + } + } else { + splitPane.getItems().remove(sidePane); + } + }); + mainStage.showingProperty().removeListener(this); observable.removeListener(this); } @@ -631,6 +641,14 @@ public void changed(ObservableValue observable, Boolean oldVa statusLabel.setForeground(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR.darker()); } + private void setDividerPosition() { + splitPane.setDividerPositions(prefs.getDouble(JabRefPreferences.SIDE_PANE_WIDTH)); + if (!splitPane.getDividers().isEmpty()) { + EasyBind.subscribe(splitPane.getDividers().get(0).positionProperty(), + position -> prefs.putDouble(JabRefPreferences.SIDE_PANE_WIDTH, position.doubleValue())); + } + } + private Node createToolbar() { Pane leftSpacer = new Pane(); HBox.setHgrow(leftSpacer, Priority.SOMETIMES); @@ -652,7 +670,7 @@ private Node createToolbar() { factory.createIconButton(StandardActions.SAVE_LIBRARY, new OldDatabaseCommandWrapper(Actions.SAVE, this, Globals.stateManager)), leftSpacer); - leftSide.minWidthProperty().bind(sidePane.widthProperty()); + leftSide.setMinWidth(100); leftSide.prefWidthProperty().bind(sidePane.widthProperty()); leftSide.maxWidthProperty().bind(sidePane.widthProperty()); From d8914a88ed466b1bedf33d914a39f6a0b2e1ca95 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 27 Feb 2018 18:28:01 +0100 Subject: [PATCH 04/28] Save order of columns across sessions (#3783) --- .../org/jabref/gui/BasePanelPreferences.java | 2 +- .../gui/maintable/ColumnPreferences.java | 83 ------------ .../org/jabref/gui/maintable/MainTable.java | 7 +- .../gui/maintable/MainTableColumnFactory.java | 2 +- .../gui/maintable/MainTablePreferences.java | 10 -- ...ableColumn.java => NormalTableColumn.java} | 26 ++-- .../PersistenceTableColumnListener.java | 123 ------------------ .../PersistenceVisualStateTable.java | 58 +++++++++ .../jabref/gui/preftabs/TableColumnsTab.java | 91 ++++++------- .../org/jabref/model/entry/FieldName.java | 1 - .../model/entry/InternalBibtexFields.java | 6 - .../jabref/preferences/JabRefPreferences.java | 86 +++++++++++- 12 files changed, 194 insertions(+), 301 deletions(-) rename src/main/java/org/jabref/gui/maintable/{StringTableColumn.java => NormalTableColumn.java} (87%) delete mode 100644 src/main/java/org/jabref/gui/maintable/PersistenceTableColumnListener.java create mode 100644 src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java diff --git a/src/main/java/org/jabref/gui/BasePanelPreferences.java b/src/main/java/org/jabref/gui/BasePanelPreferences.java index 52415e959b4..c248f869dcc 100644 --- a/src/main/java/org/jabref/gui/BasePanelPreferences.java +++ b/src/main/java/org/jabref/gui/BasePanelPreferences.java @@ -32,7 +32,7 @@ public BasePanelPreferences(MainTablePreferences tablePreferences, AutoCompleteP public static BasePanelPreferences from(JabRefPreferences preferences) { BasePanelPreferences basePanelPreferences = new BasePanelPreferences( - MainTablePreferences.from(preferences), + preferences.getMainTablePreferences(), preferences.getAutoCompletePreferences(), EntryEditorPreferences.from(preferences), Globals.getKeyPrefs(), diff --git a/src/main/java/org/jabref/gui/maintable/ColumnPreferences.java b/src/main/java/org/jabref/gui/maintable/ColumnPreferences.java index ceebacb1e40..ead48b18a3d 100644 --- a/src/main/java/org/jabref/gui/maintable/ColumnPreferences.java +++ b/src/main/java/org/jabref/gui/maintable/ColumnPreferences.java @@ -1,23 +1,13 @@ package org.jabref.gui.maintable; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.TreeMap; -import java.util.stream.Collectors; import org.jabref.model.entry.BibtexSingleField; import org.jabref.model.entry.specialfields.SpecialField; -import org.jabref.preferences.JabRefPreferences; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class ColumnPreferences { - private static final Logger LOGGER = LoggerFactory.getLogger(ColumnPreferences.class); - private final boolean showFileColumn; private final boolean showUrlColumn; private final boolean preferDoiOverUrl; @@ -38,79 +28,6 @@ public ColumnPreferences(boolean showFileColumn, boolean showUrlColumn, boolean this.columnWidths = columnWidths; } - public static ColumnPreferences from(JabRefPreferences preferences) { - return new ColumnPreferences( - preferences.getBoolean(JabRefPreferences.FILE_COLUMN), - preferences.getBoolean(JabRefPreferences.URL_COLUMN), - preferences.getBoolean(JabRefPreferences.PREFER_URL_DOI), - preferences.getBoolean(JabRefPreferences.ARXIV_COLUMN), - preferences.getStringList(JabRefPreferences.COLUMN_NAMES), - createSpecialFieldColumns(preferences), - createExtraFileColumns(preferences), - createColumnWidths(preferences) - ); - } - - private static Map createColumnWidths(JabRefPreferences preferences) { - List columns = preferences.getStringList(JabRefPreferences.COLUMN_NAMES); - List widths = preferences - .getStringList(JabRefPreferences.COLUMN_WIDTHS) - .stream() - .map(string -> { - try { - return Double.parseDouble(string); - } catch (NumberFormatException e) { - LOGGER.error("Exception while parsing column widths. Choosing default.", e); - return BibtexSingleField.DEFAULT_FIELD_LENGTH; - } - }) - .collect(Collectors.toList()); - - Map map = new TreeMap<>(); - for (int i = 0; i < columns.size(); i++) { - map.put(columns.get(i), widths.get(i)); - } - return map; - } - - private static List createExtraFileColumns(JabRefPreferences preferences) { - if (preferences.getBoolean(JabRefPreferences.EXTRA_FILE_COLUMNS)) { - return preferences.getStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS); - } else { - return Collections.emptyList(); - } - } - - private static List createSpecialFieldColumns(JabRefPreferences preferences) { - if (preferences.getBoolean(JabRefPreferences.SPECIALFIELDSENABLED)) { - List fieldsToShow = new ArrayList<>(); - if (preferences.getBoolean(JabRefPreferences.SHOWCOLUMN_RANKING)) { - fieldsToShow.add(SpecialField.RANKING); - } - if (preferences.getBoolean(JabRefPreferences.SHOWCOLUMN_RELEVANCE)) { - fieldsToShow.add(SpecialField.RELEVANCE); - } - if (preferences.getBoolean(JabRefPreferences.SHOWCOLUMN_QUALITY)) { - fieldsToShow.add(SpecialField.QUALITY); - } - - if (preferences.getBoolean(JabRefPreferences.SHOWCOLUMN_PRIORITY)) { - fieldsToShow.add(SpecialField.PRIORITY); - } - - if (preferences.getBoolean(JabRefPreferences.SHOWCOLUMN_PRINTED)) { - fieldsToShow.add(SpecialField.PRINTED); - } - - if (preferences.getBoolean(JabRefPreferences.SHOWCOLUMN_READ)) { - fieldsToShow.add(SpecialField.READ_STATUS); - } - return fieldsToShow; - } else { - return Collections.emptyList(); - } - } - public boolean showFileColumn() { return showFileColumn; } diff --git a/src/main/java/org/jabref/gui/maintable/MainTable.java b/src/main/java/org/jabref/gui/maintable/MainTable.java index 84d8f548af1..1df86ee0b3c 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTable.java +++ b/src/main/java/org/jabref/gui/maintable/MainTable.java @@ -73,7 +73,7 @@ public class MainTable extends TableView { private final BibDatabaseContext database; private final UndoManager undoManager; // needed to activate/deactivate the listener - private PersistenceTableColumnListener tableColumnListener; + private PersistenceVisualStateTable tableColumnListener; private final MainTableDataModel model; @@ -135,9 +135,8 @@ public String getToolTipText(MouseEvent event) { } */ - // TODO: store column widths - //this.tableColumnListener = new PersistenceTableColumnListener(this); - //setWidths(); + // Store visual state + new PersistenceVisualStateTable(this, Globals.prefs); // TODO: enable DnD //setDragEnabled(true); diff --git a/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java b/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java index e079282a5fe..71ae07ed67d 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java @@ -101,7 +101,7 @@ public MainTableColumnFactory(BibDatabaseContext database, ColumnPreferences pre // Stored column name will be used as header // There might be more than one field to display, e.g., "author/editor" or "date/year" - so split String[] fields = columnName.split(FieldName.FIELD_SEPARATOR); - StringTableColumn column = new StringTableColumn(columnName, Arrays.asList(fields), database.getDatabase()); + NormalTableColumn column = new NormalTableColumn(columnName, Arrays.asList(fields), database.getDatabase()); new ValueTableCellFactory() .withText(text -> text) .install(column); diff --git a/src/main/java/org/jabref/gui/maintable/MainTablePreferences.java b/src/main/java/org/jabref/gui/maintable/MainTablePreferences.java index a16aed83f92..f4c1b6baec9 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTablePreferences.java +++ b/src/main/java/org/jabref/gui/maintable/MainTablePreferences.java @@ -1,8 +1,5 @@ package org.jabref.gui.maintable; -import org.jabref.Globals; -import org.jabref.preferences.JabRefPreferences; - public class MainTablePreferences { private final boolean showGrid; private final ColumnPreferences columnPreferences; @@ -14,13 +11,6 @@ public MainTablePreferences(boolean showGrid, ColumnPreferences columnPreference this.resizeColumnsToFit = resizeColumnsToFit; } - public static MainTablePreferences from(JabRefPreferences preferences) { - return new MainTablePreferences( - Globals.prefs.getBoolean(JabRefPreferences.TABLE_SHOW_GRID), - ColumnPreferences.from(preferences), - Globals.prefs.getBoolean(JabRefPreferences.AUTO_RESIZE_MODE)); - } - public ColumnPreferences getColumnPreferences() { return columnPreferences; } diff --git a/src/main/java/org/jabref/gui/maintable/StringTableColumn.java b/src/main/java/org/jabref/gui/maintable/NormalTableColumn.java similarity index 87% rename from src/main/java/org/jabref/gui/maintable/StringTableColumn.java rename to src/main/java/org/jabref/gui/maintable/NormalTableColumn.java index 252ff5970c6..59b1b69ce3f 100644 --- a/src/main/java/org/jabref/gui/maintable/StringTableColumn.java +++ b/src/main/java/org/jabref/gui/maintable/NormalTableColumn.java @@ -20,7 +20,7 @@ import org.jabref.model.entry.FieldProperty; import org.jabref.model.entry.InternalBibtexFields; -public class StringTableColumn extends MainTableColumn { +public class NormalTableColumn extends MainTableColumn { private final List bibtexFields; @@ -31,31 +31,17 @@ public class StringTableColumn extends MainTableColumn { private final Optional database; private final LayoutFormatter toUnicode = new LatexToUnicodeFormatter(); + private final String columnName; - public StringTableColumn(String columnName) { - super(columnName); - this.bibtexFields = Collections.emptyList(); - this.isIconColumn = false; - this.iconLabel = Optional.empty(); - this.database = Optional.empty(); - } - - public StringTableColumn(String columnName, List bibtexFields, BibDatabase database) { + public NormalTableColumn(String columnName, List bibtexFields, BibDatabase database) { super(columnName); + this.columnName = columnName; this.bibtexFields = Collections.unmodifiableList(bibtexFields); this.isIconColumn = false; this.iconLabel = Optional.empty(); this.database = Optional.of(database); } - public StringTableColumn(String columnName, List bibtexFields, JabRefIcon iconLabel) { - super(columnName); - this.bibtexFields = Collections.unmodifiableList(bibtexFields); - this.isIconColumn = true; - this.iconLabel = Optional.of(iconLabel); - this.database = Optional.empty(); - } - /** * Get the table column name to be displayed in the UI * @@ -161,4 +147,8 @@ public boolean isResolved(BibEntry entry) { } return (!resolvedFieldContent.equals(plainFieldContent)); } + + public String getColumnName() { + return columnName; + } } diff --git a/src/main/java/org/jabref/gui/maintable/PersistenceTableColumnListener.java b/src/main/java/org/jabref/gui/maintable/PersistenceTableColumnListener.java deleted file mode 100644 index a2fde3ff259..00000000000 --- a/src/main/java/org/jabref/gui/maintable/PersistenceTableColumnListener.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.jabref.gui.maintable; - -import javax.swing.event.ChangeEvent; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.TableColumnModelEvent; -import javax.swing.event.TableColumnModelListener; - -/** - * Listens for TableColumnModelEvents to keep track of changes made to the - * MainTable columns, like reordering or resizing. - * - * Changes to columns without a name and the "#" column are not saved. To have - * consistent behavior (e.g. as in TableColumnsTab). - * - * @author Fabian Bieker - * @author Daniel Waeber - * @since 12/2008 - * - */ -public class PersistenceTableColumnListener implements TableColumnModelListener { - - private static final String RECEIVED_NULL_EVENT = " received null event"; - - private static final String SIMPLE_CLASS_NAME = PersistenceTableColumnListener.class.getSimpleName(); - - // needed to get column names / indices mapped from view to model - // and to access the table model - private final MainTable mainTable; - - /** - * @param mainTable - */ - public PersistenceTableColumnListener(final MainTable mainTable) { - this.mainTable = mainTable; - } - - /** - * update columns names and their width, store it in the global prefs. - */ - private void updateColumnPrefs() { - /* - final int columnCount = mainTable.getColumnCount(); - List storedColumns = new ArrayList<>(columnCount - 1); - List columnsWidths = new ArrayList<>(columnCount - 1); - int ncWidth = -1; - - for (int i = 0; i < columnCount; i++) { - final String name = mainTable.getColumnName(i); - if ((name != null) && !name.isEmpty()) { - if (FieldName.NUMBER_COL.equals(name)) { - ncWidth = mainTable.getColumnModel().getColumn(i).getWidth(); - } else { - storedColumns.add(name.toLowerCase(Locale.ROOT)); - columnsWidths.add(String.valueOf(mainTable.getColumnModel().getColumn(i).getWidth())); - } - } - } - - // Finally, we store the new preferences. - Globals.prefs.putStringList(JabRefPreferences.COLUMN_NAMES, storedColumns); - Globals.prefs.putStringList(JabRefPreferences.COLUMN_WIDTHS, columnsWidths); - - // width of the number ("#") column - Globals.prefs.putInt(JabRefPreferences.NUMBER_COL_WIDTH, ncWidth); - */ - } - - /** - * @see javax.swing.event.TableColumnModelListener#columnAdded(javax.swing.event.TableColumnModelEvent) - */ - @Override - public void columnAdded(TableColumnModelEvent e) { - assert e != null : PersistenceTableColumnListener.SIMPLE_CLASS_NAME + RECEIVED_NULL_EVENT; - - updateColumnPrefs(); - } - - /** - * @see javax.swing.event.TableColumnModelListener#columnMarginChanged(javax.swing.event.ChangeEvent) - */ - @Override - public void columnMarginChanged(ChangeEvent e) { - assert e != null : PersistenceTableColumnListener.SIMPLE_CLASS_NAME + RECEIVED_NULL_EVENT; - - updateColumnPrefs(); - } - - /** - * @see javax.swing.event.TableColumnModelListener#columnMoved(javax.swing.event.TableColumnModelEvent) - */ - @Override - public void columnMoved(TableColumnModelEvent e) { - assert e != null : PersistenceTableColumnListener.SIMPLE_CLASS_NAME + RECEIVED_NULL_EVENT; - - // not really moved, ignore ... - if (e.getFromIndex() == e.getToIndex()) { - return; - } - - updateColumnPrefs(); - - } - - /** - * @see javax.swing.event.TableColumnModelListener#columnRemoved(javax.swing.event.TableColumnModelEvent) - */ - @Override - public void columnRemoved(TableColumnModelEvent e) { - assert e != null : PersistenceTableColumnListener.SIMPLE_CLASS_NAME + RECEIVED_NULL_EVENT; - - updateColumnPrefs(); - - } - - /** - * @see javax.swing.event.TableColumnModelListener#columnSelectionChanged(javax.swing.event.ListSelectionEvent) - */ - @Override - public void columnSelectionChanged(ListSelectionEvent e) { - // ignore - } - -} diff --git a/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java b/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java new file mode 100644 index 00000000000..2b6e3708466 --- /dev/null +++ b/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java @@ -0,0 +1,58 @@ +package org.jabref.gui.maintable; + +import java.util.ArrayList; +import java.util.List; + +import javafx.collections.ListChangeListener; +import javafx.scene.control.TableColumn; + +import org.jabref.preferences.JabRefPreferences; + +/** + * Keep track of changes made to the columns, like reordering or resizing. + * + */ +public class PersistenceVisualStateTable { + + private final MainTable mainTable; + private final JabRefPreferences preferences; + + public PersistenceVisualStateTable(final MainTable mainTable, JabRefPreferences preferences) { + this.mainTable = mainTable; + this.preferences = preferences; + + mainTable.getColumns().addListener(this::onColumnsChanged); + } + + private void onColumnsChanged(ListChangeListener.Change> change) { + boolean changed = false; + while (change.next()) { + changed = true; + } + + if (changed) { + updateColumnPreferences(); + } + } + + /** + * Store shown columns and their width in preferences. + */ + private void updateColumnPreferences() { + List columnNames = new ArrayList<>(); + List columnsWidths = new ArrayList<>(); + + for (TableColumn column : mainTable.getColumns()) { + if (column instanceof NormalTableColumn) { + NormalTableColumn normalColumn = (NormalTableColumn) column; + + columnNames.add(normalColumn.getColumnName()); + columnsWidths.add(String.valueOf(normalColumn.getWidth())); + } + } + + // Finally, we store the new preferences. + preferences.putStringList(JabRefPreferences.COLUMN_NAMES, columnNames); + preferences.putStringList(JabRefPreferences.COLUMN_WIDTHS, columnsWidths); + } +} diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index 91b77e62d7f..d47fb04aff6 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -41,7 +41,6 @@ import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibtexSingleField; -import org.jabref.model.entry.FieldName; import org.jabref.preferences.JabRefPreferences; import com.jgoodies.forms.builder.DefaultFormBuilder; @@ -58,7 +57,6 @@ class TableColumnsTab extends JPanel implements PrefsTab { private boolean tableChanged; private final JTable colSetup; private int rowCount = -1; - private int ncWidth = -1; private final List tableRows = new ArrayList<>(10); private final JabRefFrame frame; @@ -118,9 +116,6 @@ public int getColumnCount() { @Override public Object getValueAt(int row, int column) { int internalRow = row; - if (internalRow == 0) { - return column == 0 ? FieldName.NUMBER_COL : String.valueOf(ncWidth); - } internalRow--; if (internalRow >= tableRows.size()) { return ""; @@ -164,11 +159,6 @@ public void setValueAt(Object value, int row, int col) { tableRows.add(new TableRow("", -1)); } - if ((row == 0) && (col == 1)) { - ncWidth = Integer.parseInt(value.toString()); - return; - } - TableRow rowContent = tableRows.get(row - 1); if (col == 0) { @@ -332,45 +322,6 @@ public void setValueAt(Object value, int row, int col) { add(pan, BorderLayout.CENTER); } - /*** end: special fields ***/ - - static class TableRow { - - private String name; - private double length; - - public TableRow() { - name = ""; - length = BibtexSingleField.DEFAULT_FIELD_LENGTH; - } - - public TableRow(String name) { - this.name = name; - length = BibtexSingleField.DEFAULT_FIELD_LENGTH; - } - - public TableRow(String name, int length) { - this.name = name; - this.length = length; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public double getLength() { - return length; - } - - public void setLength(int length) { - this.length = length; - } - } - @Override public void setValues() { fileColumn.setSelected(prefs.getBoolean(JabRefPreferences.FILE_COLUMN)); @@ -438,14 +389,51 @@ public void setValues() { List lengths = prefs.getStringList(JabRefPreferences.COLUMN_WIDTHS); for (int i = 0; i < names.size(); i++) { if (i < lengths.size()) { - tableRows.add(new TableRow(names.get(i), Integer.parseInt(lengths.get(i)))); + tableRows.add(new TableRow(names.get(i), Double.parseDouble(lengths.get(i)))); } else { tableRows.add(new TableRow(names.get(i))); } } rowCount = tableRows.size() + 5; - ncWidth = prefs.getInt(JabRefPreferences.NUMBER_COL_WIDTH); + } + + /*** end: special fields ***/ + + static class TableRow { + + private String name; + private double length; + + public TableRow() { + name = ""; + length = BibtexSingleField.DEFAULT_FIELD_LENGTH; + } + + public TableRow(String name) { + this.name = name; + length = BibtexSingleField.DEFAULT_FIELD_LENGTH; + } + public TableRow(String name, double length) { + this.name = name; + this.length = length; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } } class DeleteRowAction extends AbstractAction { @@ -769,7 +757,6 @@ public void storeSettings() { List names = new ArrayList<>(tableRows.size()); List widths = new ArrayList<>(tableRows.size()); - prefs.putInt(JabRefPreferences.NUMBER_COL_WIDTH, ncWidth); for (TableRow tr : tableRows) { names.add(tr.getName().toLowerCase(Locale.ROOT)); widths.add(String.valueOf(tr.getLength())); diff --git a/src/main/java/org/jabref/model/entry/FieldName.java b/src/main/java/org/jabref/model/entry/FieldName.java index ad2a55a0a95..97022fc2f7d 100644 --- a/src/main/java/org/jabref/model/entry/FieldName.java +++ b/src/main/java/org/jabref/model/entry/FieldName.java @@ -145,7 +145,6 @@ public class FieldName { // JabRef internal field names public static final String OWNER = "owner"; public static final String TIMESTAMP = "timestamp"; // Not the actual field name, but the default value - public static final String NUMBER_COL = "#"; public static final String GROUPS = "groups"; public static final String SEARCH_INTERNAL = "__search"; public static final String GROUPSEARCH_INTERNAL = "__groupsearch"; diff --git a/src/main/java/org/jabref/model/entry/InternalBibtexFields.java b/src/main/java/org/jabref/model/entry/InternalBibtexFields.java index 689b028fd1c..ee2bfb21d99 100644 --- a/src/main/java/org/jabref/model/entry/InternalBibtexFields.java +++ b/src/main/java/org/jabref/model/entry/InternalBibtexFields.java @@ -190,12 +190,6 @@ private InternalBibtexFields() { add(dummy); // some internal fields ---------------------------------------------- - dummy = new BibtexSingleField(FieldName.NUMBER_COL, false, 32); - dummy.setPrivate(); - dummy.setWriteable(false); - dummy.setDisplayable(false); - add(dummy); - dummy = new BibtexSingleField(FieldName.OWNER, false).withProperties(FieldProperty.OWNER); dummy.setPrivate(); add(dummy); diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 5826722fb4e..569f569941b 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -25,6 +25,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.TreeMap; import java.util.UUID; import java.util.prefs.BackingStoreException; import java.util.prefs.InvalidPreferencesFormatException; @@ -41,6 +42,8 @@ import org.jabref.gui.desktop.JabRefDesktop; import org.jabref.gui.entryeditor.EntryEditorTabList; import org.jabref.gui.keyboard.KeyBindingRepository; +import org.jabref.gui.maintable.ColumnPreferences; +import org.jabref.gui.maintable.MainTablePreferences; import org.jabref.gui.preftabs.ImportSettingsTab; import org.jabref.logic.bibtex.FieldContentParserPreferences; import org.jabref.logic.bibtex.LatexFieldFormatterPreferences; @@ -74,9 +77,11 @@ import org.jabref.model.bibtexkeypattern.GlobalBibtexKeyPattern; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibtexSingleField; import org.jabref.model.entry.CustomEntryType; import org.jabref.model.entry.FieldName; import org.jabref.model.entry.InternalBibtexFields; +import org.jabref.model.entry.specialfields.SpecialField; import org.jabref.model.metadata.FileDirectoryPreferences; import org.jabref.model.metadata.SaveOrderConfig; import org.jabref.model.strings.StringUtil; @@ -182,7 +187,6 @@ public class JabRefPreferences implements PreferencesService { public static final String EXPORT_WORKING_DIRECTORY = "exportWorkingDirectory"; public static final String PREFS_EXPORT_PATH = "prefsExportPath"; public static final String WORKING_DIRECTORY = "workingDirectory"; - public static final String NUMBER_COL_WIDTH = "numberColWidth"; public static final String EDITOR_EMACS_KEYBINDINGS = "editorEMACSkeyBindings"; public static final String EDITOR_EMACS_KEYBINDINGS_REBIND_CA = "editorEMACSkeyBindingsRebindCA"; public static final String EDITOR_EMACS_KEYBINDINGS_REBIND_CF = "editorEMACSkeyBindingsRebindCF"; @@ -554,7 +558,6 @@ private JabRefPreferences() { defaults.put(COLUMN_WIDTHS, "75;300;470;60;130;100"); defaults.put(XMP_PRIVACY_FILTERS, "pdf;timestamp;keywords;owner;note;review"); defaults.put(USE_XMP_PRIVACY_FILTER, Boolean.FALSE); - defaults.put(NUMBER_COL_WIDTH, 32); defaults.put(WORKING_DIRECTORY, USER_HOME); defaults.put(EXPORT_WORKING_DIRECTORY, USER_HOME); // Remembers working directory of last import @@ -1714,4 +1717,83 @@ public void storeSidePanePreferredPositions(Map preferred putStringList(SIDE_PANE_COMPONENT_NAMES, names); putStringList(SIDE_PANE_COMPONENT_PREFERRED_POSITIONS, positions); } + + private List createExtraFileColumns() { + if (getBoolean(EXTRA_FILE_COLUMNS)) { + return getStringList(LIST_OF_FILE_COLUMNS); + } else { + return Collections.emptyList(); + } + } + + private List createSpecialFieldColumns() { + if (getBoolean(SPECIALFIELDSENABLED)) { + List fieldsToShow = new ArrayList<>(); + if (getBoolean(SHOWCOLUMN_RANKING)) { + fieldsToShow.add(SpecialField.RANKING); + } + if (getBoolean(SHOWCOLUMN_RELEVANCE)) { + fieldsToShow.add(SpecialField.RELEVANCE); + } + if (getBoolean(SHOWCOLUMN_QUALITY)) { + fieldsToShow.add(SpecialField.QUALITY); + } + + if (getBoolean(SHOWCOLUMN_PRIORITY)) { + fieldsToShow.add(SpecialField.PRIORITY); + } + + if (getBoolean(SHOWCOLUMN_PRINTED)) { + fieldsToShow.add(SpecialField.PRINTED); + } + + if (getBoolean(SHOWCOLUMN_READ)) { + fieldsToShow.add(SpecialField.READ_STATUS); + } + return fieldsToShow; + } else { + return Collections.emptyList(); + } + } + + private Map createColumnWidths() { + List columns = getStringList(COLUMN_NAMES); + List widths = getStringList(COLUMN_WIDTHS) + .stream() + .map(string -> { + try { + return Double.parseDouble(string); + } catch (NumberFormatException e) { + LOGGER.error("Exception while parsing column widths. Choosing default.", e); + return BibtexSingleField.DEFAULT_FIELD_LENGTH; + } + }) + .collect(Collectors.toList()); + + Map map = new TreeMap<>(); + for (int i = 0; i < columns.size(); i++) { + map.put(columns.get(i), widths.get(i)); + } + return map; + } + + public ColumnPreferences getColumnPreferences() { + return new ColumnPreferences( + getBoolean(FILE_COLUMN), + getBoolean(URL_COLUMN), + getBoolean(PREFER_URL_DOI), + getBoolean(ARXIV_COLUMN), + getStringList(COLUMN_NAMES), + createSpecialFieldColumns(), + createExtraFileColumns(), + createColumnWidths() + ); + } + + public MainTablePreferences getMainTablePreferences() { + return new MainTablePreferences( + getBoolean(TABLE_SHOW_GRID), + getColumnPreferences(), + getBoolean(AUTO_RESIZE_MODE)); + } } From 3710be84321997c2a5c3810d3e7c9a92be3a815b Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 1 Mar 2018 17:03:03 +0100 Subject: [PATCH 05/28] Track telemetry of each action (#3789) --- .../java/org/jabref/gui/actions/JabRefAction.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/actions/JabRefAction.java b/src/main/java/org/jabref/gui/actions/JabRefAction.java index 8c9b05a79c1..78793e9a206 100644 --- a/src/main/java/org/jabref/gui/actions/JabRefAction.java +++ b/src/main/java/org/jabref/gui/actions/JabRefAction.java @@ -1,5 +1,6 @@ package org.jabref.gui.actions; +import org.jabref.Globals; import org.jabref.gui.keyboard.KeyBindingRepository; import de.saxsys.mvvmfx.utils.commands.Command; @@ -20,6 +21,14 @@ public JabRefAction(Action action, KeyBindingRepository keyBindingRepository) { public JabRefAction(Action action, Command command, KeyBindingRepository keyBindingRepository) { this(action, keyBindingRepository); - setEventHandler(event -> command.execute()); + setEventHandler(event -> { + command.execute(); + trackExecute(); + }); + } + + private void trackExecute() { + Globals.getTelemetryClient() + .ifPresent(telemetryClient -> telemetryClient.trackEvent(getText())); } } From f4f527d492a96189219f480e47e09aaf1d0105cb Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 2 Mar 2018 12:07:17 +0100 Subject: [PATCH 06/28] Set main stage for file dialogs (#3790) * Track telemetry of each action * Set main stage for file dialogs --- .../java/org/jabref/gui/FXDialogService.java | 18 +++++++++++++----- src/main/java/org/jabref/gui/JabRefFrame.java | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/jabref/gui/FXDialogService.java b/src/main/java/org/jabref/gui/FXDialogService.java index 7ed25ab4324..be049824e77 100644 --- a/src/main/java/org/jabref/gui/FXDialogService.java +++ b/src/main/java/org/jabref/gui/FXDialogService.java @@ -18,6 +18,7 @@ import javafx.scene.layout.Region; import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; +import javafx.stage.Window; import org.jabref.JabRefGUI; import org.jabref.gui.util.DirectoryDialogConfiguration; @@ -38,11 +39,18 @@ */ public class FXDialogService implements DialogService { + private final Window mainWindow; + /** * @deprecated try not to initialize a new dialog service but reuse the one constructed in {@link org.jabref.JabRefMain}. */ @Deprecated public FXDialogService() { + this(null); + } + + public FXDialogService(Window mainWindow) { + this.mainWindow = mainWindow; } private static FXDialog createDialog(AlertType type, String title, String content) { @@ -168,7 +176,7 @@ public void notify(String message) { @Override public Optional showFileSaveDialog(FileDialogConfiguration fileDialogConfiguration) { FileChooser chooser = getConfiguredFileChooser(fileDialogConfiguration); - File file = chooser.showSaveDialog(null); + File file = chooser.showSaveDialog(mainWindow); Optional.ofNullable(chooser.getSelectedExtensionFilter()).ifPresent(fileDialogConfiguration::setSelectedExtensionFilter); return Optional.ofNullable(file).map(File::toPath); } @@ -176,7 +184,7 @@ public Optional showFileSaveDialog(FileDialogConfiguration fileDialogConfi @Override public Optional showFileOpenDialog(FileDialogConfiguration fileDialogConfiguration) { FileChooser chooser = getConfiguredFileChooser(fileDialogConfiguration); - File file = chooser.showOpenDialog(null); + File file = chooser.showOpenDialog(mainWindow); Optional.ofNullable(chooser.getSelectedExtensionFilter()).ifPresent(fileDialogConfiguration::setSelectedExtensionFilter); return Optional.ofNullable(file).map(File::toPath); } @@ -184,14 +192,14 @@ public Optional showFileOpenDialog(FileDialogConfiguration fileDialogConfi @Override public Optional showDirectorySelectionDialog(DirectoryDialogConfiguration directoryDialogConfiguration) { DirectoryChooser chooser = getConfiguredDirectoryChooser(directoryDialogConfiguration); - File file = chooser.showDialog(null); + File file = chooser.showDialog(mainWindow); return Optional.ofNullable(file).map(File::toPath); } @Override public List showFileOpenDialogAndGetMultipleFiles(FileDialogConfiguration fileDialogConfiguration) { FileChooser chooser = getConfiguredFileChooser(fileDialogConfiguration); - List files = chooser.showOpenMultipleDialog(null); + List files = chooser.showOpenMultipleDialog(mainWindow); return files != null ? files.stream().map(File::toPath).collect(Collectors.toList()) : Collections.emptyList(); } @@ -212,6 +220,6 @@ private FileChooser getConfiguredFileChooser(FileDialogConfiguration fileDialogC @Override public boolean showPrintDialog(PrinterJob job) { - return job.showPrintDialog(null); + return job.showPrintDialog(mainWindow); } } diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index ab1d548af17..fad1469599d 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -215,7 +215,7 @@ public class JabRefFrame extends BorderPane implements OutputPrinter { public JabRefFrame(Stage mainStage) { this.mainStage = mainStage; - this.dialogService = new FXDialogService(); + this.dialogService = new FXDialogService(mainStage); init(); } From 403986f1c244723911cafadeb369064ec2f551cd Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 2 Mar 2018 12:07:40 +0100 Subject: [PATCH 07/28] Fix delete action and convert confirmation dialog to JavaFX (#3778) * Fix delete action and convert confirmation dialog to JavaFX * Named buttons in delete confirmation dialog --- src/main/java/org/jabref/gui/BasePanel.java | 23 +++--- .../java/org/jabref/gui/DialogService.java | 30 +++++++- src/main/java/org/jabref/gui/FXDialog.java | 70 +------------------ .../java/org/jabref/gui/FXDialogService.java | 59 +++++++++++++++- src/main/java/org/jabref/gui/JabRefFrame.java | 2 +- src/main/resources/l10n/JabRef_en.properties | 3 + 6 files changed, 101 insertions(+), 86 deletions(-) diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index a2f1bd40be8..dc6d3c14753 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -349,8 +349,6 @@ private void setupActions() { actions.put(Actions.CUT, (BaseAction) mainTable::cut); - //when you modify this action be sure to adjust Actions.CUT, - //they are the same except of the Localization, delete confirmation and Actions.COPY call actions.put(Actions.DELETE, (BaseAction) () -> delete(false)); // The action for pasting entries or cell contents. @@ -1562,22 +1560,21 @@ private void changeType(List entries, String newType) { public boolean showDeleteConfirmationDialog(int numberOfEntries) { if (Globals.prefs.getBoolean(JabRefPreferences.CONFIRM_DELETE)) { - String msg; - msg = Localization.lang("Really delete the selected entry?"); String title = Localization.lang("Delete entry"); + String message = Localization.lang("Really delete the selected entry?"); + String okButton = Localization.lang("Delete entry"); + String cancelButton = Localization.lang("Keep entry"); if (numberOfEntries > 1) { - msg = Localization.lang("Really delete the %0 selected entries?", Integer.toString(numberOfEntries)); title = Localization.lang("Delete multiple entries"); + message = Localization.lang("Really delete the %0 selected entries?", Integer.toString(numberOfEntries)); + okButton = Localization.lang("Delete entries"); + cancelButton = Localization.lang("Keep entries"); } - CheckBoxMessage cb = new CheckBoxMessage(msg, Localization.lang("Disable this confirmation dialog"), false); - - int answer = JOptionPane.showConfirmDialog(null, cb, title, JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE); - if (cb.isSelected()) { - Globals.prefs.putBoolean(JabRefPreferences.CONFIRM_DELETE, false); - } - return answer == JOptionPane.YES_OPTION; + return dialogService.showConfirmationDialogWithOptOutAndWait(title, message, + okButton, cancelButton, + Localization.lang("Disable this confirmation dialog"), + optOut -> Globals.prefs.putBoolean(JabRefPreferences.CONFIRM_DELETE, !optOut)); } else { return true; } diff --git a/src/main/java/org/jabref/gui/DialogService.java b/src/main/java/org/jabref/gui/DialogService.java index bdf35371b18..1c177988d08 100644 --- a/src/main/java/org/jabref/gui/DialogService.java +++ b/src/main/java/org/jabref/gui/DialogService.java @@ -3,6 +3,7 @@ import java.nio.file.Path; import java.util.List; import java.util.Optional; +import java.util.function.Consumer; import javafx.concurrent.Task; import javafx.print.PrinterJob; @@ -92,7 +93,7 @@ default void showErrorDialogAndWait(Exception exception) { * Create and display a new confirmation dialog. * It will include a blue question icon on the left and * a OK (with given label) and Cancel button. To create a confirmation dialog with custom - * buttons see also {@link #showCustomButtonDialogAndWait(Alert.AlertType, String, String, ButtonType...)} + * buttons see also {@link #showCustomButtonDialogAndWait(Alert.AlertType, String, String, ButtonType...)}. * * @return true if the use clicked "OK" otherwise false */ @@ -102,12 +103,37 @@ default void showErrorDialogAndWait(Exception exception) { * Create and display a new confirmation dialog. * It will include a blue question icon on the left and * a OK (with given label) and Cancel (also with given label) button. To create a confirmation dialog with custom - * buttons see also {@link #showCustomButtonDialogAndWait(Alert.AlertType, String, String, ButtonType...)} + * buttons see also {@link #showCustomButtonDialogAndWait(Alert.AlertType, String, String, ButtonType...)}. * * @return true if the use clicked "OK" otherwise false */ boolean showConfirmationDialogAndWait(String title, String content, String okButtonLabel, String cancelButtonLabel); + /** + * Create and display a new confirmation dialog. + * It will include a blue question icon on the left and + * a YES (with given label) and Cancel (also with given label) button. To create a confirmation dialog with custom + * buttons see also {@link #showCustomButtonDialogAndWait(Alert.AlertType, String, String, ButtonType...)}. + * Moreover, the dialog contains a opt-out checkbox with the given text to support "Do not ask again"-behaviour. + * + * @return true if the use clicked "YES" otherwise false + */ + boolean showConfirmationDialogWithOptOutAndWait(String title, String content, + String optOutMessage, Consumer optOutAction); + + /** + * Create and display a new confirmation dialog. + * It will include a blue question icon on the left and + * a YES (with given label) and Cancel (also with given label) button. To create a confirmation dialog with custom + * buttons see also {@link #showCustomButtonDialogAndWait(Alert.AlertType, String, String, ButtonType...)}. + * Moreover, the dialog contains a opt-out checkbox with the given text to support "Do not ask again"-behaviour. + * + * @return true if the use clicked "YES" otherwise false + */ + boolean showConfirmationDialogWithOptOutAndWait(String title, String content, + String okButtonLabel, String cancelButtonLabel, + String optOutMessage, Consumer optOutAction); + /** * This will create and display a new dialog of the specified * {@link Alert.AlertType} but with user defined buttons as optional diff --git a/src/main/java/org/jabref/gui/FXDialog.java b/src/main/java/org/jabref/gui/FXDialog.java index 515ca87ea23..6b99c8c18c5 100644 --- a/src/main/java/org/jabref/gui/FXDialog.java +++ b/src/main/java/org/jabref/gui/FXDialog.java @@ -1,10 +1,5 @@ package org.jabref.gui; -import java.awt.Window; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - -import javafx.application.Platform; import javafx.fxml.FXMLLoader; import javafx.scene.control.Alert; import javafx.scene.control.Dialog; @@ -19,11 +14,7 @@ /** * This class provides a super class for all dialogs implemented in JavaFX. - * It mimics the behavior of a Swing JDialog which means once a object of this class - * is shown all Swing windows will be blocked and stay in the background. Since this - * class extends from a JavaFX {@link Alert} it behaves as a normal dialog towards all - * windows in the JavaFX thread. - *

+ * * To create a custom JavaFX dialog one should create an instance of this class and set a dialog * pane through the inherited {@link Dialog#setDialogPane(DialogPane)} method. * The dialog can be shown via {@link Dialog#show()} or {@link Dialog#showAndWait()}. @@ -33,33 +24,6 @@ */ public class FXDialog extends Alert { - /** - * The WindowAdapter will be added to all Swing windows once an instance - * of this class is shown and redirects the focus towards this instance. - * The WindowAdapter will be removed once the instance of this class gets hidden. - * - */ - private final WindowAdapter fxOverSwingHelper = new WindowAdapter() { - - @Override - public void windowActivated(WindowEvent e) { - Platform.runLater(() -> { - Stage fxDialogWindow = getDialogWindow(); - fxDialogWindow.toFront(); - fxDialogWindow.requestFocus(); - }); - } - - @Override - public void windowGainedFocus(WindowEvent e) { - Platform.runLater(() -> { - Stage fxDialogWindow = getDialogWindow(); - fxDialogWindow.toFront(); - fxDialogWindow.requestFocus(); - }); - } - }; - public FXDialog(AlertType type, String title, Image image, boolean isModal) { this(type, title, isModal); setDialogIcon(image); @@ -92,13 +56,6 @@ public FXDialog(AlertType type, boolean isModal) { } else { initModality(Modality.NONE); } - dialogWindow.setOnShown(evt -> { - setSwingWindowsEnabledAndFocusable(!isModal); - setLocationRelativeToMainWindow(); - }); - dialogWindow.setOnHiding(evt -> setSwingWindowsEnabledAndFocusable(true)); - - dialogWindow.setOnCloseRequest(evt -> this.close()); dialogWindow.getScene().setOnKeyPressed(event -> { KeyBindingRepository keyBindingRepository = Globals.getKeyPrefs(); @@ -112,7 +69,7 @@ public FXDialog(AlertType type) { this(type, true); } - public void setDialogIcon(Image image) { + private void setDialogIcon(Image image) { Stage fxDialogWindow = getDialogWindow(); fxDialogWindow.getIcons().add(image); } @@ -121,27 +78,4 @@ private Stage getDialogWindow() { return (Stage) getDialogPane().getScene().getWindow(); } - private void setSwingWindowsEnabledAndFocusable(boolean enabled) { - for (Window swingWindow : Window.getWindows()) { - swingWindow.setEnabled(enabled); - if (!enabled) { - swingWindow.addWindowListener(fxOverSwingHelper); - } else { - swingWindow.removeWindowListener(fxOverSwingHelper); - } - } - } - - private void setLocationRelativeToMainWindow() { - /* - double mainWindowX = JabRefGUI.getMainFrame().getLocationOnScreen().getX(); - double mainWindowY = JabRefGUI.getMainFrame().getLocationOnScreen().getY(); - double mainWindowWidth = JabRefGUI.getMainFrame().getSize().getWidth(); - double mainWindowHeight = JabRefGUI.getMainFrame().getSize().getHeight(); - - setX((mainWindowX + (mainWindowWidth / 2)) - (getWidth() / 2)); - setY((mainWindowY + (mainWindowHeight / 2)) - (getHeight() / 2)); - */ - } - } diff --git a/src/main/java/org/jabref/gui/FXDialogService.java b/src/main/java/org/jabref/gui/FXDialogService.java index be049824e77..4513c5e6c27 100644 --- a/src/main/java/org/jabref/gui/FXDialogService.java +++ b/src/main/java/org/jabref/gui/FXDialogService.java @@ -5,14 +5,18 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.Consumer; import java.util.stream.Collectors; import javafx.concurrent.Task; import javafx.print.PrinterJob; +import javafx.scene.Group; +import javafx.scene.Node; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; import javafx.scene.control.ButtonBar; import javafx.scene.control.ButtonType; +import javafx.scene.control.CheckBox; import javafx.scene.control.DialogPane; import javafx.scene.control.TextInputDialog; import javafx.scene.layout.Region; @@ -61,6 +65,38 @@ private static FXDialog createDialog(AlertType type, String title, String conten return alert; } + private static FXDialog createDialogWithOptOut(AlertType type, String title, String content, + String optOutMessage, Consumer optOutAction) { + FXDialog alert = new FXDialog(type, title, true); + // Need to force the alert to layout in order to grab the graphic as we are replacing the dialog pane with a custom pane + alert.getDialogPane().applyCss(); + Node graphic = alert.getDialogPane().getGraphic(); + + // Create a new dialog pane that has a checkbox instead of the hide/show details button + // Use the supplied callback for the action of the checkbox + alert.setDialogPane(new DialogPane() { + @Override + protected Node createDetailsButton() { + CheckBox optOut = new CheckBox(); + optOut.setText(optOutMessage); + optOut.setOnAction(e -> optOutAction.accept(optOut.isSelected())); + return optOut; + } + }); + + // Fool the dialog into thinking there is some expandable content; a group won't take up any space if it has no children + alert.getDialogPane().setExpandableContent(new Group()); + alert.getDialogPane().setExpanded(true); + + // Reset the dialog graphic using the default style + alert.getDialogPane().setGraphic(graphic); + + alert.setHeaderText(null); + alert.setContentText(content); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); + return alert; + } + @Override public Optional showInputDialogAndWait(String title, String content) { TextInputDialog inputDialog = new TextInputDialog(); @@ -123,8 +159,8 @@ public boolean showConfirmationDialogAndWait(String title, String content, Strin } @Override - public boolean showConfirmationDialogAndWait(String title, String content, String okButtonLabel, - String cancelButtonLabel) { + public boolean showConfirmationDialogAndWait(String title, String content, + String okButtonLabel, String cancelButtonLabel) { FXDialog alert = createDialog(AlertType.CONFIRMATION, title, content); ButtonType okButtonType = new ButtonType(okButtonLabel, ButtonBar.ButtonData.OK_DONE); ButtonType cancelButtonType = new ButtonType(cancelButtonLabel, ButtonBar.ButtonData.NO); @@ -132,6 +168,25 @@ public boolean showConfirmationDialogAndWait(String title, String content, Strin return alert.showAndWait().filter(buttonType -> buttonType == okButtonType).isPresent(); } + @Override + public boolean showConfirmationDialogWithOptOutAndWait(String title, String content, + String optOutMessage, Consumer optOutAction) { + FXDialog alert = createDialogWithOptOut(AlertType.CONFIRMATION, title, content, optOutMessage, optOutAction); + alert.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO); + return alert.showAndWait().filter(buttonType -> buttonType == ButtonType.YES).isPresent(); + } + + @Override + public boolean showConfirmationDialogWithOptOutAndWait(String title, String content, + String okButtonLabel, String cancelButtonLabel, + String optOutMessage, Consumer optOutAction) { + FXDialog alert = createDialogWithOptOut(AlertType.CONFIRMATION, title, content, optOutMessage, optOutAction); + ButtonType okButtonType = new ButtonType(okButtonLabel, ButtonBar.ButtonData.YES); + ButtonType cancelButtonType = new ButtonType(cancelButtonLabel, ButtonBar.ButtonData.NO); + alert.getButtonTypes().setAll(okButtonType, cancelButtonType); + return alert.showAndWait().filter(buttonType -> buttonType == okButtonType).isPresent(); + } + @Override public Optional showCustomButtonDialogAndWait(AlertType type, String title, String content, ButtonType... buttonTypes) { diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index fad1469599d..e3775659f91 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -895,7 +895,7 @@ private MenuBar createMenu() { new SeparatorMenuItem(), - factory.createMenuItem(StandardActions.DELETE_ENTRY, new EditAction(Actions.DELETE)), + factory.createMenuItem(StandardActions.DELETE_ENTRY, new OldDatabaseCommandWrapper(Actions.DELETE, this, Globals.stateManager)), new SeparatorMenuItem(), diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index b24020fc760..ec161e421c9 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2333,3 +2333,6 @@ Look\ up\ document\ identifier=Look up document identifier Next\ library=Next library Previous\ library=Previous library add\ group=add group +Delete\ entries=Delete entries +Keep\ entries=Keep entries +Keep\ entry=Keep entry From 84ab6974feaa3c3379e35d5a68ad6faccc57152a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lenhard?= Date: Fri, 2 Mar 2018 20:50:30 +0100 Subject: [PATCH 08/28] Extend toolbar with more icons and add tool tips (#3767) * Add more buttons to the toolbar * Reenable tool tips for toolbar buttons * Add undo/redo buttons * Do not bind rightSide width * Description as tooltip --- src/main/java/org/jabref/gui/JabRefFrame.java | 24 +++++++++++++++++-- .../org/jabref/gui/actions/ActionFactory.java | 4 +++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index e3775659f91..a67d16f978b 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -668,19 +668,39 @@ private Node createToolbar() { newLibrary, factory.createIconButton(StandardActions.OPEN_LIBRARY, new OpenDatabaseAction(this)), factory.createIconButton(StandardActions.SAVE_LIBRARY, new OldDatabaseCommandWrapper(Actions.SAVE, this, Globals.stateManager)), - leftSpacer); leftSide.setMinWidth(100); leftSide.prefWidthProperty().bind(sidePane.widthProperty()); leftSide.maxWidthProperty().bind(sidePane.widthProperty()); + PushToApplicationButton pushToExternal = new PushToApplicationButton(this, pushApplications.getApplications()); + HBox rightSide = new HBox ( + factory.createIconButton(StandardActions.NEW_ENTRY, new NewEntryAction(this, BiblatexEntryTypes.ARTICLE)), + factory.createIconButton(StandardActions.DELETE_ENTRY, new EditAction(Actions.DELETE)), + + factory.createIconButton(StandardActions.UNDO, new OldDatabaseCommandWrapper(Actions.UNDO, this, Globals.stateManager)), + factory.createIconButton(StandardActions.REDO, new OldDatabaseCommandWrapper(Actions.REDO, this, Globals.stateManager)), + factory.createIconButton(StandardActions.CUT, new EditAction(Actions.CUT)), + factory.createIconButton(StandardActions.COPY, new EditAction(Actions.COPY)), + factory.createIconButton(StandardActions.PASTE, new EditAction(Actions.PASTE)), + + factory.createIconButton(StandardActions.CLEANUP_ENTRIES, new OldDatabaseCommandWrapper(Actions.CLEANUP, this, Globals.stateManager)), + factory.createIconButton(pushToExternal.getMenuAction(), pushToExternal), + + factory.createIconButton(StandardActions.FORK_ME, new OpenBrowserAction("https://github.com/JabRef/jabref")), + factory.createIconButton(StandardActions.OPEN_FACEBOOK, new OpenBrowserAction("https://www.facebook.com/JabRef/")), + factory.createIconButton(StandardActions.OPEN_TWITTER, new OpenBrowserAction("https://twitter.com/jabref_org")) + + ); + ToolBar toolBar = new ToolBar( leftSide, globalSearchBar, rightSpacer, - factory.createIconButton(StandardActions.NEW_ENTRY, new NewEntryAction(this, BiblatexEntryTypes.ARTICLE))); + rightSide + ); toolBar.getStyleClass().add("mainToolbar"); return toolBar; diff --git a/src/main/java/org/jabref/gui/actions/ActionFactory.java b/src/main/java/org/jabref/gui/actions/ActionFactory.java index 915bb9b3ee4..3bf0e2bccf1 100644 --- a/src/main/java/org/jabref/gui/actions/ActionFactory.java +++ b/src/main/java/org/jabref/gui/actions/ActionFactory.java @@ -5,6 +5,7 @@ import javafx.scene.control.Button; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; +import javafx.scene.control.Tooltip; import org.jabref.gui.keyboard.KeyBindingRepository; @@ -58,7 +59,8 @@ public Menu createSubMenu(Action action, MenuItem... children) { public Button createIconButton(Action action, Command command) { Button button = ActionUtils.createButton(new JabRefAction(action, command, keyBindingRepository), ActionUtils.ActionTextBehavior.HIDE); button.getStyleClass().add("flatButton"); - + button.setTooltip(new Tooltip(action.getDescription())); + // For some reason the graphic is not set correctly, so let's fix this button.graphicProperty().unbind(); action.getIcon().ifPresent(icon -> button.setGraphic(icon.getGraphicNode())); From 2c2e864eda83f7c2b06811dd97804c4c31672e4e Mon Sep 17 00:00:00 2001 From: Christoph Date: Fri, 2 Mar 2018 22:29:11 +0100 Subject: [PATCH 09/28] Change open last edited dialgo to javafx (#3800) * Change open last edited dialgo to javafx * Rename variable Add missing localization keys --- src/main/java/org/jabref/JabRefGUI.java | 7 ++-- .../java/org/jabref/gui/FXDialogService.java | 2 +- .../jabref/gui/dialogs/BackupUIManager.java | 32 +++++++++++-------- .../importer/actions/OpenDatabaseAction.java | 16 ++++------ src/main/resources/l10n/JabRef_en.properties | 4 +++ 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index e616e1165f9..e1e55ea0fe8 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -20,6 +20,7 @@ import org.jabref.gui.AbstractView; import org.jabref.gui.BasePanel; +import org.jabref.gui.FXDialogService; import org.jabref.gui.GUIGlobals; import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefFrame; @@ -86,7 +87,7 @@ private void openWindow(Stage mainStage) { // If the option is enabled, open the last edited libraries, if any. if (!isBlank && Globals.prefs.getBoolean(JabRefPreferences.OPEN_LAST_EDITED)) { - openLastEditedDatabases(); + openLastEditedDatabases(mainStage); } GUIGlobals.init(); @@ -190,7 +191,7 @@ private void openWindow(Stage mainStage) { LOGGER.debug("Finished adding panels"); } - private void openLastEditedDatabases() { + private void openLastEditedDatabases(Stage mainStage) { if (Globals.prefs.get(JabRefPreferences.LAST_EDITED) == null) { return; } @@ -205,7 +206,7 @@ private void openLastEditedDatabases() { } if (BackupManager.checkForBackupFile(dbFile.toPath())) { - BackupUIManager.showRestoreBackupDialog(null, dbFile.toPath()); + BackupUIManager.showRestoreBackupDialog(new FXDialogService(mainStage), dbFile.toPath()); } ParserResult parsedDatabase = OpenDatabase.loadDatabase(fileName, diff --git a/src/main/java/org/jabref/gui/FXDialogService.java b/src/main/java/org/jabref/gui/FXDialogService.java index 4513c5e6c27..41d5ba1aa3e 100644 --- a/src/main/java/org/jabref/gui/FXDialogService.java +++ b/src/main/java/org/jabref/gui/FXDialogService.java @@ -46,7 +46,7 @@ public class FXDialogService implements DialogService { private final Window mainWindow; /** - * @deprecated try not to initialize a new dialog service but reuse the one constructed in {@link org.jabref.JabRefMain}. + * @deprecated try not to initialize a new dialog service but reuse the one constructed in {@link org.jabref.gui.JabRefFrame}. */ @Deprecated public FXDialogService() { diff --git a/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java b/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java index 29e1bc12cc9..33e4391cecd 100644 --- a/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java +++ b/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java @@ -2,9 +2,7 @@ import java.nio.file.Path; -import javax.swing.JFrame; -import javax.swing.JOptionPane; - +import org.jabref.gui.DialogService; import org.jabref.logic.autosaveandbackup.BackupManager; import org.jabref.logic.l10n.Localization; @@ -14,20 +12,26 @@ public class BackupUIManager { private BackupUIManager() { + } - public static void showRestoreBackupDialog(JFrame frame, Path originalPath) { - int answer = JOptionPane.showConfirmDialog(null, - new StringBuilder() - .append(Localization.lang("A backup file for '%0' was found.", originalPath.getFileName().toString())) - .append("\n") - .append(Localization.lang("This could indicate that JabRef did not shut down cleanly last time the file was used.")) - .append("\n\n") - .append(Localization.lang("Do you want to recover the library from the backup file?")).toString(), - Localization.lang("Backup found"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); - - if (answer == 0) { + public static void showRestoreBackupDialog(DialogService dialogService, Path originalPath) { + String content = new StringBuilder() + .append(Localization.lang("A backup file for '%0' was found.", originalPath.getFileName().toString())) + .append("\n") + .append(Localization.lang("This could indicate that JabRef did not shut down cleanly last time the file was used.")) + .append("\n\n") + .append(Localization.lang("Do you want to recover the library from the backup file?")) + .toString(); + + boolean restoreClicked = dialogService.showConfirmationDialogAndWait( + Localization.lang("Backup found"), content, + Localization.lang("Restore from backup"), + Localization.lang("Ignore backup")); + + if (restoreClicked) { BackupManager.restoreBackup(originalPath); } + } } diff --git a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java index 35f9532022d..7c6aad61d90 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -49,7 +49,6 @@ // The action concerned with opening an existing database. public class OpenDatabaseAction extends SimpleCommand { - public static final Logger LOGGER = LoggerFactory.getLogger(OpenDatabaseAction.class); // List of actions that may need to be called after opening the file. Such as // upgrade actions etc. that may depend on the JabRef version that wrote the file: @@ -65,7 +64,6 @@ public class OpenDatabaseAction extends SimpleCommand { // Warning about and handling duplicate BibTeX keys: new HandleDuplicateWarnings()); - private final JabRefFrame frame; public OpenDatabaseAction(JabRefFrame frame) { @@ -87,6 +85,7 @@ public static void performPostOpenActions(BasePanel panel, ParserResult result) } } + @Override public void execute() { List filesToOpen = new ArrayList<>(); @@ -131,7 +130,7 @@ public void openFiles(List filesToOpen, boolean raisePanel) { int removed = 0; // Check if any of the files are already open: - for (Iterator iterator = filesToOpen.iterator(); iterator.hasNext(); ) { + for (Iterator iterator = filesToOpen.iterator(); iterator.hasNext();) { Path file = iterator.next(); for (int i = 0; i < frame.getTabbedPane().getTabs().size(); i++) { BasePanel basePanel = frame.getBasePanelAt(i); @@ -212,7 +211,7 @@ private void openTheFile(Path file, boolean raisePanel) { } if (BackupManager.checkForBackupFile(fileToLoad)) { - BackupUIManager.showRestoreBackupDialog(null, fileToLoad); + BackupUIManager.showRestoreBackupDialog(frame.getDialogService(), fileToLoad); } ParserResult result; @@ -262,10 +261,9 @@ private BasePanel addNewDatabase(ParserResult result, final Path file, boolean r } return DefaultTaskExecutor.runInJavaFXThread(() -> { - BasePanel basePanel = new BasePanel(frame, BasePanelPreferences.from(Globals.prefs), result.getDatabaseContext(), ExternalFileTypes.getInstance()); - frame.addTab(basePanel, raisePanel); - return basePanel; - } - ); + BasePanel basePanel = new BasePanel(frame, BasePanelPreferences.from(Globals.prefs), result.getDatabaseContext(), ExternalFileTypes.getInstance()); + frame.addTab(basePanel, raisePanel); + return basePanel; + }); } } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index ec161e421c9..0c1e109c089 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2336,3 +2336,7 @@ add\ group=add group 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 From e3ea6ae2ddb803f13dcedfc69cff46dfce97e0ed Mon Sep 17 00:00:00 2001 From: Christoph Date: Sat, 3 Mar 2018 19:46:43 +0100 Subject: [PATCH 10/28] Remove setting of tooltip manually The setting of the tooltip led to an exception. It is already implicit set from the Action Description --- src/main/java/org/jabref/gui/actions/ActionFactory.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/actions/ActionFactory.java b/src/main/java/org/jabref/gui/actions/ActionFactory.java index 3bf0e2bccf1..fcd85665570 100644 --- a/src/main/java/org/jabref/gui/actions/ActionFactory.java +++ b/src/main/java/org/jabref/gui/actions/ActionFactory.java @@ -59,7 +59,6 @@ public Menu createSubMenu(Action action, MenuItem... children) { public Button createIconButton(Action action, Command command) { Button button = ActionUtils.createButton(new JabRefAction(action, command, keyBindingRepository), ActionUtils.ActionTextBehavior.HIDE); button.getStyleClass().add("flatButton"); - button.setTooltip(new Tooltip(action.getDescription())); // For some reason the graphic is not set correctly, so let's fix this button.graphicProperty().unbind(); From fd98056c76bc340ab7ed62944e13414b20d5a117 Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 4 Mar 2018 12:02:55 +0100 Subject: [PATCH 11/28] Enable travis build for maintable-beta (#3804) I think it would be nice to have travis build for maintable-beta. That would show us some potential errornous tests or --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 63bf1713ef5..4aaf9abf217 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,6 +60,7 @@ after_failure: branches: only: - master + - maintable-beta # cache gradle dependencies # https://docs.travis-ci.com/user/languages/java#Caching From 9c6bd692a67623e1884ddd2f54ccbd8da1420db4 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 5 Mar 2018 12:11:47 +0100 Subject: [PATCH 12/28] Add group coloring in maintable as replacement for marked entries (#3769) * Prototype * Make transparent * Remove everything related to marked entries * Display proper group membership for entry * Add migration from markings to groups --- src/main/java/org/jabref/gui/BasePanel.java | 41 ---- src/main/java/org/jabref/gui/EntryMarker.java | 199 ------------------ src/main/java/org/jabref/gui/IconTheme.java | 19 +- .../gui/InternalMaterialDesignIcon.java | 5 + src/main/java/org/jabref/gui/JabRefFrame.java | 18 +- src/main/java/org/jabref/gui/JabRefIcon.java | 3 + .../java/org/jabref/gui/actions/Actions.java | 3 - .../org/jabref/gui/groups/GroupMatcher.java | 19 -- .../jabref/gui/groups/GroupNodeViewModel.java | 15 +- .../gui/importer/ImportInspectionDialog.java | 14 -- .../jabref/gui/importer/ImportMenuItem.java | 6 - .../org/jabref/gui/keyboard/KeyBinding.java | 2 - .../gui/maintable/BibEntryTableViewModel.java | 23 ++ .../org/jabref/gui/maintable/MainTable.java | 41 +--- .../gui/maintable/MainTableColumnFactory.java | 62 +++++- .../gui/plaintextimport/TextInputDialog.java | 11 +- .../org/jabref/gui/preftabs/GeneralTab.java | 12 -- .../jabref/gui/preftabs/TablePrefsTab.java | 11 - .../util/comparator/IsMarkedComparator.java | 17 -- .../jabref/gui/worker/MarkEntriesAction.java | 95 --------- .../jabref/logic/importer/OpenDatabase.java | 8 +- .../migrations/ConvertMarkingToGroups.java | 92 ++++++++ .../model/groups/GroupEntryChanger.java | 3 +- .../jabref/model/groups/GroupTreeNode.java | 13 +- .../jabref/model/groups/WordKeywordGroup.java | 2 +- .../jabref/preferences/JabRefPreferences.java | 10 - src/main/resources/l10n/JabRef_en.properties | 5 +- .../KeyBindingsDialogViewModelTest.java | 14 +- .../ConvertMarkingToGroupsTest.java | 34 +++ src/test/resources/testbib/complex.bib | 4 +- 30 files changed, 269 insertions(+), 532 deletions(-) delete mode 100644 src/main/java/org/jabref/gui/EntryMarker.java delete mode 100644 src/main/java/org/jabref/gui/groups/GroupMatcher.java delete mode 100644 src/main/java/org/jabref/gui/util/comparator/IsMarkedComparator.java delete mode 100644 src/main/java/org/jabref/gui/worker/MarkEntriesAction.java create mode 100644 src/main/java/org/jabref/migrations/ConvertMarkingToGroups.java create mode 100644 src/test/java/org/jabref/migrations/ConvertMarkingToGroupsTest.java 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\;; } From f6df529630539d0b03d4d486b2b806d7c0b67962 Mon Sep 17 00:00:00 2001 From: Linus Dietz Date: Mon, 5 Mar 2018 13:53:29 +0100 Subject: [PATCH 13/28] Remove unused import --- src/main/java/org/jabref/gui/actions/ActionFactory.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/actions/ActionFactory.java b/src/main/java/org/jabref/gui/actions/ActionFactory.java index fcd85665570..915bb9b3ee4 100644 --- a/src/main/java/org/jabref/gui/actions/ActionFactory.java +++ b/src/main/java/org/jabref/gui/actions/ActionFactory.java @@ -5,7 +5,6 @@ import javafx.scene.control.Button; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; -import javafx.scene.control.Tooltip; import org.jabref.gui.keyboard.KeyBindingRepository; @@ -59,7 +58,7 @@ public Menu createSubMenu(Action action, MenuItem... children) { public Button createIconButton(Action action, Command command) { Button button = ActionUtils.createButton(new JabRefAction(action, command, keyBindingRepository), ActionUtils.ActionTextBehavior.HIDE); button.getStyleClass().add("flatButton"); - + // For some reason the graphic is not set correctly, so let's fix this button.graphicProperty().unbind(); action.getIcon().ifPresent(icon -> button.setGraphic(icon.getGraphicNode())); From 21355ab4ec260cb4402ed03910f0c607c21c11c9 Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 5 Mar 2018 16:11:55 +0100 Subject: [PATCH 14/28] Dialogstojavafx (#3801) * convert dialogs to javafx start with preferences * convert open office and other preferences * Convert entryTypeList and entry customization and shared database * And convert some more * Pass dialogService instead of frame convert some more dialogs Fix index out of bounds in Entry Table columns Pref Tab * entry types list * create choice dialog * ADd method for returning list in Encodings Display charsets in Choices dialog * Convert some more confirmation dialogs * convert some more dialogs Extend choice dialog with cancel button and ok button label * fix checkstyle and add missing lang keys * fix dialog conditions * add better title for share db dialog * Add dialogservice to push to apps Remove comment form import insepction dlg * add new keys * fix dialog service in push * checkstyle and convert some open office dlgs, too * use dialogservice as local variable Fix l10n keys * pass Dialog service to push dialogs as ctor arg * checkstyle --- src/main/java/org/jabref/JabRefGUI.java | 26 +-- src/main/java/org/jabref/gui/BasePanel.java | 19 +- .../java/org/jabref/gui/DialogService.java | 20 +- .../java/org/jabref/gui/EntryTypeDialog.java | 11 +- .../java/org/jabref/gui/FXDialogService.java | 24 ++- src/main/java/org/jabref/gui/JabRefFrame.java | 4 +- .../org/jabref/gui/actions/ActionFactory.java | 2 +- .../org/jabref/gui/actions/CleanupAction.java | 35 ++-- .../org/jabref/gui/actions/JabRefAction.java | 3 + .../gui/actions/MassSetFieldAction.java | 29 ++- .../org/jabref/gui/collab/ChangeScanner.java | 15 +- .../EntryCustomizationDialog.java | 19 +- .../gui/customentrytypes/EntryTypeList.java | 31 +-- .../jabref/gui/exporter/ExportCommand.java | 32 ++-- .../gui/exporter/SaveDatabaseAction.java | 178 +++++++++--------- .../externalfiles/DownloadExternalFile.java | 59 +++--- .../gui/externalfiles/FindFullTextAction.java | 38 ++-- .../contextmenu/ProtectedTermsMenu.java | 2 +- .../jabref/gui/importer/ImportCommand.java | 8 +- .../gui/importer/ImportInspectionDialog.java | 116 ++++++------ .../importer/actions/OpenDatabaseAction.java | 28 +-- .../MergeWithFetchedEntryAction.java | 20 +- .../DetectOpenOfficeInstallation.java | 1 + .../gui/openoffice/OpenOfficePanel.java | 149 +++++++-------- .../gui/openoffice/StyleSelectDialog.java | 55 +++--- .../org/jabref/gui/preftabs/AdvancedTab.java | 29 +-- .../gui/preftabs/AppearancePrefsTab.java | 18 +- .../org/jabref/gui/preftabs/ExternalTab.java | 19 +- .../java/org/jabref/gui/preftabs/FileTab.java | 28 ++- .../org/jabref/gui/preftabs/GeneralTab.java | 30 +-- .../org/jabref/gui/preftabs/NetworkTab.java | 16 +- .../gui/preftabs/PreferencesDialog.java | 50 ++--- .../jabref/gui/preftabs/PreviewPrefsTab.java | 85 +++++---- .../jabref/gui/preftabs/TableColumnsTab.java | 32 ++-- .../NewProtectedTermsFileDialog.java | 14 +- .../protectedterms/ProtectedTermsDialog.java | 59 +++--- .../gui/push/AbstractPushToApplication.java | 9 +- .../gui/push/PushToApplicationAction.java | 14 +- .../jabref/gui/push/PushToApplications.java | 23 +-- .../java/org/jabref/gui/push/PushToEmacs.java | 34 ++-- .../java/org/jabref/gui/push/PushToLyx.java | 8 +- .../org/jabref/gui/push/PushToTeXstudio.java | 5 + .../org/jabref/gui/push/PushToTexmaker.java | 5 + .../java/org/jabref/gui/push/PushToVim.java | 27 ++- .../org/jabref/gui/push/PushToWinEdt.java | 5 + .../shared/ConnectToSharedDatabaseDialog.java | 23 ++- .../java/org/jabref/logic/l10n/Encodings.java | 11 +- src/main/resources/l10n/JabRef_en.properties | 14 ++ 48 files changed, 799 insertions(+), 683 deletions(-) diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index e1e55ea0fe8..7a3acdedecf 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -20,6 +20,7 @@ import org.jabref.gui.AbstractView; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.gui.FXDialogService; import org.jabref.gui.GUIGlobals; import org.jabref.gui.IconTheme; @@ -51,12 +52,14 @@ public class JabRefGUI { private final boolean isBlank; private final List failed = new ArrayList<>(); private final List toOpenTab = new ArrayList<>(); + private final DialogService dialogService; private final String focusedFile; public JabRefGUI(Stage mainStage, List argsDatabases, boolean isBlank) { this.bibDatabases = argsDatabases; this.isBlank = isBlank; + this.dialogService = new FXDialogService(mainStage); // passed file (we take the first one) should be focused focusedFile = argsDatabases.stream().findFirst().flatMap(ParserResult::getFile).map(File::getAbsolutePath) @@ -87,7 +90,7 @@ private void openWindow(Stage mainStage) { // If the option is enabled, open the last edited libraries, if any. if (!isBlank && Globals.prefs.getBoolean(JabRefPreferences.OPEN_LAST_EDITED)) { - openLastEditedDatabases(mainStage); + openLastEditedDatabases(); } GUIGlobals.init(); @@ -159,12 +162,11 @@ private void openWindow(Stage mainStage) { }); for (ParserResult pr : failed) { - String message = "" + Localization.lang("Error opening file '%0'.", pr.getFile().get().getName()) - + "

" - + pr.getErrorMessage() + ""; + String message = Localization.lang("Error opening file '%0'.", pr.getFile().get().getName()) + "\n" + + pr.getErrorMessage(); + + dialogService.showErrorDialogAndWait(Localization.lang("Error opening file"), message); - JOptionPane.showMessageDialog(null, message, Localization.lang("Error opening file"), - JOptionPane.ERROR_MESSAGE); } // Display warnings, if any @@ -191,7 +193,7 @@ private void openWindow(Stage mainStage) { LOGGER.debug("Finished adding panels"); } - private void openLastEditedDatabases(Stage mainStage) { + private void openLastEditedDatabases() { if (Globals.prefs.get(JabRefPreferences.LAST_EDITED) == null) { return; } @@ -206,7 +208,7 @@ private void openLastEditedDatabases(Stage mainStage) { } if (BackupManager.checkForBackupFile(dbFile.toPath())) { - BackupUIManager.showRestoreBackupDialog(new FXDialogService(mainStage), dbFile.toPath()); + BackupUIManager.showRestoreBackupDialog(dialogService, dbFile.toPath()); } ParserResult parsedDatabase = OpenDatabase.loadDatabase(fileName, @@ -264,11 +266,11 @@ private void setLookAndFeel() { // also set system l&f as default Globals.prefs.put(JabRefPreferences.WIN_LOOK_AND_FEEL, systemLookFeel); // notify the user - JOptionPane.showMessageDialog(null, - Localization - .lang("Unable to find the requested look and feel and thus the default one is used."), - Localization.lang("Warning"), JOptionPane.WARNING_MESSAGE); + LOGGER.warn("Unable to find requested look and feel", e); + dialogService.showWarningDialogAndWait(Localization.lang("Warning"), + Localization.lang("Unable to find the requested look and feel and thus the default one is used.")); + } } diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 4af3c52fca1..8d63b8f60fe 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -84,7 +84,6 @@ import org.jabref.gui.undo.UndoableRemoveEntry; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; -import org.jabref.gui.util.component.CheckBoxMessage; import org.jabref.gui.worker.AbstractWorker; import org.jabref.gui.worker.CallBack; import org.jabref.gui.worker.CitationStyleToClipboardWorker; @@ -420,15 +419,16 @@ public void run() { // if we're going to override some cite keys warn the user about it } else if (Globals.prefs.getBoolean(JabRefPreferences.WARN_BEFORE_OVERWRITING_KEY)) { if (entries.parallelStream().anyMatch(BibEntry::hasCiteKey)) { - CheckBoxMessage cbm = new CheckBoxMessage( + + boolean overwriteKeysPressed = dialogService.showConfirmationDialogWithOptOutAndWait(Localization.lang("Overwrite keys"), Localization.lang("One or more keys will be overwritten. Continue?"), - Localization.lang("Disable this confirmation dialog"), false); - final int answer = JOptionPane.showConfirmDialog(null, cbm, - Localization.lang("Overwrite keys"), JOptionPane.YES_NO_OPTION); - Globals.prefs.putBoolean(JabRefPreferences.WARN_BEFORE_OVERWRITING_KEY, !cbm.isSelected()); + Localization.lang("Overwrite keys"), + Localization.lang("Cancel"), + Localization.lang("Disable this confirmation dialog"), + optOut -> Globals.prefs.putBoolean(JabRefPreferences.WARN_BEFORE_OVERWRITING_KEY, !optOut)); // The user doesn't want to overide cite keys - if (answer == JOptionPane.NO_OPTION) { + if (!overwriteKeysPressed) { canceled = true; return; } @@ -525,7 +525,7 @@ public void update() { actions.put(Actions.OPEN_URL, new OpenURLAction()); - actions.put(Actions.MERGE_WITH_FETCHED_ENTRY, new MergeWithFetchedEntryAction(this)); + actions.put(Actions.MERGE_WITH_FETCHED_ENTRY, new MergeWithFetchedEntryAction(this, frame.getDialogService())); actions.put(Actions.REPLACE_ALL, (BaseAction) () -> { final ReplaceStringDialog rsd = new ReplaceStringDialog(frame); @@ -616,7 +616,7 @@ public void update() { actions.put(Actions.REMOVE_FROM_GROUP, new GroupAddRemoveDialog(this, false, false)); actions.put(Actions.MOVE_TO_GROUP, new GroupAddRemoveDialog(this, true, true)); - actions.put(Actions.DOWNLOAD_FULL_TEXT, new FindFullTextAction(this)); + actions.put(Actions.DOWNLOAD_FULL_TEXT, new FindFullTextAction(frame.getDialogService(), this)); } /** @@ -925,6 +925,7 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset enc, new String[] {Localization.lang("Save"), tryDiff, Localization.lang("Cancel")}, tryDiff); if (answer == JOptionPane.NO_OPTION) { + // The user wants to use another encoding. Object choice = JOptionPane.showInputDialog(null, Localization.lang("Select encoding"), SAVE_DATABASE, JOptionPane.QUESTION_MESSAGE, null, Encodings.ENCODINGS_DISPLAYNAMES, enc); diff --git a/src/main/java/org/jabref/gui/DialogService.java b/src/main/java/org/jabref/gui/DialogService.java index 1c177988d08..5900555e656 100644 --- a/src/main/java/org/jabref/gui/DialogService.java +++ b/src/main/java/org/jabref/gui/DialogService.java @@ -1,6 +1,7 @@ package org.jabref.gui; import java.nio.file.Path; +import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.function.Consumer; @@ -9,7 +10,9 @@ import javafx.print.PrinterJob; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; +import javafx.scene.control.ChoiceDialog; import javafx.scene.control.DialogPane; +import javafx.scene.control.TextInputDialog; import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.gui.util.FileDialogConfiguration; @@ -22,6 +25,14 @@ */ public interface DialogService { + /** + * This will create and display new {@link ChoiceDialog} of type T with a default choice and a collection of possible choices + */ + Optional showChoiceDialogAndWait(String title, String content, String okButtonLabel, T defaultChoice, Collection choices); + + /** + * This will create and display new {@link TextInputDialog} with a text fields to enter data + */ Optional showInputDialogAndWait(String title, String content); /** @@ -119,7 +130,7 @@ default void showErrorDialogAndWait(Exception exception) { * @return true if the use clicked "YES" otherwise false */ boolean showConfirmationDialogWithOptOutAndWait(String title, String content, - String optOutMessage, Consumer optOutAction); + String optOutMessage, Consumer optOutAction); /** * Create and display a new confirmation dialog. @@ -131,8 +142,8 @@ boolean showConfirmationDialogWithOptOutAndWait(String title, String content, * @return true if the use clicked "YES" otherwise false */ boolean showConfirmationDialogWithOptOutAndWait(String title, String content, - String okButtonLabel, String cancelButtonLabel, - String optOutMessage, Consumer optOutAction); + String okButtonLabel, String cancelButtonLabel, + String optOutMessage, Consumer optOutAction); /** * This will create and display a new dialog of the specified @@ -142,7 +153,7 @@ boolean showConfirmationDialogWithOptOutAndWait(String title, String content, * @return Optional with the pressed Button as ButtonType */ Optional showCustomButtonDialogAndWait(Alert.AlertType type, String title, String content, - ButtonType... buttonTypes); + ButtonType... buttonTypes); /** * This will create and display a new dialog showing a custom {@link DialogPane} @@ -224,4 +235,5 @@ Optional showCustomButtonDialogAndWait(Alert.AlertType type, String * @return false if the user opts to cancel printing */ boolean showPrintDialog(PrinterJob job); + } diff --git a/src/main/java/org/jabref/gui/EntryTypeDialog.java b/src/main/java/org/jabref/gui/EntryTypeDialog.java index 133da8b8d11..5a0f7eb7b8a 100644 --- a/src/main/java/org/jabref/gui/EntryTypeDialog.java +++ b/src/main/java/org/jabref/gui/EntryTypeDialog.java @@ -20,7 +20,6 @@ import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; @@ -331,13 +330,13 @@ protected void done() { dispose(); } else if (searchID.trim().isEmpty()) { - JOptionPane.showMessageDialog(null, Localization.lang("The given search ID was empty."), Localization.lang("Empty search ID"), JOptionPane.WARNING_MESSAGE); + frame.getDialogService().showWarningDialogAndWait(Localization.lang("Empty search ID"), + Localization.lang("The given search ID was empty.")); } else if (!fetcherException) { - JOptionPane.showMessageDialog(null, Localization.lang("Fetcher '%0' did not find an entry for id '%1'.", fetcher.getName(), searchID) + "\n" + fetcherExceptionMessage, Localization.lang("No files found."), JOptionPane.WARNING_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("No files found.", + Localization.lang("Fetcher '%0' did not find an entry for id '%1'.", fetcher.getName(), searchID) + "\n" + fetcherExceptionMessage)); } else { - JOptionPane.showMessageDialog(null, - Localization.lang("Error while fetching from %0", fetcher.getName()) + "." + "\n" + fetcherExceptionMessage, - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Error"), Localization.lang("Error while fetching from %0", fetcher.getName()) + "." + "\n" + fetcherExceptionMessage); } fetcherWorker = new FetcherWorker(); SwingUtilities.invokeLater(() -> { diff --git a/src/main/java/org/jabref/gui/FXDialogService.java b/src/main/java/org/jabref/gui/FXDialogService.java index 41d5ba1aa3e..db753727612 100644 --- a/src/main/java/org/jabref/gui/FXDialogService.java +++ b/src/main/java/org/jabref/gui/FXDialogService.java @@ -2,6 +2,7 @@ import java.io.File; import java.nio.file.Path; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -17,6 +18,7 @@ import javafx.scene.control.ButtonBar; import javafx.scene.control.ButtonType; import javafx.scene.control.CheckBox; +import javafx.scene.control.ChoiceDialog; import javafx.scene.control.DialogPane; import javafx.scene.control.TextInputDialog; import javafx.scene.layout.Region; @@ -66,7 +68,7 @@ private static FXDialog createDialog(AlertType type, String title, String conten } private static FXDialog createDialogWithOptOut(AlertType type, String title, String content, - String optOutMessage, Consumer optOutAction) { + String optOutMessage, Consumer optOutAction) { FXDialog alert = new FXDialog(type, title, true); // Need to force the alert to layout in order to grab the graphic as we are replacing the dialog pane with a custom pane alert.getDialogPane().applyCss(); @@ -75,6 +77,7 @@ private static FXDialog createDialogWithOptOut(AlertType type, String title, Str // Create a new dialog pane that has a checkbox instead of the hide/show details button // Use the supplied callback for the action of the checkbox alert.setDialogPane(new DialogPane() { + @Override protected Node createDetailsButton() { CheckBox optOut = new CheckBox(); @@ -97,6 +100,17 @@ protected Node createDetailsButton() { return alert; } + @Override + public Optional showChoiceDialogAndWait(String title, String content, String okButtonLabel, T defaultChoice, Collection choices) { + ChoiceDialog choiceDialog = new ChoiceDialog<>(defaultChoice, choices); + ButtonType okButtonType = new ButtonType(okButtonLabel, ButtonBar.ButtonData.OK_DONE); + choiceDialog.getDialogPane().getButtonTypes().setAll(ButtonType.CANCEL, okButtonType); + choiceDialog.setHeaderText(title); + choiceDialog.setContentText(content); + return choiceDialog.showAndWait(); + + } + @Override public Optional showInputDialogAndWait(String title, String content) { TextInputDialog inputDialog = new TextInputDialog(); @@ -160,7 +174,7 @@ public boolean showConfirmationDialogAndWait(String title, String content, Strin @Override public boolean showConfirmationDialogAndWait(String title, String content, - String okButtonLabel, String cancelButtonLabel) { + String okButtonLabel, String cancelButtonLabel) { FXDialog alert = createDialog(AlertType.CONFIRMATION, title, content); ButtonType okButtonType = new ButtonType(okButtonLabel, ButtonBar.ButtonData.OK_DONE); ButtonType cancelButtonType = new ButtonType(cancelButtonLabel, ButtonBar.ButtonData.NO); @@ -170,7 +184,7 @@ public boolean showConfirmationDialogAndWait(String title, String content, @Override public boolean showConfirmationDialogWithOptOutAndWait(String title, String content, - String optOutMessage, Consumer optOutAction) { + String optOutMessage, Consumer optOutAction) { FXDialog alert = createDialogWithOptOut(AlertType.CONFIRMATION, title, content, optOutMessage, optOutAction); alert.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO); return alert.showAndWait().filter(buttonType -> buttonType == ButtonType.YES).isPresent(); @@ -178,8 +192,8 @@ public boolean showConfirmationDialogWithOptOutAndWait(String title, String cont @Override public boolean showConfirmationDialogWithOptOutAndWait(String title, String content, - String okButtonLabel, String cancelButtonLabel, - String optOutMessage, Consumer optOutAction) { + String okButtonLabel, String cancelButtonLabel, + String optOutMessage, Consumer optOutAction) { FXDialog alert = createDialogWithOptOut(AlertType.CONFIRMATION, title, content, optOutMessage, optOutAction); ButtonType okButtonType = new ButtonType(okButtonLabel, ButtonBar.ButtonData.YES); ButtonType cancelButtonType = new ButtonType(cancelButtonLabel, ButtonBar.ButtonData.NO); diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 709b695e075..491ec9fb98e 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -570,7 +570,7 @@ public boolean quit() { private void initLayout() { setProgressBarVisible(false); - pushApplications = new PushToApplications(); + pushApplications = new PushToApplications(this.getDialogService()); BorderPane head = new BorderPane(); head.setTop(createMenu()); @@ -670,7 +670,7 @@ private Node createToolbar() { HBox rightSide = new HBox ( factory.createIconButton(StandardActions.NEW_ENTRY, new NewEntryAction(this, BiblatexEntryTypes.ARTICLE)), factory.createIconButton(StandardActions.DELETE_ENTRY, new EditAction(Actions.DELETE)), - + factory.createIconButton(StandardActions.UNDO, new OldDatabaseCommandWrapper(Actions.UNDO, this, Globals.stateManager)), factory.createIconButton(StandardActions.REDO, new OldDatabaseCommandWrapper(Actions.REDO, this, Globals.stateManager)), factory.createIconButton(StandardActions.CUT, new EditAction(Actions.CUT)), diff --git a/src/main/java/org/jabref/gui/actions/ActionFactory.java b/src/main/java/org/jabref/gui/actions/ActionFactory.java index 915bb9b3ee4..38a7f99ddee 100644 --- a/src/main/java/org/jabref/gui/actions/ActionFactory.java +++ b/src/main/java/org/jabref/gui/actions/ActionFactory.java @@ -16,7 +16,7 @@ */ public class ActionFactory { - private KeyBindingRepository keyBindingRepository; + private final KeyBindingRepository keyBindingRepository; public ActionFactory(KeyBindingRepository keyBindingRepository) { this.keyBindingRepository = Objects.requireNonNull(keyBindingRepository); diff --git a/src/main/java/org/jabref/gui/actions/CleanupAction.java b/src/main/java/org/jabref/gui/actions/CleanupAction.java index 0c23296cd6b..7382d4d076e 100644 --- a/src/main/java/org/jabref/gui/actions/CleanupAction.java +++ b/src/main/java/org/jabref/gui/actions/CleanupAction.java @@ -12,7 +12,6 @@ import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.gui.util.DefaultTaskExecutor; -import org.jabref.gui.util.component.CheckBoxMessage; import org.jabref.gui.worker.AbstractWorker; import org.jabref.logic.cleanup.CleanupPreset; import org.jabref.logic.cleanup.CleanupWorker; @@ -73,15 +72,15 @@ public void run() { cleanupPreset.storeInPreferences(preferences); if (cleanupPreset.isRenamePDF() && Globals.prefs.getBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN)) { - CheckBoxMessage cbm = new CheckBoxMessage( + + boolean autogeneratePressed = dialogService.showConfirmationDialogWithOptOutAndWait(Localization.lang("Autogenerate PDF Names"), Localization.lang("Auto-generating PDF-Names does not support undo. Continue?"), - Localization.lang("Disable this confirmation dialog"), false); - int answer = JOptionPane.showConfirmDialog(null, cbm, Localization.lang("Autogenerate PDF Names"), - JOptionPane.YES_NO_OPTION); - if (cbm.isSelected()) { - Globals.prefs.putBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN, false); - } - if (answer == JOptionPane.NO_OPTION) { + Localization.lang("Autogenerate PDF Names"), + Localization.lang("Cancel"), + Localization.lang("Disable this confirmation dialog"), + optOut -> Globals.prefs.putBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN, !optOut)); + + if (!autogeneratePressed) { canceled = true; return; } @@ -117,15 +116,15 @@ public void update() { } String message; switch (modifiedEntriesCount) { - case 0: - message = Localization.lang("No entry needed a clean up"); - break; - case 1: - message = Localization.lang("One entry needed a clean up"); - break; - default: - message = Localization.lang("%0 entries needed a clean up", Integer.toString(modifiedEntriesCount)); - break; + case 0: + message = Localization.lang("No entry needed a clean up"); + break; + case 1: + message = Localization.lang("One entry needed a clean up"); + break; + default: + message = Localization.lang("%0 entries needed a clean up", Integer.toString(modifiedEntriesCount)); + break; } panel.output(message); } diff --git a/src/main/java/org/jabref/gui/actions/JabRefAction.java b/src/main/java/org/jabref/gui/actions/JabRefAction.java index 78793e9a206..d000f716040 100644 --- a/src/main/java/org/jabref/gui/actions/JabRefAction.java +++ b/src/main/java/org/jabref/gui/actions/JabRefAction.java @@ -10,13 +10,16 @@ */ class JabRefAction extends org.controlsfx.control.action.Action { + public JabRefAction(Action action, KeyBindingRepository keyBindingRepository) { super(action.getText()); action.getIcon() .ifPresent(icon -> setGraphic(icon.getGraphicNode())); action.getKeyBinding() .ifPresent(keyBinding -> setAccelerator(keyBindingRepository.getKeyCombination(keyBinding))); + setLongText(action.getDescription()); + } public JabRefAction(Action action, Command command, KeyBindingRepository keyBindingRepository) { diff --git a/src/main/java/org/jabref/gui/actions/MassSetFieldAction.java b/src/main/java/org/jabref/gui/actions/MassSetFieldAction.java index 24ca4064ff7..2d6e2a907db 100644 --- a/src/main/java/org/jabref/gui/actions/MassSetFieldAction.java +++ b/src/main/java/org/jabref/gui/actions/MassSetFieldAction.java @@ -20,7 +20,6 @@ import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; -import javax.swing.JOptionPane; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.undo.UndoableEdit; @@ -63,7 +62,6 @@ public class MassSetFieldAction extends SimpleCommand { private boolean canceled = true; private JCheckBox overwrite; - public MassSetFieldAction(JabRefFrame frame) { this.frame = frame; } @@ -98,8 +96,8 @@ private void createDialog() { } set.addChangeListener(e -> - // Entering a setText is only relevant if we are setting, not clearing: - textFieldSet.setEnabled(set.isSelected())); + // Entering a setText is only relevant if we are setting, not clearing: + textFieldSet.setEnabled(set.isSelected())); append.addChangeListener(e -> { // Text to append is only required if we are appending: @@ -109,12 +107,12 @@ private void createDialog() { }); clear.addChangeListener(e -> - // Overwrite protection makes no sense if we are clearing the field: - overwrite.setEnabled(!clear.isSelected() && !append.isSelected())); + // Overwrite protection makes no sense if we are clearing the field: + overwrite.setEnabled(!clear.isSelected() && !append.isSelected())); rename.addChangeListener(e -> - // Entering a setText is only relevant if we are renaming - textFieldRename.setEnabled(rename.isSelected())); + // Entering a setText is only relevant if we are renaming + textFieldRename.setEnabled(rename.isSelected())); overwrite = new JCheckBox(Localization.lang("Overwrite existing field values"), true); ButtonGroup bg = new ButtonGroup(); @@ -158,8 +156,9 @@ private void createDialog() { // Check that any field name is set String fieldText = (String) field.getSelectedItem(); if ((fieldText == null) || fieldText.trim().isEmpty()) { - JOptionPane.showMessageDialog(diag, Localization.lang("You must enter at least one field name"), "", - JOptionPane.ERROR_MESSAGE); + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("You must enter at least one field name")); + return; // Do not close the dialog. } @@ -167,8 +166,9 @@ private void createDialog() { if (rename.isSelected()) { String[] fields = getFieldNames(fieldText); if (fields.length > 1) { - JOptionPane.showMessageDialog(diag, Localization.lang("You can only rename one field at a time"), - "", JOptionPane.ERROR_MESSAGE); + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("You can only rename one field at a time")); + return; // Do not close the dialog. } } @@ -243,8 +243,7 @@ public void execute() { NamedCompound compoundEdit = new NamedCompound(Localization.lang("Set field")); if (rename.isSelected()) { if (fields.length > 1) { - JOptionPane.showMessageDialog(diag, Localization.lang("You can only rename one field at a time"), "", - JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("You can only rename one field at a time")); return; // Do not close the dialog. } else { compoundEdit.addEdit(MassSetFieldAction.massRenameField(entryList, fields[0], textFieldRename.getText(), @@ -258,7 +257,7 @@ public void execute() { for (String field : fields) { compoundEdit.addEdit(MassSetFieldAction.massSetField(entryList, field, set.isSelected() ? toSet : null, - overwrite.isSelected())); + overwrite.isSelected())); } } compoundEdit.end(); diff --git a/src/main/java/org/jabref/gui/collab/ChangeScanner.java b/src/main/java/org/jabref/gui/collab/ChangeScanner.java index ae1b1355832..3ee754dae4d 100644 --- a/src/main/java/org/jabref/gui/collab/ChangeScanner.java +++ b/src/main/java/org/jabref/gui/collab/ChangeScanner.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.Optional; -import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultMutableTreeNode; @@ -38,6 +37,7 @@ import org.slf4j.LoggerFactory; public class ChangeScanner implements Runnable { + private static final Logger LOGGER = LoggerFactory.getLogger(ChangeScanner.class); private final File file; @@ -94,8 +94,9 @@ public void displayResult(final DisplayResultCallback fup) { }); } else { - JOptionPane.showMessageDialog(null, Localization.lang("No actual changes found."), - Localization.lang("External changes"), JOptionPane.INFORMATION_MESSAGE); + frame.getDialogService().showInformationDialogAndWait(Localization.lang("External changes"), + Localization.lang("No actual changes found.")); + fup.scanResultsResolved(true); } } @@ -103,8 +104,11 @@ public void displayResult(final DisplayResultCallback fup) { private void storeTempDatabase() { JabRefExecutorService.INSTANCE.execute(() -> { try { - SavePreferences prefs = SavePreferences.loadForSaveFromPreferences(Globals.prefs).withMakeBackup(false) - .withEncoding(panel.getBibDatabaseContext().getMetaData().getEncoding() + SavePreferences prefs = SavePreferences.loadForSaveFromPreferences(Globals.prefs) + .withMakeBackup(false) + .withEncoding(panel.getBibDatabaseContext() + .getMetaData() + .getEncoding() .orElse(Globals.prefs.getDefaultEncoding())); BibDatabaseWriter databaseWriter = new BibtexDatabaseWriter<>(FileSaveSession::new); @@ -176,6 +180,7 @@ private ChangeViewModel createBibEntryDiff(BibEntryDiff diff) { @FunctionalInterface public interface DisplayResultCallback { + void scanResultsResolved(boolean resolved); } } diff --git a/src/main/java/org/jabref/gui/customentrytypes/EntryCustomizationDialog.java b/src/main/java/org/jabref/gui/customentrytypes/EntryCustomizationDialog.java index d8ef951c9f8..6fa48081af5 100644 --- a/src/main/java/org/jabref/gui/customentrytypes/EntryCustomizationDialog.java +++ b/src/main/java/org/jabref/gui/customentrytypes/EntryCustomizationDialog.java @@ -26,7 +26,6 @@ import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JList; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.ListSelectionModel; import javax.swing.event.ListDataEvent; @@ -101,7 +100,7 @@ private void initGui() { List entryTypes = new ArrayList<>(); entryTypes.addAll(EntryTypes.getAllTypes(bibDatabaseMode)); - typeComp = new EntryTypeList(entryTypes, bibDatabaseMode); + typeComp = new EntryTypeList(frame.getDialogService(), entryTypes, bibDatabaseMode); typeComp.addListSelectionListener(this); typeComp.addAdditionActionListener(e -> typeComp.selectField(e.getActionCommand())); typeComp.addDefaultActionListener(new DefaultListener()); @@ -323,14 +322,14 @@ private void deleteType(String name) { if (type.isPresent() && (type.get() instanceof CustomEntryType)) { if (!EntryTypes.getStandardType(name, bibDatabaseMode).isPresent()) { - int reply = JOptionPane.showConfirmDialog - (null, Localization.lang("All entries of this " - + "type will be declared " - + "typeless. Continue?"), - Localization.lang("Delete custom format") + - " '" + StringUtil.capitalizeFirst(name) + '\'', JOptionPane.YES_NO_OPTION, - JOptionPane.WARNING_MESSAGE); - if (reply != JOptionPane.YES_OPTION) { + + boolean deleteCustomClicked = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Delete custom format") + + " '" + StringUtil.capitalizeFirst(name) + '\'', Localization.lang("All entries of this " + + "type will be declared " + + "typeless. Continue?"), + Localization.lang("Delete custom format"), Localization.lang("Cancel")); + + if (!deleteCustomClicked) { return; } } diff --git a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeList.java b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeList.java index 5f27c6a14e8..e4550b529f1 100644 --- a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeList.java +++ b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeList.java @@ -7,11 +7,11 @@ import java.util.Optional; import javax.swing.JButton; -import javax.swing.JOptionPane; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.jabref.Globals; +import org.jabref.gui.DialogService; import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator; import org.jabref.logic.l10n.Localization; import org.jabref.model.EntryTypes; @@ -29,11 +29,14 @@ public class EntryTypeList extends FieldSetComponent implements ListSelectionLis private final JButton def = new JButton(Localization.lang("Default")); private final BibDatabaseMode mode; + private final DialogService dialogService; - /** Creates a new instance of EntryTypeList */ - public EntryTypeList(List fields, BibDatabaseMode mode) { - super(Localization.lang("Entry types"), fields, false, true); + /** Creates a new instance of EntryTypeList + * @param frame */ + public EntryTypeList(DialogService dialogService, List fields, BibDatabaseMode mode) { + super(Localization.lang("Entry types"), fields, fields, false, true); this.mode = mode; + this.dialogService = dialogService; con.gridx = 0; con.gridy = 2; @@ -61,15 +64,17 @@ protected void addField(String str) { Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); if (!testString.equals(s) || (s.indexOf('&') >= 0)) { // Report error and exit. - JOptionPane.showMessageDialog(this, Localization.lang("Entry type names are not allowed to contain white space or the following " - + "characters") + ": # { } ~ , ^ &", - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); + + dialogService.showErrorDialogAndWait(Localization.lang("Error"), + Localization.lang("Entry type names are not allowed to contain white space or the following " + + "characters") + ": # { } ~ , ^ &"); + return; - } - else if ("comment".equalsIgnoreCase(s)) { + } else if ("comment".equalsIgnoreCase(s)) { // Report error and exit. - JOptionPane.showMessageDialog(this, Localization.lang("The name 'comment' cannot be used as an entry type name."), - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); + dialogService.showErrorDialogAndWait(Localization.lang("Error"), + Localization.lang("The name 'comment' cannot be used as an entry type name.")); + return; } addFieldUncritically(s); @@ -93,8 +98,8 @@ protected void removeSelected() { listModel.removeElementAt(selected[selected.length - 1 - i]); } else { // This shouldn't happen, since the Remove button should be disabled. - JOptionPane.showMessageDialog(null, Localization.lang("This entry type cannot be removed."), - Localization.lang("Remove entry type"), JOptionPane.ERROR_MESSAGE); + dialogService.showErrorDialogAndWait(Localization.lang("Remove entry type"), + Localization.lang("This entry type cannot be removed.")); } } } diff --git a/src/main/java/org/jabref/gui/exporter/ExportCommand.java b/src/main/java/org/jabref/gui/exporter/ExportCommand.java index c503960a631..22134072914 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportCommand.java +++ b/src/main/java/org/jabref/gui/exporter/ExportCommand.java @@ -5,8 +5,6 @@ import java.util.List; import java.util.stream.Collectors; -import javax.swing.JOptionPane; - import javafx.stage.FileChooser; import org.jabref.Globals; @@ -50,9 +48,8 @@ public void execute() { Globals.exportFactory = ExporterFactory.create(Globals.prefs, Globals.journalAbbreviationLoader); FileDialogConfiguration fileDialogConfiguration = createExportFileChooser(Globals.exportFactory, Globals.prefs.get(JabRefPreferences.EXPORT_WORKING_DIRECTORY)); DialogService dialogService = frame.getDialogService(); - DefaultTaskExecutor.runInJavaFXThread(() -> - dialogService.showFileSaveDialog(fileDialogConfiguration) - .ifPresent(path -> export(path, fileDialogConfiguration.getSelectedExtensionFilter(), Globals.exportFactory.getExporters()))); + DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileSaveDialog(fileDialogConfiguration) + .ifPresent(path -> export(path, fileDialogConfiguration.getSelectedExtensionFilter(), Globals.exportFactory.getExporters()))); } private void export(Path file, FileChooser.ExtensionFilter selectedExtensionFilter, List exporters) { @@ -63,9 +60,13 @@ private void export(Path file, FileChooser.ExtensionFilter selectedExtensionFilt if (Files.exists(file)) { // Warn that the file exists: - if (JOptionPane.showConfirmDialog(null, + + boolean overwriteFilePressed = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Export"), Localization.lang("'%0' exists. Overwrite file?", file.getFileName().toString()), - Localization.lang("Export"), JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION) { + Localization.lang("Overwrite file"), + Localization.lang("Cancel")); + + if (!overwriteFilePressed) { return; } } @@ -82,8 +83,9 @@ private void export(Path file, FileChooser.ExtensionFilter selectedExtensionFilt // Set the global variable for this database's file directory before exporting, // so formatters can resolve linked files correctly. // (This is an ugly hack!) - Globals.prefs.fileDirForDatabase = frame.getCurrentBasePanel().getBibDatabaseContext() - .getFileDirectories(Globals.prefs.getFileDirectoryPreferences()); + Globals.prefs.fileDirForDatabase = frame.getCurrentBasePanel() + .getBibDatabaseContext() + .getFileDirectories(Globals.prefs.getFileDirectoryPreferences()); // Make sure we remember which filter was used, to set // the default for next time: @@ -100,8 +102,11 @@ public void run() { try { format.export(frame.getCurrentBasePanel().getBibDatabaseContext(), file, - frame.getCurrentBasePanel().getBibDatabaseContext().getMetaData().getEncoding() - .orElse(Globals.prefs.getDefaultEncoding()), + frame.getCurrentBasePanel() + .getBibDatabaseContext() + .getMetaData() + .getEncoding() + .orElse(Globals.prefs.getDefaultEncoding()), finEntries); } catch (Exception ex) { LOGGER.warn("Problem exporting", ex); @@ -123,9 +128,8 @@ public void update() { else { frame.output(Localization.lang("Could not save file.") + " - " + errorMessage); // Need to warn the user that saving failed! - JOptionPane.showMessageDialog(null, - Localization.lang("Could not save file.") + "\n" + errorMessage, - Localization.lang("Save library"), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Save library"), Localization.lang("Could not save file.") + "\n" + errorMessage); + } } }; diff --git a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java index 39434593f4b..06efe18baa9 100644 --- a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java +++ b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java @@ -9,6 +9,9 @@ import javax.swing.JOptionPane; import javax.swing.JTextArea; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonType; + import org.jabref.Globals; import org.jabref.JabRefExecutorService; import org.jabref.gui.BasePanel; @@ -140,7 +143,9 @@ public void run() { // Save the database success = saveDatabase(panel.getBibDatabaseContext().getDatabaseFile().get(), false, - panel.getBibDatabaseContext().getMetaData().getEncoding() + panel.getBibDatabaseContext() + .getMetaData() + .getEncoding() .orElse(Globals.prefs.getDefaultEncoding())); panel.updateTimeStamp(); @@ -188,12 +193,10 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) panel.registerUndoableChanges(session); } catch (UnsupportedCharsetException ex) { - JOptionPane.showMessageDialog(null, - Localization.lang("Could not save file.") - + Localization.lang("Character encoding '%0' is not supported.", encoding.displayName()), - Localization.lang("Save library"), JOptionPane.ERROR_MESSAGE); - // FIXME: rethrow anti-pattern - throw new SaveException("rt"); + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Save library"), Localization.lang("Could not save file.") + + Localization.lang("Character encoding '%0' is not supported.", encoding.displayName())); + throw ex; } catch (SaveException ex) { if (ex == SaveException.FILE_LOCKED) { throw ex; @@ -208,8 +211,7 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) JOptionPane.showMessageDialog(null, Localization.lang("Could not save file.") + ".\n" + ex.getMessage(), Localization.lang("Save library"), JOptionPane.ERROR_MESSAGE); - // FIXME: rethrow anti-pattern - throw new SaveException("rt"); + throw ex; } // handle encoding problems @@ -224,46 +226,48 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) builder.add(ta).xy(3, 1); builder.add(Localization.lang("What do you want to do?")).xy(1, 3); String tryDiff = Localization.lang("Try different encoding"); + + //TODO: Old Swing panel int answer = JOptionPane.showOptionDialog(null, builder.getPanel(), Localization.lang("Save library"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, new String[] {Localization.lang("Save"), tryDiff, Localization.lang("Cancel")}, tryDiff); if (answer == JOptionPane.NO_OPTION) { // The user wants to use another encoding. - Object choice = JOptionPane.showInputDialog(null, Localization.lang("Select encoding"), - Localization.lang("Save library"), JOptionPane.QUESTION_MESSAGE, null, - Encodings.ENCODINGS_DISPLAYNAMES, encoding); - if (choice == null) { - success = false; - } else { - Charset newEncoding = Charset.forName((String) choice); + Optional selectedCharSet = frame.getDialogService().showChoiceDialogAndWait(Localization.lang("Save library"), Localization.lang("Select encoding"), Localization.lang("Save library"), encoding, Encodings.getCharsets()); + + if (selectedCharSet.isPresent()) { + + Charset newEncoding = selectedCharSet.get(); return saveDatabase(file, selectedOnly, newEncoding); + } else { + success = false; } - } else if (answer == JOptionPane.CANCEL_OPTION) { - success = false; } - } - // backup file? - try { - if (success) { - session.commit(file.toPath()); - // Make sure to remember which encoding we used. - panel.getBibDatabaseContext().getMetaData().setEncoding(encoding, ChangePropagation.DO_NOT_POST_EVENT); - } else { - session.cancel(); - } - } catch (SaveException e) { - int ans = JOptionPane.showConfirmDialog(null, - Localization.lang("Save failed during backup creation") + ". " - + Localization.lang("Save without backup?"), - Localization.lang("Unable to create backup"), JOptionPane.YES_NO_OPTION); - if (ans == JOptionPane.YES_OPTION) { - session.setUseBackup(false); - session.commit(file.toPath()); - panel.getBibDatabaseContext().getMetaData().setEncoding(encoding, ChangePropagation.DO_NOT_POST_EVENT); - } else { - success = false; + // backup file? + try { + if (success) { + session.commit(file.toPath()); + // Make sure to remember which encoding we used. + panel.getBibDatabaseContext().getMetaData().setEncoding(encoding, ChangePropagation.DO_NOT_POST_EVENT); + } else { + session.cancel(); + } + } catch (SaveException e) { + LOGGER.debug("Problems saving during backup creationg", e); + boolean saveWithoutBackupClicked = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Unable to create backup"), + Localization.lang("Save failed during backup creation") + ". " + Localization.lang("Save without backup?"), + Localization.lang("Save without backup"), Localization.lang("Cancel")); + + if (saveWithoutBackupClicked) { + session.setUseBackup(false); + + session.commit(file.toPath()); + panel.getBibDatabaseContext().getMetaData().setEncoding(encoding, ChangePropagation.DO_NOT_POST_EVENT); + } else { + success = false; + } } } @@ -288,7 +292,8 @@ public void saveAs() throws Exception { FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .addExtensionFilter(FileType.BIBTEX_DB) .withDefaultExtension(FileType.BIBTEX_DB) - .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)) + .build(); DialogService dialogService = frame.getDialogService(); Optional path = dialogService.showFileSaveDialog(fileDialogConfiguration); if (path.isPresent()) { @@ -389,53 +394,56 @@ public boolean isCanceled() { private boolean checkExternalModification() { // Check for external modifications: if (panel.isUpdatedExternally()) { - String[] opts = new String[] {Localization.lang("Review changes"), Localization.lang("Save"), - Localization.lang("Cancel")}; - int answer = JOptionPane.showOptionDialog(null, - Localization.lang("File has been updated externally. " + "What do you want to do?"), - Localization.lang("File updated externally"), JOptionPane.YES_NO_CANCEL_OPTION, - JOptionPane.QUESTION_MESSAGE, null, opts, opts[0]); - - if (answer == JOptionPane.CANCEL_OPTION) { - canceled = true; - return true; - } else if (answer == JOptionPane.YES_OPTION) { - canceled = true; - - JabRefExecutorService.INSTANCE.execute(() -> { - - if (!FileBasedLock - .waitForFileLock(panel.getBibDatabaseContext().getDatabaseFile().get().toPath())) { - // TODO: GUI handling of the situation when the externally modified file keeps being locked. - LOGGER.error("File locked, this will be trouble."); - } - ChangeScanner scanner = new ChangeScanner(panel.frame(), panel, - panel.getBibDatabaseContext().getDatabaseFile().get(), panel.getTempFile()); - JabRefExecutorService.INSTANCE.executeInterruptableTaskAndWait(scanner); - if (scanner.changesFound()) { - scanner.displayResult(resolved -> { - if (resolved) { - panel.markExternalChangesAsResolved(); - DefaultTaskExecutor.runInJavaFXThread(() -> panel.getSidePaneManager().hide(SidePaneType.FILE_UPDATE_NOTIFICATION)); - } else { - canceled = true; - } - }); - } - }); - - return true; - } else { // User indicated to store anyway. - if (panel.getBibDatabaseContext().getMetaData().isProtected()) { - JOptionPane.showMessageDialog(null, - Localization - .lang("Library is protected. Cannot save until external changes have been reviewed."), - Localization.lang("Protected library"), JOptionPane.ERROR_MESSAGE); + ButtonType save = new ButtonType(Localization.lang("Save")); + ButtonType reviewChanges = new ButtonType(Localization.lang("Review changes")); + + Optional buttonPressed = frame.getDialogService().showCustomButtonDialogAndWait(AlertType.CONFIRMATION, Localization.lang("File updated externally"), + Localization.lang("File has been updated externally. " + "What do you want to do?"), reviewChanges, save, ButtonType.CANCEL); + + if (buttonPressed.isPresent()) { + if (buttonPressed.get() == ButtonType.CANCEL) { canceled = true; - } else { - panel.markExternalChangesAsResolved(); - panel.getSidePaneManager().hide(SidePaneType.FILE_UPDATE_NOTIFICATION); + return true; + } + if (buttonPressed.get().equals(reviewChanges)) { + canceled = true; + + JabRefExecutorService.INSTANCE.execute(() -> { + + if (!FileBasedLock + .waitForFileLock(panel.getBibDatabaseContext().getDatabaseFile().get().toPath())) { + // TODO: GUI handling of the situation when the externally modified file keeps being locked. + LOGGER.error("File locked, this will be trouble."); + } + + ChangeScanner scanner = new ChangeScanner(panel.frame(), panel, + panel.getBibDatabaseContext().getDatabaseFile().get(), panel.getTempFile()); + JabRefExecutorService.INSTANCE.executeInterruptableTaskAndWait(scanner); + if (scanner.changesFound()) { + scanner.displayResult(resolved -> { + if (resolved) { + panel.markExternalChangesAsResolved(); + DefaultTaskExecutor.runInJavaFXThread(() -> panel.getSidePaneManager().hide(SidePaneType.FILE_UPDATE_NOTIFICATION)); + } else { + canceled = true; + } + }); + } + }); + + return true; + } else { // User indicated to store anyway. + if (panel.getBibDatabaseContext().getMetaData().isProtected()) { + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Protected library"), + Localization.lang("Library is protected. Cannot save until external changes have been reviewed.")); + + canceled = true; + } else { + panel.markExternalChangesAsResolved(); + panel.getSidePaneManager().hide(SidePaneType.FILE_UPDATE_NOTIFICATION); + } } } } diff --git a/src/main/java/org/jabref/gui/externalfiles/DownloadExternalFile.java b/src/main/java/org/jabref/gui/externalfiles/DownloadExternalFile.java index 8985ccd4f02..e556332e59d 100644 --- a/src/main/java/org/jabref/gui/externalfiles/DownloadExternalFile.java +++ b/src/main/java/org/jabref/gui/externalfiles/DownloadExternalFile.java @@ -8,12 +8,11 @@ import java.util.List; import java.util.Optional; -import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.jabref.Globals; import org.jabref.JabRefExecutorService; -import org.jabref.gui.JabRefFrame; +import org.jabref.gui.DialogService; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.filelist.FileListEntryEditor; @@ -45,16 +44,16 @@ public class DownloadExternalFile { private static final Logger LOGGER = LoggerFactory.getLogger(DownloadExternalFile.class); - private final JabRefFrame frame; private final BibDatabaseContext databaseContext; private final BibEntry entry; + private final DialogService dialogService; + private FileListEntryEditor editor; private boolean downloadFinished; private boolean dontShowDialog; - - public DownloadExternalFile(JabRefFrame frame, BibDatabaseContext databaseContext, BibEntry entry) { - this.frame = frame; + public DownloadExternalFile(DialogService dialogService, BibDatabaseContext databaseContext, BibEntry entry) { + this.dialogService = dialogService; this.databaseContext = databaseContext; this.entry = entry; } @@ -121,22 +120,21 @@ public static String getSuffix(final String link) { */ public void download(final DownloadCallback callback) throws IOException { dontShowDialog = false; - final String res = JOptionPane.showInputDialog(frame, Localization.lang("Enter URL to download")); - if ((res == null) || res.trim().isEmpty()) { - return; - } + Optional res = dialogService.showInputDialogAndWait(Localization.lang("Download file"), Localization.lang("Enter URL to download")); - URL url; - try { - url = new URL(res); - } catch (MalformedURLException ex1) { - JOptionPane.showMessageDialog(null, Localization.lang("Invalid URL"), Localization.lang("Download file"), - JOptionPane.ERROR_MESSAGE); - return; - } + if (res.isPresent()) { + URL url; + try { + url = new URL(res.get()); + } catch (MalformedURLException ex1) { + dialogService.showErrorDialogAndWait(Localization.lang("Download file"), + Localization.lang("Invalid URL")); - download(url, callback); + return; + } + download(url, callback); + } } /** @@ -160,9 +158,8 @@ public void download(URL url, final DownloadCallback callback) throws IOExceptio // TODO: stop editor dialog if this results in an error: mimeType = udl.getMimeType(); // Read MIME type } catch (IOException ex) { - JOptionPane.showMessageDialog(null, Localization.lang("Invalid URL") + ": " + ex.getMessage(), - Localization.lang("Download file"), JOptionPane.ERROR_MESSAGE); LOGGER.info("Error while downloading " + "'" + res + "'", ex); + dialogService.showErrorDialogAndWait(Localization.lang("Download file"), Localization.lang("Invalid URL") + ": " + ex.getMessage(), ex); return; } final URL urlF = url; @@ -176,9 +173,11 @@ public void download(URL url, final DownloadCallback callback) throws IOExceptio if ((editor != null) && editor.isVisible()) { editor.setVisible(false, false); } - JOptionPane.showMessageDialog(null, Localization.lang("Invalid URL") + ": " + e2.getMessage(), - Localization.lang("Download file"), JOptionPane.ERROR_MESSAGE); + LOGGER.info("Error while downloading " + "'" + urlF + "'", e2); + + dialogService.showErrorDialogAndWait(Localization.lang("Download file"), Localization.lang("Invalid URL") + ": " + e2.getMessage()); + return; } // Download finished: call the method that stops the progress bar etc.: @@ -220,14 +219,16 @@ public void download(URL url, final DownloadCallback callback) throws IOExceptio editor.setExternalConfirm(closeEntry -> { File f = directory == null ? new File(closeEntry.getLink()) : expandFilename(directory, closeEntry.getLink()); if (f.isDirectory()) { - JOptionPane.showMessageDialog(null, Localization.lang("Target file cannot be a directory."), - Localization.lang("Download file"), JOptionPane.ERROR_MESSAGE); + dialogService.showErrorDialogAndWait(Localization.lang("Download file"), + Localization.lang("Target file cannot be a directory.")); + return false; } if (f.exists()) { - return JOptionPane.showConfirmDialog(null, - Localization.lang("'%0' exists. Overwrite file?", f.getName()), - Localization.lang("Download file"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION; + return dialogService.showConfirmationDialogAndWait(Localization.lang("Download file"), + Localization.lang("'%0' exists. Overwrite file?", f.getName()), Localization.lang("Overwrite file"), + Localization.lang("Cancel")); + } else { return true; } @@ -334,13 +335,13 @@ private String getSuggestedFileName(String suffix) { return plannedName; } - /** * Callback interface that users of this class must implement in order to receive * notification when download is complete. */ @FunctionalInterface public interface DownloadCallback { + void downloadComplete(LinkedFile file); } } diff --git a/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java b/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java index a743d05a00d..549efc6fec4 100644 --- a/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java +++ b/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java @@ -9,10 +9,9 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import javax.swing.JOptionPane; - import org.jabref.Globals; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.worker.AbstractWorker; @@ -36,9 +35,11 @@ public class FindFullTextAction extends AbstractWorker { private final BasePanel basePanel; private final Map, BibEntry> downloads = new ConcurrentHashMap<>(); + private final DialogService dialogService; - public FindFullTextAction(BasePanel basePanel) { + public FindFullTextAction(DialogService dialogService, BasePanel basePanel) { this.basePanel = basePanel; + this.dialogService = dialogService; } @Override @@ -55,16 +56,16 @@ public void run() { if (basePanel.getSelectedEntries().size() >= WARNING_LIMIT) { String[] options = new String[] {Localization.lang("Look up full text documents"), Localization.lang("Cancel")}; - int answer = JOptionPane.showOptionDialog(null, - Localization.lang( - "You are about to look up full text documents for %0 entries.", - String.valueOf(basePanel.getSelectedEntries().size())) + "\n" - + Localization.lang("JabRef will send at least one request per entry to a publisher.") - + "\n" - + Localization.lang("Do you still want to continue?"), - Localization.lang("Look up full text documents"), JOptionPane.OK_CANCEL_OPTION, - JOptionPane.WARNING_MESSAGE, null, options, options[0]); - if (answer != JOptionPane.OK_OPTION) { + + boolean getFullTextForAllCliecked = dialogService.showConfirmationDialogAndWait(Localization.lang("Look up full text documents"), Localization.lang( + "You are about to look up full text documents for %0 entries.", + String.valueOf(basePanel.getSelectedEntries().size())) + "\n" + + Localization.lang("JabRef will send at least one request per entry to a publisher.") + + "\n" + + Localization.lang("Do you still want to continue?"), Localization.lang("Look up full text documents"), + Localization.lang("Cancel")); + + if (!getFullTextForAllCliecked) { basePanel.output(Localization.lang("Operation canceled.")); return; } @@ -85,13 +86,14 @@ public void update() { Optional dir = basePanel.getBibDatabaseContext().getFirstExistingFileDir(Globals.prefs.getFileDirectoryPreferences()); if (!dir.isPresent()) { - JOptionPane.showMessageDialog(null, + + dialogService.showErrorDialogAndWait(Localization.lang("Directory not found"), Localization.lang("Main file directory not set!") + " " + Localization.lang("Preferences") - + " -> " + Localization.lang("File"), - Localization.lang("Directory not found"), JOptionPane.ERROR_MESSAGE); + + " -> " + Localization.lang("File")); + return; } - DownloadExternalFile def = new DownloadExternalFile(basePanel.frame(), + DownloadExternalFile def = new DownloadExternalFile(dialogService, basePanel.getBibDatabaseContext(), entry); try { def.download(result.get(), file -> { @@ -117,7 +119,7 @@ public void update() { entry.getCiteKeyOptional().orElse(Localization.lang("undefined"))); basePanel.output(message); - JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE); + dialogService.showErrorDialogAndWait(title, message); } remove.add(result); } diff --git a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java index 33a09471a67..3ede64f1fea 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java +++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java @@ -67,7 +67,7 @@ private void updateFiles() { externalFiles.getItems().add(new SeparatorMenuItem()); MenuItem addToNewFileItem = new MenuItem(Localization.lang("New") + "..."); addToNewFileItem.setOnAction(event -> { - NewProtectedTermsFileDialog dialog = new NewProtectedTermsFileDialog(JabRefGUI.getMainFrame(), + NewProtectedTermsFileDialog dialog = new NewProtectedTermsFileDialog(JabRefGUI.getMainFrame().getDialogService(), loader); SwingUtilities.invokeLater(() -> { diff --git a/src/main/java/org/jabref/gui/importer/ImportCommand.java b/src/main/java/org/jabref/gui/importer/ImportCommand.java index 5059c771b87..4849fce65ec 100644 --- a/src/main/java/org/jabref/gui/importer/ImportCommand.java +++ b/src/main/java/org/jabref/gui/importer/ImportCommand.java @@ -8,8 +8,6 @@ import java.util.SortedSet; import java.util.stream.Collectors; -import javax.swing.JOptionPane; - import javafx.stage.FileChooser; import org.jabref.Globals; @@ -61,9 +59,9 @@ public void execute() { private void doImport(Path file, SortedSet importers, FileChooser.ExtensionFilter selectedExtensionFilter) { if (!Files.exists(file)) { - JOptionPane.showMessageDialog(null, - Localization.lang("File not found") + ": '" + file.getFileName() + "'.", - Localization.lang("Import"), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Import"), + Localization.lang("File not found") + ": '" + file.getFileName() + "'."); + return; } Optional format = FileFilterConverter.getImporter(selectedExtensionFilter, importers); diff --git a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java index e4425f8e171..34293fc8dca 100644 --- a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java @@ -80,7 +80,6 @@ import org.jabref.gui.undo.UndoableRemoveEntry; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.comparator.IconComparator; -import org.jabref.gui.util.component.CheckBoxMessage; import org.jabref.logic.bibtex.DuplicateCheck; import org.jabref.logic.bibtex.comparator.FieldComparator; import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator; @@ -185,7 +184,6 @@ public class ImportInspectionDialog extends JabRefDialog implements ImportInspec private boolean generatedKeys; // Set to true after keys have been generated. private boolean defaultSelected = true; - /** * Creates a dialog that displays the given list of fields in the table. The * dialog allows another process to add entries dynamically while the dialog @@ -651,8 +649,8 @@ public void showMessage(String message) { */ public void showErrorMessage(String fetcherTitle, String localizedException) { showMessage(Localization.lang("Error while fetching from %0", fetcherTitle) + "\n" + - Localization.lang("Please try again later and/or check your network connection.") + "\n" + - localizedException, + Localization.lang("Please try again later and/or check your network connection.") + "\n" + + localizedException, Localization.lang("Search %0", fetcherTitle), JOptionPane.ERROR_MESSAGE); } @@ -681,7 +679,6 @@ class AddToGroupAction extends AbstractAction { private final GroupTreeNode node; - public AddToGroupAction(GroupTreeNode node) { super(node.getName()); this.node = node; @@ -732,16 +729,15 @@ public void actionPerformed(ActionEvent event) { // This status // is indicated by the entry's group hit status: if (entry.isGroupHit()) { - CheckBoxMessage cbm = new CheckBoxMessage( - Localization - .lang("There are possible duplicates (marked with an icon) that haven't been resolved. Continue?"), - Localization.lang("Disable this confirmation dialog"), false); - int answer = JOptionPane.showConfirmDialog(ImportInspectionDialog.this, cbm, - Localization.lang("Duplicates found"), JOptionPane.YES_NO_OPTION); - if (cbm.isSelected()) { - Globals.prefs.putBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION, false); - } - if (answer == JOptionPane.NO_OPTION) { + + boolean continuePressed = frame.getDialogService().showConfirmationDialogWithOptOutAndWait(Localization.lang("Duplicates found"), + Localization.lang("There are possible duplicates (marked with an icon) that haven't been resolved. Continue?"), + Localization.lang("Continue"), + Localization.lang("Cancel"), + Localization.lang("Disable this confirmation dialog"), + optOut -> Globals.prefs.putBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION, !optOut)); + + if (!continuePressed) { return; } break; @@ -836,10 +832,13 @@ private boolean addToGroups(NamedCompound ce, BibEntry entry, Set // The best course of action is probably to ask the // user if a key should be generated // immediately. - int answer = JOptionPane.showConfirmDialog(ImportInspectionDialog.this, + + boolean generateKeysPressed = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Add to group"), Localization.lang("Cannot add entries to group without generating keys. Generate keys now?"), - Localization.lang("Add to group"), JOptionPane.YES_NO_OPTION); - if (answer == JOptionPane.YES_OPTION) { + Localization.lang("Generate keys"), + Localization.lang("Cancel")); + + if (generateKeysPressed) { generateKeys(); } else { groupingCanceled = true; @@ -851,7 +850,7 @@ private boolean addToGroups(NamedCompound ce, BibEntry entry, Set for (GroupTreeNode node : groups) { if (node.getGroup() instanceof GroupEntryChanger) { // Add the entry: - GroupEntryChanger entryChanger = (GroupEntryChanger)node.getGroup(); + GroupEntryChanger entryChanger = (GroupEntryChanger) node.getGroup(); List undo = entryChanger.add(Collections.singletonList(entry)); if (!undo.isEmpty()) { ce.addEdit(UndoableChangeEntriesOfGroup.getUndoableEdit(new GroupTreeNodeViewModel(node), @@ -922,7 +921,6 @@ private class SelectionButton implements ActionListener { private final Boolean enable; - public SelectionButton(boolean enable) { this.enable = enable; } @@ -1188,15 +1186,16 @@ public void actionPerformed(ActionEvent event) { return; } BibEntry entry = selectionModel.getSelected().get(0); - String result = JOptionPane.showInputDialog(ImportInspectionDialog.this, Localization.lang("Enter URL"), - entry.getField(FieldName.URL).orElse("")); + + Optional result = frame.getDialogService().showInputDialogAndWait(Localization.lang("Enter URL"), Localization.lang("Enter URL")); + entries.getReadWriteLock().writeLock().lock(); try { - if (result != null) { - if (result.isEmpty()) { + if (result.isPresent()) { + if (result.get().isEmpty()) { entry.clearField(FieldName.URL); } else { - entry.setField(FieldName.URL, result); + entry.setField(FieldName.URL, result.get()); } } } finally { @@ -1210,7 +1209,6 @@ class DownloadFile extends JMenuItem implements ActionListener, DownloadExternal private BibEntry entry; - public DownloadFile() { super(Localization.lang("Download file")); addActionListener(this); @@ -1223,14 +1221,17 @@ public void actionPerformed(ActionEvent actionEvent) { } entry = selectionModel.getSelected().get(0); if (!entry.getCiteKeyOptional().isPresent()) { - int answer = JOptionPane.showConfirmDialog(null, + + boolean generateKeyPressed = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Download file"), Localization.lang("This entry has no BibTeX key. Generate key now?"), - Localization.lang("Download file"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); - if (answer == JOptionPane.OK_OPTION) { + Localization.lang("Generate key"), + Localization.lang("Cancel")); + + if (generateKeyPressed) { generateKeyForEntry(entry); } } - DownloadExternalFile def = new DownloadExternalFile(frame, bibDatabaseContext, entry); + DownloadExternalFile def = new DownloadExternalFile(frame.getDialogService(), bibDatabaseContext, entry); try { def.download(this); } catch (IOException ex) { @@ -1265,10 +1266,13 @@ public void actionPerformed(ActionEvent actionEvent) { } final BibEntry entry = selectionModel.getSelected().get(0); if (!entry.hasCiteKey()) { - int answer = JOptionPane.showConfirmDialog(null, + + boolean generateKeyPressed = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Download file"), Localization.lang("This entry has no BibTeX key. Generate key now?"), - Localization.lang("Download file"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); - if (answer == JOptionPane.OK_OPTION) { + Localization.lang("Generate key"), + Localization.lang("Cancel")); + + if (generateKeyPressed) { generateKeyForEntry(entry); } else { return; // Can't go on without the bibtex key. @@ -1291,7 +1295,7 @@ public void actionPerformed(ActionEvent actionEvent) { } glTable.repaint(); } - } , diag)); + }, diag)); } } @@ -1300,7 +1304,6 @@ private class LinkLocalFile extends JMenuItem implements ActionListener, Downloa private BibEntry entry; - public LinkLocalFile() { super(Localization.lang("Link local file")); addActionListener(this); @@ -1343,7 +1346,6 @@ class EntryTable extends JTable { private final GeneralRenderer renderer = new GeneralRenderer(Color.white); - public EntryTable(TableModel model) { super(model); getTableHeader().setReorderingAllowed(false); @@ -1408,29 +1410,29 @@ public Object getColumnValue(BibEntry entry, int i) { return entry.isSearchHit() ? Boolean.TRUE : Boolean.FALSE; } else if (i < PAD) { switch (i) { - case DUPL_COL: - return entry.isGroupHit() ? duplLabel : null; - case FILE_COL: - if (entry.hasField(FieldName.FILE)) { - FileListTableModel model = new FileListTableModel(); - entry.getField(FieldName.FILE).ifPresent(model::setContent); - fileLabel.setToolTipText(model.getToolTipHTMLRepresentation()); - if ((model.getRowCount() > 0) && model.getEntry(0).getType().isPresent()) { - fileLabel.setIcon(model.getEntry(0).getType().get().getIcon().getSmallIcon()); + case DUPL_COL: + return entry.isGroupHit() ? duplLabel : null; + case FILE_COL: + if (entry.hasField(FieldName.FILE)) { + FileListTableModel model = new FileListTableModel(); + entry.getField(FieldName.FILE).ifPresent(model::setContent); + fileLabel.setToolTipText(model.getToolTipHTMLRepresentation()); + if ((model.getRowCount() > 0) && model.getEntry(0).getType().isPresent()) { + fileLabel.setIcon(model.getEntry(0).getType().get().getIcon().getSmallIcon()); + } + return fileLabel; + } else { + return null; } - return fileLabel; - } else { - return null; - } - case URL_COL: - if (entry.hasField(FieldName.URL)) { - urlLabel.setToolTipText(entry.getField(FieldName.URL).orElse("")); - return urlLabel; - } else { + case URL_COL: + if (entry.hasField(FieldName.URL)) { + urlLabel.setToolTipText(entry.getField(FieldName.URL).orElse("")); + return urlLabel; + } else { + return null; + } + default: return null; - } - default: - return null; } } else { String field = INSPECTION_FIELDS.get(i - PAD); diff --git a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java index 7c6aad61d90..ed00f2e30af 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -14,7 +14,6 @@ import java.util.Optional; import java.util.stream.Collectors; -import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.jabref.Globals; @@ -191,21 +190,25 @@ private void openTheFile(Path file, boolean raisePanel) { if ((modificationTime.isPresent()) && ((System.currentTimeMillis() - modificationTime.get().toMillis()) > FileBasedLock.LOCKFILE_CRITICAL_AGE)) { // The lock file is fairly old, so we can offer to "steal" the file: - int answer = JOptionPane.showConfirmDialog(null, - "" + Localization.lang("Error opening file") + " '" + fileName + "'. " - + Localization.lang("File is locked by another JabRef instance.") + "

" + + boolean overWriteFileLockPressed = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("File locked"), + Localization.lang("Error opening file") + " '" + fileName + "'. " + + Localization.lang("File is locked by another JabRef instance.") + "\n" + Localization.lang("Do you want to override the file lock?"), - Localization.lang("File locked"), JOptionPane.YES_NO_OPTION); - if (answer == JOptionPane.YES_OPTION) { + Localization.lang("Overwrite file lock"), + Localization.lang("Cancel")); + + if (overWriteFileLockPressed) { FileBasedLock.deleteLockFile(file); } else { return; } } else if (!FileBasedLock.waitForFileLock(file)) { - JOptionPane.showMessageDialog(null, + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Error"), Localization.lang("Error opening file") + " '" + fileName + "'. " - + Localization.lang("File is locked by another JabRef instance."), - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); + + Localization.lang("File is locked by another JabRef instance.")); + return; } } @@ -226,9 +229,10 @@ private void openTheFile(Path file, boolean raisePanel) { result.getDatabaseContext().clearDatabaseFile(); // do not open the original file result.getDatabase().clearSharedDatabaseID(); LOGGER.error("Connection error", e); - JOptionPane.showMessageDialog(null, - e.getMessage() + "\n\n" + Localization.lang("A local copy will be opened."), - Localization.lang("Connection error"), JOptionPane.WARNING_MESSAGE); + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Connection error"), + e.getMessage() + "\n\n" + Localization.lang("A local copy will be opened.")); + } } diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeWithFetchedEntryAction.java b/src/main/java/org/jabref/gui/mergeentries/MergeWithFetchedEntryAction.java index 28015717f25..5d0d016e3d1 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeWithFetchedEntryAction.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeWithFetchedEntryAction.java @@ -1,8 +1,7 @@ package org.jabref.gui.mergeentries; -import javax.swing.JOptionPane; - import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.gui.actions.BaseAction; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; @@ -11,9 +10,11 @@ public class MergeWithFetchedEntryAction implements BaseAction { private final BasePanel basePanel; + private final DialogService dialogService; - public MergeWithFetchedEntryAction(BasePanel basePanel) { + public MergeWithFetchedEntryAction(BasePanel basePanel, DialogService dialogService) { this.basePanel = basePanel; + this.dialogService = dialogService; } @Override @@ -22,13 +23,12 @@ public void action() { BibEntry originalEntry = basePanel.getMainTable().getSelectedEntries().get(0); new FetchAndMergeEntry(originalEntry, basePanel, FetchAndMergeEntry.SUPPORTED_FIELDS); } else { - JOptionPane.showMessageDialog(null, - Localization.lang("This operation requires exactly one item to be selected."), - Localization.lang("Merge entry with %0 information", - FieldName.orFields(FieldName.getDisplayName(FieldName.DOI), - FieldName.getDisplayName(FieldName.ISBN), - FieldName.getDisplayName(FieldName.EPRINT))), - JOptionPane.INFORMATION_MESSAGE); + dialogService.showInformationDialogAndWait(Localization.lang("Merge entry with %0 information", + FieldName.orFields(FieldName.getDisplayName(FieldName.DOI), + FieldName.getDisplayName(FieldName.ISBN), + FieldName.getDisplayName(FieldName.EPRINT))), + Localization.lang("This operation requires exactly one item to be selected.")); + } } } diff --git a/src/main/java/org/jabref/gui/openoffice/DetectOpenOfficeInstallation.java b/src/main/java/org/jabref/gui/openoffice/DetectOpenOfficeInstallation.java index 14501f74f0a..0348b1a672e 100644 --- a/src/main/java/org/jabref/gui/openoffice/DetectOpenOfficeInstallation.java +++ b/src/main/java/org/jabref/gui/openoffice/DetectOpenOfficeInstallation.java @@ -153,6 +153,7 @@ private Optional chooseAmongInstallations(List installDirs) { builder.add(Localization.lang("Found more than one OpenOffice/LibreOffice executable.")).xy(1, 1); builder.add(Localization.lang("Please choose which one to connect to:")).xy(1, 3); builder.add(fileList).xy(1, 5); + int answer = JOptionPane.showConfirmDialog(null, builder.getPanel(), Localization.lang("Choose OpenOffice/LibreOffice executable"), JOptionPane.OK_CANCEL_OPTION); if (answer == JOptionPane.CANCEL_OPTION) { diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index 3d6a95f28da..981d7bc8723 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -78,6 +78,7 @@ * Pane to manage the interaction between JabRef and OpenOffice. */ public class OpenOfficePanel extends AbstractWorker { + private static final Logger LOGGER = LoggerFactory.getLogger(OpenOfficePanel.class); private JPanel content; @@ -99,7 +100,7 @@ public class OpenOfficePanel extends AbstractWorker { private final JButton help = new HelpAction(Localization.lang("OpenOffice/LibreOffice integration"), HelpFile.OPENOFFICE_LIBREOFFICE).getHelpButton(); private OOBibBase ooBase; - private JabRefFrame frame; + private final JabRefFrame frame; private OOBibStyle style; private StyleSelectDialog styleDialog; private boolean dialogOkPressed; @@ -150,9 +151,8 @@ private void initPanel() { + ooBase.getCurrentDocumentTitle().orElse("")); } catch (UnknownPropertyException | WrappedTargetException | IndexOutOfBoundsException | NoSuchElementException | NoDocumentException ex) { - JOptionPane.showMessageDialog(null, ex.getMessage(), Localization.lang("Error"), - JOptionPane.ERROR_MESSAGE); LOGGER.warn("Problem connecting", ex); + frame.getDialogService().showErrorDialogAndWait(ex); } }); @@ -203,11 +203,10 @@ public void actionPerformed(ActionEvent e) { List unresolvedKeys = ooBase.refreshCiteMarkers(databases, style); ooBase.rebuildBibTextSection(databases, style); if (!unresolvedKeys.isEmpty()) { - JOptionPane.showMessageDialog(null, - Localization.lang( - "Your OpenOffice/LibreOffice document references the BibTeX key '%0', which could not be found in your current library.", - unresolvedKeys.get(0)), - Localization.lang("Unable to synchronize bibliography"), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Unable to synchronize bibliography"), + Localization.lang("Your OpenOffice/LibreOffice document references the BibTeX key '%0', which could not be found in your current library.", + unresolvedKeys.get(0))); + } } catch (UndefinedCharacterFormatException ex) { reportUndefinedCharacterFormat(ex); @@ -216,18 +215,16 @@ public void actionPerformed(ActionEvent e) { } catch (ConnectionLostException ex) { showConnectionLostErrorMessage(); } catch (IOException ex) { - JOptionPane.showMessageDialog(null, - Localization - .lang("You must select either a valid style file, or use one of the default styles."), - Localization.lang("No valid style file defined"), JOptionPane.ERROR_MESSAGE); LOGGER.warn("Problem with style file", ex); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("No valid style file defined"), + Localization.lang("You must select either a valid style file, or use one of the default styles.")); + } catch (BibEntryNotFoundException ex) { - JOptionPane.showMessageDialog(null, - Localization.lang( - "Your OpenOffice/LibreOffice document references the BibTeX key '%0', which could not be found in your current library.", - ex.getBibtexKey()), - Localization.lang("Unable to synchronize bibliography"), JOptionPane.ERROR_MESSAGE); LOGGER.debug("BibEntry not found", ex); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Unable to synchronize bibliography"), Localization.lang( + "Your OpenOffice/LibreOffice document references the BibTeX key '%0', which could not be found in your current library.", + ex.getBibtexKey())); + } catch (com.sun.star.lang.IllegalArgumentException | PropertyVetoException | UnknownPropertyException | WrappedTargetException | NoSuchElementException | CreationException ex) { LOGGER.warn("Could not update bibliography", ex); @@ -321,11 +318,11 @@ private void exportEntries() { List unresolvedKeys = ooBase.refreshCiteMarkers(databases, style); BibDatabase newDatabase = ooBase.generateDatabase(databases); if (!unresolvedKeys.isEmpty()) { - JOptionPane.showMessageDialog(null, - Localization.lang( - "Your OpenOffice/LibreOffice document references the BibTeX key '%0', which could not be found in your current library.", - unresolvedKeys.get(0)), - Localization.lang("Unable to generate new library"), JOptionPane.ERROR_MESSAGE); + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Unable to generate new library"), + Localization.lang("Your OpenOffice/LibreOffice document references the BibTeX key '%0', which could not be found in your current library.", + unresolvedKeys.get(0))); + } Defaults defaults = new Defaults(Globals.prefs.getDefaultBibDatabaseMode()); @@ -334,12 +331,11 @@ private void exportEntries() { this.frame.addTab(databaseContext, true); } catch (BibEntryNotFoundException ex) { - JOptionPane.showMessageDialog(null, - Localization.lang( - "Your OpenOffice/LibreOffice document references the BibTeX key '%0', which could not be found in your current library.", - ex.getBibtexKey()), - Localization.lang("Unable to synchronize bibliography"), JOptionPane.ERROR_MESSAGE); LOGGER.debug("BibEntry not found", ex); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Unable to synchronize bibliography"), + Localization.lang("Your OpenOffice/LibreOffice document references the BibTeX key '%0', which could not be found in your current library.", + ex.getBibtexKey())); + } catch (com.sun.star.lang.IllegalArgumentException | UnknownPropertyException | PropertyVetoException | UndefinedCharacterFormatException | NoSuchElementException | WrappedTargetException | IOException | CreationException e) { @@ -366,8 +362,7 @@ private void connect(boolean autoDetect) { DetectOpenOfficeInstallation officeInstallation = new DetectOpenOfficeInstallation(diag, preferences); if (!officeInstallation.isInstalled()) { - JOptionPane.showMessageDialog(diag, Localization.lang("Autodetection failed"), - Localization.lang("Autodetection failed"), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Autodetection failed"), Localization.lang("Autodetection failed")); return; } diag.dispose(); @@ -411,16 +406,20 @@ private void connect(boolean autoDetect) { } catch (UnsatisfiedLinkError e) { LOGGER.warn("Could not connect to running OpenOffice/LibreOffice", e); - JOptionPane.showMessageDialog(null, - Localization.lang("Unable to connect. One possible reason is that JabRef " - + "and OpenOffice/LibreOffice are not both running in either 32 bit mode or 64 bit mode.")); + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Unable to connect. One possible reason is that JabRef " + + "and OpenOffice/LibreOffice are not both running in either 32 bit mode or 64 bit mode.")); + } catch (IOException e) { LOGGER.warn("Could not connect to running OpenOffice/LibreOffice", e); - JOptionPane.showMessageDialog(null, + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Could not connect to running OpenOffice/LibreOffice."), Localization.lang("Could not connect to running OpenOffice/LibreOffice.") + "\n" + Localization.lang("Make sure you have installed OpenOffice/LibreOffice with Java support.") + "\n" + Localization.lang("If connecting manually, please verify program and library paths.") - + "\n" + "\n" + Localization.lang("Error message:") + " " + e.getMessage()); + + "\n" + "\n" + Localization.lang("Error message:"), + e); + } finally { if (progressDialog != null) { progressDialog.dispose(); @@ -459,7 +458,7 @@ private static void addURL(List jarList) throws IOException { URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); Class sysclass = URLClassLoader.class; try { - Method method = sysclass.getDeclaredMethod("addURL", (Class[]) new Class[] {URL.class}); + Method method = sysclass.getDeclaredMethod("addURL", new Class[] {URL.class}); method.setAccessible(true); for (URL anU : jarList) { method.invoke(sysloader, anU); @@ -479,35 +478,31 @@ private void showManualConnectionDialog() { final DialogService dialogService = frame.getDialogService(); DirectoryDialogConfiguration dirDialogConfiguration = new DirectoryDialogConfiguration.Builder() - .withInitialDirectory(nativeDesktop.getApplicationDirectory()).build(); + .withInitialDirectory(nativeDesktop.getApplicationDirectory()) + .build(); FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() - .withInitialDirectory(nativeDesktop.getApplicationDirectory()).build(); + .withInitialDirectory(nativeDesktop.getApplicationDirectory()) + .build(); // Path fields final JTextField ooPath = new JTextField(30); JButton browseOOPath = new JButton(Localization.lang("Browse")); ooPath.setText(preferences.getInstallationPath()); - browseOOPath.addActionListener(e -> - DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showDirectorySelectionDialog(dirDialogConfiguration)) - .ifPresent(f -> ooPath.setText(f.toAbsolutePath().toString())) - ); + browseOOPath.addActionListener(e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showDirectorySelectionDialog(dirDialogConfiguration)) + .ifPresent(f -> ooPath.setText(f.toAbsolutePath().toString()))); final JTextField ooExec = new JTextField(30); JButton browseOOExec = new JButton(Localization.lang("Browse")); ooExec.setText(preferences.getExecutablePath()); - browseOOExec.addActionListener(e -> - DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)) - .ifPresent(f -> ooExec.setText(f.toAbsolutePath().toString())) - ); + browseOOExec.addActionListener(e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)) + .ifPresent(f -> ooExec.setText(f.toAbsolutePath().toString()))); final JTextField ooJars = new JTextField(30); ooJars.setText(preferences.getJarsPath()); JButton browseOOJars = new JButton(Localization.lang("Browse")); - browseOOJars.addActionListener(e -> - DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showDirectorySelectionDialog(dirDialogConfiguration)) - .ifPresent(f -> ooJars.setText(f.toAbsolutePath().toString())) - ); + browseOOJars.addActionListener(e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showDirectorySelectionDialog(dirDialogConfiguration)) + .ifPresent(f -> ooJars.setText(f.toAbsolutePath().toString()))); FormBuilder builder = FormBuilder.create() .layout(new FormLayout("left:pref, 4dlu, fill:pref:grow, 4dlu, fill:pref", "pref")); @@ -642,13 +637,13 @@ private boolean checkThatEntriesHaveKeys(List entries) { } // Ask if keys should be generated - String[] options = {Localization.lang("Generate keys"), Localization.lang("Cancel")}; - int answer = JOptionPane.showOptionDialog(null, + boolean citePressed = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Cite"), Localization.lang("Cannot cite entries without BibTeX keys. Generate keys now?"), - Localization.lang("Cite"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, - null); + Localization.lang("Generate keys"), + Localization.lang("Cancel")); + BasePanel panel = frame.getCurrentBasePanel(); - if ((answer == JOptionPane.OK_OPTION) && (panel != null)) { + if (citePressed && (panel != null)) { // Generate keys BibtexKeyPatternPreferences prefs = Globals.prefs.getBibtexKeyPatternPreferences(); NamedCompound undoCompound = new NamedCompound(Localization.lang("Cite")); @@ -672,40 +667,32 @@ private boolean checkThatEntriesHaveKeys(List entries) { } private void showConnectionLostErrorMessage() { - JOptionPane.showMessageDialog(null, + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Connection lost"), Localization.lang("Connection to OpenOffice/LibreOffice has been lost. " - + "Please make sure OpenOffice/LibreOffice is running, and try to reconnect."), - Localization.lang("Connection lost"), JOptionPane.ERROR_MESSAGE); + + "Please make sure OpenOffice/LibreOffice is running, and try to reconnect.")); + } private void reportUndefinedParagraphFormat(UndefinedParagraphFormatException ex) { - JOptionPane - .showMessageDialog( - null, "" - + Localization.lang( - "Your style file specifies the paragraph format '%0', " - + "which is undefined in your current OpenOffice/LibreOffice document.", - ex.getFormatName()) - + "
" - + Localization - .lang("The paragraph format is controlled by the property 'ReferenceParagraphFormat' or 'ReferenceHeaderParagraphFormat' in the style file.") - + "", - "", JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Undefined paragraph format"), + Localization.lang("Your style file specifies the paragraph format '%0', " + + "which is undefined in your current OpenOffice/LibreOffice document.", + ex.getFormatName()) + + "\n" + + Localization.lang("The paragraph format is controlled by the property 'ReferenceParagraphFormat' or 'ReferenceHeaderParagraphFormat' in the style file.")); + } private void reportUndefinedCharacterFormat(UndefinedCharacterFormatException ex) { - JOptionPane - .showMessageDialog( - null, "" - + Localization.lang( - "Your style file specifies the character format '%0', " - + "which is undefined in your current OpenOffice/LibreOffice document.", - ex.getFormatName()) - + "
" - + Localization - .lang("The character format is controlled by the citation property 'CitationCharacterFormat' in the style file.") - + "", - "", JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Undefined character format"), + Localization.lang( + "Your style file specifies the character format '%0', " + + "which is undefined in your current OpenOffice/LibreOffice document.", + ex.getFormatName()) + + "\n" + + Localization.lang("The character format is controlled by the citation property 'CitationCharacterFormat' in the style file.") + + ); } private void showSettingsPopup() { diff --git a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.java b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.java index 61fc21d3d8f..38496ae4108 100644 --- a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.java +++ b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.java @@ -22,7 +22,6 @@ import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JMenuItem; -import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -167,8 +166,8 @@ private void init() { @Override public void actionPerformed(ActionEvent event) { if ((table.getRowCount() == 0) || (table.getSelectedRowCount() == 0)) { - JOptionPane.showMessageDialog(diag, Localization.lang("You must select a valid style file."), - Localization.lang("Style selection"), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Style selection"), + Localization.lang("You must select a valid style file.")); return; } okPressed = true; @@ -272,9 +271,11 @@ private void setupPopupMenu() { // Create action listener for removing a style, also used for the remove button removeAction = actionEvent -> getSelectedStyle().ifPresent(style -> { - if (!style.isFromResource() && (JOptionPane.showConfirmDialog(diag, - Localization.lang("Are you sure you want to remove the style?"), Localization.lang("Remove style"), - JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)) { + + if (!style.isFromResource() && frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Remove style"), + Localization.lang("Are you sure you want to remove the style?"), + Localization.lang("Remove style"), + Localization.lang("Cancel"))) { if (!loader.removeStyle(style)) { LOGGER.info("Problem removing style"); } @@ -285,7 +286,9 @@ private void setupPopupMenu() { remove.addActionListener(removeAction); // Add action listener to the "Reload" menu item, which is supposed to reload an external style file - reload.addActionListener(actionEvent -> getSelectedStyle().ifPresent(style -> { + reload.addActionListener(actionEvent -> + + getSelectedStyle().ifPresent(style -> { try { style.ensureUpToDate(); } catch (IOException e) { @@ -374,28 +377,28 @@ public int getColumnCount() { @Override public String getColumnName(int i) { switch (i) { - case 0: - return Localization.lang("Name"); - case 1: - return Localization.lang("Journals"); - case 2: - return Localization.lang("File"); - default: - return ""; + case 0: + return Localization.lang("Name"); + case 1: + return Localization.lang("Journals"); + case 2: + return Localization.lang("File"); + default: + return ""; } } @Override public Object getColumnValue(OOBibStyle style, int i) { switch (i) { - case 0: - return style.getName(); - case 1: - return String.join(", ", style.getJournals()); - case 2: - return style.isFromResource() ? Localization.lang("Internal style") : style.getFile().getName(); - default: - return ""; + case 0: + return style.getName(); + case 1: + return String.join(", ", style.getJournals()); + case 2: + return style.isFromResource() ? Localization.lang("Internal style") : style.getFile().getName(); + default: + return ""; } } } @@ -472,7 +475,8 @@ public AddFileDialog() { FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .addExtensionFilter(FileType.JSTYLE) .withDefaultExtension(FileType.JSTYLE) - .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)) + .build(); browse.addActionListener(e -> { Optional file = DefaultTaskExecutor @@ -515,7 +519,8 @@ public void actionPerformed(ActionEvent e) { addCancelButton.addActionListener(cancelAction); // Key bindings: - bb.getPanel().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) + bb.getPanel() + .getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE_DIALOG), "close"); bb.getPanel().getActionMap().put("close", cancelAction); pack(); diff --git a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java index d83cdcc85b5..523b3ba741b 100644 --- a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java @@ -6,11 +6,11 @@ import javax.swing.BorderFactory; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import org.jabref.Globals; +import org.jabref.gui.DialogService; import org.jabref.gui.help.HelpAction; import org.jabref.gui.remote.JabRefMessageHandler; import org.jabref.logic.help.HelpFile; @@ -33,9 +33,10 @@ class AdvancedTab extends JPanel implements PrefsTab { private final JCheckBox useCaseKeeperOnSearch; private final JCheckBox useUnitFormatterOnSearch; private final RemotePreferences remotePreferences; + private final DialogService dialogService; - - public AdvancedTab(JabRefPreferences prefs) { + public AdvancedTab(DialogService dialogService, JabRefPreferences prefs) { + this.dialogService = dialogService; preferences = prefs; remotePreferences = prefs.getRemotePreferences(); @@ -45,9 +46,8 @@ public AdvancedTab(JabRefPreferences prefs) { useCaseKeeperOnSearch = new JCheckBox(Localization.lang("Add {} to specified title words on search to keep the correct case")); useUnitFormatterOnSearch = new JCheckBox(Localization.lang("Format units by adding non-breaking separators and keeping the correct case on search")); - FormLayout layout = new FormLayout - ("1dlu, 8dlu, left:pref, 4dlu, fill:3dlu",//, 4dlu, fill:pref",// 4dlu, left:pref, 4dlu", - ""); + FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:3dlu", //, 4dlu, fill:pref",// 4dlu, left:pref, 4dlu", + ""); DefaultFormBuilder builder = new DefaultFormBuilder(layout); JPanel pan = new JPanel(); @@ -121,10 +121,12 @@ private void storeRemoteSettings() { remotePreferences.setPort(newPort); if (remotePreferences.useRemoteServer()) { - JOptionPane.showMessageDialog(null, - Localization.lang("Remote server port").concat(" ") - .concat(Localization.lang("You must restart JabRef for this to come into effect.")), - Localization.lang("Remote server port"), JOptionPane.WARNING_MESSAGE); + + dialogService.showWarningDialogAndWait(Localization.lang("Remote server port"), + Localization.lang("Remote server port") + .concat(" ") + .concat(Localization.lang("You must restart JabRef for this to come into effect."))); + } } }); @@ -156,10 +158,11 @@ public boolean validateSettings() { throw new NumberFormatException(); } } catch (NumberFormatException ex) { - JOptionPane.showMessageDialog(null, + + dialogService.showErrorDialogAndWait(Localization.lang("Remote server port"), Localization.lang("You must enter an integer value in the interval 1025-65535 in the text field for") - + " '" + Localization.lang("Remote server port") + '\'', - Localization.lang("Remote server port"), JOptionPane.ERROR_MESSAGE); + + " '" + Localization.lang("Remote server port") + '\''); + return false; } } diff --git a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java index 0972a46ab15..c884fd07f1a 100644 --- a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java @@ -12,12 +12,12 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; +import org.jabref.gui.DialogService; import org.jabref.gui.GUIGlobals; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; @@ -56,6 +56,8 @@ class AppearancePrefsTab extends JPanel implements PrefsTab { private final JCheckBox customLAF; private final JCheckBox fxFontTweaksLAF; + private final DialogService dialogService; + static class LookAndFeel { public static Set getAvailableLookAndFeels() { @@ -68,7 +70,8 @@ public static Set getAvailableLookAndFeels() { * * @param prefs a JabRefPreferences value */ - public AppearancePrefsTab(JabRefPreferences prefs) { + public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) { + this.dialogService = dialogService; this.prefs = prefs; setLayout(new BorderLayout()); @@ -283,10 +286,8 @@ public void storeSettings() { } if (isRestartRequired) { - JOptionPane.showMessageDialog( - null, - Localization.lang("Some appearance settings you changed require to restart JabRef to come into effect."), - Localization.lang("Settings"), JOptionPane.WARNING_MESSAGE); + dialogService.showWarningDialogAndWait(Localization.lang("Settings"), + Localization.lang("Some appearance settings you changed require to restart JabRef to come into effect.")); } prefs.putInt(JabRefPreferences.TABLE_ROW_PADDING, padding); @@ -301,9 +302,8 @@ private boolean validateIntegerField(String fieldName, String fieldValue, String // Test if the field value is a number: Integer.parseInt(fieldValue); } catch (NumberFormatException ex) { - JOptionPane.showMessageDialog(null, - Localization.lang("You must enter an integer value in the text field for") + " '" + fieldName + "'", - errorTitle, JOptionPane.ERROR_MESSAGE); + + dialogService.showErrorDialogAndWait(errorTitle, Localization.lang("You must enter an integer value in the text field for") + " '" + fieldName + "'"); return false; } return true; diff --git a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java index e3f3a50378f..83999f529ea 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java @@ -29,9 +29,8 @@ import com.jgoodies.forms.layout.FormLayout; class ExternalTab extends JPanel implements PrefsTab { - private final JabRefPreferences prefs; - private final JabRefFrame frame; + private final JabRefPreferences prefs; private final JTextField emailSubject; private final JTextField citeCommand; @@ -51,14 +50,13 @@ class ExternalTab extends JPanel implements PrefsTab { public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPreferences prefs) { this.prefs = prefs; - this.frame = frame; + setLayout(new BorderLayout()); JButton editFileTypes = new JButton(Localization.lang("Manage external file types")); citeCommand = new JTextField(25); editFileTypes.addActionListener(ExternalFileTypeEditor.getAction(prefsDiag)); - defaultConsole = new JRadioButton(Localization.lang("Use default terminal emulator")); executeConsole = new JRadioButton(Localization.lang("Execute command") + ":"); consoleCommand = new JTextField(); @@ -72,15 +70,13 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere sumatraReaderPath = new JTextField(); browseSumatraReader = new JButton(Localization.lang("Browse")); - - JLabel commandDescription = new JLabel(Localization.lang( - "Note: Use the placeholder %0 for the location of the opened library file.", "%DIR")); + JLabel commandDescription = new JLabel(Localization.lang("Note: Use the placeholder %0 for the location of the opened library file.", "%DIR")); ButtonGroup consoleOptions = new ButtonGroup(); consoleOptions.add(defaultConsole); consoleOptions.add(executeConsole); - ButtonGroup readerOptions = new ButtonGroup(); + ButtonGroup readerOptions = new ButtonGroup(); readerOptions.add(adobeAcrobatReader); JPanel pdfOptionPanel = new JPanel(new GridBagLayout()); @@ -124,7 +120,7 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere pdfOptionPanel.add(adobeAcrobatReader, pdfLayoutConstrains); pdfLayoutConstrains.gridx = 1; - pdfOptionPanel.add(adobeAcrobatReaderPath,pdfLayoutConstrains); + pdfOptionPanel.add(adobeAcrobatReaderPath, pdfLayoutConstrains); pdfLayoutConstrains.gridx = 2; pdfOptionPanel.add(browseAdobeAcrobatReader, pdfLayoutConstrains); @@ -134,7 +130,7 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere browseSumatraReader.addActionListener(e -> showSumatraChooser()); pdfLayoutConstrains.gridy = 1; pdfLayoutConstrains.gridx = 0; - pdfOptionPanel.add(sumatraReader,pdfLayoutConstrains); + pdfOptionPanel.add(sumatraReader, pdfLayoutConstrains); pdfLayoutConstrains.gridx = 1; pdfOptionPanel.add(sumatraReaderPath, pdfLayoutConstrains); @@ -289,8 +285,7 @@ private void showSumatraChooser() { private void readerSelected() { if (adobeAcrobatReader.isSelected()) { prefs.put(JabRefPreferences.USE_PDF_READER, adobeAcrobatReaderPath.getText()); - } - else if (sumatraReader.isSelected()) { + } else if (sumatraReader.isSelected()) { prefs.put(JabRefPreferences.USE_PDF_READER, sumatraReaderPath.getText()); } } diff --git a/src/main/java/org/jabref/gui/preftabs/FileTab.java b/src/main/java/org/jabref/gui/preftabs/FileTab.java index 76d74bf8ba5..5e6f34dcea4 100644 --- a/src/main/java/org/jabref/gui/preftabs/FileTab.java +++ b/src/main/java/org/jabref/gui/preftabs/FileTab.java @@ -18,7 +18,7 @@ import javax.swing.JRadioButton; import javax.swing.JTextField; -import org.jabref.gui.JabRefFrame; +import org.jabref.gui.DialogService; import org.jabref.gui.help.HelpAction; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.DirectoryDialogConfiguration; @@ -39,7 +39,6 @@ class FileTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; - private final JabRefFrame frame; private final JCheckBox backup; private final JCheckBox localAutoSave; @@ -62,9 +61,8 @@ class FileTab extends JPanel implements PrefsTab { Localization.lang("Autolink files with names starting with the BibTeX key")); private final JTextField regExpTextField; - public FileTab(JabRefFrame frame, JabRefPreferences prefs) { + public FileTab(DialogService dialogService, JabRefPreferences prefs) { this.prefs = prefs; - this.frame = frame; fileDir = new JTextField(25); bibLocAsPrimaryDir = new JCheckBox(Localization.lang("Use the BIB file location as primary file directory")); @@ -140,8 +138,8 @@ public FileTab(JabRefFrame frame, JabRefPreferences prefs) { DirectoryDialogConfiguration dirDialogConfiguration = new DirectoryDialogConfiguration.Builder() .withInitialDirectory(Paths.get(fileDir.getText())).build(); - DefaultTaskExecutor.runInJavaFXThread(() -> frame.getDialogService().showDirectorySelectionDialog(dirDialogConfiguration)) - .ifPresent(f -> fileDir.setText(f.toString())); + DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showDirectorySelectionDialog(dirDialogConfiguration)) + .ifPresent(f -> fileDir.setText(f.toString())); }); builder.append(browse); @@ -232,15 +230,15 @@ public void storeSettings() { String newline; switch (newlineSeparator.getSelectedIndex()) { - case 0: - newline = "\r"; - break; - case 2: - newline = "\n"; - break; - default: - newline = "\r\n"; - break; + case 0: + newline = "\r"; + break; + case 2: + newline = "\n"; + break; + default: + newline = "\r\n"; + break; } prefs.put(JabRefPreferences.NEWLINE, newline); // we also have to change Globals variable as globals is not a getter, but a constant diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index 3764acf1ca7..0494758071d 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -13,11 +13,11 @@ import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import org.jabref.Globals; +import org.jabref.gui.DialogService; import org.jabref.gui.help.HelpAction; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Encodings; @@ -51,8 +51,10 @@ class GeneralTab extends JPanel implements PrefsTab { private final JComboBox language = new JComboBox<>(LANGUAGES.keySet().toArray(new String[LANGUAGES.keySet().size()])); private final JComboBox encodings; private final JComboBox biblatexMode; + private final DialogService dialogService; public class DefaultBibModeRenderer extends DefaultListCellRenderer { + @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { @@ -62,9 +64,9 @@ public Component getListCellRendererComponent(JList list, Object value, int i } } - - public GeneralTab(JabRefPreferences prefs) { + public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { this.prefs = prefs; + this.dialogService = dialogService; setLayout(new BorderLayout()); biblatexMode = new JComboBox<>(BibDatabaseMode.values()); @@ -204,10 +206,10 @@ public void storeSettings() { prefs.putBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY, enforceLegalKeys.isSelected()); prefs.setShouldCollectTelemetry(shouldCollectTelemetry.isSelected()); if (prefs.getBoolean(JabRefPreferences.MEMORY_STICK_MODE) && !memoryStick.isSelected()) { - JOptionPane.showMessageDialog(null, Localization.lang("To disable the memory stick mode" - + " rename or remove the jabref.xml file in the same folder as JabRef."), - Localization.lang("Memory stick mode"), - JOptionPane.INFORMATION_MESSAGE); + + dialogService.showInformationDialogAndWait(Localization.lang("Memory stick mode"), + Localization.lang("To disable the memory stick mode" + + " rename or remove the jabref.xml file in the same folder as JabRef.")); } prefs.putBoolean(JabRefPreferences.MEMORY_STICK_MODE, memoryStick.isSelected()); prefs.putBoolean(JabRefPreferences.CONFIRM_DELETE, confirmDelete.isSelected()); @@ -227,12 +229,11 @@ public void storeSettings() { // Update any defaults that might be language dependent: Globals.prefs.setLanguageDependentDefaultValues(); // Warn about restart needed: - JOptionPane.showMessageDialog(null, + + dialogService.showWarningDialogAndWait(Localization.lang("Changed language settings"), Localization.lang("You have changed the language setting.") .concat(" ") - .concat(Localization.lang("You must restart JabRef for this to come into effect.")), - Localization.lang("Changed language settings"), - JOptionPane.WARNING_MESSAGE); + .concat(Localization.lang("You must restart JabRef for this to come into effect."))); } } @@ -243,10 +244,9 @@ public boolean validateSettings() { DateTimeFormatter.ofPattern(timeStampFormat.getText()); } catch (IllegalArgumentException ex2) { - JOptionPane.showMessageDialog - (null, Localization.lang("The chosen date format for new entries is not valid"), - Localization.lang("Invalid date format"), - JOptionPane.ERROR_MESSAGE); + dialogService.showErrorDialogAndWait(Localization.lang("Invalid date format"), + Localization.lang("The chosen date format for new entries is not valid")); + return false; } return true; diff --git a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java index 37fd48116aa..8db58a1e39e 100644 --- a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java @@ -7,11 +7,11 @@ import javax.swing.BorderFactory; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; +import org.jabref.gui.DialogService; import org.jabref.logic.l10n.Localization; import org.jabref.logic.net.ProxyPreferences; import org.jabref.logic.net.ProxyRegisterer; @@ -30,8 +30,10 @@ public class NetworkTab extends JPanel implements PrefsTab { private final JPasswordField passwordTextField; private final JabRefPreferences preferences; private ProxyPreferences oldProxyPreferences; + private final DialogService dialogService; - public NetworkTab(JabRefPreferences preferences) { + public NetworkTab(DialogService dialogService, JabRefPreferences preferences) { + this.dialogService = dialogService; this.preferences = preferences; setLayout(new BorderLayout()); @@ -158,11 +160,13 @@ public boolean validateSettings() { } if (!validSetting) { if (validAuthenticationSetting) { - JOptionPane.showMessageDialog(null, Localization.lang("Please specify both hostname and port"), - Localization.lang("Invalid setting"), JOptionPane.ERROR_MESSAGE); + + dialogService.showErrorDialogAndWait(Localization.lang("Invalid setting"), + Localization.lang("Please specify both hostname and port")); } else { - JOptionPane.showMessageDialog(null, Localization.lang("Please specify both username and password"), - Localization.lang("Invalid setting"), JOptionPane.ERROR_MESSAGE); + dialogService.showErrorDialogAndWait(Localization.lang("Invalid setting"), + Localization.lang("Please specify both username and password")); + } } return validSetting; diff --git a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java index 1e4f6e7837c..75098d4a599 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java +++ b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java @@ -16,7 +16,6 @@ import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JList; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; @@ -81,11 +80,11 @@ public PreferencesDialog(JabRefFrame parent) { main.setLayout(cardLayout); List tabs = new ArrayList<>(); - tabs.add(new GeneralTab(prefs)); - tabs.add(new FileTab(frame, prefs)); + tabs.add(new GeneralTab(frame.getDialogService(), prefs)); + tabs.add(new FileTab(frame.getDialogService(), prefs)); tabs.add(new TablePrefsTab(prefs)); tabs.add(new TableColumnsTab(prefs, parent)); - tabs.add(new PreviewPrefsTab()); + tabs.add(new PreviewPrefsTab(frame.getDialogService())); tabs.add(new ExternalTab(frame, this, prefs)); tabs.add(new GroupsPrefsTab(prefs)); tabs.add(new EntryEditorPrefsTab(prefs)); @@ -94,9 +93,9 @@ public PreferencesDialog(JabRefFrame parent) { tabs.add(new ExportSortingPrefsTab(prefs)); tabs.add(new NameFormatterTab(prefs)); tabs.add(new XmpPrefsTab(prefs)); - tabs.add(new NetworkTab(prefs)); - tabs.add(new AdvancedTab(prefs)); - tabs.add(new AppearancePrefsTab(prefs)); + tabs.add(new NetworkTab(frame.getDialogService(), prefs)); + tabs.add(new AdvancedTab(frame.getDialogService(), prefs)); + tabs.add(new AppearancePrefsTab(frame.getDialogService(), prefs)); // add all tabs tabs.forEach(tab -> main.add((Component) tab, tab.getTabName())); @@ -161,7 +160,8 @@ public PreferencesDialog(JabRefFrame parent) { FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .addExtensionFilter(FileType.XML) .withDefaultExtension(FileType.XML) - .withInitialDirectory(getPrefsExportPath()).build(); + .withInitialDirectory(getPrefsExportPath()) + .build(); DialogService ds = frame.getDialogService(); Optional fileName = DefaultTaskExecutor @@ -171,14 +171,14 @@ public PreferencesDialog(JabRefFrame parent) { try { prefs.importPreferences(fileName.get().toString()); updateAfterPreferenceChanges(); - JOptionPane.showMessageDialog(PreferencesDialog.this, - Localization.lang("You must restart JabRef for this to come into effect."), - Localization.lang("Import preferences"), JOptionPane.WARNING_MESSAGE); + + frame.getDialogService().showWarningDialogAndWait(Localization.lang("Import preferences"), + Localization.lang("You must restart JabRef for this to come into effect.")); + this.dispose(); } catch (JabRefException ex) { LOGGER.warn(ex.getMessage(), ex); - JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), - Localization.lang("Import preferences"), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Import preferences"), ex); } } }); @@ -186,19 +186,22 @@ public PreferencesDialog(JabRefFrame parent) { showPreferences.addActionListener( e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs), null).setVisible(true)); resetPreferences.addActionListener(e -> { - if (JOptionPane.showConfirmDialog(PreferencesDialog.this, + + boolean resetPreferencesClicked = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Reset preferences"), Localization.lang("Are you sure you want to reset all settings to default values?"), - Localization.lang("Reset preferences"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { + Localization.lang("Reset preferences"), Localization.lang("Cancel")); + + if (resetPreferencesClicked) { try { prefs.clear(); new SharedDatabasePreferences().clear(); - JOptionPane.showMessageDialog(PreferencesDialog.this, - Localization.lang("You must restart JabRef for this to come into effect."), - Localization.lang("Reset preferences"), JOptionPane.WARNING_MESSAGE); + + frame.getDialogService().showWarningDialogAndWait(Localization.lang("Reset preferences"), + Localization.lang("You must restart JabRef for this to come into effect.")); + } catch (BackingStoreException ex) { LOGGER.warn(ex.getMessage(), ex); - JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), - Localization.lang("Reset preferences"), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Reset preferences"), ex); } updateAfterPreferenceChanges(); } @@ -284,7 +287,8 @@ public void actionPerformed(ActionEvent e) { FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .addExtensionFilter(FileType.XML) .withDefaultExtension(FileType.XML) - .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)) + .build(); DialogService ds = frame.getDialogService(); Optional path = DefaultTaskExecutor .runInJavaFXThread(() -> ds.showFileSaveDialog(fileDialogConfiguration)); @@ -296,8 +300,8 @@ public void actionPerformed(ActionEvent e) { Globals.prefs.put(JabRefPreferences.PREFS_EXPORT_PATH, exportFile.toString()); } catch (JabRefException ex) { LOGGER.warn(ex.getMessage(), ex); - JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), - Localization.lang("Export preferences"), JOptionPane.WARNING_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Export preferences"), ex); + } }); } diff --git a/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java index a4888a5131c..5eab6420a78 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java @@ -1,7 +1,6 @@ package org.jabref.gui.preftabs; import java.awt.BorderLayout; -import java.awt.Dimension; import java.util.ArrayList; import java.util.Comparator; import java.util.Enumeration; @@ -12,22 +11,22 @@ import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JList; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.ListSelectionModel; import javax.swing.SwingWorker; -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; +import javafx.scene.control.ButtonType; +import javafx.scene.control.DialogPane; import org.jabref.Globals; import org.jabref.JabRefGUI; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.gui.FXDialogService; import org.jabref.gui.PreviewPanel; -import org.jabref.gui.customjfx.CustomJFXPanel; +import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.TestEntry; @@ -56,14 +55,15 @@ public class PreviewPrefsTab extends JPanel implements PrefsTab { private final JButton btnUp = new JButton(Localization.lang("Up")); private final JButton btnDown = new JButton(Localization.lang("Down")); - private final JTextArea layout = new JTextArea("", 1, 1); private final JButton btnTest = new JButton(Localization.lang("Test")); private final JButton btnDefault = new JButton(Localization.lang("Default")); private final JScrollPane scrollPane = new JScrollPane(layout); + private final DialogService dialogService; - public PreviewPrefsTab() { + public PreviewPrefsTab(DialogService dialogService) { + this.dialogService = dialogService; setupLogic(); setupGui(); } @@ -97,7 +97,7 @@ private void setupLogic() { List newSelectedIndices = new ArrayList<>(); for (int oldIndex : chosen.getSelectedIndices()) { boolean alreadyTaken = newSelectedIndices.contains(oldIndex - 1); - int newIndex = (oldIndex > 0 && !alreadyTaken) ? oldIndex - 1 : oldIndex; + int newIndex = ((oldIndex > 0) && !alreadyTaken) ? oldIndex - 1 : oldIndex; chosenModel.add(newIndex, chosenModel.remove(oldIndex)); newSelectedIndices.add(newIndex); } @@ -110,7 +110,7 @@ private void setupLogic() { for (int i = selectedIndices.length - 1; i >= 0; i--) { int oldIndex = selectedIndices[i]; boolean alreadyTaken = newSelectedIndices.contains(oldIndex + 1); - int newIndex = (oldIndex < chosenModel.getSize() - 1 && !alreadyTaken) ? oldIndex + 1 : oldIndex; + int newIndex = ((oldIndex < (chosenModel.getSize() - 1)) && !alreadyTaken) ? oldIndex + 1 : oldIndex; chosenModel.add(newIndex, chosenModel.remove(oldIndex)); newSelectedIndices.add(newIndex); } @@ -118,22 +118,31 @@ private void setupLogic() { }); btnDefault.addActionListener(event -> layout.setText(Globals.prefs.getPreviewPreferences() - .getPreviewStyleDefault().replace("__NEWLINE__", "\n"))); + .getPreviewStyleDefault() + .replace("__NEWLINE__", "\n"))); btnTest.addActionListener(event -> { try { - PreviewPanel testPane = new PreviewPanel(null, null, Globals.getKeyPrefs(), Globals.prefs.getPreviewPreferences(), new FXDialogService()); - testPane.setFixedLayout(layout.getText()); - testPane.setEntry(TestEntry.getTestEntry()); - JFXPanel container = CustomJFXPanel.wrap(new Scene(testPane)); - container.setPreferredSize(new Dimension(800, 350)); - JOptionPane.showMessageDialog(PreviewPrefsTab.this, container, Localization.lang("Preview"), JOptionPane.PLAIN_MESSAGE); + DefaultTaskExecutor.runInJavaFXThread(() -> { + + PreviewPanel testPane = new PreviewPanel(null, null, Globals.getKeyPrefs(), Globals.prefs.getPreviewPreferences(), new FXDialogService()); + testPane.setFixedLayout(layout.getText()); + testPane.setEntry(TestEntry.getTestEntry()); + + DialogPane pane = new DialogPane(); + pane.setContent(testPane); + + dialogService.showCustomDialogAndWait(Localization.lang("Preview"), pane, ButtonType.OK); + + }); + } catch (StringIndexOutOfBoundsException exception) { LOGGER.warn("Parsing error.", exception); - JOptionPane.showMessageDialog(null, - Localization.lang("Parsing error") + ": " + Localization.lang("illegal backslash expression") - + ".\n" + exception.getMessage(), - Localization.lang("Parsing error"), JOptionPane.ERROR_MESSAGE); + + dialogService.showErrorDialogAndWait(Localization.lang("Parsing error"), + Localization.lang("Parsing error") + ": " + Localization.lang("illegal backslash expression"), + exception); + } }); } @@ -144,14 +153,21 @@ private void setupGui() { .rows("pref, $lg, fill:pref:grow, $lg, pref:grow, $lg, pref:grow, $lg, pref:grow") .padding(Paddings.DIALOG) - .addSeparator(Localization.lang("Current Preview")).xyw(1, 1, 5) - .add(available).xywh(1, 3, 1, 7) - .add(chosen).xywh(5, 3, 1, 7) - - .add(btnRight).xy(3, 3, "fill, bottom") - .add(btnLeft).xy(3, 5, "fill, top") - .add(btnUp).xy(3, 7, "fill, bottom") - .add(btnDown).xy(3, 9, "fill, top") + .addSeparator(Localization.lang("Current Preview")) + .xyw(1, 1, 5) + .add(available) + .xywh(1, 3, 1, 7) + .add(chosen) + .xywh(5, 3, 1, 7) + + .add(btnRight) + .xy(3, 3, "fill, bottom") + .add(btnLeft) + .xy(3, 5, "fill, top") + .add(btnUp) + .xy(3, 7, "fill, bottom") + .add(btnDown) + .xy(3, 9, "fill, top") .build(); JPanel preview = FormBuilder.create() @@ -159,10 +175,14 @@ private void setupGui() { .rows("pref, $lg, fill:pref:grow") .padding(Paddings.DIALOG) - .addSeparator(Localization.lang("Preview")).xy(1, 1) - .add(btnTest).xy(3, 1) - .add(btnDefault).xy(5, 1) - .add(scrollPane).xyw(1, 3, 5) + .addSeparator(Localization.lang("Preview")) + .xy(1, 1) + .add(btnTest) + .xy(3, 1) + .add(btnDefault) + .xy(5, 1) + .add(scrollPane) + .xyw(1, 3, 5) .build(); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); @@ -204,6 +224,7 @@ public void setValues() { } discoverCitationStyleWorker = new SwingWorker, Void>() { + @Override protected List doInBackground() throws Exception { return CitationStyle.discoverCitationStyles(); diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index d47fb04aff6..02aecc34061 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -19,7 +19,6 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JList; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; @@ -90,7 +89,6 @@ class TableColumnsTab extends JPanel implements PrefsTab { private boolean oldSyncKeyWords; private boolean oldWriteSpecialFields; - /** * Customization of external program paths. * @@ -117,9 +115,10 @@ public int getColumnCount() { public Object getValueAt(int row, int column) { int internalRow = row; internalRow--; - if (internalRow >= tableRows.size()) { + if ((internalRow == -1) || (internalRow >= tableRows.size())) { return ""; } + TableRow rowContent = tableRows.get(internalRow); if (rowContent == null) { return ""; @@ -134,8 +133,7 @@ public Object getValueAt(int row, int column) { @Override public String getColumnName(int col) { - return col == 0 ? Localization.lang("Field name") : - Localization.lang("Column width"); + return col == 0 ? Localization.lang("Field name") : Localization.lang("Column width"); } @Override @@ -166,8 +164,7 @@ public void setValueAt(Object value, int row, int col) { if ("".equals(getValueAt(row, 1))) { setValueAt(String.valueOf(BibtexSingleField.DEFAULT_FIELD_LENGTH), row, 1); } - } - else { + } else { if (value == null) { rowContent.setLength(-1); } else { @@ -183,15 +180,13 @@ public void setValueAt(Object value, int row, int col) { cm.getColumn(0).setPreferredWidth(140); cm.getColumn(1).setPreferredWidth(80); - FormLayout layout = new FormLayout - ("1dlu, 8dlu, left:pref, 4dlu, fill:pref",""); + FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref", ""); DefaultFormBuilder builder = new DefaultFormBuilder(layout); JPanel pan = new JPanel(); JPanel tabPanel = new JPanel(); tabPanel.setLayout(new BorderLayout()); - JScrollPane sp = new JScrollPane - (colSetup, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + JScrollPane sp = new JScrollPane(colSetup, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); colSetup.setPreferredScrollableViewportSize(new Dimension(250, 200)); sp.setMinimumSize(new Dimension(250, 300)); tabPanel.add(sp, BorderLayout.CENTER); @@ -346,8 +341,7 @@ public void setValues() { } } listOfFileColumns.setSelectedIndices(indicesToSelect); - } - else { + } else { listOfFileColumns.setSelectedIndices(new int[] {}); } @@ -663,7 +657,6 @@ public void actionPerformed(ActionEvent e) { } } - /** * Store changes to table preferences. This method is called when * the user clicks Ok. @@ -711,12 +704,11 @@ public void storeSettings() { (oldSyncKeyWords != newSyncKeyWords) || (oldWriteSpecialFields != newWriteSpecialFields); if (restartRequired) { - JOptionPane.showMessageDialog(null, + frame.getDialogService().showWarningDialogAndWait(Localization.lang("Changed special field settings"), Localization.lang("You have changed settings for special fields.") - .concat(" ") - .concat(Localization.lang("You must restart JabRef for this to come into effect.")), - Localization.lang("Changed special field settings"), - JOptionPane.WARNING_MESSAGE); + .concat(" ") + .concat(Localization.lang("You must restart JabRef for this to come into effect."))); + } // restart required implies that the settings have been changed diff --git a/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java b/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java index d10f203fba4..c546df15777 100644 --- a/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java +++ b/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java @@ -17,9 +17,7 @@ import org.jabref.Globals; import org.jabref.gui.DialogService; -import org.jabref.gui.FXDialogService; import org.jabref.gui.JabRefDialog; -import org.jabref.gui.JabRefFrame; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; @@ -39,18 +37,21 @@ public class NewProtectedTermsFileDialog extends JabRefDialog { private final JCheckBox enabled = new JCheckBox(Localization.lang("Enabled")); private boolean addOKPressed; private final ProtectedTermsLoader loader; - private JFrame parent; + private final DialogService dialogService; - public NewProtectedTermsFileDialog(JDialog parent, ProtectedTermsLoader loader) { + public NewProtectedTermsFileDialog(JDialog parent, ProtectedTermsLoader loader, DialogService dialogService) { super(parent, Localization.lang("New protected terms file"), true, NewProtectedTermsFileDialog.class); this.loader = loader; + this.dialogService = dialogService; + setupDialog(); setLocationRelativeTo(parent); } - public NewProtectedTermsFileDialog(JabRefFrame mainFrame, ProtectedTermsLoader loader) { + public NewProtectedTermsFileDialog(DialogService dialogService, ProtectedTermsLoader loader) { super((JFrame) null, Localization.lang("New protected terms file"), true, NewProtectedTermsFileDialog.class); this.loader = loader; + this.dialogService = dialogService; setupDialog(); } @@ -61,11 +62,10 @@ private void setupDialog() { .addExtensionFilter(FileType.TERMS) .withDefaultExtension(FileType.TERMS) .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); - DialogService ds = new FXDialogService(); browse.addActionListener(e -> { Optional file = DefaultTaskExecutor - .runInJavaFXThread(() -> ds.showFileSaveDialog(fileDialogConfiguration)); + .runInJavaFXThread(() -> dialogService.showFileSaveDialog(fileDialogConfiguration)); file.ifPresent(f -> newFile.setText(f.toAbsolutePath().toString())); }); diff --git a/src/main/java/org/jabref/gui/protectedterms/ProtectedTermsDialog.java b/src/main/java/org/jabref/gui/protectedterms/ProtectedTermsDialog.java index 15e67700fa8..8936805bd96 100644 --- a/src/main/java/org/jabref/gui/protectedterms/ProtectedTermsDialog.java +++ b/src/main/java/org/jabref/gui/protectedterms/ProtectedTermsDialog.java @@ -22,7 +22,6 @@ import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JMenuItem; -import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -113,7 +112,7 @@ private void init() { removeButton.setToolTipText(Localization.lang("Remove protected terms file")); newButton.addActionListener(actionEvent -> { - NewProtectedTermsFileDialog newDialog = new NewProtectedTermsFileDialog(diag, loader); + NewProtectedTermsFileDialog newDialog = new NewProtectedTermsFileDialog(diag, loader, frame.getDialogService()); newDialog.setVisible(true); tableModel.fireTableDataChanged(); }); @@ -254,10 +253,10 @@ private void setupPopupMenu() { // Create action listener for removing a term file, also used for the remove button removeAction = actionEvent -> getSelectedTermsList().ifPresent(list -> { - if (!list.isInternalList() && (JOptionPane.showConfirmDialog(diag, + if (!list.isInternalList() && frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Remove protected terms file"), Localization.lang("Are you sure you want to remove the protected terms file?"), Localization.lang("Remove protected terms file"), - JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)) { + Localization.lang("Cancel"))) { if (!loader.removeProtectedTermsList(list)) { LOGGER.info("Problem removing protected terms file"); } @@ -309,30 +308,30 @@ public int getRowCount() { @Override public String getColumnName(int i) { switch (i) { - case 0: - return Localization.lang("Enabled"); - case 1: - return Localization.lang("Description"); - case 2: - return Localization.lang("File"); - default: - return ""; + case 0: + return Localization.lang("Enabled"); + case 1: + return Localization.lang("Description"); + case 2: + return Localization.lang("File"); + default: + return ""; } } @Override public Object getValueAt(int row, int column) { switch (column) { - case 0: - return loader.getProtectedTermsLists().get(row).isEnabled(); - case 1: - return loader.getProtectedTermsLists().get(row).getDescription(); - case 2: - ProtectedTermsList list = loader.getProtectedTermsLists().get(row); - return list.isInternalList() ? Localization.lang("Internal list") + " - " + list.getLocation() : list - .getLocation(); - default: - return ""; + case 0: + return loader.getProtectedTermsLists().get(row).isEnabled(); + case 1: + return loader.getProtectedTermsLists().get(row).getDescription(); + case 2: + ProtectedTermsList list = loader.getProtectedTermsLists().get(row); + return list.isInternalList() ? Localization.lang("Internal list") + " - " + list.getLocation() : list + .getLocation(); + default: + return ""; } } @@ -344,14 +343,14 @@ public boolean isCellEditable(int row, int column) { @Override public Class getColumnClass(int column) { switch (column) { - case 0: - return Boolean.class; - case 1: - return String.class; - case 2: - return String.class; - default: - return String.class; + case 0: + return Boolean.class; + case 1: + return String.class; + case 2: + return String.class; + default: + return String.class; } } diff --git a/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java b/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java index b901293c849..fcd5332ae6c 100644 --- a/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java +++ b/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java @@ -10,7 +10,6 @@ import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; -import org.jabref.gui.FXDialogService; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.logic.l10n.Localization; @@ -40,6 +39,11 @@ public abstract class AbstractPushToApplication implements PushToApplication { protected String commandPath; protected String commandPathPreferenceKey; protected FormBuilder builder; + protected DialogService dialogService; + + public AbstractPushToApplication(DialogService dialogService) { + this.dialogService = dialogService; + } @Override public String getName() { @@ -164,10 +168,9 @@ protected void initSettingsPanel() { FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); - DialogService ds = new FXDialogService(); browse.addActionListener( - e -> DefaultTaskExecutor.runInJavaFXThread(() -> ds.showFileOpenDialog(fileDialogConfiguration)) + e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)) .ifPresent(f -> path.setText(f.toAbsolutePath().toString()))); builder.add(browse).xy(5, 1); settings = builder.build(); diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationAction.java b/src/main/java/org/jabref/gui/push/PushToApplicationAction.java index 41b9dbf1243..468fb8b57dc 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationAction.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationAction.java @@ -6,7 +6,6 @@ import javax.swing.AbstractAction; import javax.swing.Action; -import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.jabref.JabRefExecutorService; @@ -19,12 +18,12 @@ * An Action class representing the process of invoking a PushToApplication operation. */ class PushToApplicationAction extends AbstractAction implements Runnable { + private final PushToApplication operation; private final JabRefFrame frame; private BasePanel panel; private List entries; - public PushToApplicationAction(JabRefFrame frame, PushToApplication operation) { this.frame = frame; putValue(Action.SMALL_ICON, operation.getIcon()); @@ -45,7 +44,9 @@ public void actionPerformed(ActionEvent e) { // Check if any entries are selected: entries = panel.getSelectedEntries(); if (entries.isEmpty()) { - JOptionPane.showMessageDialog(null, Localization.lang("This operation requires one or more entries to be selected."), (String) getValue(Action.NAME), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait((String) getValue(Action.NAME), + Localization.lang("This operation requires one or more entries to be selected.")); + return; } @@ -53,10 +54,9 @@ public void actionPerformed(ActionEvent e) { if (operation.requiresBibtexKeys()) { for (BibEntry entry : entries) { if (!(entry.getCiteKeyOptional().isPresent()) || entry.getCiteKeyOptional().get().trim().isEmpty()) { - JOptionPane.showMessageDialog(null, - Localization - .lang("This operation requires all selected entries to have BibTeX keys defined."), - (String) getValue(Action.NAME), JOptionPane.ERROR_MESSAGE); + frame.getDialogService().showErrorDialogAndWait((String) getValue(Action.NAME), + Localization.lang("This operation requires all selected entries to have BibTeX keys defined.")); + return; } } diff --git a/src/main/java/org/jabref/gui/push/PushToApplications.java b/src/main/java/org/jabref/gui/push/PushToApplications.java index 4f295459a3d..558f1ff5381 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplications.java +++ b/src/main/java/org/jabref/gui/push/PushToApplications.java @@ -3,24 +3,25 @@ import java.util.ArrayList; import java.util.List; +import org.jabref.gui.DialogService; + public class PushToApplications { private final List applications; - - public PushToApplications() { - /** - * Set up the current available choices: - */ + public PushToApplications(DialogService dialogService) { + /** + * Set up the current available hoices: + */ applications = new ArrayList<>(); - applications.add(new PushToEmacs()); - applications.add(new PushToLyx()); - applications.add(new PushToTexmaker()); - applications.add(new PushToTeXstudio()); - applications.add(new PushToVim()); - applications.add(new PushToWinEdt()); + applications.add(new PushToEmacs(dialogService)); + applications.add(new PushToLyx(dialogService)); + applications.add(new PushToTexmaker(dialogService)); + applications.add(new PushToTeXstudio(dialogService)); + applications.add(new PushToVim(dialogService)); + applications.add(new PushToWinEdt(dialogService)); } public List getApplications() { diff --git a/src/main/java/org/jabref/gui/push/PushToEmacs.java b/src/main/java/org/jabref/gui/push/PushToEmacs.java index 624bb1a2995..0f7648e20c6 100644 --- a/src/main/java/org/jabref/gui/push/PushToEmacs.java +++ b/src/main/java/org/jabref/gui/push/PushToEmacs.java @@ -4,13 +4,13 @@ import java.io.InputStream; import java.util.List; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import org.jabref.Globals; import org.jabref.JabRefExecutorService; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefIcon; import org.jabref.logic.l10n.Localization; @@ -26,9 +26,12 @@ public class PushToEmacs extends AbstractPushToApplication implements PushToApplication { private static final Logger LOGGER = LoggerFactory.getLogger(PushToEmacs.class); - private final JTextField additionalParams = new JTextField(30); + public PushToEmacs(DialogService dialogService) { + super(dialogService); + } + @Override public String getApplicationName() { return "Emacs"; @@ -91,12 +94,12 @@ public void pushEntries(BibDatabase database, List entries, String key // java string: "(insert \\\"\\\\cite{Blah2001}\\\")"; // so cmd receives: (insert \"\\cite{Blah2001}\") // so emacs receives: (insert "\cite{Blah2001}") - prefix.concat("\\\"\\" + getCiteCommand().replaceAll("\\\\", "\\\\\\\\") + "{" + keys + "}\\\"").concat(suffix) : - // Linux gnuclient/emacslient escaping: - // java string: "(insert \"\\\\cite{Blah2001}\")" - // so sh receives: (insert "\\cite{Blah2001}") - // so emacs receives: (insert "\cite{Blah2001}") - prefix.concat("\"" + getCiteCommand().replaceAll("\\\\", "\\\\\\\\") + "{" + keys + "}\"").concat(suffix); + prefix.concat("\\\"\\" + getCiteCommand().replaceAll("\\\\", "\\\\\\\\") + "{" + keys + "}\\\"").concat(suffix) : + // Linux gnuclient/emacslient escaping: + // java string: "(insert \"\\\\cite{Blah2001}\")" + // so sh receives: (insert "\\cite{Blah2001}") + // so emacs receives: (insert "\cite{Blah2001}") + prefix.concat("\"" + getCiteCommand().replaceAll("\\\\", "\\\\\\\\") + "{" + keys + "}\"").concat(suffix); final Process p = Runtime.getRuntime().exec(com); @@ -129,16 +132,17 @@ public void pushEntries(BibDatabase database, List entries, String key @Override public void operationCompleted(BasePanel panel) { if (couldNotConnect) { - JOptionPane.showMessageDialog(null, "" + + + dialogService.showErrorDialogAndWait(Localization.lang("Error pushing entries"), Localization.lang("Could not connect to a running gnuserv process. Make sure that " - + "Emacs or XEmacs is running,
and that the server has been started " - + "(by running the command 'server-start'/'gnuserv-start').") + "", - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); + + "Emacs or XEmacs is running, and that the server has been started " + + "(by running the command 'server-start'/'gnuserv-start').")); + } else if (couldNotCall) { - JOptionPane.showMessageDialog(null, + dialogService.showErrorDialogAndWait(Localization.lang("Error pushing entries"), Localization.lang("Could not run the gnuclient/emacsclient program. Make sure you have " - + "the emacsclient/gnuclient program installed and available in the PATH."), - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); + + "the emacsclient/gnuclient program installed and available in the PATH.")); + } else { super.operationCompleted(panel); } diff --git a/src/main/java/org/jabref/gui/push/PushToLyx.java b/src/main/java/org/jabref/gui/push/PushToLyx.java index c78064f140b..9d84a81380c 100644 --- a/src/main/java/org/jabref/gui/push/PushToLyx.java +++ b/src/main/java/org/jabref/gui/push/PushToLyx.java @@ -12,6 +12,7 @@ import org.jabref.Globals; import org.jabref.JabRefExecutorService; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefIcon; import org.jabref.logic.l10n.Localization; @@ -27,6 +28,10 @@ public class PushToLyx extends AbstractPushToApplication implements PushToApplic private static final Logger LOGGER = LoggerFactory.getLogger(PushToLyx.class); + public PushToLyx(DialogService dialogService) { + super(dialogService); + } + @Override public String getApplicationName() { return "LyX/Kile"; @@ -66,8 +71,7 @@ protected void initSettingsPanel() { } @Override - public void pushEntries(BibDatabase database, final List entries, final String keyString, - MetaData metaData) { + public void pushEntries(BibDatabase database, final List entries, final String keyString, MetaData metaData) { couldNotConnect = false; couldNotCall = false; diff --git a/src/main/java/org/jabref/gui/push/PushToTeXstudio.java b/src/main/java/org/jabref/gui/push/PushToTeXstudio.java index 7082bad60df..366fd579ab9 100644 --- a/src/main/java/org/jabref/gui/push/PushToTeXstudio.java +++ b/src/main/java/org/jabref/gui/push/PushToTeXstudio.java @@ -1,11 +1,16 @@ package org.jabref.gui.push; +import org.jabref.gui.DialogService; import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefIcon; import org.jabref.preferences.JabRefPreferences; public class PushToTeXstudio extends AbstractPushToApplication implements PushToApplication { + public PushToTeXstudio(DialogService dialogService) { + super(dialogService); + } + @Override public String getApplicationName() { return "TeXstudio"; diff --git a/src/main/java/org/jabref/gui/push/PushToTexmaker.java b/src/main/java/org/jabref/gui/push/PushToTexmaker.java index 2f6ec7bedaa..38a32d952c2 100644 --- a/src/main/java/org/jabref/gui/push/PushToTexmaker.java +++ b/src/main/java/org/jabref/gui/push/PushToTexmaker.java @@ -1,5 +1,6 @@ package org.jabref.gui.push; +import org.jabref.gui.DialogService; import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefIcon; import org.jabref.preferences.JabRefPreferences; @@ -9,6 +10,10 @@ */ public class PushToTexmaker extends AbstractPushToApplication implements PushToApplication { + public PushToTexmaker(DialogService dialogService) { + super(dialogService); + } + @Override public String getApplicationName() { return "Texmaker"; diff --git a/src/main/java/org/jabref/gui/push/PushToVim.java b/src/main/java/org/jabref/gui/push/PushToVim.java index a3c1b692464..bf702b2abdf 100644 --- a/src/main/java/org/jabref/gui/push/PushToVim.java +++ b/src/main/java/org/jabref/gui/push/PushToVim.java @@ -4,13 +4,13 @@ import java.io.InputStream; import java.util.List; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import org.jabref.Globals; import org.jabref.JabRefExecutorService; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefIcon; import org.jabref.logic.l10n.Localization; @@ -25,9 +25,12 @@ public class PushToVim extends AbstractPushToApplication implements PushToApplication { private static final Logger LOGGER = LoggerFactory.getLogger(PushToVim.class); - private final JTextField vimServer = new JTextField(30); + public PushToVim(DialogService dialogService) { + super(dialogService); + } + @Override public String getApplicationName() { return "Vim"; @@ -78,7 +81,7 @@ public void pushEntries(BibDatabase database, List entries, String key String[] com = new String[] {commandPath, "--servername", Globals.prefs.get(JabRefPreferences.VIM_SERVER), "--remote-send", "a" + getCiteCommand() + - "{" + keys + "}"}; + "{" + keys + "}"}; final Process p = Runtime.getRuntime().exec(com); @@ -112,18 +115,14 @@ public void pushEntries(BibDatabase database, List entries, String key @Override public void operationCompleted(BasePanel panel) { if (couldNotConnect) { - JOptionPane.showMessageDialog( - null, - "" + - Localization.lang("Could not connect to Vim server. Make sure that " - + "Vim is running
with correct server name.") - + "", - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); + + dialogService.showErrorDialogAndWait(Localization.lang("Error pushing entries"), + Localization.lang("Could not connect to Vim server. Make sure that Vim is running with correct server name.")); + } else if (couldNotCall) { - JOptionPane.showMessageDialog( - null, - Localization.lang("Could not run the 'vim' program."), - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); + dialogService.showErrorDialogAndWait(Localization.lang("Error pushing entries"), + Localization.lang("Could not run the 'vim' program.")); + } else { super.operationCompleted(panel); } diff --git a/src/main/java/org/jabref/gui/push/PushToWinEdt.java b/src/main/java/org/jabref/gui/push/PushToWinEdt.java index 3adf22a12c5..629a8484866 100644 --- a/src/main/java/org/jabref/gui/push/PushToWinEdt.java +++ b/src/main/java/org/jabref/gui/push/PushToWinEdt.java @@ -1,11 +1,16 @@ package org.jabref.gui.push; +import org.jabref.gui.DialogService; import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefIcon; import org.jabref.preferences.JabRefPreferences; public class PushToWinEdt extends AbstractPushToApplication implements PushToApplication { + public PushToWinEdt(DialogService dialogService) { + super(dialogService); + } + @Override public String getApplicationName() { return "WinEdt"; diff --git a/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java b/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java index 1c936e5df81..607b7423c16 100644 --- a/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java +++ b/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java @@ -115,9 +115,10 @@ public ConnectToSharedDatabaseDialog(JabRefFrame frame) { public void openSharedDatabase() { if (isSharedDatabaseAlreadyPresent()) { - JOptionPane.showMessageDialog(ConnectToSharedDatabaseDialog.this, - Localization.lang("You are already connected to a database using entered connection details."), - Localization.lang("Warning"), JOptionPane.WARNING_MESSAGE); + + frame.getDialogService().showWarningDialogAndWait(Localization.lang("Shared database connection"), + Localization.lang("You are already connected to a database using entered connection details.")); + return; } @@ -126,10 +127,13 @@ public void openSharedDatabase() { Path localFilePath = Paths.get(fileLocationField.getText()); if (Files.exists(localFilePath) && !Files.isDirectory(localFilePath)) { - int answer = JOptionPane.showConfirmDialog(this, + + boolean overwriteFilePressed = frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Existing file"), Localization.lang("'%0' exists. Overwrite file?", localFilePath.getFileName().toString()), - Localization.lang("Existing file"), JOptionPane.YES_NO_OPTION); - if (answer == JOptionPane.NO_OPTION) { + Localization.lang("Overwrite file"), + Localization.lang("Cancel")); + + if (!overwriteFilePressed) { fileLocationField.requestFocus(); return; } @@ -183,8 +187,8 @@ public void actionPerformed(ActionEvent e) { openSharedDatabase(); } catch (JabRefException exception) { - JOptionPane.showMessageDialog(ConnectToSharedDatabaseDialog.this, exception.getMessage(), - Localization.lang("Warning"), JOptionPane.WARNING_MESSAGE); + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Warning"), exception); + } } }; @@ -471,7 +475,8 @@ private void showFileChooser() { FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .addExtensionFilter(FileType.BIBTEX_DB) .withDefaultExtension(FileType.BIBTEX_DB) - .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)) + .build(); DialogService ds = frame.getDialogService(); Optional path = DefaultTaskExecutor diff --git a/src/main/java/org/jabref/logic/l10n/Encodings.java b/src/main/java/org/jabref/logic/l10n/Encodings.java index 76d57972745..c67d80684f1 100644 --- a/src/main/java/org/jabref/logic/l10n/Encodings.java +++ b/src/main/java/org/jabref/logic/l10n/Encodings.java @@ -8,16 +8,21 @@ public class Encodings { public static final Charset[] ENCODINGS; public static final String[] ENCODINGS_DISPLAYNAMES; + private static List encodingsList = Charset.availableCharsets().values().stream().distinct() + .collect(Collectors.toList()); + + private Encodings() { + } static { - List encodingsList = Charset.availableCharsets().values().stream().distinct() - .collect(Collectors.toList()); List encodingsStringList = encodingsList.stream().map(Charset::displayName).distinct() .collect(Collectors.toList()); ENCODINGS = encodingsList.toArray(new Charset[encodingsList.size()]); ENCODINGS_DISPLAYNAMES = encodingsStringList.toArray(new String[encodingsStringList.size()]); } - private Encodings() { + public static List getCharsets() { + return encodingsList; } + } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 22ac6ea2d49..c9c844d61f9 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2339,3 +2339,17 @@ Keep\ entries=Keep entries Keep\ entry=Keep entry Ignore\ backup=Ignore backup Restore\ from\ backup=Restore from backup + +Continue=Continue +Generate\ key=Generate key +Overwrite\ file=Overwrite file +Overwrite\ file\ lock=Overwrite file lock +Save\ without\ backup=Save without backup +Shared\ database\ connection=Shared database connection + +Could\ not\ connect\ to\ Vim\ server.\ Make\ sure\ that\ Vim\ is\ running\ with\ correct\ server\ name.=Could not connect to Vim server. Make sure that Vim is running with correct server name. +Could\ not\ connect\ to\ a\ running\ gnuserv\ process.\ Make\ sure\ that\ Emacs\ or\ XEmacs\ is\ running,\ and\ that\ the\ server\ has\ been\ started\ (by\ running\ the\ command\ 'server-start'/'gnuserv-start').=Could not connect to a running gnuserv process. Make sure that Emacs or XEmacs is running, and that the server has been started (by running the command 'server-start'/'gnuserv-start'). +Error\ pushing\ entries=Error pushing entries + +Undefined\ character\ format=Undefined character format +Undefined\ paragraph\ format=Undefined paragraph format From 2eee861dd3ab3579de8aa558c8b318e1cbc02ffd Mon Sep 17 00:00:00 2001 From: Linus Dietz Date: Mon, 5 Mar 2018 16:21:09 +0100 Subject: [PATCH 15/28] Fix Codacy Unused Params, Fields (#3753) --- src/main/java/org/jabref/gui/BasePanel.java | 2 - src/main/java/org/jabref/gui/IconTheme.java | 14 +---- .../org/jabref/gui/collab/ChangeScanner.java | 5 +- .../gui/collab/MetaDataChangeViewModel.java | 7 +-- .../gui/fieldeditors/JournalEditor.java | 12 ++--- .../gui/filelist/FileListEntryEditor.java | 26 ++++----- .../jabref/gui/groups/GroupTreeViewModel.java | 12 ++--- .../gui/groups/UndoableModifyGroup.java | 54 ------------------- .../gui/importer/fetcher/OAI2Fetcher.java | 46 ++++++---------- .../gui/openoffice/StyleSelectDialog.java | 8 +-- .../JournalAbbreviationRepository.java | 4 -- .../migrations/PreferencesMigrations.java | 23 ++++---- src/main/resources/l10n/JabRef_en.properties | 2 - .../GrammarBasedSearchRuleDescriberTest.java | 8 --- .../logic/exporter/ModsExportFormatTest.java | 6 +-- .../bibtexfields/RegexFormatterTest.java | 13 ++--- 16 files changed, 59 insertions(+), 183 deletions(-) delete mode 100644 src/main/java/org/jabref/gui/groups/UndoableModifyGroup.java diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 8d63b8f60fe..2279e25e27f 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -1920,8 +1920,6 @@ private class RedoAction implements BaseAction { @Override public void action() { try { - - JComponent focused = Globals.getFocusListener().getFocused(); getUndoManager().redo(); markBaseChanged(); frame.output(Localization.lang("Redo")); diff --git a/src/main/java/org/jabref/gui/IconTheme.java b/src/main/java/org/jabref/gui/IconTheme.java index 7c1526701de..cade39ed2ce 100644 --- a/src/main/java/org/jabref/gui/IconTheme.java +++ b/src/main/java/org/jabref/gui/IconTheme.java @@ -51,19 +51,9 @@ public class IconTheme { private static final Map KEY_TO_ICON = readIconThemeFile( IconTheme.class.getResource("/images/Icons.properties"), "/images/external/"); - // Christmas edition - //public static final Color DEFAULT_COLOR = new Color(0x155115); - //public static final Color DEFAULT_DISABLED_COLOR = new Color(0x990000); - private static Font FONT_16; - private static javafx.scene.text.Font FX_FONT; - static { try (InputStream stream = getMaterialDesignIconsStream()) { FONT = Font.createFont(Font.TRUETYPE_FONT, stream); - FONT_16 = FONT.deriveFont(Font.PLAIN, 16f); - try (InputStream stream2 = getMaterialDesignIconsStream()) { - FX_FONT = javafx.scene.text.Font.loadFont(stream2, JabRefPreferences.getInstance().getInt(JabRefPreferences.ICON_SIZE_LARGE)); - } } catch (FontFormatException | IOException e) { LOGGER.warn("Error loading font", e); } @@ -92,14 +82,14 @@ 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) { + private static Image getImageFX(String name) { return new Image(getIconUrl(name).toString()); } diff --git a/src/main/java/org/jabref/gui/collab/ChangeScanner.java b/src/main/java/org/jabref/gui/collab/ChangeScanner.java index 3ee754dae4d..0d6858d47ee 100644 --- a/src/main/java/org/jabref/gui/collab/ChangeScanner.java +++ b/src/main/java/org/jabref/gui/collab/ChangeScanner.java @@ -31,7 +31,6 @@ import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibtexString; -import org.jabref.model.metadata.MetaData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +42,6 @@ public class ChangeScanner implements Runnable { private final File file; private final Path tempFile; private final BibDatabaseContext databaseInMemory; - private final MetaData metadataInMemory; private final BasePanel panel; private final JabRefFrame frame; @@ -62,7 +60,6 @@ public ChangeScanner(JabRefFrame frame, BasePanel bp, File file, Path tempFile) this.panel = bp; this.frame = frame; this.databaseInMemory = bp.getDatabaseContext(); - this.metadataInMemory = bp.getBibDatabaseContext().getMetaData(); this.file = file; this.tempFile = tempFile; } @@ -136,7 +133,7 @@ public void run() { // Start looking at changes. BibDatabaseDiff differences = BibDatabaseDiff.compare(databaseInTemp, databaseOnDisk); differences.getMetaDataDifferences().ifPresent(diff -> { - changes.add(new MetaDataChangeViewModel(metadataInMemory, diff)); + changes.add(new MetaDataChangeViewModel(diff)); diff.getGroupDifferences().ifPresent(groupDiff -> changes.add(new GroupChangeViewModel(groupDiff))); }); differences.getPreambleDifferences().ifPresent(diff -> changes.add(new PreambleChangeViewModel(databaseInMemory.getDatabase().getPreamble().orElse(""), diff))); diff --git a/src/main/java/org/jabref/gui/collab/MetaDataChangeViewModel.java b/src/main/java/org/jabref/gui/collab/MetaDataChangeViewModel.java index 307fba9f4a0..7418ff1695f 100644 --- a/src/main/java/org/jabref/gui/collab/MetaDataChangeViewModel.java +++ b/src/main/java/org/jabref/gui/collab/MetaDataChangeViewModel.java @@ -10,19 +10,14 @@ import org.jabref.model.database.BibDatabase; import org.jabref.model.metadata.MetaData; -/** - * - */ class MetaDataChangeViewModel extends ChangeViewModel { private final InfoPane infoPane = new InfoPane(); private final JScrollPane sp = new JScrollPane(infoPane); - private final MetaData originalMetaData; private final MetaData newMetaData; - public MetaDataChangeViewModel(MetaData originalMetaData, MetaDataDiff metaDataDiff) { + public MetaDataChangeViewModel(MetaDataDiff metaDataDiff) { super(Localization.lang("Metadata change")); - this.originalMetaData = originalMetaData; this.newMetaData = metaDataDiff.getNewMetaData(); infoPane.setText("" + Localization.lang("Metadata change") + ""); diff --git a/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java b/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java index 5bf822128fa..ceb03d4a35f 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java @@ -1,7 +1,5 @@ package org.jabref.gui.fieldeditors; -import java.util.Optional; - import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Parent; @@ -18,9 +16,10 @@ public class JournalEditor extends HBox implements FieldEditorFX { - @FXML private JournalEditorViewModel viewModel; - @FXML private EditorTextArea textArea; - private Optional entry; + @FXML + private JournalEditorViewModel viewModel; + @FXML + private EditorTextArea textArea; public JournalEditor(String fieldName, JournalAbbreviationLoader journalAbbreviationLoader, JabRefPreferences preferences, AutoCompleteSuggestionProvider suggestionProvider, FieldCheckers fieldCheckers) { this.viewModel = new JournalEditorViewModel(fieldName, suggestionProvider, journalAbbreviationLoader, preferences.getJournalAbbreviationPreferences(), fieldCheckers); @@ -41,7 +40,6 @@ public JournalEditorViewModel getViewModel() { @Override public void bindToEntry(BibEntry entry) { - this.entry = Optional.of(entry); viewModel.bindToEntry(entry); } @@ -51,7 +49,7 @@ public Parent getNode() { } @FXML - private void toggleAbbreviation(ActionEvent event) { + private void toggleAbbreviation(ActionEvent unused) { viewModel.toggleAbbreviation(); } } diff --git a/src/main/java/org/jabref/gui/filelist/FileListEntryEditor.java b/src/main/java/org/jabref/gui/filelist/FileListEntryEditor.java index d6cd64833c1..0201d148e03 100644 --- a/src/main/java/org/jabref/gui/filelist/FileListEntryEditor.java +++ b/src/main/java/org/jabref/gui/filelist/FileListEntryEditor.java @@ -73,7 +73,7 @@ public class FileListEntryEditor { private final JComboBox types; private final JProgressBar prog = new JProgressBar(SwingConstants.HORIZONTAL); private final JLabel downloadLabel = new JLabel(Localization.lang("Downloading...")); - private JDialog diag; + private JDialog dialog; //Do not make this variable final, as then the lambda action listener will fail on compile private JabRefFrame frame; private boolean showSaveDialog; @@ -142,7 +142,7 @@ public FileListEntryEditor(LinkedFile entry, boolean showProgressBar, boolean sh return; } } - diag.dispose(); + dialog.dispose(); storeSettings(FileListEntryEditor.this.entry); okPressed = true; }; @@ -198,7 +198,7 @@ public FileListEntryEditor(LinkedFile entry, boolean showProgressBar, boolean sh @Override public void actionPerformed(ActionEvent e) { - diag.dispose(); + dialog.dispose(); } }; cancel.addActionListener(cancelAction); @@ -228,13 +228,13 @@ public void changedUpdate(DocumentEvent documentEvent) { }); - diag = new JDialog(); - diag.setTitle(Localization.lang("Select files")); - diag.setModal(true); - diag.getContentPane().add(builder.getPanel(), BorderLayout.CENTER); - diag.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH); - diag.pack(); - diag.addWindowListener(new WindowAdapter() { + dialog = new JDialog(); + dialog.setTitle(Localization.lang("Select files")); + dialog.setModal(true); + dialog.getContentPane().add(builder.getPanel(), BorderLayout.CENTER); + dialog.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH); + dialog.pack(); + dialog.addWindowListener(new WindowAdapter() { @Override public void windowActivated(WindowEvent event) { @@ -314,12 +314,12 @@ public void setVisible(boolean visible, boolean openBrowse) { } else { title = Localization.lang("Select files"); } - diag.setTitle(title); - diag.setVisible(visible); + dialog.setTitle(title); + dialog.setVisible(visible); } public boolean isVisible() { - return (diag != null) && diag.isVisible(); + return (dialog != null) && dialog.isVisible(); } private void setValues(LinkedFile entry) { diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java b/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java index 0ad63a4c994..14874771dd8 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java @@ -25,7 +25,6 @@ import org.jabref.gui.StateManager; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.l10n.Localization; -import org.jabref.model.FieldChange; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.groups.AbstractGroup; @@ -139,7 +138,7 @@ public void addNewSubgroup(GroupNodeViewModel parent) { SwingUtilities.invokeLater(() -> { Optional newGroup = dialogService.showCustomDialogAndWait(new GroupDialog()); newGroup.ifPresent(group -> { - GroupTreeNode newGroupNode = parent.addSubgroup(group); + parent.addSubgroup(group); // TODO: Add undo //UndoableAddOrRemoveGroup undo = new UndoableAddOrRemoveGroup(parent, new GroupTreeNodeViewModel(newGroupNode), UndoableAddOrRemoveGroup.ADD_NODE); @@ -176,7 +175,7 @@ public void editGroup(GroupNodeViewModel oldGroup) { boolean removePreviousAssignents = (oldGroup.getGroupNode().getGroup() instanceof ExplicitGroup) && (group instanceof ExplicitGroup); - List addChange = oldGroup.getGroupNode().setGroup( + oldGroup.getGroupNode().setGroup( group, keepPreviousAssignments, removePreviousAssignents, @@ -262,7 +261,7 @@ public void removeGroupAndSubgroups(GroupNodeViewModel group) { } void removeGroupsAndSubGroupsFromEntries(GroupNodeViewModel group) { - for (GroupNodeViewModel child: group.getChildren()) { + for (GroupNodeViewModel child : group.getChildren()) { removeGroupsAndSubGroupsFromEntries(child); } @@ -278,7 +277,7 @@ public void addSelectedEntries(GroupNodeViewModel group) { // if (!WarnAssignmentSideEffects.warnAssignmentSideEffects(node.getNode().getGroup(), panel.frame())) { // return; // user aborted operation - List addChange = group.getGroupNode().addEntriesToGroup(stateManager.getSelectedEntries()); + group.getGroupNode().addEntriesToGroup(stateManager.getSelectedEntries()); // TODO: Add undo // NamedCompound undoAll = new NamedCompound(Localization.lang("change assignment of entries")); @@ -306,7 +305,7 @@ public void removeSelectedEntries(GroupNodeViewModel group) { // if (!WarnAssignmentSideEffects.warnAssignmentSideEffects(mNode.getNode().getGroup(), mPanel.frame())) { // return; // user aborted operation - List removeChange = group.getGroupNode().removeEntriesFromGroup(stateManager.getSelectedEntries()); + group.getGroupNode().removeEntriesFromGroup(stateManager.getSelectedEntries()); // TODO: Add undo // if (!undo.isEmpty()) { @@ -315,6 +314,5 @@ public void removeSelectedEntries(GroupNodeViewModel group) { public void sortAlphabeticallyRecursive(GroupNodeViewModel group) { group.getGroupNode().sortChildren(compAlphabetIgnoreCase, true); - } } diff --git a/src/main/java/org/jabref/gui/groups/UndoableModifyGroup.java b/src/main/java/org/jabref/gui/groups/UndoableModifyGroup.java deleted file mode 100644 index c4b67ddc683..00000000000 --- a/src/main/java/org/jabref/gui/groups/UndoableModifyGroup.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.jabref.gui.groups; - -import java.util.List; - -import org.jabref.gui.undo.AbstractUndoableJabRefEdit; -import org.jabref.logic.l10n.Localization; -import org.jabref.model.groups.AbstractGroup; -import org.jabref.model.groups.GroupTreeNode; - -class UndoableModifyGroup extends AbstractUndoableJabRefEdit { - - private final GroupSidePane groupSidePane; - private final AbstractGroup m_oldGroupBackup; - private final AbstractGroup m_newGroupBackup; - private final GroupTreeNode m_groupsRootHandle; - private final List m_pathToNode; - - - /** - * @param node - * The node which still contains the old group. - * @param newGroup - * The new group to replace the one currently stored in node - * . - */ - public UndoableModifyGroup(GroupSidePane gs, GroupTreeNodeViewModel groupsRoot, - GroupTreeNodeViewModel node, AbstractGroup newGroup) { - groupSidePane = gs; - m_oldGroupBackup = node.getNode().getGroup().deepCopy(); - m_newGroupBackup = newGroup.deepCopy(); - m_pathToNode = node.getNode().getIndexedPathFromRoot(); - m_groupsRootHandle = groupsRoot.getNode(); - } - - @Override - public String getPresentationName() { - return Localization.lang("modify group"); - } - - @Override - public void undo() { - super.undo(); - //TODO: NULL - m_groupsRootHandle.getDescendant(m_pathToNode).get().setGroup( - m_oldGroupBackup.deepCopy()); - } - - @Override - public void redo() { - super.redo(); - m_groupsRootHandle.getDescendant(m_pathToNode).get().setGroup( - m_newGroupBackup.deepCopy()); - } -} diff --git a/src/main/java/org/jabref/gui/importer/fetcher/OAI2Fetcher.java b/src/main/java/org/jabref/gui/importer/fetcher/OAI2Fetcher.java index 4f9d592cfc9..a59979a8a2f 100644 --- a/src/main/java/org/jabref/gui/importer/fetcher/OAI2Fetcher.java +++ b/src/main/java/org/jabref/gui/importer/fetcher/OAI2Fetcher.java @@ -33,14 +33,12 @@ import org.xml.sax.helpers.DefaultHandler; /** - * * This class can be used to access any archive offering an OAI2 interface. By * default it will access ArXiv.org * - * @see - * * @author Ulrich Stärk * @author Christian Kopf + * @see */ public class OAI2Fetcher implements EntryFetcher { @@ -49,40 +47,30 @@ public class OAI2Fetcher implements EntryFetcher { private static final String OAI2_ARXIV_HOST = "export.arxiv.org"; private static final String OAI2_ARXIV_SCRIPT = "oai2"; private static final String OAI2_ARXIV_METADATAPREFIX = "arXiv"; - private static final String OAI2_ARXIV_ARCHIVENAME = "ArXiv.org"; private static final String OAI2_IDENTIFIER_FIELD = "oai2identifier"; private SAXParser saxParser; private final String oai2Host; private final String oai2Script; private final String oai2MetaDataPrefix; private final String oai2PrefixIdentifier; - private final String oai2ArchiveName; private boolean shouldContinue = true; private long waitTime = -1; private Date lastCall; /** - * - * - * @param oai2Host - * the host to query without leading http:// and without trailing / - * @param oai2Script - * the relative location of the oai2 interface without leading - * and trailing / - * @param oai2Metadataprefix - * the urlencoded metadataprefix - * @param oai2Prefixidentifier - * the urlencoded prefix identifier - * @param waitTimeMs - * Time to wait in milliseconds between query-requests. + * @param oai2Host the host to query without leading http:// and without trailing / + * @param oai2Script the relative location of the oai2 interface without leading + * and trailing / + * @param oai2Metadataprefix the urlencoded metadataprefix + * @param oai2Prefixidentifier the urlencoded prefix identifier + * @param waitTimeMs Time to wait in milliseconds between query-requests. */ public OAI2Fetcher(String oai2Host, String oai2Script, String oai2Metadataprefix, String oai2Prefixidentifier, - String oai2ArchiveName, long waitTimeMs) { + long waitTimeMs) { this.oai2Host = oai2Host; this.oai2Script = oai2Script; this.oai2MetaDataPrefix = oai2Metadataprefix; this.oai2PrefixIdentifier = oai2Prefixidentifier; - this.oai2ArchiveName = oai2ArchiveName; this.waitTime = waitTimeMs; try { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); @@ -94,19 +82,16 @@ public OAI2Fetcher(String oai2Host, String oai2Script, String oai2Metadataprefix /** * Default Constructor. The archive queried will be ArXiv.org - * */ public OAI2Fetcher() { this(OAI2Fetcher.OAI2_ARXIV_HOST, OAI2Fetcher.OAI2_ARXIV_SCRIPT, OAI2Fetcher.OAI2_ARXIV_METADATAPREFIX, - OAI2Fetcher.OAI2_ARXIV_PREFIXIDENTIFIER, OAI2Fetcher.OAI2_ARXIV_ARCHIVENAME, 20000L); + OAI2Fetcher.OAI2_ARXIV_PREFIXIDENTIFIER, 20000L); } /** * Construct the query URL * - * @param key - * The key of the OAI2 entry that the url should point to. - * + * @param key The key of the OAI2 entry that the url should point to. * @return a String denoting the query URL */ public String constructUrl(String key) { @@ -154,12 +139,11 @@ public static String fixKey(String key) { * Import an entry from an OAI2 archive. The BibEntry provided has to * have the field OAI2_IDENTIFIER_FIELD set to the search string. * - * @param key - * The OAI2 key to fetch from ArXiv. + * @param key The OAI2 key to fetch from ArXiv. * @return The imported BibEntry or null if none. */ protected BibEntry importOai2Entry(String key) throws IOException, SAXException { - /** + /* * Fix for problem reported in mailing-list: * https://sourceforge.net/forum/message.php?msg_id=4087158 */ @@ -252,7 +236,7 @@ public boolean processQuery(String query, ImportInspector dialog, OutputPrinter } catch (SAXException e) { String url = constructUrl(OAI2Fetcher.fixKey(key)); LOGGER.error("Error while fetching from " + getTitle(), e); - ((ImportInspectionDialog)dialog).showMessage(Localization.lang("Error while fetching from %0", getTitle()) + "\n" + + ((ImportInspectionDialog) dialog).showMessage(Localization.lang("Error while fetching from %0", getTitle()) + "\n" + Localization.lang("A SAX exception occurred while parsing '%0':", url), Localization.lang("Search %0", getTitle()), JOptionPane.ERROR_MESSAGE); } @@ -273,8 +257,8 @@ public boolean processQuery(String query, ImportInspector dialog, OutputPrinter return true; } catch (IOException | InterruptedException e) { LOGGER.error("Error while fetching from " + getTitle(), e); - ((ImportInspectionDialog)dialog).showErrorMessage(this.getTitle(), e.getLocalizedMessage()); - } + ((ImportInspectionDialog) dialog).showErrorMessage(this.getTitle(), e.getLocalizedMessage()); + } return false; } diff --git a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.java b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.java index 38496ae4108..09824d81494 100644 --- a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.java +++ b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.java @@ -2,7 +2,6 @@ import java.awt.BorderLayout; import java.awt.Dimension; -import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; @@ -96,7 +95,6 @@ class StyleSelectDialog { private PreviewPanel preview; private ActionListener removeAction; - private final Rectangle toRect = new Rectangle(0, 0, 1, 1); private final JButton ok = new JButton(Localization.lang("OK")); private final JButton cancel = new JButton(Localization.lang("Cancel")); private final BibEntry prevEntry; @@ -106,13 +104,11 @@ class StyleSelectDialog { private final OpenOfficePreferences preferences; public StyleSelectDialog(JabRefFrame frame, OpenOfficePreferences preferences, StyleLoader loader) { - this.frame = Objects.requireNonNull(frame); this.preferences = Objects.requireNonNull(preferences); this.loader = Objects.requireNonNull(loader); prevEntry = TestEntry.getTestEntry(); init(); - } private void init() { @@ -128,7 +124,6 @@ private void init() { } }); updateStyles(); - }); addButton.setToolTipText(Localization.lang("Add style file")); @@ -295,7 +290,6 @@ private void setupPopupMenu() { LOGGER.warn("Problem with style file '" + style.getPath() + "'", e); } })); - } public void setVisible(boolean visible) { @@ -358,6 +352,7 @@ public Optional getStyle() { /** * Get the currently selected style. + * * @return the selected style, or empty if no style is selected. */ private Optional getSelectedStyle() { @@ -537,6 +532,5 @@ public Optional getFileName() { public void setDirectoryPath(String path) { this.newFile.setText(path); } - } } diff --git a/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java b/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java index 305bb340aa6..72a90329e4b 100644 --- a/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java +++ b/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java @@ -7,15 +7,11 @@ import java.util.Optional; import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * A repository for all journal abbreviations, including add and find methods. */ public class JournalAbbreviationRepository { - private static final Logger LOGGER = LoggerFactory.getLogger(JournalAbbreviationRepository.class); private final Set abbreviations = new HashSet<>(16000); // We have over 15.000 abbreviations in the built-in lists public JournalAbbreviationRepository(Abbreviation... abbreviations) { diff --git a/src/main/java/org/jabref/migrations/PreferencesMigrations.java b/src/main/java/org/jabref/migrations/PreferencesMigrations.java index 81c2ae2cda0..30c6a8066f9 100644 --- a/src/main/java/org/jabref/migrations/PreferencesMigrations.java +++ b/src/main/java/org/jabref/migrations/PreferencesMigrations.java @@ -31,8 +31,6 @@ private PreferencesMigrations() { * Migrate all preferences from net/sf/jabref to org/jabref */ public static void upgradePrefsToOrgJabRef() { - - JabRefPreferences prefs = Globals.prefs; Preferences mainPrefsNode = Preferences.userNodeForPackage(JabRefMain.class); try { if (mainPrefsNode.childrenNames().length != 0) { @@ -173,7 +171,6 @@ public static void upgradeLabelPatternToBibtexKeyPattern() { prefs.put(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN, oldDefault); LOGGER.info("Upgraded old default key generator pattern '" + oldDefault + "' to new version."); } - } //Pref node already exists do not migrate from previous version if (mainPrefsNode.nodeExists(JabRefPreferences.BIBTEX_KEY_PATTERNS_NODE)) { @@ -198,16 +195,16 @@ public static void upgradeLabelPatternToBibtexKeyPattern() { * Migrate Import File Name and Directory name Patterns from versions <=4.0 to new BracketedPatterns */ private static void migrateFileImportPattern(String oldStylePattern, String newStylePattern, - JabRefPreferences prefs, Preferences mainPrefsNode) { + JabRefPreferences prefs, Preferences mainPrefsNode) { String preferenceFileNamePattern = mainPrefsNode.get(JabRefPreferences.IMPORT_FILENAMEPATTERN, null); if (preferenceFileNamePattern != null && - oldStylePattern.equals(preferenceFileNamePattern)) { + oldStylePattern.equals(preferenceFileNamePattern)) { // Upgrade the old-style File Name pattern to new one: mainPrefsNode.put(JabRefPreferences.IMPORT_FILENAMEPATTERN, newStylePattern); LOGGER.info("migrated old style " + JabRefPreferences.IMPORT_FILENAMEPATTERN + - " value \"" + oldStylePattern + "\" to new value \"" + - newStylePattern + "\" in the preference file"); + " value \"" + oldStylePattern + "\" to new value \"" + + newStylePattern + "\" in the preference file"); if (prefs.hasKey(JabRefPreferences.IMPORT_FILENAMEPATTERN)) { // Update also the key in the current application settings, if necessary: @@ -215,8 +212,8 @@ private static void migrateFileImportPattern(String oldStylePattern, String newS if (oldStylePattern.equals(fileNamePattern)) { prefs.put(JabRefPreferences.IMPORT_FILENAMEPATTERN, newStylePattern); LOGGER.info("migrated old style " + JabRefPreferences.IMPORT_FILENAMEPATTERN + - " value \"" + oldStylePattern + "\" to new value \"" + - newStylePattern + "\" in the running application"); + " value \"" + oldStylePattern + "\" to new value \"" + + newStylePattern + "\" in the running application"); } } } @@ -231,9 +228,9 @@ public static void upgradeImportFileAndDirePatterns() { // Check for prefs node for Version <= 4.0 if (mainPrefsNode.get(JabRefPreferences.IMPORT_FILENAMEPATTERN, null) != null) { - String[] oldStylePatterns = new String[] {"\\bibtexkey", + String[] oldStylePatterns = new String[]{"\\bibtexkey", "\\bibtexkey\\begin{title} - \\format[RemoveBrackets]{\\title}\\end{title}"}; - String[] newStylePatterns = new String[] {"[bibtexkey]", + String[] newStylePatterns = new String[]{"[bibtexkey]", "[bibtexkey] - [fulltitle]"}; for (int i = 0; i < oldStylePatterns.length; i++) { migrateFileImportPattern(oldStylePatterns[i], newStylePatterns[i], prefs, mainPrefsNode); @@ -257,7 +254,6 @@ public static void upgradeKeyBindingsToJavaFX() { List keys = prefs.getStringList(JabRefPreferences.BINDINGS); keys.replaceAll(replaceKeys); prefs.putStringList(JabRefPreferences.BINDINGS, keys); - } public static void addCrossRefRelatedFieldsForAutoComplete() { @@ -286,7 +282,7 @@ public static void upgradeObsoleteLookAndFeels() { JabRefPreferences prefs = Globals.prefs; String currentLandF = prefs.get(JabRefPreferences.WIN_LOOK_AND_FEEL); if ("com.jgoodies.looks.windows.WindowsLookAndFeel".equals(currentLandF) || - "com.jgoodies.plaf.plastic.Plastic3DLookAndFeel".equals(currentLandF) ) { + "com.jgoodies.plaf.plastic.Plastic3DLookAndFeel".equals(currentLandF)) { if (OS.WINDOWS) { String windowsLandF = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; prefs.put(JabRefPreferences.WIN_LOOK_AND_FEEL, windowsLandF); @@ -298,5 +294,4 @@ public static void upgradeObsoleteLookAndFeels() { } } } - } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index c9c844d61f9..b6efc53008b 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -715,8 +715,6 @@ Modified\ string=Modified string Modify=Modify -modify\ group=modify group - Move\ down=Move down Move\ external\ links\ to\ 'file'\ field=Move external links to 'file' field diff --git a/src/test/java/org/jabref/gui/search/GrammarBasedSearchRuleDescriberTest.java b/src/test/java/org/jabref/gui/search/GrammarBasedSearchRuleDescriberTest.java index 451be0e80b0..47152884ce5 100644 --- a/src/test/java/org/jabref/gui/search/GrammarBasedSearchRuleDescriberTest.java +++ b/src/test/java/org/jabref/gui/search/GrammarBasedSearchRuleDescriberTest.java @@ -25,7 +25,6 @@ private TextFlow createDescription(String query, boolean caseSensitive, boolean @Test public void testSimpleQueryCaseSensitiveRegex() { - double textSize = 13; String query = "a=b"; List expectedTexts = Arrays.asList(TooltipTextUtil.createText("This search contains entries in which "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("a", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the regular expression "), TooltipTextUtil.createText("b", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(". "), @@ -37,7 +36,6 @@ public void testSimpleQueryCaseSensitiveRegex() { @Test public void testSimpleQueryCaseSensitive() { - double textSize = 13; String query = "a=b"; List expectedTexts = Arrays.asList(TooltipTextUtil.createText("This search contains entries in which "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("a", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the term "), TooltipTextUtil.createText("b", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(". "), @@ -49,7 +47,6 @@ public void testSimpleQueryCaseSensitive() { @Test public void testSimpleQuery() { - double textSize = 13; String query = "a=b"; List expectedTexts = Arrays.asList(TooltipTextUtil.createText("This search contains entries in which "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("a", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the term "), TooltipTextUtil.createText("b", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(". "), @@ -61,7 +58,6 @@ public void testSimpleQuery() { @Test public void testSimpleQueryRegex() { - double textSize = 13; String query = "a=b"; List expectedTexts = Arrays.asList(TooltipTextUtil.createText("This search contains entries in which "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("a", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the regular expression "), TooltipTextUtil.createText("b", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(". "), @@ -73,7 +69,6 @@ public void testSimpleQueryRegex() { @Test public void testComplexQueryCaseSensitiveRegex() { - double textSize = 13; String query = "not a=b and c=e or e=\"x\""; List expectedTexts = Arrays.asList(TooltipTextUtil.createText("This search contains entries in which "), TooltipTextUtil.createText("not "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("a", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the regular expression "), TooltipTextUtil.createText("b", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" and "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("c", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the regular expression "), @@ -86,7 +81,6 @@ public void testComplexQueryCaseSensitiveRegex() { @Test public void testComplexQueryRegex() { - double textSize = 13; String query = "not a=b and c=e or e=\"x\""; List expectedTexts = Arrays.asList(TooltipTextUtil.createText("This search contains entries in which "), TooltipTextUtil.createText("not "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("a", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the regular expression "), TooltipTextUtil.createText("b", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" and "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("c", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the regular expression "), @@ -99,7 +93,6 @@ public void testComplexQueryRegex() { @Test public void testComplexQueryCaseSensitive() { - double textSize = 13; String query = "not a=b and c=e or e=\"x\""; List expectedTexts = Arrays.asList(TooltipTextUtil.createText("This search contains entries in which "), TooltipTextUtil.createText("not "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("a", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the term "), TooltipTextUtil.createText("b", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" and "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("c", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the term "), TooltipTextUtil.createText("e", TooltipTextUtil.TextType.BOLD), @@ -111,7 +104,6 @@ public void testComplexQueryCaseSensitive() { @Test public void testComplexQuery() { - double textSize = 13; String query = "not a=b and c=e or e=\"x\""; List expectedTexts = Arrays.asList(TooltipTextUtil.createText("This search contains entries in which "), TooltipTextUtil.createText("not "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("a", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the term "), TooltipTextUtil.createText("b", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" and "), TooltipTextUtil.createText("the field "), TooltipTextUtil.createText("c", TooltipTextUtil.TextType.BOLD), TooltipTextUtil.createText(" contains the term "), TooltipTextUtil.createText("e", TooltipTextUtil.TextType.BOLD), diff --git a/src/test/java/org/jabref/logic/exporter/ModsExportFormatTest.java b/src/test/java/org/jabref/logic/exporter/ModsExportFormatTest.java index 011c0139144..017cc32cabc 100644 --- a/src/test/java/org/jabref/logic/exporter/ModsExportFormatTest.java +++ b/src/test/java/org/jabref/logic/exporter/ModsExportFormatTest.java @@ -27,21 +27,19 @@ public class ModsExportFormatTest { public Charset charset; private ModsExporter modsExportFormat; private BibDatabaseContext databaseContext; - private BibtexImporter bibtexImporter; private Path tempFile; @Rule public TemporaryFolder testFolder = new TemporaryFolder(); - private Path importFile; @Before public void setUp() throws Exception { databaseContext = new BibDatabaseContext(); charset = StandardCharsets.UTF_8; modsExportFormat = new ModsExporter(); - bibtexImporter = new BibtexImporter(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS), new DummyFileUpdateMonitor()); + new BibtexImporter(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS), new DummyFileUpdateMonitor()); tempFile = testFolder.newFile().toPath(); - importFile = Paths.get(ModsExportFormatTest.class.getResource("ModsExportFormatTestAllFields.bib").toURI()); + Paths.get(ModsExportFormatTest.class.getResource("ModsExportFormatTestAllFields.bib").toURI()); } @Test diff --git a/src/test/java/org/jabref/logic/formatter/bibtexfields/RegexFormatterTest.java b/src/test/java/org/jabref/logic/formatter/bibtexfields/RegexFormatterTest.java index a01e31f1bdc..58f3d4bd751 100644 --- a/src/test/java/org/jabref/logic/formatter/bibtexfields/RegexFormatterTest.java +++ b/src/test/java/org/jabref/logic/formatter/bibtexfields/RegexFormatterTest.java @@ -20,41 +20,40 @@ public void setUp() { @Test public void spacesReplacedCorrectly() { String regexInput = "(\" \",\"-\")"; - formatter.setRegex(regexInput); + RegexFormatter.setRegex(regexInput); assertEquals("replace-all-spaces", formatter.format("replace all spaces")); } @Test public void protectedSpacesNotReplacedInSingleProtectedBlock() { String regexInput = "(\" \",\"-\")"; - formatter.setRegex(regexInput); + RegexFormatter.setRegex(regexInput); assertEquals("replace-spaces-{not these ones}", formatter.format("replace spaces {not these ones}")); } @Test public void protectedSpacesNotReplacedInTwoProtectedBlocks() { String regexInput = "(\" \",\"-\")"; - formatter.setRegex(regexInput); + RegexFormatter.setRegex(regexInput); assertEquals("replace-spaces-{not these ones}-{or these ones}-but-these-ones", formatter.format("replace spaces {not these ones} {or these ones} but these ones")); } @Test public void escapedBracesAreNotReplaced() { String regexInput = "(\" \",\"-\")"; - formatter.setRegex(regexInput); + RegexFormatter.setRegex(regexInput); assertEquals("replace-spaces-\\{-these-ones\\}-and-these-ones", formatter.format("replace spaces \\{ these ones\\} and these ones")); } @Test public void escapedBracesAreNotReplacedInTwoCases() { String regexInput = "(\" \",\"-\")"; - formatter.setRegex(regexInput); + RegexFormatter.setRegex(regexInput); assertEquals("replace-spaces-\\{-these-ones\\},-these-ones,-and-\\{-these-ones\\}", formatter.format("replace spaces \\{ these ones\\}, these ones, and \\{ these ones\\}")); } @Test public void escapedBracesAreNotReplacedAndProtectionStillWorks() { - String regexInput = "(\" \",\"-\")"; assertEquals("replace-spaces-{not these ones},-these-ones,-and-\\{-these-ones\\}", formatter.format("replace spaces {not these ones}, these ones, and \\{ these ones\\}")); } @@ -62,6 +61,4 @@ public void escapedBracesAreNotReplacedAndProtectionStillWorks() { public void formatExample() { assertEquals("Please-replace-the-spaces", formatter.format(formatter.getExampleInput())); } - - } From f711c1e560e36e9ab47ce898ab81bd43da57eb50 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 5 Mar 2018 17:45:42 +0100 Subject: [PATCH 16/28] Allow search field to be smaller --- src/main/java/org/jabref/gui/JabRefFrame.java | 3 ++- src/main/java/org/jabref/gui/search/GlobalSearchBar.java | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 491ec9fb98e..3838555e3ea 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -683,9 +683,10 @@ private Node createToolbar() { factory.createIconButton(StandardActions.FORK_ME, new OpenBrowserAction("https://github.com/JabRef/jabref")), factory.createIconButton(StandardActions.OPEN_FACEBOOK, new OpenBrowserAction("https://www.facebook.com/JabRef/")), factory.createIconButton(StandardActions.OPEN_TWITTER, new OpenBrowserAction("https://twitter.com/jabref_org")) - ); + HBox.setHgrow(globalSearchBar, Priority.ALWAYS); + ToolBar toolBar = new ToolBar( leftSide, diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index aa2ce21acb7..1527129ecee 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -14,6 +14,7 @@ import javafx.css.PseudoClass; import javafx.event.Event; import javafx.geometry.Orientation; +import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.ContentDisplay; @@ -30,6 +31,7 @@ import javafx.scene.input.MouseButton; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; import javafx.scene.text.TextFlow; import javafx.util.Duration; @@ -180,9 +182,9 @@ public void actionPerformed(ActionEvent e) { int initialSize = 400; int expandedSize = 700; searchField.getStyleClass().add("search-field"); - searchField.setMinWidth(200); + searchField.setMinWidth(100); searchField.setMaxWidth(initialSize); - searchField.setPrefWidth(expandedSize); + HBox.setHgrow(searchField, Priority.ALWAYS); EasyBind.subscribe(searchField.textProperty(), searchText -> performSearch()); EasyBind.subscribe(searchField.focusedProperty(), isFocused -> { if (isFocused) { @@ -202,6 +204,7 @@ public void actionPerformed(ActionEvent e) { searchField, currentResults ); + this.setAlignment(Pos.CENTER_LEFT); } public void performGlobalSearch() { From 175719e824b44636a58bf7e47cc1dc948c23eb78 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 11:00:02 +0100 Subject: [PATCH 17/28] Fix some non FX Thread issues Main drawback: Cleanup panel is in backgroung due to swing thread) --- src/main/java/org/jabref/gui/BasePanel.java | 4 +- .../org/jabref/gui/actions/CleanupAction.java | 73 +++++++++++-------- .../jabref/gui/dialogs/BackupUIManager.java | 5 +- 3 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 2279e25e27f..2b7024c2cb0 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -157,7 +157,7 @@ public class BasePanel extends StackPane implements ClipboardOwner { // Keeps track of the string dialog if it is open. private final Map actions = new HashMap<>(); private final SidePaneManager sidePaneManager; - private final PreviewPanel preview; + private PreviewPanel preview; private final BasePanelPreferences preferences; private final ExternalFileTypes externalFileTypes; @@ -236,7 +236,7 @@ public BasePanel(JabRefFrame frame, BasePanelPreferences preferences, BibDatabas this.entryEditor = new EntryEditor(this, preferences.getEntryEditorPreferences(), Globals.getFileUpdateMonitor(), dialogService); - this.preview = new PreviewPanel(this, getBibDatabaseContext(), preferences.getKeyBindings(), preferences.getPreviewPreferences(), dialogService); + DefaultTaskExecutor.runInJavaFXThread(() -> this.preview = new PreviewPanel(this, getBibDatabaseContext(), preferences.getKeyBindings(), preferences.getPreviewPreferences(), dialogService)); DefaultTaskExecutor.runInJavaFXThread(() -> frame().getGlobalSearchBar().getSearchQueryHighlightObservable().addSearchListener(preview)); } diff --git a/src/main/java/org/jabref/gui/actions/CleanupAction.java b/src/main/java/org/jabref/gui/actions/CleanupAction.java index 7382d4d076e..b8e966a304c 100644 --- a/src/main/java/org/jabref/gui/actions/CleanupAction.java +++ b/src/main/java/org/jabref/gui/actions/CleanupAction.java @@ -3,6 +3,7 @@ import java.util.List; import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; import org.jabref.Globals; import org.jabref.gui.BasePanel; @@ -58,46 +59,54 @@ public void init() { @Override public void run() { - if (canceled) { - return; - } - CleanupPresetPanel presetPanel = new CleanupPresetPanel(panel.getBibDatabaseContext(), - CleanupPreset.loadFromPreferences(preferences)); - int choice = showDialog(presetPanel); - if (choice != JOptionPane.OK_OPTION) { - canceled = true; - return; - } - CleanupPreset cleanupPreset = presetPanel.getCleanupPreset(); - cleanupPreset.storeInPreferences(preferences); - if (cleanupPreset.isRenamePDF() && Globals.prefs.getBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN)) { + SwingUtilities.invokeLater(() -> { - boolean autogeneratePressed = dialogService.showConfirmationDialogWithOptOutAndWait(Localization.lang("Autogenerate PDF Names"), - Localization.lang("Auto-generating PDF-Names does not support undo. Continue?"), - Localization.lang("Autogenerate PDF Names"), - Localization.lang("Cancel"), - Localization.lang("Disable this confirmation dialog"), - optOut -> Globals.prefs.putBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN, !optOut)); + if (canceled) { + return; + } + CleanupPresetPanel presetPanel = new CleanupPresetPanel(panel.getBibDatabaseContext(), + CleanupPreset.loadFromPreferences(preferences)); + + int choice = showDialog(presetPanel); - if (!autogeneratePressed) { + if (choice != JOptionPane.OK_OPTION) { canceled = true; return; } - } + CleanupPreset cleanupPreset = presetPanel.getCleanupPreset(); + cleanupPreset.storeInPreferences(preferences); + + if (cleanupPreset.isRenamePDF() && Globals.prefs.getBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN)) { + + boolean autogeneratePressed = DefaultTaskExecutor.runInJavaFXThread(()->dialogService.showConfirmationDialogWithOptOutAndWait(Localization.lang("Autogenerate PDF Names"), + Localization.lang("Auto-generating PDF-Names does not support undo. Continue?"), + Localization.lang("Autogenerate PDF Names"), + Localization.lang("Cancel"), + Localization.lang("Disable this confirmation dialog"), + optOut -> Globals.prefs.putBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN, !optOut))); + + if (!autogeneratePressed) { + canceled = true; + return; + } + } - for (BibEntry entry : panel.getSelectedEntries()) { - // undo granularity is on entry level - NamedCompound ce = new NamedCompound(Localization.lang("Cleanup entry")); + for (BibEntry entry : panel.getSelectedEntries()) { + // undo granularity is on entry level + NamedCompound ce = new NamedCompound(Localization.lang("Cleanup entry")); - doCleanup(cleanupPreset, entry, ce); + doCleanup(cleanupPreset, entry, ce); - ce.end(); - if (ce.hasEdits()) { - modifiedEntriesCount++; - panel.getUndoManager().addEdit(ce); + ce.end(); + if (ce.hasEdits()) { + modifiedEntriesCount++; + panel.getUndoManager().addEdit(ce); + } } - } + + }); + } @Override @@ -130,10 +139,14 @@ public void update() { } private int showDialog(CleanupPresetPanel presetPanel) { + String dialogTitle = Localization.lang("Cleanup entries"); + Object[] messages = {Localization.lang("What would you like to clean up?"), presetPanel.getScrollPane()}; + return JOptionPane.showConfirmDialog(null, messages, dialogTitle, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + } /** diff --git a/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java b/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java index 33e4391cecd..5dca94d742b 100644 --- a/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java +++ b/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java @@ -3,6 +3,7 @@ import java.nio.file.Path; import org.jabref.gui.DialogService; +import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.autosaveandbackup.BackupManager; import org.jabref.logic.l10n.Localization; @@ -24,10 +25,10 @@ public static void showRestoreBackupDialog(DialogService dialogService, Path ori .append(Localization.lang("Do you want to recover the library from the backup file?")) .toString(); - boolean restoreClicked = dialogService.showConfirmationDialogAndWait( + boolean restoreClicked = DefaultTaskExecutor.runInJavaFXThread(()-> dialogService.showConfirmationDialogAndWait( Localization.lang("Backup found"), content, Localization.lang("Restore from backup"), - Localization.lang("Ignore backup")); + Localization.lang("Ignore backup"))); if (restoreClicked) { BackupManager.restoreBackup(originalPath); From 0f3320ef5c93030e5018fe18eb48db813b66e2ad Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 11:35:21 +0100 Subject: [PATCH 18/28] embed cleanup dialog in javafx --- .../org/jabref/gui/actions/CleanupAction.java | 85 +++++++++++-------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/jabref/gui/actions/CleanupAction.java b/src/main/java/org/jabref/gui/actions/CleanupAction.java index b8e966a304c..c70b1af4e9e 100644 --- a/src/main/java/org/jabref/gui/actions/CleanupAction.java +++ b/src/main/java/org/jabref/gui/actions/CleanupAction.java @@ -1,10 +1,14 @@ package org.jabref.gui.actions; import java.util.List; +import java.util.Optional; import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; +import javax.swing.JScrollPane; +import javafx.embed.swing.SwingNode; +import javafx.scene.control.ButtonType; +import javafx.scene.control.DialogPane; import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; @@ -60,52 +64,59 @@ public void init() { @Override public void run() { - SwingUtilities.invokeLater(() -> { + if (canceled) { + return; + } + CleanupPresetPanel presetPanel = new CleanupPresetPanel(panel.getBibDatabaseContext(), + CleanupPreset.loadFromPreferences(preferences)); - if (canceled) { - return; - } - CleanupPresetPanel presetPanel = new CleanupPresetPanel(panel.getBibDatabaseContext(), - CleanupPreset.loadFromPreferences(preferences)); + SwingNode node = new SwingNode(); + presetPanel.getScrollPane().setVisible(true); + + JScrollPane scrollPane = presetPanel.getScrollPane(); + node.setContent(scrollPane); + node.setVisible(true); + + DialogPane pane = new DialogPane(); + pane.setContent(node); + pane.setPrefSize(600, 600); + + Optional ok = dialogService.showCustomDialogAndWait(Localization.lang("Cleanup entries"), pane, ButtonType.OK, ButtonType.CANCEL); + + if (!ok.isPresent() || ((ok.isPresent() && (ok.get() == ButtonType.CANCEL)))) { + canceled = true; + return; + } + CleanupPreset cleanupPreset = presetPanel.getCleanupPreset(); + cleanupPreset.storeInPreferences(preferences); - int choice = showDialog(presetPanel); + if (cleanupPreset.isRenamePDF() && Globals.prefs.getBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN)) { + + boolean autogeneratePressed = DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showConfirmationDialogWithOptOutAndWait(Localization.lang("Autogenerate PDF Names"), + Localization.lang("Auto-generating PDF-Names does not support undo. Continue?"), + Localization.lang("Autogenerate PDF Names"), + Localization.lang("Cancel"), + Localization.lang("Disable this confirmation dialog"), + optOut -> Globals.prefs.putBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN, !optOut))); - if (choice != JOptionPane.OK_OPTION) { + if (!autogeneratePressed) { canceled = true; return; } - CleanupPreset cleanupPreset = presetPanel.getCleanupPreset(); - cleanupPreset.storeInPreferences(preferences); - - if (cleanupPreset.isRenamePDF() && Globals.prefs.getBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN)) { - - boolean autogeneratePressed = DefaultTaskExecutor.runInJavaFXThread(()->dialogService.showConfirmationDialogWithOptOutAndWait(Localization.lang("Autogenerate PDF Names"), - Localization.lang("Auto-generating PDF-Names does not support undo. Continue?"), - Localization.lang("Autogenerate PDF Names"), - Localization.lang("Cancel"), - Localization.lang("Disable this confirmation dialog"), - optOut -> Globals.prefs.putBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN, !optOut))); - - if (!autogeneratePressed) { - canceled = true; - return; - } - } + } - for (BibEntry entry : panel.getSelectedEntries()) { - // undo granularity is on entry level - NamedCompound ce = new NamedCompound(Localization.lang("Cleanup entry")); + for (BibEntry entry : panel.getSelectedEntries()) { + // undo granularity is on entry level + NamedCompound ce = new NamedCompound(Localization.lang("Cleanup entry")); - doCleanup(cleanupPreset, entry, ce); + doCleanup(cleanupPreset, entry, ce); - ce.end(); - if (ce.hasEdits()) { - modifiedEntriesCount++; - panel.getUndoManager().addEdit(ce); - } + ce.end(); + if (ce.hasEdits()) { + modifiedEntriesCount++; + panel.getUndoManager().addEdit(ce); } - - }); + } } From dabd1752a606741b9d4b6556bfaa914dc7d7c87e Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 5 Mar 2018 16:22:28 +0100 Subject: [PATCH 19/28] Update test order -> Execute checkstyle first (#3807) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4aaf9abf217..a7f3c9eb12b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,11 +17,11 @@ env: global: - GRADLE_OPTS=-Dorg.gradle.daemon=false matrix: + - TEST_SUITE=checkstyle - TEST_SUITE=check OPTIONS=modernizer - TEST_SUITE=fetcherTest - TEST_SUITE=databaseTest - TEST_SUITE=guiTest - - TEST_SUITE=checkstyle - TEST_SUITE=codecov - DEPENDENCY_UPDATES=check From 0c833eacdd858e87fef152b5ee8fcf3b5422ba2f Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 11:47:33 +0100 Subject: [PATCH 20/28] checkstyle argh! --- src/main/java/org/jabref/gui/actions/CleanupAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/jabref/gui/actions/CleanupAction.java b/src/main/java/org/jabref/gui/actions/CleanupAction.java index c70b1af4e9e..d1e859277cb 100644 --- a/src/main/java/org/jabref/gui/actions/CleanupAction.java +++ b/src/main/java/org/jabref/gui/actions/CleanupAction.java @@ -9,6 +9,7 @@ import javafx.embed.swing.SwingNode; import javafx.scene.control.ButtonType; import javafx.scene.control.DialogPane; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; From 313b258ff4cfc8ab58da38ad3f5114c289354b01 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 14:26:23 +0100 Subject: [PATCH 21/28] Set resizable for custom dialog with dialog pane convert merge entries dlg to javafx and make action working again --- src/main/java/org/jabref/gui/BasePanel.java | 3 ++- src/main/java/org/jabref/gui/FXDialogService.java | 2 ++ .../java/org/jabref/gui/actions/CleanupAction.java | 3 +-- .../org/jabref/gui/actions/MergeEntriesAction.java | 2 +- .../gui/mergeentries/MergeEntriesDialog.java | 14 ++++++++------ 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 2b7024c2cb0..41fdfffe226 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -71,6 +71,7 @@ import org.jabref.gui.journals.UnabbreviateAction; import org.jabref.gui.maintable.MainTable; import org.jabref.gui.maintable.MainTableDataModel; +import org.jabref.gui.mergeentries.MergeEntriesDialog; import org.jabref.gui.mergeentries.MergeWithFetchedEntryAction; import org.jabref.gui.specialfields.SpecialFieldDatabaseChangeListener; import org.jabref.gui.specialfields.SpecialFieldValueViewModel; @@ -465,7 +466,7 @@ public void update() { // The action for cleaning up entry. actions.put(Actions.CLEANUP, cleanUpAction); - //actions.put(Actions.MERGE_ENTRIES, (BaseAction) () -> new MergeEntriesDialog(BasePanel.this)); + actions.put(Actions.MERGE_ENTRIES, (BaseAction) () -> new MergeEntriesDialog(BasePanel.this, dialogService)); actions.put(Actions.SEARCH, (BaseAction) frame.getGlobalSearchBar()::focus); actions.put(Actions.GLOBAL_SEARCH, (BaseAction) frame.getGlobalSearchBar()::performGlobalSearch); diff --git a/src/main/java/org/jabref/gui/FXDialogService.java b/src/main/java/org/jabref/gui/FXDialogService.java index db753727612..0b25b524cd6 100644 --- a/src/main/java/org/jabref/gui/FXDialogService.java +++ b/src/main/java/org/jabref/gui/FXDialogService.java @@ -215,6 +215,8 @@ public Optional showCustomDialogAndWait(String title, DialogPane con FXDialog alert = new FXDialog(AlertType.NONE, title); alert.setDialogPane(contentPane); alert.getButtonTypes().setAll(buttonTypes); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); + alert.setResizable(true); return alert.showAndWait(); } diff --git a/src/main/java/org/jabref/gui/actions/CleanupAction.java b/src/main/java/org/jabref/gui/actions/CleanupAction.java index d1e859277cb..f0f34af7379 100644 --- a/src/main/java/org/jabref/gui/actions/CleanupAction.java +++ b/src/main/java/org/jabref/gui/actions/CleanupAction.java @@ -53,8 +53,7 @@ public void init() { canceled = false; modifiedEntriesCount = 0; if (panel.getSelectedEntries().isEmpty()) { // None selected. Inform the user to select entries first. - JOptionPane.showMessageDialog(null, Localization.lang("First select entries to clean up."), - Localization.lang("Cleanup entry"), JOptionPane.INFORMATION_MESSAGE); + dialogService.showInformationDialogAndWait(Localization.lang("Cleanup entry"), Localization.lang("First select entries to clean up.")); canceled = true; return; } diff --git a/src/main/java/org/jabref/gui/actions/MergeEntriesAction.java b/src/main/java/org/jabref/gui/actions/MergeEntriesAction.java index a7aef9d6eb4..257c8b04a18 100644 --- a/src/main/java/org/jabref/gui/actions/MergeEntriesAction.java +++ b/src/main/java/org/jabref/gui/actions/MergeEntriesAction.java @@ -13,7 +13,7 @@ public MergeEntriesAction(JabRefFrame jabRefFrame) { @Override public void execute() { - MergeEntriesDialog dlg = new MergeEntriesDialog(jabRefFrame.getCurrentBasePanel()); + MergeEntriesDialog dlg = new MergeEntriesDialog(jabRefFrame.getCurrentBasePanel(), jabRefFrame.getDialogService()); dlg.setVisible(true); } diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java index 2ce502a3b78..e81d82278c6 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java @@ -4,10 +4,10 @@ import javax.swing.JButton; import javax.swing.JFrame; -import javax.swing.JOptionPane; import javax.swing.JSeparator; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.gui.JabRefDialog; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableInsertEntry; @@ -35,10 +35,11 @@ public class MergeEntriesDialog extends JabRefDialog { private final BasePanel panel; private final CellConstraints cc = new CellConstraints(); + private final DialogService dialogService; - public MergeEntriesDialog(BasePanel panel) { + public MergeEntriesDialog(BasePanel panel, DialogService dialogService) { super((JFrame) null, MERGE_ENTRIES, true, MergeEntriesDialog.class); - + this.dialogService = dialogService; this.panel = panel; // Start setting up the dialog @@ -54,9 +55,10 @@ private void init(List selected) { // Check if there are two entries selected if (selected.size() != 2) { // None selected. Inform the user to select entries first. - JOptionPane.showMessageDialog(null, - Localization.lang("You have to choose exactly two entries to merge."), - MERGE_ENTRIES, JOptionPane.INFORMATION_MESSAGE); + + dialogService.showInformationDialogAndWait(Localization.lang("Merge entries"), + Localization.lang("You have to choose exactly two entries to merge.")); + this.dispose(); return; } From 839533341527606572f0a14630fe0c2c001e732a Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 14:37:13 +0100 Subject: [PATCH 22/28] fix cut, copy & paste action from toolbar --- src/main/java/org/jabref/gui/JabRefFrame.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 3838555e3ea..55719e04a5f 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -669,13 +669,13 @@ private Node createToolbar() { PushToApplicationButton pushToExternal = new PushToApplicationButton(this, pushApplications.getApplications()); HBox rightSide = new HBox ( factory.createIconButton(StandardActions.NEW_ENTRY, new NewEntryAction(this, BiblatexEntryTypes.ARTICLE)), - factory.createIconButton(StandardActions.DELETE_ENTRY, new EditAction(Actions.DELETE)), + factory.createIconButton(StandardActions.DELETE_ENTRY, new OldDatabaseCommandWrapper(Actions.DELETE, this, Globals.stateManager)), factory.createIconButton(StandardActions.UNDO, new OldDatabaseCommandWrapper(Actions.UNDO, this, Globals.stateManager)), factory.createIconButton(StandardActions.REDO, new OldDatabaseCommandWrapper(Actions.REDO, this, Globals.stateManager)), - factory.createIconButton(StandardActions.CUT, new EditAction(Actions.CUT)), - factory.createIconButton(StandardActions.COPY, new EditAction(Actions.COPY)), - factory.createIconButton(StandardActions.PASTE, new EditAction(Actions.PASTE)), + factory.createIconButton(StandardActions.CUT, new OldDatabaseCommandWrapper(Actions.CUT, this, Globals.stateManager)), + factory.createIconButton(StandardActions.COPY, new OldDatabaseCommandWrapper(Actions.COPY, this, Globals.stateManager)), + factory.createIconButton(StandardActions.PASTE, new OldDatabaseCommandWrapper(Actions.PASTE, this, Globals.stateManager)), factory.createIconButton(StandardActions.CLEANUP_ENTRIES, new OldDatabaseCommandWrapper(Actions.CLEANUP, this, Globals.stateManager)), factory.createIconButton(pushToExternal.getMenuAction(), pushToExternal), From d7ff5a71a9e6c628b5b15b2042b9e93a9ecbb64c Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 21:05:41 +0100 Subject: [PATCH 23/28] run find fulltext dialog in fx thread --- .../java/org/jabref/gui/externalfiles/FindFullTextAction.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java b/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java index 549efc6fec4..bb4f747465d 100644 --- a/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java +++ b/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java @@ -54,8 +54,6 @@ public void init() throws Exception { @Override public void run() { if (basePanel.getSelectedEntries().size() >= WARNING_LIMIT) { - String[] options = new String[] {Localization.lang("Look up full text documents"), - Localization.lang("Cancel")}; boolean getFullTextForAllCliecked = dialogService.showConfirmationDialogAndWait(Localization.lang("Look up full text documents"), Localization.lang( "You are about to look up full text documents for %0 entries.", @@ -119,7 +117,7 @@ public void update() { entry.getCiteKeyOptional().orElse(Localization.lang("undefined"))); basePanel.output(message); - dialogService.showErrorDialogAndWait(title, message); + DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showErrorDialogAndWait(title, message)); } remove.add(result); } From 242170f57c5519d22b086695ce9e5ae3a68e2383 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 21:28:06 +0100 Subject: [PATCH 24/28] Replace swing export dialog in ExportToClipboardAction with fx choices dlg --- .../java/org/jabref/gui/DialogService.java | 2 +- .../gui/exporter/ExportToClipboardAction.java | 70 +++++++++---------- .../org/jabref/logic/exporter/Exporter.java | 11 ++- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/jabref/gui/DialogService.java b/src/main/java/org/jabref/gui/DialogService.java index 5900555e656..0ffaa0de55a 100644 --- a/src/main/java/org/jabref/gui/DialogService.java +++ b/src/main/java/org/jabref/gui/DialogService.java @@ -26,7 +26,7 @@ public interface DialogService { /** - * This will create and display new {@link ChoiceDialog} of type T with a default choice and a collection of possible choices + * This will create and display new {@link ChoiceDialog} of type T with a default choice (can be null) and a collection of possible choices */ Optional showChoiceDialogAndWait(String title, String content, String okButtonLabel, T defaultChoice, Collection choices); diff --git a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java index 94eeae9c59b..2e74c1b5031 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java +++ b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java @@ -2,19 +2,16 @@ import java.awt.Toolkit; import java.awt.datatransfer.ClipboardOwner; -import java.io.File; -import java.io.FileInputStream; +import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; -import java.util.Comparator; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; - -import javax.swing.BorderFactory; -import javax.swing.JList; -import javax.swing.JOptionPane; -import javax.swing.ListSelectionModel; +import java.util.Optional; import org.jabref.Globals; import org.jabref.gui.BasePanel; @@ -38,7 +35,6 @@ public class ExportToClipboardAction extends AbstractWorker { */ private String message; - public ExportToClipboardAction(JabRefFrame frame) { this.frame = Objects.requireNonNull(frame); } @@ -55,48 +51,45 @@ public void run() { return; } - List exporters = Globals.exportFactory.getExporters(); - exporters.sort(Comparator.comparing(Exporter::getDisplayName)); - List exportFormatDisplayNames = exporters.stream().map(Exporter::getDisplayName).collect(Collectors.toList()); - - JList list = new JList<>(exportFormatDisplayNames.toArray(new String[exportFormatDisplayNames.size()])); - list.setBorder(BorderFactory.createEtchedBorder()); - list.setSelectionInterval(0, 0); - list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - int answer = JOptionPane.showOptionDialog(null, list, Localization.lang("Select export format"), - JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, - new String[] {Localization.lang("Export"), - Localization.lang("Cancel")}, - Localization.lang("Export")); - if (answer == JOptionPane.NO_OPTION) { + List exporters = new ArrayList<>(Globals.exportFactory.getExporters()); + + Optional selectedExporter = frame.getDialogService().showChoiceDialogAndWait(Localization.lang("Export"), Localization.lang("Select export format"), + Localization.lang("Export"), null, exporters); + + if (!selectedExporter.isPresent()) { return; } - Exporter exporter = exporters.get(list.getSelectedIndex()); + Exporter exporter = selectedExporter.get(); // Set the global variable for this database's file directory before exporting, // so formatters can resolve linked files correctly. // (This is an ugly hack!) - Globals.prefs.fileDirForDatabase = frame.getCurrentBasePanel().getBibDatabaseContext() + Globals.prefs.fileDirForDatabase = frame.getCurrentBasePanel() + .getBibDatabaseContext() .getFileDirectories(Globals.prefs.getFileDirectoryPreferences()); - File tmp = null; + Path tmp = null; try { // To simplify the exporter API we simply do a normal export to a temporary // file, and read the contents afterwards: - tmp = File.createTempFile("jabrefCb", ".tmp"); - tmp.deleteOnExit(); + tmp = Files.createTempFile("jabrefCb", ".tmp"); + List entries = panel.getSelectedEntries(); // Write to file: - exporter.export(panel.getBibDatabaseContext(), tmp.toPath(), - panel.getBibDatabaseContext().getMetaData().getEncoding() + exporter.export(panel.getBibDatabaseContext(), tmp, + panel.getBibDatabaseContext() + .getMetaData() + .getEncoding() .orElse(Globals.prefs.getDefaultEncoding()), entries); // Read the file and put the contents on the clipboard: StringBuilder sb = new StringBuilder(); - try (Reader reader = new InputStreamReader(new FileInputStream(tmp), - panel.getBibDatabaseContext().getMetaData().getEncoding() + try (Reader reader = new InputStreamReader(Files.newInputStream(tmp, StandardOpenOption.DELETE_ON_CLOSE), + panel.getBibDatabaseContext() + .getMetaData() + .getEncoding() .orElse(Globals.prefs.getDefaultEncoding()))) { int s; while ((s = reader.read()) != -1) { @@ -107,7 +100,8 @@ public void run() { // Do nothing }; RtfTransferable rs = new RtfTransferable(sb.toString()); - Toolkit.getDefaultToolkit().getSystemClipboard() + Toolkit.getDefaultToolkit() + .getSystemClipboard() .setContents(rs, owner); message = Localization.lang("Entries exported to clipboard") + ": " + entries.size(); @@ -116,8 +110,12 @@ public void run() { message = Localization.lang("Error exporting to clipboard"); } finally { // Clean up: - if ((tmp != null) && !tmp.delete()) { - LOGGER.info("Cannot delete temporary clipboard file"); + if ((tmp != null) && Files.exists(tmp)) { + try { + Files.delete(tmp); + } catch (IOException e) { + LOGGER.info("Cannot delete temporary clipboard file", e); + } } } } diff --git a/src/main/java/org/jabref/logic/exporter/Exporter.java b/src/main/java/org/jabref/logic/exporter/Exporter.java index 781ca7ca353..96f18fa750b 100644 --- a/src/main/java/org/jabref/logic/exporter/Exporter.java +++ b/src/main/java/org/jabref/logic/exporter/Exporter.java @@ -10,9 +10,9 @@ public abstract class Exporter { - private String id; - private String displayName; - private FileType fileType; + private final String id; + private final String displayName; + private final FileType fileType; public Exporter(String id, String displayName, FileType fileType) { this.id = id; @@ -41,6 +41,11 @@ public FileType getFileType() { return fileType; } + @Override + public String toString() { + return displayName; + } + /** * Performs the export. * From dcbfcbc0766699e2aa4249330d4b3526bf39244a Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 21:51:23 +0100 Subject: [PATCH 25/28] Convert swing error dialog in save db action to custom fx dialog --- .../gui/exporter/SaveDatabaseAction.java | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java index 06efe18baa9..516317828ec 100644 --- a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java +++ b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java @@ -7,10 +7,14 @@ import java.util.Optional; import javax.swing.JOptionPane; -import javax.swing.JTextArea; import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonBar.ButtonData; import javafx.scene.control.ButtonType; +import javafx.scene.control.DialogPane; +import javafx.scene.control.TextArea; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; import org.jabref.Globals; import org.jabref.JabRefExecutorService; @@ -41,8 +45,6 @@ import org.jabref.model.entry.BibEntry; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -217,23 +219,25 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) // handle encoding problems boolean success = true; if (!session.getWriter().couldEncodeAll()) { - FormBuilder builder = FormBuilder.create() - .layout(new FormLayout("left:pref, 4dlu, fill:pref", "pref, 4dlu, pref")); - JTextArea ta = new JTextArea(session.getWriter().getProblemCharacters()); - ta.setEditable(false); - builder.add(Localization.lang("The chosen encoding '%0' could not encode the following characters:", - session.getEncoding().displayName())).xy(1, 1); - builder.add(ta).xy(3, 1); - builder.add(Localization.lang("What do you want to do?")).xy(1, 3); - String tryDiff = Localization.lang("Try different encoding"); - - //TODO: Old Swing panel - int answer = JOptionPane.showOptionDialog(null, builder.getPanel(), Localization.lang("Save library"), - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, - new String[] {Localization.lang("Save"), tryDiff, Localization.lang("Cancel")}, tryDiff); - - if (answer == JOptionPane.NO_OPTION) { - // The user wants to use another encoding. + + DialogPane pane = new DialogPane(); + TextArea area = new TextArea(session.getWriter().getProblemCharacters()); + VBox vbox = new VBox(); + vbox.getChildren().addAll( + new Text(Localization.lang("The chosen encoding '%0' could not encode the following characters:", + session.getEncoding().displayName())), + area, + new Text(Localization.lang("What do you want to do?")) + + ); + pane.setContent(vbox); + + ButtonType tryDiff = new ButtonType(Localization.lang("Try different encoding"), ButtonData.OTHER); + ButtonType save = new ButtonType(Localization.lang("Save"), ButtonData.APPLY); + + Optional clickedBtn = frame.getDialogService().showCustomDialogAndWait(Localization.lang("Save library"), pane, save, tryDiff, ButtonType.CANCEL); + + if (clickedBtn.isPresent() && clickedBtn.get().equals(tryDiff)) { Optional selectedCharSet = frame.getDialogService().showChoiceDialogAndWait(Localization.lang("Save library"), Localization.lang("Select encoding"), Localization.lang("Save library"), encoding, Encodings.getCharsets()); if (selectedCharSet.isPresent()) { From e7171d65bdda585e426dd4616d89fa80443c4548 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 22:06:00 +0100 Subject: [PATCH 26/28] replace open office install selection dialog with choice dialog Wrap error messages in fx executor (because abstract worker is swing thread) --- .../DetectOpenOfficeInstallation.java | 57 +++++++------------ .../gui/openoffice/OpenOfficePanel.java | 35 ++++++------ 2 files changed, 37 insertions(+), 55 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/DetectOpenOfficeInstallation.java b/src/main/java/org/jabref/gui/openoffice/DetectOpenOfficeInstallation.java index 0348b1a672e..6c462dfb7f3 100644 --- a/src/main/java/org/jabref/gui/openoffice/DetectOpenOfficeInstallation.java +++ b/src/main/java/org/jabref/gui/openoffice/DetectOpenOfficeInstallation.java @@ -1,23 +1,17 @@ package org.jabref.gui.openoffice; import java.awt.BorderLayout; -import java.io.File; import java.nio.file.Path; import java.util.List; import java.util.Optional; import javax.swing.BorderFactory; -import javax.swing.DefaultListModel; import javax.swing.JDialog; import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JOptionPane; import javax.swing.JProgressBar; -import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import org.jabref.gui.DialogService; -import org.jabref.gui.FXDialogService; import org.jabref.gui.desktop.JabRefDesktop; import org.jabref.gui.desktop.os.NativeDesktop; import org.jabref.gui.util.DefaultTaskExecutor; @@ -29,23 +23,22 @@ import org.jabref.logic.util.OS; import org.jabref.logic.util.io.FileUtil; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; - /** * Tools for automatically detecting OpenOffice or LibreOffice installations. */ public class DetectOpenOfficeInstallation extends AbstractWorker { private final OpenOfficePreferences preferences; - private final JDialog parent; + private final DialogService dialogService; + private boolean foundPaths; private JDialog progressDialog; - public DetectOpenOfficeInstallation(JDialog parent, OpenOfficePreferences preferences) { + public DetectOpenOfficeInstallation(JDialog parent, OpenOfficePreferences preferences, DialogService dialogService) { this.parent = parent; this.preferences = preferences; + this.dialogService = dialogService; } public boolean isInstalled() { @@ -76,16 +69,15 @@ public void update() { } private Optional selectInstallationPath() { + final NativeDesktop nativeDesktop = JabRefDesktop.getNativeDesktop(); - JOptionPane.showMessageDialog(parent, - Localization.lang("Unable to autodetect OpenOffice/LibreOffice installation. Please choose the installation directory manually."), - Localization.lang("Could not find OpenOffice/LibreOffice installation"), - JOptionPane.INFORMATION_MESSAGE); - DialogService ds = new FXDialogService(); + DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showInformationDialogAndWait(Localization.lang("Could not find OpenOffice/LibreOffice installation"), + Localization.lang("Unable to autodetect OpenOffice/LibreOffice installation. Please choose the installation directory manually."))); DirectoryDialogConfiguration dirDialogConfiguration = new DirectoryDialogConfiguration.Builder() - .withInitialDirectory(nativeDesktop.getApplicationDirectory()).build(); - Optional path = DefaultTaskExecutor.runInJavaFXThread(() -> ds.showDirectorySelectionDialog(dirDialogConfiguration)); + .withInitialDirectory(nativeDesktop.getApplicationDirectory()) + .build(); + Optional path = DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showDirectorySelectionDialog(dirDialogConfiguration)); if (path.isPresent()) { return path; @@ -141,26 +133,15 @@ private Optional chooseAmongInstallations(List installDirs) { if (installDirs.size() == 1) { return Optional.of(installDirs.get(0).toAbsolutePath()); } - // Otherwise more than one installation was found, select among them - DefaultListModel mod = new DefaultListModel<>(); - for (Path tmpfile : installDirs) { - mod.addElement(tmpfile.toFile()); - } - JList fileList = new JList<>(mod); - fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - fileList.setSelectedIndex(0); - FormBuilder builder = FormBuilder.create().layout(new FormLayout("pref:grow", "pref, 2dlu, pref, 4dlu, pref")); - builder.add(Localization.lang("Found more than one OpenOffice/LibreOffice executable.")).xy(1, 1); - builder.add(Localization.lang("Please choose which one to connect to:")).xy(1, 3); - builder.add(fileList).xy(1, 5); - - int answer = JOptionPane.showConfirmDialog(null, builder.getPanel(), - Localization.lang("Choose OpenOffice/LibreOffice executable"), JOptionPane.OK_CANCEL_OPTION); - if (answer == JOptionPane.CANCEL_OPTION) { - return Optional.empty(); - } else { - return Optional.of(fileList.getSelectedValue().toPath()); - } + + String content = Localization.lang("Found more than one OpenOffice/LibreOffice executable.") + + "\n" + Localization.lang("Please choose which one to connect to:"); + + Optional selectedPath = DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showChoiceDialogAndWait( + Localization.lang("Choose OpenOffice/LibreOffice executable"), + content, Localization.lang("Use selected instance"), null, installDirs)); + + return selectedPath; } public JDialog showProgressDialog(JDialog progressParent, String title, String message) { diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index 981d7bc8723..a015b6a6116 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -25,7 +25,6 @@ import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JMenuItem; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JRadioButtonMenuItem; @@ -359,7 +358,7 @@ private List getBaseList() { private void connect(boolean autoDetect) { if (autoDetect) { - DetectOpenOfficeInstallation officeInstallation = new DetectOpenOfficeInstallation(diag, preferences); + DetectOpenOfficeInstallation officeInstallation = new DetectOpenOfficeInstallation(diag, preferences, frame.getDialogService()); if (!officeInstallation.isInstalled()) { frame.getDialogService().showErrorDialogAndWait(Localization.lang("Autodetection failed"), Localization.lang("Autodetection failed")); @@ -380,7 +379,7 @@ private void connect(boolean autoDetect) { loadOpenOfficeJars(Paths.get(preferences.getInstallationPath())); // Show progress dialog: - progressDialog = new DetectOpenOfficeInstallation(diag, preferences) + progressDialog = new DetectOpenOfficeInstallation(diag, preferences, frame.getDialogService()) .showProgressDialog(diag, Localization.lang("Connecting"), Localization.lang("Please wait...")); getWorker().run(); // Do the actual connection, using Spin to get off the EDT. progressDialog.dispose(); @@ -556,10 +555,11 @@ private void showManualConnectionDialog() { private void pushEntries(boolean inParenthesisIn, boolean withText, boolean addPageInfo) { if (!ooBase.isConnectedToDocument()) { - JOptionPane.showMessageDialog(null, - Localization.lang("Not connected to any Writer document. Please" - + " make sure a document is open, and use the 'Select Writer document' button to connect to it."), - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); + + DefaultTaskExecutor.runInJavaFXThread(() -> frame.getDialogService().showErrorDialogAndWait( + Localization.lang("Error pushing entries"), Localization.lang("Not connected to any Writer document. Please" + + " make sure a document is open, and use the 'Select Writer document' button to connect to it."))); + return; } @@ -591,10 +591,11 @@ private void pushEntries(boolean inParenthesisIn, boolean withText, boolean addP ooBase.insertEntry(entries, database, getBaseList(), style, inParenthesis, withText, pageInfo, preferences.syncWhenCiting()); } catch (FileNotFoundException ex) { - JOptionPane.showMessageDialog(null, - Localization - .lang("You must select either a valid style file, or use one of the default styles."), - Localization.lang("No valid style file defined"), JOptionPane.ERROR_MESSAGE); + + DefaultTaskExecutor.runInJavaFXThread(() -> frame.getDialogService().showErrorDialogAndWait( + Localization.lang("No valid style file defined"), + Localization.lang("You must select either a valid style file, or use one of the default styles."))); + LOGGER.warn("Problem with style file", ex); } catch (ConnectionLostException ex) { showConnectionLostErrorMessage(); @@ -667,24 +668,24 @@ private boolean checkThatEntriesHaveKeys(List entries) { } private void showConnectionLostErrorMessage() { - frame.getDialogService().showErrorDialogAndWait(Localization.lang("Connection lost"), + DefaultTaskExecutor.runInJavaFXThread(() -> frame.getDialogService().showErrorDialogAndWait(Localization.lang("Connection lost"), Localization.lang("Connection to OpenOffice/LibreOffice has been lost. " - + "Please make sure OpenOffice/LibreOffice is running, and try to reconnect.")); + + "Please make sure OpenOffice/LibreOffice is running, and try to reconnect."))); } private void reportUndefinedParagraphFormat(UndefinedParagraphFormatException ex) { - frame.getDialogService().showErrorDialogAndWait(Localization.lang("Undefined paragraph format"), + DefaultTaskExecutor.runInJavaFXThread(() -> frame.getDialogService().showErrorDialogAndWait(Localization.lang("Undefined paragraph format"), Localization.lang("Your style file specifies the paragraph format '%0', " + "which is undefined in your current OpenOffice/LibreOffice document.", ex.getFormatName()) + "\n" + - Localization.lang("The paragraph format is controlled by the property 'ReferenceParagraphFormat' or 'ReferenceHeaderParagraphFormat' in the style file.")); + Localization.lang("The paragraph format is controlled by the property 'ReferenceParagraphFormat' or 'ReferenceHeaderParagraphFormat' in the style file."))); } private void reportUndefinedCharacterFormat(UndefinedCharacterFormatException ex) { - frame.getDialogService().showErrorDialogAndWait(Localization.lang("Undefined character format"), + DefaultTaskExecutor.runInJavaFXThread(() -> frame.getDialogService().showErrorDialogAndWait(Localization.lang("Undefined character format"), Localization.lang( "Your style file specifies the character format '%0', " + "which is undefined in your current OpenOffice/LibreOffice document.", @@ -692,7 +693,7 @@ private void reportUndefinedCharacterFormat(UndefinedCharacterFormatException ex + "\n" + Localization.lang("The character format is controlled by the citation property 'CitationCharacterFormat' in the style file.") - ); + )); } private void showSettingsPopup() { From bead86ac84493517e0d09aabd65004297093487c Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 7 Mar 2018 23:07:23 +0100 Subject: [PATCH 27/28] adjust line wrapping on column --- .../gui/exporter/ExportToClipboardAction.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java index 2e74c1b5031..2144d73a5fb 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java +++ b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java @@ -54,7 +54,7 @@ public void run() { List exporters = new ArrayList<>(Globals.exportFactory.getExporters()); Optional selectedExporter = frame.getDialogService().showChoiceDialogAndWait(Localization.lang("Export"), Localization.lang("Select export format"), - Localization.lang("Export"), null, exporters); + Localization.lang("Export"), null, exporters); if (!selectedExporter.isPresent()) { return; @@ -66,8 +66,8 @@ public void run() { // so formatters can resolve linked files correctly. // (This is an ugly hack!) Globals.prefs.fileDirForDatabase = frame.getCurrentBasePanel() - .getBibDatabaseContext() - .getFileDirectories(Globals.prefs.getFileDirectoryPreferences()); + .getBibDatabaseContext() + .getFileDirectories(Globals.prefs.getFileDirectoryPreferences()); Path tmp = null; try { @@ -79,18 +79,18 @@ public void run() { // Write to file: exporter.export(panel.getBibDatabaseContext(), tmp, - panel.getBibDatabaseContext() - .getMetaData() - .getEncoding() - .orElse(Globals.prefs.getDefaultEncoding()), - entries); + panel.getBibDatabaseContext() + .getMetaData() + .getEncoding() + .orElse(Globals.prefs.getDefaultEncoding()), + entries); // Read the file and put the contents on the clipboard: StringBuilder sb = new StringBuilder(); try (Reader reader = new InputStreamReader(Files.newInputStream(tmp, StandardOpenOption.DELETE_ON_CLOSE), - panel.getBibDatabaseContext() - .getMetaData() - .getEncoding() - .orElse(Globals.prefs.getDefaultEncoding()))) { + panel.getBibDatabaseContext() + .getMetaData() + .getEncoding() + .orElse(Globals.prefs.getDefaultEncoding()))) { int s; while ((s = reader.read()) != -1) { sb.append((char) s); @@ -101,8 +101,8 @@ public void run() { }; RtfTransferable rs = new RtfTransferable(sb.toString()); Toolkit.getDefaultToolkit() - .getSystemClipboard() - .setContents(rs, owner); + .getSystemClipboard() + .setContents(rs, owner); message = Localization.lang("Entries exported to clipboard") + ": " + entries.size(); } catch (Exception e) { From 13f59f00572d780f15138367746437a74b6705c0 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 9 Mar 2018 10:49:57 +0100 Subject: [PATCH 28/28] Fixes #3796: Pretend that we have every translation for every key (#3820) --- src/main/java/org/jabref/logic/l10n/Localization.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/logic/l10n/Localization.java b/src/main/java/org/jabref/logic/l10n/Localization.java index ae975c7fb09..0d5c647856e 100644 --- a/src/main/java/org/jabref/logic/l10n/Localization.java +++ b/src/main/java/org/jabref/logic/l10n/Localization.java @@ -214,9 +214,11 @@ private static class LocalizationBundle extends ResourceBundle { lookup = lookupMap; } + @Override public final Object handleGetObject(String key) { Objects.requireNonNull(key); - return lookup.get(key); + return Optional.ofNullable(lookup.get(key)) + .orElse(key); } @Override @@ -231,7 +233,8 @@ protected Set handleKeySet() { @Override public boolean containsKey(String key) { - return (key != null) && lookup.containsKey(key); + // Pretend we have every key + return true; } } }