From b2971edc506d022e7cfac9577ef65e87449fd6e1 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Thu, 18 Apr 2019 20:43:07 +0200 Subject: [PATCH 01/24] convert search worker to javafx --- .../jabref/gui/search/GlobalSearchBar.java | 2 +- .../org/jabref/gui/search/SearchWorker.java | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 8426b3fb290..27f5d1d9c4a 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -219,7 +219,7 @@ public void performSearch() { // TODO: Remove search worker as this is doing the work twice now searchWorker = new SearchWorker(currentBasePanel, searchQuery, searchDisplayMode); - searchWorker.execute(); + Globals.TASK_EXECUTOR.execute(searchWorker); } private void informUserAboutInvalidSearchQuery() { diff --git a/src/main/java/org/jabref/gui/search/SearchWorker.java b/src/main/java/org/jabref/gui/search/SearchWorker.java index 816a17185e1..5a49ac889a9 100644 --- a/src/main/java/org/jabref/gui/search/SearchWorker.java +++ b/src/main/java/org/jabref/gui/search/SearchWorker.java @@ -5,12 +5,11 @@ import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; -import javax.swing.SwingWorker; +import javafx.concurrent.Task; import org.jabref.JabRefGUI; import org.jabref.gui.BasePanel; import org.jabref.gui.search.rules.describer.SearchDescribers; -import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.search.SearchQuery; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; @@ -18,11 +17,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * Not reusable. Always create a new instance for each search! */ -class SearchWorker extends SwingWorker, Void> { +class SearchWorker extends Task> { private static final Logger LOGGER = LoggerFactory.getLogger(SearchWorker.class); @@ -41,10 +39,10 @@ public SearchWorker(BasePanel basePanel, SearchQuery searchQuery, SearchDisplayM } @Override - protected List doInBackground() throws Exception { + protected List call() throws Exception { return database.getEntries().parallelStream() - .filter(searchQuery::isMatch) - .collect(Collectors.toList()); + .filter(searchQuery::isMatch) + .collect(Collectors.toList()); } @Override @@ -52,7 +50,11 @@ protected void done() { if (isCancelled()) { return; } + } + @Override + protected void succeeded() { + super.succeeded(); try { updateUIWithSearchResult(get()); } catch (InterruptedException | ExecutionException e) { @@ -63,10 +65,9 @@ protected void done() { private void updateUIWithSearchResult(List matchedEntries) { GlobalSearchBar globalSearchBar = JabRefGUI.getMainFrame().getGlobalSearchBar(); - DefaultTaskExecutor.runInJavaFXThread(() -> - globalSearchBar.updateResults(matchedEntries.size(), - SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), - searchQuery.isGrammarBasedSearch())); + globalSearchBar.updateResults(matchedEntries.size(), + SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), + searchQuery.isGrammarBasedSearch()); globalSearchBar.getSearchQueryHighlightObservable().fireSearchlistenerEvent(searchQuery); } From 2bb96e2fde748326e32bb9312a158df3734cbfc5 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 20 Apr 2019 10:31:26 +0200 Subject: [PATCH 02/24] remove obsolete search worker --- .../jabref/gui/search/GlobalSearchBar.java | 12 --- .../org/jabref/gui/search/SearchWorker.java | 74 ------------------- 2 files changed, 86 deletions(-) delete mode 100644 src/main/java/org/jabref/gui/search/SearchWorker.java diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 27f5d1d9c4a..a90b8cdc979 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -73,8 +73,6 @@ public class GlobalSearchBar extends HBox { private final Button searchModeButton = new Button(); private final Label currentResults = new Label(""); private final SearchQueryHighlightObservable searchQueryHighlightObservable = new SearchQueryHighlightObservable(); - private SearchWorker searchWorker; - private SearchDisplayMode searchDisplayMode; public GlobalSearchBar(JabRefFrame frame) { @@ -171,7 +169,6 @@ public void endSearch() { clearSearch(); MainTable mainTable = frame.getCurrentBasePanel().getMainTable(); mainTable.requestFocus(); - //SwingUtilities.invokeLater(() -> mainTable.ensureVisible(mainTable.getSelectedRow())); } } @@ -198,11 +195,6 @@ public void performSearch() { if (currentBasePanel == null) { return; } - - if (searchWorker != null) { - searchWorker.cancel(true); - } - // An empty search field should cause the search to be cleared. if (searchField.getText().isEmpty()) { clearSearch(); @@ -216,10 +208,6 @@ public void performSearch() { } Globals.stateManager.setSearchQuery(searchQuery); - - // TODO: Remove search worker as this is doing the work twice now - searchWorker = new SearchWorker(currentBasePanel, searchQuery, searchDisplayMode); - Globals.TASK_EXECUTOR.execute(searchWorker); } private void informUserAboutInvalidSearchQuery() { diff --git a/src/main/java/org/jabref/gui/search/SearchWorker.java b/src/main/java/org/jabref/gui/search/SearchWorker.java deleted file mode 100644 index 5a49ac889a9..00000000000 --- a/src/main/java/org/jabref/gui/search/SearchWorker.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.jabref.gui.search; - -import java.util.List; -import java.util.Objects; -import java.util.concurrent.ExecutionException; -import java.util.stream.Collectors; - -import javafx.concurrent.Task; - -import org.jabref.JabRefGUI; -import org.jabref.gui.BasePanel; -import org.jabref.gui.search.rules.describer.SearchDescribers; -import org.jabref.logic.search.SearchQuery; -import org.jabref.model.database.BibDatabase; -import org.jabref.model.entry.BibEntry; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Not reusable. Always create a new instance for each search! - */ -class SearchWorker extends Task> { - - private static final Logger LOGGER = LoggerFactory.getLogger(SearchWorker.class); - - private final BasePanel basePanel; - private final BibDatabase database; - - private final SearchQuery searchQuery; - private final SearchDisplayMode searchDisplayMode; - - public SearchWorker(BasePanel basePanel, SearchQuery searchQuery, SearchDisplayMode searchDisplayMode) { - this.basePanel = Objects.requireNonNull(basePanel); - this.database = Objects.requireNonNull(basePanel.getDatabase()); - this.searchQuery = Objects.requireNonNull(searchQuery); - this.searchDisplayMode = Objects.requireNonNull(searchDisplayMode); - LOGGER.debug("Search (" + this.searchDisplayMode.getDisplayName() + "): " + this.searchQuery); - } - - @Override - protected List call() throws Exception { - return database.getEntries().parallelStream() - .filter(searchQuery::isMatch) - .collect(Collectors.toList()); - } - - @Override - protected void done() { - if (isCancelled()) { - return; - } - } - - @Override - protected void succeeded() { - super.succeeded(); - try { - updateUIWithSearchResult(get()); - } catch (InterruptedException | ExecutionException e) { - LOGGER.error("something went wrong during the search", e); - } - } - - private void updateUIWithSearchResult(List matchedEntries) { - GlobalSearchBar globalSearchBar = JabRefGUI.getMainFrame().getGlobalSearchBar(); - - globalSearchBar.updateResults(matchedEntries.size(), - SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), - searchQuery.isGrammarBasedSearch()); - globalSearchBar.getSearchQueryHighlightObservable().fireSearchlistenerEvent(searchQuery); - } - -} From b374c0e450227f1aaf680b20e54d515004a8924f Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 24 Apr 2019 21:59:53 +0200 Subject: [PATCH 03/24] Add search query update result count --- src/main/java/org/jabref/gui/StateManager.java | 13 ++++++++++++- .../jabref/gui/maintable/MainTableDataModel.java | 5 +++++ .../java/org/jabref/gui/search/GlobalSearchBar.java | 7 +++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/StateManager.java b/src/main/java/org/jabref/gui/StateManager.java index 630d5511eb9..00e9eb18536 100644 --- a/src/main/java/org/jabref/gui/StateManager.java +++ b/src/main/java/org/jabref/gui/StateManager.java @@ -6,8 +6,10 @@ import java.util.stream.Collectors; import javafx.beans.binding.Bindings; +import javafx.beans.property.IntegerProperty; import javafx.beans.property.ReadOnlyListProperty; import javafx.beans.property.ReadOnlyListWrapper; +import javafx.beans.property.SimpleIntegerProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.ObservableMap; @@ -34,6 +36,7 @@ public class StateManager { private final ObservableList selectedEntries = FXCollections.observableArrayList(); private final ObservableMap> selectedGroups = FXCollections.observableHashMap(); private final OptionalObjectProperty activeSearchQuery = OptionalObjectProperty.empty(); + private final IntegerProperty searchResultSize = new SimpleIntegerProperty(); public StateManager() { activeGroups.bind(Bindings.valueAt(selectedGroups, activeDatabase.orElse(null))); @@ -79,7 +82,7 @@ public Optional getActiveDatabase() { public List getEntriesInCurrentDatabase() { return OptionalUtil.flatMap(activeDatabase.get(), BibDatabaseContext::getEntries) - .collect(Collectors.toList()); + .collect(Collectors.toList()); } public void clearSearchQuery() { @@ -89,4 +92,12 @@ public void clearSearchQuery() { public void setSearchQuery(SearchQuery searchQuery) { activeSearchQuery.setValue(Optional.of(searchQuery)); } + + public IntegerProperty searchResultSizeProperty() { + return searchResultSize; + } + + public void setSearchResultSize(int size) { + searchResultSize.setValue(size); + } } diff --git a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java index 57d0f4439f1..029ef622818 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java @@ -4,6 +4,7 @@ import java.util.Optional; import javafx.beans.binding.Bindings; +import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; import javafx.collections.transformation.SortedList; @@ -30,7 +31,11 @@ public MainTableDataModel(BibDatabaseContext context) { entriesFiltered.predicateProperty().bind( Bindings.createObjectBinding(() -> this::isMatched, Globals.stateManager.activeGroupProperty(), Globals.stateManager.activeSearchQueryProperty()) + ); + entriesFiltered.addListener((ListChangeListener) c -> { + Globals.stateManager.setSearchResultSize(entriesFiltered.size()); + }); // We need to wrap the list since otherwise sorting in the table does not work entriesSorted = new SortedList<>(entriesFiltered); diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index a90b8cdc979..898cc2010b6 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -42,6 +42,7 @@ import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.keyboard.KeyBindingRepository; import org.jabref.gui.maintable.MainTable; +import org.jabref.gui.search.rules.describer.SearchDescribers; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.l10n.Localization; import org.jabref.logic.search.SearchQuery; @@ -208,6 +209,12 @@ public void performSearch() { } Globals.stateManager.setSearchQuery(searchQuery); + + updateResults(Globals.stateManager.searchResultSizeProperty().get(), + SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), + searchQuery.isGrammarBasedSearch()); + getSearchQueryHighlightObservable().fireSearchlistenerEvent(searchQuery); + } private void informUserAboutInvalidSearchQuery() { From 907670e7a9a366a0d5977525090de1675bca4a7b Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 1 May 2019 15:48:48 +0200 Subject: [PATCH 04/24] First attempt at creating search highlighter for source tab --- .../jabref/gui/entryeditor/EntryEditor.css | 3 +++ .../jabref/gui/entryeditor/EntryEditor.java | 2 ++ .../org/jabref/gui/entryeditor/SourceTab.java | 26 ++++++++++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css index 313583ed222..d7a6a9420a7 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css @@ -87,5 +87,8 @@ .related-articles-tab { -fx-padding: 20 20 20 20; } +.red { + -fx-text-fill: red; +} diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index a85e7909357..e2c9aecb80f 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -297,6 +297,7 @@ private List createTabs() { // Source tab sourceTab = new SourceTab(databaseContext, undoManager, preferences.getLatexFieldFormatterPreferences(), preferences.getImportFormatPreferences(), fileMonitor, dialogService); + addSearchListener(sourceTab); tabs.add(sourceTab); return tabs; } @@ -403,6 +404,7 @@ private void fetchAndMerge(EntryBasedFetcher fetcher) { void addSearchListener(SearchQueryHighlightListener listener) { // TODO: Highlight search text in entry editors searchListeners.add(listener); + panel.frame().getGlobalSearchBar().getSearchQueryHighlightObservable().addSearchListener(listener); } diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index 2752103316d..acc9085c63b 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -3,8 +3,12 @@ import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; +import java.util.Collections; import java.util.Map; import java.util.Objects; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.swing.undo.UndoManager; @@ -31,6 +35,7 @@ import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.fileformat.BibtexParser; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.search.SearchQueryHighlightListener; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.database.BibDatabaseMode; @@ -46,7 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class SourceTab extends EntryEditorTab { +public class SourceTab extends EntryEditorTab implements SearchQueryHighlightListener { private static final Logger LOGGER = LoggerFactory.getLogger(SourceTab.class); private final LatexFieldFormatterPreferences fieldFormatterPreferences; @@ -57,6 +62,7 @@ public class SourceTab extends EntryEditorTab { private final ImportFormatPreferences importFormatPreferences; private final FileUpdateMonitor fileMonitor; private final DialogService dialogService; + private CodeArea codeArea; public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager, LatexFieldFormatterPreferences fieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor, DialogService dialogService) { this.mode = bibDatabaseContext.getMode(); @@ -140,6 +146,7 @@ protected void bindToEntry(BibEntry entry) { } }); this.setContent(codeArea); + this.codeArea = codeArea; // Store source for on focus out event in the source code (within its text area) // and update source code for every change of entry field values @@ -155,7 +162,7 @@ protected void bindToEntry(BibEntry entry) { } catch (IOException ex) { codeArea.setEditable(false); codeArea.appendText(ex.getMessage() + "\n\n" + - Localization.lang("Correct the entry, and reopen editor to display/edit source.")); + Localization.lang("Correct the entry, and reopen editor to display/edit source.")); LOGGER.debug("Incorrect entry", ex); } }); @@ -222,7 +229,7 @@ private void storeSource(BibEntry outOfFocusEntry, String text) { if (!Objects.equals(oldValue, newValue)) { // Test if the field is legally set. new LatexFieldFormatter(fieldFormatterPreferences) - .format(newValue, fieldName); + .format(newValue, fieldName); compound.addEdit(new UndoableFieldChange(outOfFocusEntry, fieldName, oldValue, newValue)); outOfFocusEntry.setField(fieldName, newValue); @@ -243,4 +250,17 @@ private void storeSource(BibEntry outOfFocusEntry, String text) { LOGGER.debug("Incorrect source", ex); } } + + @Override + public void highlightPattern(Optional highlightPattern) { + if (highlightPattern.isPresent()) { + Matcher matcher = highlightPattern.get().matcher(codeArea.getText()); + while (matcher.find()) { + for (int i = 0; i <= matcher.groupCount(); i++) { + //TODO: Styling doesn't work + codeArea.setStyle(matcher.start(), matcher.end(), Collections.singletonList("-fx-text-fill: red;")); + } + } + } + } } From 45020d2bfbf56de3ecb70325f61abf2a0b21d507 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 1 May 2019 20:56:43 +0200 Subject: [PATCH 05/24] Add custom css for codeArea highlighting on Search --- .../jabref/gui/entryeditor/BibtexSourceCodeArea.css | 7 +++++++ .../java/org/jabref/gui/entryeditor/EntryEditor.css | 5 ----- .../java/org/jabref/gui/entryeditor/SourceTab.java | 13 ++++++------- 3 files changed, 13 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css diff --git a/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css b/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css new file mode 100644 index 00000000000..4d4ac561359 --- /dev/null +++ b/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css @@ -0,0 +1,7 @@ +#bibtexSourceCodeArea .text { + -fx-fill: -fx-background-color; +} + +#bibtexSourceCodeArea .search { + -fx-fill: red; +} \ No newline at end of file diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css index d7a6a9420a7..7755b210944 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css @@ -87,8 +87,3 @@ .related-articles-tab { -fx-padding: 20 20 20 20; } -.red { - -fx-text-fill: red; -} - - diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index acc9085c63b..2844413cc41 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; -import java.util.Collections; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -121,6 +120,9 @@ private CodeArea createSourceEditor() { codeArea.insertText(codeArea.getCaretPosition(), committed); } }); + codeArea.setId("bibtexSourceCodeArea"); + codeArea.getStylesheets().add(SourceTab.class.getResource("BibtexSourceCodeArea.css").toExternalForm()); + return codeArea; } @@ -215,8 +217,7 @@ private void storeSource(BibEntry outOfFocusEntry, String text) { String fieldValue = field.getValue(); if (InternalBibtexFields.isDisplayableField(fieldName) && !newEntry.hasField(fieldName)) { - compound.addEdit( - new UndoableFieldChange(outOfFocusEntry, fieldName, fieldValue, null)); + compound.addEdit(new UndoableFieldChange(outOfFocusEntry, fieldName, fieldValue, null)); outOfFocusEntry.clearField(fieldName); } } @@ -228,8 +229,7 @@ private void storeSource(BibEntry outOfFocusEntry, String text) { String newValue = field.getValue(); if (!Objects.equals(oldValue, newValue)) { // Test if the field is legally set. - new LatexFieldFormatter(fieldFormatterPreferences) - .format(newValue, fieldName); + new LatexFieldFormatter(fieldFormatterPreferences).format(newValue, fieldName); compound.addEdit(new UndoableFieldChange(outOfFocusEntry, fieldName, oldValue, newValue)); outOfFocusEntry.setField(fieldName, newValue); @@ -257,8 +257,7 @@ public void highlightPattern(Optional highlightPattern) { Matcher matcher = highlightPattern.get().matcher(codeArea.getText()); while (matcher.find()) { for (int i = 0; i <= matcher.groupCount(); i++) { - //TODO: Styling doesn't work - codeArea.setStyle(matcher.start(), matcher.end(), Collections.singletonList("-fx-text-fill: red;")); + codeArea.setStyleClass(matcher.start(), matcher.end(), "search"); } } } From 7b01b92e8665e5190c93c4e0d68e4e50fd26ba7a Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 1 May 2019 20:59:34 +0200 Subject: [PATCH 06/24] fix exception loop --- .../java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css b/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css index 4d4ac561359..8829b17cb5a 100644 --- a/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css +++ b/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css @@ -1,7 +1,3 @@ -#bibtexSourceCodeArea .text { - -fx-fill: -fx-background-color; -} - #bibtexSourceCodeArea .search { -fx-fill: red; } \ No newline at end of file From a4465c27a4fc0360cfc25d66e211314638ef6e68 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Thu, 2 May 2019 16:34:52 +0200 Subject: [PATCH 07/24] inline search listener --- .../jabref/gui/entryeditor/EntryEditor.java | 2 -- .../org/jabref/gui/entryeditor/SourceTab.java | 30 ++++++++----------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index e2c9aecb80f..d1b3f9a2876 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -297,7 +297,6 @@ private List createTabs() { // Source tab sourceTab = new SourceTab(databaseContext, undoManager, preferences.getLatexFieldFormatterPreferences(), preferences.getImportFormatPreferences(), fileMonitor, dialogService); - addSearchListener(sourceTab); tabs.add(sourceTab); return tabs; } @@ -405,7 +404,6 @@ void addSearchListener(SearchQueryHighlightListener listener) { // TODO: Highlight search text in entry editors searchListeners.add(listener); - panel.frame().getGlobalSearchBar().getSearchQueryHighlightObservable().addSearchListener(listener); } public void setFocusToField(String fieldName) { diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index 2844413cc41..e490b0c5a60 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -5,9 +5,7 @@ import java.io.StringWriter; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.swing.undo.UndoManager; @@ -18,6 +16,7 @@ import javafx.scene.control.Tooltip; import javafx.scene.input.InputMethodRequests; +import org.jabref.JabRefGUI; import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.undo.CountingUndoManager; @@ -34,7 +33,6 @@ import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.fileformat.BibtexParser; import org.jabref.logic.l10n.Localization; -import org.jabref.logic.search.SearchQueryHighlightListener; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.database.BibDatabaseMode; @@ -50,7 +48,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class SourceTab extends EntryEditorTab implements SearchQueryHighlightListener { +public class SourceTab extends EntryEditorTab { private static final Logger LOGGER = LoggerFactory.getLogger(SourceTab.class); private final LatexFieldFormatterPreferences fieldFormatterPreferences; @@ -61,7 +59,6 @@ public class SourceTab extends EntryEditorTab implements SearchQueryHighlightLis private final ImportFormatPreferences importFormatPreferences; private final FileUpdateMonitor fileMonitor; private final DialogService dialogService; - private CodeArea codeArea; public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager, LatexFieldFormatterPreferences fieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor, DialogService dialogService) { this.mode = bibDatabaseContext.getMode(); @@ -148,7 +145,17 @@ protected void bindToEntry(BibEntry entry) { } }); this.setContent(codeArea); - this.codeArea = codeArea; + + JabRefGUI.getMainFrame().getGlobalSearchBar().getSearchQueryHighlightObservable().addSearchListener(highlightPattern -> { + if (highlightPattern.isPresent()) { + Matcher matcher = highlightPattern.get().matcher(codeArea.getText()); + while (matcher.find()) { + for (int i = 0; i <= matcher.groupCount(); i++) { + codeArea.setStyleClass(matcher.start(), matcher.end(), "search"); + } + } + } + }); // Store source for on focus out event in the source code (within its text area) // and update source code for every change of entry field values @@ -251,15 +258,4 @@ private void storeSource(BibEntry outOfFocusEntry, String text) { } } - @Override - public void highlightPattern(Optional highlightPattern) { - if (highlightPattern.isPresent()) { - Matcher matcher = highlightPattern.get().matcher(codeArea.getText()); - while (matcher.find()) { - for (int i = 0; i <= matcher.groupCount(); i++) { - codeArea.setStyleClass(matcher.start(), matcher.end(), "search"); - } - } - } - } } From 79e77c5b8578513bc32e948e9eb381920e464616 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Fri, 3 May 2019 11:57:23 +0200 Subject: [PATCH 08/24] refactor searchQueryHighlightobservable --- src/main/java/org/jabref/gui/BasePanel.java | 1 - .../java/org/jabref/gui/StateManager.java | 20 +++++++++++++++++++ .../org/jabref/gui/entryeditor/SourceTab.java | 4 ++-- .../jabref/gui/search/GlobalSearchBar.java | 8 ++------ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 055eaba332f..189938c871b 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -189,7 +189,6 @@ public BasePanel(JabRefFrame frame, BasePanelPreferences preferences, BibDatabas this.entryEditor = new EntryEditor(this, preferences.getEntryEditorPreferences(), Globals.getFileUpdateMonitor(), dialogService, externalFileTypes, Globals.TASK_EXECUTOR); this.preview = new PreviewPanel(this, getBibDatabaseContext(), preferences.getKeyBindings(), preferences.getPreviewPreferences(), dialogService, externalFileTypes); - frame().getGlobalSearchBar().getSearchQueryHighlightObservable().addSearchListener(preview); } @Subscribe diff --git a/src/main/java/org/jabref/gui/StateManager.java b/src/main/java/org/jabref/gui/StateManager.java index 00e9eb18536..c1b081eded4 100644 --- a/src/main/java/org/jabref/gui/StateManager.java +++ b/src/main/java/org/jabref/gui/StateManager.java @@ -16,6 +16,8 @@ import org.jabref.gui.util.OptionalObjectProperty; import org.jabref.logic.search.SearchQuery; +import org.jabref.logic.search.SearchQueryHighlightListener; +import org.jabref.logic.search.SearchQueryHighlightObservable; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.groups.GroupTreeNode; @@ -37,6 +39,7 @@ public class StateManager { private final ObservableMap> selectedGroups = FXCollections.observableHashMap(); private final OptionalObjectProperty activeSearchQuery = OptionalObjectProperty.empty(); private final IntegerProperty searchResultSize = new SimpleIntegerProperty(); + private final SearchQueryHighlightObservable searchQueryHighlightObservable = new SearchQueryHighlightObservable(); public StateManager() { activeGroups.bind(Bindings.valueAt(selectedGroups, activeDatabase.orElse(null))); @@ -100,4 +103,21 @@ public IntegerProperty searchResultSizeProperty() { public void setSearchResultSize(int size) { searchResultSize.setValue(size); } + + public SearchQueryHighlightObservable getSearchQueryHighlightObservable() { + return searchQueryHighlightObservable; + } + + public void fireSearchQueryHighlightEvent(SearchQuery searchQuery) { + searchQueryHighlightObservable.fireSearchlistenerEvent(searchQuery); + } + + public void resetSearchQueryHighlightObservable() + { + searchQueryHighlightObservable.reset(); + } + + public void addSearchQueryHighlightListener(SearchQueryHighlightListener listener) { + searchQueryHighlightObservable.addSearchListener(listener); + } } diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index e490b0c5a60..3724ab4fd21 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -16,7 +16,7 @@ import javafx.scene.control.Tooltip; import javafx.scene.input.InputMethodRequests; -import org.jabref.JabRefGUI; +import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.undo.CountingUndoManager; @@ -146,7 +146,7 @@ protected void bindToEntry(BibEntry entry) { }); this.setContent(codeArea); - JabRefGUI.getMainFrame().getGlobalSearchBar().getSearchQueryHighlightObservable().addSearchListener(highlightPattern -> { + Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { if (highlightPattern.isPresent()) { Matcher matcher = highlightPattern.get().matcher(codeArea.getText()); while (matcher.find()) { diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 898cc2010b6..a9fc6ff6922 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -186,8 +186,7 @@ public void focus() { private void clearSearch() { currentResults.setText(""); searchField.setText(""); - searchQueryHighlightObservable.reset(); - + Globals.stateManager.resetSearchQueryHighlightObservable(); Globals.stateManager.clearSearchQuery(); } @@ -213,7 +212,7 @@ public void performSearch() { updateResults(Globals.stateManager.searchResultSizeProperty().get(), SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), searchQuery.isGrammarBasedSearch()); - getSearchQueryHighlightObservable().fireSearchlistenerEvent(searchQuery); + Globals.stateManager.fireSearchQueryHighlightEvent(searchQuery); } @@ -254,9 +253,6 @@ private AutoCompletePopup getPopup(AutoCompletionBinding autoCompletio } } - public SearchQueryHighlightObservable getSearchQueryHighlightObservable() { - return searchQueryHighlightObservable; - } private SearchQuery getSearchQuery() { SearchQuery searchQuery = new SearchQuery(this.searchField.getText(), this.caseSensitive.isSelected(), this.regularExp.isSelected()); From 11ac5ab3cc3585c63a5cf09ed980e137dfab180e Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Fri, 3 May 2019 12:06:42 +0200 Subject: [PATCH 09/24] fix checkstyle --- src/main/java/org/jabref/gui/search/GlobalSearchBar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index a9fc6ff6922..f5adc6011ca 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -253,7 +253,6 @@ private AutoCompletePopup getPopup(AutoCompletionBinding autoCompletio } } - private SearchQuery getSearchQuery() { SearchQuery searchQuery = new SearchQuery(this.searchField.getText(), this.caseSensitive.isSelected(), this.regularExp.isSelected()); this.frame.getCurrentBasePanel().setCurrentSearchQuery(searchQuery); @@ -357,6 +356,7 @@ public AutoCompletePopup getSkinnable() { @Override public void dispose() { + //empty } } } From 26145236669d36fdfc6c66325db4baab337ddbfd Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Fri, 3 May 2019 13:31:50 +0200 Subject: [PATCH 10/24] fireSearchQueryHighlitghter on focus change --- src/main/java/org/jabref/gui/StateManager.java | 6 ++++-- src/main/java/org/jabref/gui/entryeditor/SourceTab.java | 2 ++ src/main/java/org/jabref/gui/search/GlobalSearchBar.java | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/StateManager.java b/src/main/java/org/jabref/gui/StateManager.java index c1b081eded4..141c0e247d9 100644 --- a/src/main/java/org/jabref/gui/StateManager.java +++ b/src/main/java/org/jabref/gui/StateManager.java @@ -108,8 +108,10 @@ public SearchQueryHighlightObservable getSearchQueryHighlightObservable() { return searchQueryHighlightObservable; } - public void fireSearchQueryHighlightEvent(SearchQuery searchQuery) { - searchQueryHighlightObservable.fireSearchlistenerEvent(searchQuery); + public void fireSearchQueryHighlightEvent() { + if (activeSearchQuery.get().isPresent()) { + searchQueryHighlightObservable.fireSearchlistenerEvent(activeSearchQuery.getValue().get()); + } } public void resetSearchQueryHighlightObservable() diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index 3724ab4fd21..fbe49fa4942 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -168,6 +168,8 @@ protected void bindToEntry(BibEntry entry) { codeArea.clear(); try { codeArea.appendText(getSourceString(entry, mode, fieldFormatterPreferences)); + Globals.stateManager.fireSearchQueryHighlightEvent(); + } catch (IOException ex) { codeArea.setEditable(false); codeArea.appendText(ex.getMessage() + "\n\n" + diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index f5adc6011ca..cdd04c7e1da 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -212,7 +212,7 @@ public void performSearch() { updateResults(Globals.stateManager.searchResultSizeProperty().get(), SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), searchQuery.isGrammarBasedSearch()); - Globals.stateManager.fireSearchQueryHighlightEvent(searchQuery); + Globals.stateManager.fireSearchQueryHighlightEvent(); } From 75b089c9ca9b5f7fc00e197f2ef72e94dd410705 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 4 May 2019 17:22:05 +0200 Subject: [PATCH 11/24] Add sample js for highlighting --- .../java/org/jabref/gui/PreviewPanel.java | 54 +++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/PreviewPanel.java b/src/main/java/org/jabref/gui/PreviewPanel.java index ff26ee6765b..e3633e3d50b 100644 --- a/src/main/java/org/jabref/gui/PreviewPanel.java +++ b/src/main/java/org/jabref/gui/PreviewPanel.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.StringReader; import java.nio.file.Path; import java.util.List; @@ -11,6 +12,14 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import javafx.beans.value.ObservableValue; +import javafx.concurrent.Worker; import javafx.print.PrinterJob; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; @@ -30,7 +39,6 @@ import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.keyboard.KeyBindingRepository; import org.jabref.gui.util.BackgroundTask; -import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.exporter.ExporterFactory; import org.jabref.logic.l10n.Localization; @@ -316,17 +324,55 @@ public void update() { } } + String js = " "; + private void setPreviewLabel(String text) { - DefaultTaskExecutor.runInJavaFXThread(() -> { - previewView.getEngine().loadContent(text); - this.setHvalue(0); + String myText = js + text; + previewView.getEngine().setJavaScriptEnabled(true); + previewView.getEngine().loadContent(myText); + this.setHvalue(0); + + previewView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue observable, + Worker.State oldValue, + Worker.State newValue) -> { + if (newValue != Worker.State.SUCCEEDED) { + return; + } + previewView.getEngine().executeScript("highlight('Abel');"); + Document doc = previewView.getEngine().getDocument(); + try { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); + + transformer.transform(new DOMSource(doc), + new StreamResult(new OutputStreamWriter(System.out, "UTF-8"))); + } catch (Exception ex) { + ex.printStackTrace(); + } + // Your logic here }); + } @Override public void highlightPattern(Optional newPattern) { // TODO: Implement that search phrases are highlighted + update(); + } /** From 2b20ecd0a98993ebae1f484adadba30497904285 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 4 May 2019 18:02:17 +0200 Subject: [PATCH 12/24] add search query highlither to handle the highlighting --- .../java/org/jabref/gui/PreviewPanel.java | 65 ++++++++----------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/jabref/gui/PreviewPanel.java b/src/main/java/org/jabref/gui/PreviewPanel.java index e3633e3d50b..b99936b5b16 100644 --- a/src/main/java/org/jabref/gui/PreviewPanel.java +++ b/src/main/java/org/jabref/gui/PreviewPanel.java @@ -2,22 +2,16 @@ import java.io.File; import java.io.IOException; -import java.io.OutputStreamWriter; import java.io.StringReader; import java.nio.file.Path; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.concurrent.Future; +import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - import javafx.beans.value.ObservableValue; import javafx.concurrent.Worker; import javafx.print.PrinterJob; @@ -39,6 +33,7 @@ import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.keyboard.KeyBindingRepository; import org.jabref.gui.util.BackgroundTask; +import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.exporter.ExporterFactory; import org.jabref.logic.l10n.Localization; @@ -65,6 +60,17 @@ public class PreviewPanel extends ScrollPane implements SearchQueryHighlightList private static final Logger LOGGER = LoggerFactory.getLogger(PreviewPanel.class); + private static String JS_HIGHLIGHT_FUNCTION = " "; + private final ClipBoardManager clipBoardManager; private final DialogService dialogService; private final KeyBindingRepository keyBindingRepository; @@ -160,6 +166,7 @@ public PreviewPanel(BasePanel panel, BibDatabaseContext databaseContext, KeyBind createKeyBindings(); updateLayout(preferences, true); + } private void createKeyBindings() { @@ -324,21 +331,11 @@ public void update() { } } - String js = " "; - private void setPreviewLabel(String text) { - String myText = js + text; + String myText = JS_HIGHLIGHT_FUNCTION + text; previewView.getEngine().setJavaScriptEnabled(true); - previewView.getEngine().loadContent(myText); + + DefaultTaskExecutor.runInJavaFXThread(() -> previewView.getEngine().loadContent(myText)); this.setHvalue(0); previewView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue observable, @@ -347,24 +344,18 @@ private void setPreviewLabel(String text) { if (newValue != Worker.State.SUCCEEDED) { return; } - previewView.getEngine().executeScript("highlight('Abel');"); - Document doc = previewView.getEngine().getDocument(); - try { - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); - transformer.setOutputProperty(OutputKeys.METHOD, "xml"); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); - - transformer.transform(new DOMSource(doc), - new StreamResult(new OutputStreamWriter(System.out, "UTF-8"))); - } catch (Exception ex) { - ex.printStackTrace(); - } - // Your logic here - }); + Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { + if (highlightPattern.isPresent()) { + Matcher matcher = highlightPattern.get().matcher(myText); + while (matcher.find()) { + for (int i = 0; i <= matcher.groupCount(); i++) { + previewView.getEngine().executeScript("highlight('" + matcher.group(i) + "');"); + } + } + } + }); + }); } @Override From 62551110d86866efc826cf2b0266c7e00db259a3 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 4 May 2019 18:49:04 +0200 Subject: [PATCH 13/24] add new regex js --- .../java/org/jabref/gui/PreviewPanel.java | 40 ++++++------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/jabref/gui/PreviewPanel.java b/src/main/java/org/jabref/gui/PreviewPanel.java index b99936b5b16..0edec8912ec 100644 --- a/src/main/java/org/jabref/gui/PreviewPanel.java +++ b/src/main/java/org/jabref/gui/PreviewPanel.java @@ -8,8 +8,6 @@ import java.util.Objects; import java.util.Optional; import java.util.concurrent.Future; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; import javafx.beans.value.ObservableValue; @@ -40,7 +38,6 @@ import org.jabref.logic.layout.Layout; import org.jabref.logic.layout.LayoutFormatterPreferences; import org.jabref.logic.layout.LayoutHelper; -import org.jabref.logic.search.SearchQueryHighlightListener; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.event.FieldChangedEvent; @@ -56,20 +53,17 @@ /** * Displays an BibEntry using the given layout format. */ -public class PreviewPanel extends ScrollPane implements SearchQueryHighlightListener, EntryContainer { +public class PreviewPanel extends ScrollPane implements EntryContainer { private static final Logger LOGGER = LoggerFactory.getLogger(PreviewPanel.class); - private static String JS_HIGHLIGHT_FUNCTION = " "; + private static String JS_HIGHLIGHT_FUNCTION = " "; private final ClipBoardManager clipBoardManager; private final DialogService dialogService; @@ -332,7 +326,7 @@ public void update() { } private void setPreviewLabel(String text) { - String myText = JS_HIGHLIGHT_FUNCTION + text; + String myText = JS_HIGHLIGHT_FUNCTION + "
"; previewView.getEngine().setJavaScriptEnabled(true); DefaultTaskExecutor.runInJavaFXThread(() -> previewView.getEngine().loadContent(myText)); @@ -347,24 +341,16 @@ private void setPreviewLabel(String text) { Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { if (highlightPattern.isPresent()) { - Matcher matcher = highlightPattern.get().matcher(myText); - while (matcher.find()) { - for (int i = 0; i <= matcher.groupCount(); i++) { - previewView.getEngine().executeScript("highlight('" + matcher.group(i) + "');"); - } - } + String pattern = highlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); + + previewView.getEngine().executeScript("highlight('" + pattern + "');"); } }); }); - } - @Override - public void highlightPattern(Optional newPattern) { - // TODO: Implement that search phrases are highlighted + } - update(); - } /** * this fixes the Layout, the user cannot change it anymore. Useful for testing the styles in the settings From d99edc77ecea63154d2d1a3d3bc02bf5e8780a26 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 4 May 2019 19:11:11 +0200 Subject: [PATCH 14/24] remove highlith listener before adding new one use innertext in js --- src/main/java/org/jabref/gui/PreviewPanel.java | 14 ++++++-------- src/main/java/org/jabref/gui/StateManager.java | 1 + 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jabref/gui/PreviewPanel.java b/src/main/java/org/jabref/gui/PreviewPanel.java index 0edec8912ec..90b0b723c11 100644 --- a/src/main/java/org/jabref/gui/PreviewPanel.java +++ b/src/main/java/org/jabref/gui/PreviewPanel.java @@ -59,8 +59,8 @@ public class PreviewPanel extends ScrollPane implements EntryContainer { private static String JS_HIGHLIGHT_FUNCTION = " "; @@ -161,6 +161,7 @@ public PreviewPanel(BasePanel panel, BibDatabaseContext databaseContext, KeyBind createKeyBindings(); updateLayout(preferences, true); + } private void createKeyBindings() { @@ -218,6 +219,7 @@ public void setBasePanel(BasePanel basePanel) { public void updateLayout(PreviewPreferences previewPreferences) { updateLayout(previewPreferences, false); + Globals.stateManager.fireSearchQueryHighlightEvent(); } private void updateLayout(PreviewPreferences previewPreferences, boolean init) { @@ -331,27 +333,23 @@ private void setPreviewLabel(String text) { DefaultTaskExecutor.runInJavaFXThread(() -> previewView.getEngine().loadContent(myText)); this.setHvalue(0); - previewView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue observable, Worker.State oldValue, Worker.State newValue) -> { if (newValue != Worker.State.SUCCEEDED) { return; } - Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { if (highlightPattern.isPresent()) { - String pattern = highlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); + String pattern = highlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); previewView.getEngine().executeScript("highlight('" + pattern + "');"); + } }); }); - } - - /** * this fixes the Layout, the user cannot change it anymore. Useful for testing the styles in the settings * diff --git a/src/main/java/org/jabref/gui/StateManager.java b/src/main/java/org/jabref/gui/StateManager.java index 141c0e247d9..e5b30666a94 100644 --- a/src/main/java/org/jabref/gui/StateManager.java +++ b/src/main/java/org/jabref/gui/StateManager.java @@ -120,6 +120,7 @@ public void resetSearchQueryHighlightObservable() } public void addSearchQueryHighlightListener(SearchQueryHighlightListener listener) { + searchQueryHighlightObservable.removeSearchListener(listener); searchQueryHighlightObservable.addSearchListener(listener); } } From 75d3ca3ff475f515eef0525e804c5de83e06a48a Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Mon, 6 May 2019 10:20:20 +0200 Subject: [PATCH 15/24] fix merge, move code to new PreviewViewer --- src/main/java/org/jabref/gui/BasePanel.java | 1 - .../java/org/jabref/gui/PreviewPanel.java | 402 ------------------ .../org/jabref/gui/preview/PreviewViewer.java | 60 ++- 3 files changed, 44 insertions(+), 419 deletions(-) delete mode 100644 src/main/java/org/jabref/gui/PreviewPanel.java diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 932491c4800..f4ae905560a 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -185,7 +185,6 @@ public BasePanel(JabRefFrame frame, BasePanelPreferences preferences, BibDatabas this.entryEditor = new EntryEditor(this, preferences.getEntryEditorPreferences(), Globals.getFileUpdateMonitor(), dialogService, externalFileTypes, Globals.TASK_EXECUTOR); this.preview = new PreviewPanel(getBibDatabaseContext(), this, dialogService, externalFileTypes, Globals.getKeyPrefs(), preferences.getPreviewPreferences()); - frame().getGlobalSearchBar().getSearchQueryHighlightObservable().addSearchListener(preview); } @Subscribe diff --git a/src/main/java/org/jabref/gui/PreviewPanel.java b/src/main/java/org/jabref/gui/PreviewPanel.java deleted file mode 100644 index 90b0b723c11..00000000000 --- a/src/main/java/org/jabref/gui/PreviewPanel.java +++ /dev/null @@ -1,402 +0,0 @@ -package org.jabref.gui; - -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.nio.file.Path; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.Future; -import java.util.stream.Collectors; - -import javafx.beans.value.ObservableValue; -import javafx.concurrent.Worker; -import javafx.print.PrinterJob; -import javafx.scene.control.ContextMenu; -import javafx.scene.control.MenuItem; -import javafx.scene.control.ScrollPane; -import javafx.scene.control.SeparatorMenuItem; -import javafx.scene.input.ClipboardContent; -import javafx.scene.input.DataFormat; -import javafx.scene.input.Dragboard; -import javafx.scene.input.KeyEvent; -import javafx.scene.input.TransferMode; -import javafx.scene.web.WebView; - -import org.jabref.Globals; -import org.jabref.gui.externalfiles.ExternalFilesEntryLinker; -import org.jabref.gui.externalfiletype.ExternalFileTypes; -import org.jabref.gui.icon.IconTheme; -import org.jabref.gui.keyboard.KeyBinding; -import org.jabref.gui.keyboard.KeyBindingRepository; -import org.jabref.gui.util.BackgroundTask; -import org.jabref.gui.util.DefaultTaskExecutor; -import org.jabref.logic.citationstyle.CitationStyle; -import org.jabref.logic.exporter.ExporterFactory; -import org.jabref.logic.l10n.Localization; -import org.jabref.logic.layout.Layout; -import org.jabref.logic.layout.LayoutFormatterPreferences; -import org.jabref.logic.layout.LayoutHelper; -import org.jabref.model.database.BibDatabaseContext; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.event.FieldChangedEvent; -import org.jabref.preferences.PreviewPreferences; - -import com.google.common.eventbus.Subscribe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -/** - * Displays an BibEntry using the given layout format. - */ -public class PreviewPanel extends ScrollPane implements EntryContainer { - - private static final Logger LOGGER = LoggerFactory.getLogger(PreviewPanel.class); - - private static String JS_HIGHLIGHT_FUNCTION = " "; - - private final ClipBoardManager clipBoardManager; - private final DialogService dialogService; - private final KeyBindingRepository keyBindingRepository; - - private final String defaultPreviewStyle = "Preview"; - private String previewStyle; - private CitationStyle citationStyle; - private Optional basePanel = Optional.empty(); - - private boolean fixedLayout; - private Optional layout = Optional.empty(); - /** - * The entry currently shown - */ - private Optional bibEntry = Optional.empty(); - - /** - * If a database is set, the preview will attempt to resolve strings in the previewed entry using that database. - */ - private BibDatabaseContext databaseContext; - private final WebView previewView; - private Optional> citationStyleFuture = Optional.empty(); - - private final ExternalFilesEntryLinker fileLinker; - - /** - * @param panel (may be null) Only set this if the preview is associated to the main window. - * @param databaseContext Used for resolving pdf directories for links. Must not be null, just pass a new empty BibDatabaseContext() - */ - public PreviewPanel(BasePanel panel, BibDatabaseContext databaseContext, KeyBindingRepository keyBindingRepository, PreviewPreferences preferences, DialogService dialogService, ExternalFileTypes externalFileTypes) { - this.databaseContext = Objects.requireNonNull(databaseContext); - this.basePanel = Optional.ofNullable(panel); - this.dialogService = dialogService; - this.clipBoardManager = Globals.clipboardManager; - this.keyBindingRepository = keyBindingRepository; - - fileLinker = new ExternalFilesEntryLinker(externalFileTypes, Globals.prefs.getFilePreferences(), databaseContext); - - // Set up scroll pane for preview pane - setFitToHeight(true); - setFitToWidth(true); - previewView = new WebView(); - setContent(previewView); - previewView.setContextMenuEnabled(false); - setContextMenu(createPopupMenu()); - - if (this.basePanel.isPresent()) { - // Handler for drag content of preview to different window - // only created for main window (not for windows like the search results dialog) - setOnDragDetected(event -> { - startFullDrag(); - - Dragboard dragboard = startDragAndDrop(TransferMode.COPY); - ClipboardContent content = new ClipboardContent(); - content.putHtml((String) previewView.getEngine().executeScript("window.getSelection().toString()")); - dragboard.setContent(content); - - event.consume(); - }); - } - this.previewView.setOnDragOver(event -> { - if (event.getDragboard().hasFiles()) { - event.acceptTransferModes(TransferMode.COPY, TransferMode.MOVE, TransferMode.LINK); - } - event.consume(); - }); - - this.previewView.setOnDragDropped(event -> { - BibEntry entry = this.getEntry(); - boolean success = false; - if (event.getDragboard().hasContent(DataFormat.FILES)) { - List files = event.getDragboard().getFiles().stream().map(File::toPath).collect(Collectors.toList()); - - if (event.getTransferMode() == TransferMode.MOVE) { - LOGGER.debug("Mode MOVE"); //shift on win or no modifier - fileLinker.moveFilesToFileDirAndAddToEntry(entry, files); - } - if (event.getTransferMode() == TransferMode.LINK) { - LOGGER.debug("Node LINK"); //alt on win - fileLinker.addFilesToEntry(entry, files); - } - if (event.getTransferMode() == TransferMode.COPY) { - LOGGER.debug("Mode Copy"); //ctrl on win, no modifier on Xubuntu - fileLinker.copyFilesToFileDirAndAddToEntry(entry, files); - } - success = true; - } - - event.setDropCompleted(success); - event.consume(); - - }); - - createKeyBindings(); - updateLayout(preferences, true); - - - } - - private void createKeyBindings() { - addEventFilter(KeyEvent.KEY_PRESSED, event -> { - Optional keyBinding = keyBindingRepository.mapToKeyBinding(event); - if (keyBinding.isPresent()) { - switch (keyBinding.get()) { - case COPY_PREVIEW: - copyPreviewToClipBoard(); - event.consume(); - break; - case CLOSE: - close(); - event.consume(); - break; - default: - } - } - }); - } - - private ContextMenu createPopupMenu() { - MenuItem copyPreview = new MenuItem(Localization.lang("Copy preview"), IconTheme.JabRefIcons.COPY.getGraphicNode()); - copyPreview.setAccelerator(keyBindingRepository.getKeyCombination(KeyBinding.COPY_PREVIEW)); - copyPreview.setOnAction(event -> copyPreviewToClipBoard()); - MenuItem printEntryPreview = new MenuItem(Localization.lang("Print entry preview"), IconTheme.JabRefIcons.PRINTED.getGraphicNode()); - printEntryPreview.setOnAction(event -> print()); - MenuItem previousPreviewLayout = new MenuItem(Localization.lang("Previous preview layout")); - previousPreviewLayout.setAccelerator(keyBindingRepository.getKeyCombination(KeyBinding.PREVIOUS_PREVIEW_LAYOUT)); - previousPreviewLayout.setOnAction(event -> basePanel.ifPresent(BasePanel::previousPreviewStyle)); - MenuItem nextPreviewLayout = new MenuItem(Localization.lang("Next preview layout")); - nextPreviewLayout.setAccelerator(keyBindingRepository.getKeyCombination(KeyBinding.NEXT_PREVIEW_LAYOUT)); - nextPreviewLayout.setOnAction(event -> basePanel.ifPresent(BasePanel::nextPreviewStyle)); - - ContextMenu menu = new ContextMenu(); - menu.getItems().add(copyPreview); - menu.getItems().add(printEntryPreview); - menu.getItems().add(new SeparatorMenuItem()); - menu.getItems().add(nextPreviewLayout); - menu.getItems().add(previousPreviewLayout); - return menu; - } - - public void setDatabaseContext(BibDatabaseContext databaseContext) { - this.databaseContext = databaseContext; - } - - public Optional getBasePanel() { - return this.basePanel; - } - - public void setBasePanel(BasePanel basePanel) { - this.basePanel = Optional.ofNullable(basePanel); - } - - public void updateLayout(PreviewPreferences previewPreferences) { - updateLayout(previewPreferences, false); - Globals.stateManager.fireSearchQueryHighlightEvent(); - } - - private void updateLayout(PreviewPreferences previewPreferences, boolean init) { - if (fixedLayout) { - LOGGER.debug("cannot change the layout because the layout is fixed"); - return; - } - - String style = previewPreferences.getCurrentPreviewStyle(); - if (previewStyle == null) { - previewStyle = style; - CitationStyle.createCitationStyleFromFile(style).ifPresent(cs -> citationStyle = cs); - } - if (basePanel.isPresent() && !previewStyle.equals(style)) { - if (CitationStyle.isCitationStyleFile(style)) { - layout = Optional.empty(); - CitationStyle.createCitationStyleFromFile(style) - .ifPresent(cs -> { - citationStyle = cs; - if (!init) { - basePanel.get().output(Localization.lang("Preview style changed to: %0", citationStyle.getTitle())); - } - }); - previewStyle = style; - } - } else { - previewStyle = defaultPreviewStyle; - updatePreviewLayout(previewPreferences.getPreviewStyle(), previewPreferences.getLayoutFormatterPreferences()); - if (!init) { - basePanel.get().output(Localization.lang("Preview style changed to: %0", Localization.lang("Preview"))); - } - } - - update(); - } - - private void updatePreviewLayout(String layoutFile, LayoutFormatterPreferences layoutFormatterPreferences) { - StringReader sr = new StringReader(layoutFile.replace("__NEWLINE__", "\n")); - try { - layout = Optional.of(new LayoutHelper(sr, layoutFormatterPreferences).getLayoutFromText()); - } catch (IOException e) { - layout = Optional.empty(); - LOGGER.debug("no layout could be set", e); - } - } - - public void setLayout(Layout layout) { - this.layout = Optional.ofNullable(layout); - update(); - } - - public void setEntry(BibEntry newEntry) { - bibEntry.filter(e -> e != newEntry).ifPresent(e -> e.unregisterListener(this)); - bibEntry = Optional.ofNullable(newEntry); - newEntry.registerListener(this); - - update(); - } - - /** - * Listener for ChangedFieldEvent. - */ - @SuppressWarnings("unused") - @Subscribe - public void listen(FieldChangedEvent fieldChangedEvent) { - update(); - } - - @Override - public BibEntry getEntry() { - return this.bibEntry.orElse(null); - } - - public void update() { - ExporterFactory.entryNumber = 1; // Set entry number in case that is included in the preview layout. - - if (citationStyleFuture.isPresent()) { - citationStyleFuture.get().cancel(true); - citationStyleFuture = Optional.empty(); - } - - if (layout.isPresent()) { - StringBuilder sb = new StringBuilder(); - bibEntry.ifPresent(entry -> sb.append(layout.get() - .doLayout(entry, databaseContext.getDatabase()))); - setPreviewLabel(sb.toString()); - } else if (basePanel.isPresent() && bibEntry.isPresent()) { - if ((citationStyle != null) && !previewStyle.equals(defaultPreviewStyle)) { - basePanel.get().getCitationStyleCache().setCitationStyle(citationStyle); - } - Future citationStyleWorker = BackgroundTask - .wrap(() -> basePanel.get().getCitationStyleCache().getCitationFor(bibEntry.get())) - .onRunning(() -> { - CitationStyle citationStyle = basePanel.get().getCitationStyleCache().getCitationStyle(); - setPreviewLabel("" + Localization.lang("Processing %0", Localization.lang("Citation Style")) + - ": " + citationStyle.getTitle() + " ..." + ""); - }) - .onSuccess(this::setPreviewLabel) - .onFailure(exception -> { - LOGGER.error("Error while generating citation style", exception); - setPreviewLabel(Localization.lang("Error while generating citation style")); - }) - .executeWith(Globals.TASK_EXECUTOR); - this.citationStyleFuture = Optional.of(citationStyleWorker); - } - } - - private void setPreviewLabel(String text) { - String myText = JS_HIGHLIGHT_FUNCTION + "
"; - previewView.getEngine().setJavaScriptEnabled(true); - - DefaultTaskExecutor.runInJavaFXThread(() -> previewView.getEngine().loadContent(myText)); - this.setHvalue(0); - previewView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue observable, - Worker.State oldValue, - Worker.State newValue) -> { - if (newValue != Worker.State.SUCCEEDED) { - return; - } - Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { - if (highlightPattern.isPresent()) { - String pattern = highlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); - - previewView.getEngine().executeScript("highlight('" + pattern + "');"); - - } - }); - }); - } - - /** - * this fixes the Layout, the user cannot change it anymore. Useful for testing the styles in the settings - * - * @param layout should be either a {@link String} (for the old PreviewStyle) or a {@link CitationStyle}. - */ - public void setFixedLayout(String layout) { - this.fixedLayout = true; - updatePreviewLayout(layout, Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader)); - } - - public void print() { - PrinterJob job = PrinterJob.createPrinterJob(); - boolean proceed = dialogService.showPrintDialog(job); - if (!proceed) { - return; - } - - BackgroundTask.wrap(() -> { - job.getJobSettings().setJobName(bibEntry.flatMap(BibEntry::getCiteKeyOptional).orElse("NO ENTRY")); - previewView.getEngine().print(job); - job.endJob(); - return null; - }) - .onFailure(exception -> dialogService.showErrorDialogAndWait(Localization.lang("Could not print preview"), exception)) - .executeWith(Globals.TASK_EXECUTOR); - } - - public void close() { - basePanel.ifPresent(BasePanel::closeBottomPane); - } - - private void copyPreviewToClipBoard() { - StringBuilder previewStringContent = new StringBuilder(); - Document document = previewView.getEngine().getDocument(); - - NodeList nodeList = document.getElementsByTagName("html"); - - //Nodelist does not implement iterable - for (int i = 0; i < nodeList.getLength(); i++) { - Element element = (Element) nodeList.item(i); - previewStringContent.append(element.getTextContent()); - } - - ClipboardContent content = new ClipboardContent(); - content.putString(previewStringContent.toString()); - content.putHtml((String) previewView.getEngine().executeScript("document.documentElement.outerHTML")); - - clipBoardManager.setContent(content); - } -} diff --git a/src/main/java/org/jabref/gui/preview/PreviewViewer.java b/src/main/java/org/jabref/gui/preview/PreviewViewer.java index 6432ef4cc3b..9fdfad3e23f 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewViewer.java +++ b/src/main/java/org/jabref/gui/preview/PreviewViewer.java @@ -5,6 +5,8 @@ import javafx.beans.InvalidationListener; import javafx.beans.Observable; +import javafx.beans.value.ObservableValue; +import javafx.concurrent.Worker; import javafx.print.PrinterJob; import javafx.scene.control.ScrollPane; import javafx.scene.input.ClipboardContent; @@ -46,6 +48,14 @@ public class PreviewViewer extends ScrollPane implements InvalidationListener { private Optional entry = Optional.empty(); private BibDatabaseContext database; + private static String JS_HIGHLIGHT_FUNCTION = " "; + /** * @param database Used for resolving strings and pdf directories for links. */ @@ -93,18 +103,36 @@ private void update() { ExporterFactory.entryNumber = 1; // Set entry number in case that is included in the preview layout. BackgroundTask - .wrap(() -> layout.generatePreview(entry.get(), database.getDatabase())) - .onRunning(() -> setPreviewText("" + Localization.lang("Processing %0", Localization.lang("Citation Style")) + ": " + layout.getName() + " ..." + "")) - .onSuccess(this::setPreviewText) - .onFailure(exception -> { - LOGGER.error("Error while generating citation style", exception); - setPreviewText(Localization.lang("Error while generating citation style")); - }) - .executeWith(taskExecutor); + .wrap(() -> layout.generatePreview(entry.get(), database.getDatabase())) + .onRunning(() -> setPreviewText("" + Localization.lang("Processing %0", Localization.lang("Citation Style")) + ": " + layout.getName() + " ..." + "")) + .onSuccess(this::setPreviewText) + .onFailure(exception -> { + LOGGER.error("Error while generating citation style", exception); + setPreviewText(Localization.lang("Error while generating citation style")); + }) + .executeWith(taskExecutor); } private void setPreviewText(String text) { - previewView.getEngine().loadContent(text); + String myText = JS_HIGHLIGHT_FUNCTION + "
"; + previewView.getEngine().setJavaScriptEnabled(true); + previewView.getEngine().loadContent(myText); + + previewView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue observable, + Worker.State oldValue, + Worker.State newValue) -> { + if (newValue != Worker.State.SUCCEEDED) { + return; + } + Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { + if (highlightPattern.isPresent()) { + String pattern = highlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); + + previewView.getEngine().executeScript("highlight('" + pattern + "');"); + + } + }); + }); this.setHvalue(0); } @@ -116,13 +144,13 @@ public void print() { } BackgroundTask - .wrap(() -> { - job.getJobSettings().setJobName(entry.flatMap(BibEntry::getCiteKeyOptional).orElse("NO ENTRY")); - previewView.getEngine().print(job); - job.endJob(); - }) - .onFailure(exception -> dialogService.showErrorDialogAndWait(Localization.lang("Could not print preview"), exception)) - .executeWith(taskExecutor); + .wrap(() -> { + job.getJobSettings().setJobName(entry.flatMap(BibEntry::getCiteKeyOptional).orElse("NO ENTRY")); + previewView.getEngine().print(job); + job.endJob(); + }) + .onFailure(exception -> dialogService.showErrorDialogAndWait(Localization.lang("Could not print preview"), exception)) + .executeWith(taskExecutor); } public void copyPreviewToClipBoard() { From 2db64030a8c0c067ad9121b1df8321c40cf0977d Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Mon, 6 May 2019 10:38:58 +0200 Subject: [PATCH 16/24] fix checkstyle --- .../org/jabref/gui/preview/PreviewViewer.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jabref/gui/preview/PreviewViewer.java b/src/main/java/org/jabref/gui/preview/PreviewViewer.java index 9fdfad3e23f..7b7fa4fa0d8 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewViewer.java +++ b/src/main/java/org/jabref/gui/preview/PreviewViewer.java @@ -36,26 +36,27 @@ public class PreviewViewer extends ScrollPane implements InvalidationListener { private static final Logger LOGGER = LoggerFactory.getLogger(PreviewViewer.class); + private static final String JS_HIGHLIGHT_FUNCTION = " "; + private final ClipBoardManager clipBoardManager; private final DialogService dialogService; private final TaskExecutor taskExecutor = Globals.TASK_EXECUTOR; private final WebView previewView; private PreviewLayout layout; + /** * The entry currently shown */ private Optional entry = Optional.empty(); private BibDatabaseContext database; - private static String JS_HIGHLIGHT_FUNCTION = " "; - /** * @param database Used for resolving strings and pdf directories for links. */ From cd6d18167f729ab0c4a431412cf3c5b836e2046a Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sun, 12 May 2019 15:42:46 +0200 Subject: [PATCH 17/24] fix search highlighting in source editor fix listeners --- .../gui/entryeditor/BibtexSourceCodeArea.css | 4 +++ .../org/jabref/gui/entryeditor/SourceTab.java | 27 ++++++++-------- .../org/jabref/gui/preview/PreviewViewer.java | 32 ++++++++++--------- .../SearchQueryHighlightObservable.java | 1 - 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css b/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css index 8829b17cb5a..7c80f0aa151 100644 --- a/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css +++ b/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css @@ -1,3 +1,7 @@ #bibtexSourceCodeArea .search { -fx-fill: red; +} + +.bibtexSourceCodeArea .text { + -fx-fill: -fx-text-background-color; } \ No newline at end of file diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index fbe49fa4942..4f4275d5dba 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -55,10 +55,11 @@ public class SourceTab extends EntryEditorTab { private final BibDatabaseMode mode; private final UndoManager undoManager; private final ObjectProperty sourceIsValid = new SimpleObjectProperty<>(); - private final ObservableRuleBasedValidator sourceValidator = new ObservableRuleBasedValidator(sourceIsValid); + @SuppressWarnings("unchecked") private final ObservableRuleBasedValidator sourceValidator = new ObservableRuleBasedValidator(sourceIsValid); private final ImportFormatPreferences importFormatPreferences; private final FileUpdateMonitor fileMonitor; private final DialogService dialogService; + private CodeArea codeArea; public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager, LatexFieldFormatterPreferences fieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor, DialogService dialogService) { this.mode = bibDatabaseContext.getMode(); @@ -71,6 +72,17 @@ public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undo this.fileMonitor = fileMonitor; this.dialogService = dialogService; + Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { + if (highlightPattern.isPresent() && codeArea != null) { + codeArea.setStyleClass(0, codeArea.getLength(), "text"); + Matcher matcher = highlightPattern.get().matcher(codeArea.getText()); + while (matcher.find()) { + for (int i = 0; i <= matcher.groupCount(); i++) { + codeArea.setStyleClass(matcher.start(), matcher.end(), "search"); + } + } + } + }); } private static String getSourceString(BibEntry entry, BibDatabaseMode type, LatexFieldFormatterPreferences fieldFormatterPreferences) throws IOException { @@ -145,18 +157,7 @@ protected void bindToEntry(BibEntry entry) { } }); this.setContent(codeArea); - - Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { - if (highlightPattern.isPresent()) { - Matcher matcher = highlightPattern.get().matcher(codeArea.getText()); - while (matcher.find()) { - for (int i = 0; i <= matcher.groupCount(); i++) { - codeArea.setStyleClass(matcher.start(), matcher.end(), "search"); - } - } - } - }); - + this.codeArea = codeArea; // Store source for on focus out event in the source code (within its text area) // and update source code for every change of entry field values BindingsHelper.bindContentBidirectional(entry.getFieldsObservable(), codeArea.focusedProperty(), onFocus -> { diff --git a/src/main/java/org/jabref/gui/preview/PreviewViewer.java b/src/main/java/org/jabref/gui/preview/PreviewViewer.java index 7b7fa4fa0d8..d61cc819c07 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewViewer.java +++ b/src/main/java/org/jabref/gui/preview/PreviewViewer.java @@ -70,6 +70,23 @@ public PreviewViewer(BibDatabaseContext database, DialogService dialogService) { previewView = new WebView(); setContent(previewView); previewView.setContextMenuEnabled(false); + + previewView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue observable, + Worker.State oldValue, + Worker.State newValue) -> { + if (newValue != Worker.State.SUCCEEDED) { + return; + } + Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { + if (highlightPattern.isPresent()) { + String pattern = highlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); + + previewView.getEngine().executeScript("highlight('" + pattern + "');"); + + } + }); + }); + } public void setLayout(PreviewLayout newLayout) { @@ -119,21 +136,6 @@ private void setPreviewText(String text) { previewView.getEngine().setJavaScriptEnabled(true); previewView.getEngine().loadContent(myText); - previewView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue observable, - Worker.State oldValue, - Worker.State newValue) -> { - if (newValue != Worker.State.SUCCEEDED) { - return; - } - Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { - if (highlightPattern.isPresent()) { - String pattern = highlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); - - previewView.getEngine().executeScript("highlight('" + pattern + "');"); - - } - }); - }); this.setHvalue(0); } diff --git a/src/main/java/org/jabref/logic/search/SearchQueryHighlightObservable.java b/src/main/java/org/jabref/logic/search/SearchQueryHighlightObservable.java index 8046f442446..1665e1b3294 100644 --- a/src/main/java/org/jabref/logic/search/SearchQueryHighlightObservable.java +++ b/src/main/java/org/jabref/logic/search/SearchQueryHighlightObservable.java @@ -25,7 +25,6 @@ public void addSearchListener(SearchQueryHighlightListener newListener) { eventBus.register(newListener); newListener.highlightPattern(pattern); - } public void removeSearchListener(SearchQueryHighlightListener listener) { From 1210a2afe113d385af69c52b91b04f1a626e1505 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 18 May 2019 19:02:09 +0200 Subject: [PATCH 18/24] refactor state manager as parameter move css for highlighting binding for searchResultSize --- src/main/java/org/jabref/gui/BasePanel.java | 2 +- src/main/java/org/jabref/gui/StateManager.java | 4 ---- .../jabref/gui/collab/EntryAddChangeViewModel.java | 3 ++- .../gui/collab/EntryDeleteChangeViewModel.java | 3 ++- .../jabref/gui/entryeditor/BibtexSourceCodeArea.css | 7 ------- .../java/org/jabref/gui/entryeditor/EntryEditor.css | 8 ++++++++ .../org/jabref/gui/entryeditor/EntryEditor.java | 7 +++++-- .../java/org/jabref/gui/entryeditor/SourceTab.java | 13 +++++++------ .../jabref/gui/maintable/MainTableDataModel.java | 6 +----- .../gui/openoffice/StyleSelectDialogView.java | 5 +++-- .../gui/preferences/PreviewPreferencesTab.java | 2 +- .../java/org/jabref/gui/preview/PreviewPanel.java | 11 ++--------- .../java/org/jabref/gui/preview/PreviewViewer.java | 5 +++-- .../java/org/jabref/gui/search/GlobalSearchBar.java | 2 +- .../java/org/jabref/logic/search/SearchQuery.java | 6 +++--- .../org/jabref/gui/entryeditor/SourceTabTest.java | 3 ++- 16 files changed, 41 insertions(+), 46 deletions(-) delete mode 100644 src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index f4ae905560a..d64f2226ff0 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -182,7 +182,7 @@ public BasePanel(JabRefFrame frame, BasePanelPreferences preferences, BibDatabas this.getDatabase().registerListener(new UpdateTimestampListener(Globals.prefs)); - this.entryEditor = new EntryEditor(this, preferences.getEntryEditorPreferences(), Globals.getFileUpdateMonitor(), dialogService, externalFileTypes, Globals.TASK_EXECUTOR); + this.entryEditor = new EntryEditor(this, preferences.getEntryEditorPreferences(), Globals.getFileUpdateMonitor(), dialogService, externalFileTypes, Globals.TASK_EXECUTOR, Globals.stateManager); this.preview = new PreviewPanel(getBibDatabaseContext(), this, dialogService, externalFileTypes, Globals.getKeyPrefs(), preferences.getPreviewPreferences()); } diff --git a/src/main/java/org/jabref/gui/StateManager.java b/src/main/java/org/jabref/gui/StateManager.java index e5b30666a94..a73886d43a8 100644 --- a/src/main/java/org/jabref/gui/StateManager.java +++ b/src/main/java/org/jabref/gui/StateManager.java @@ -100,10 +100,6 @@ public IntegerProperty searchResultSizeProperty() { return searchResultSize; } - public void setSearchResultSize(int size) { - searchResultSize.setValue(size); - } - public SearchQueryHighlightObservable getSearchQueryHighlightObservable() { return searchQueryHighlightObservable; } diff --git a/src/main/java/org/jabref/gui/collab/EntryAddChangeViewModel.java b/src/main/java/org/jabref/gui/collab/EntryAddChangeViewModel.java index 4fa50ccca9c..45832985b5b 100644 --- a/src/main/java/org/jabref/gui/collab/EntryAddChangeViewModel.java +++ b/src/main/java/org/jabref/gui/collab/EntryAddChangeViewModel.java @@ -2,6 +2,7 @@ import javafx.scene.Node; +import org.jabref.Globals; import org.jabref.JabRefGUI; import org.jabref.gui.preview.PreviewViewer; import org.jabref.gui.undo.NamedCompound; @@ -27,7 +28,7 @@ public void makeChange(BibDatabaseContext database, NamedCompound undoEdit) { @Override public Node description() { - PreviewViewer previewViewer = new PreviewViewer(new BibDatabaseContext(), JabRefGUI.getMainFrame().getDialogService()); + PreviewViewer previewViewer = new PreviewViewer(new BibDatabaseContext(), JabRefGUI.getMainFrame().getDialogService(), Globals.stateManager); previewViewer.setEntry(diskEntry); return previewViewer; } diff --git a/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java b/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java index f8e2b88a02c..f07dcbe28c9 100644 --- a/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java +++ b/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java @@ -2,6 +2,7 @@ import javafx.scene.Node; +import org.jabref.Globals; import org.jabref.JabRefGUI; import org.jabref.gui.preview.PreviewViewer; import org.jabref.gui.undo.NamedCompound; @@ -44,7 +45,7 @@ public void makeChange(BibDatabaseContext database, NamedCompound undoEdit) { @Override public Node description() { - PreviewViewer previewViewer = new PreviewViewer(new BibDatabaseContext(), JabRefGUI.getMainFrame().getDialogService()); + PreviewViewer previewViewer = new PreviewViewer(new BibDatabaseContext(), JabRefGUI.getMainFrame().getDialogService(), Globals.stateManager); previewViewer.setEntry(memEntry); return previewViewer; } diff --git a/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css b/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css deleted file mode 100644 index 7c80f0aa151..00000000000 --- a/src/main/java/org/jabref/gui/entryeditor/BibtexSourceCodeArea.css +++ /dev/null @@ -1,7 +0,0 @@ -#bibtexSourceCodeArea .search { - -fx-fill: red; -} - -.bibtexSourceCodeArea .text { - -fx-fill: -fx-text-background-color; -} \ No newline at end of file diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css index 7755b210944..17edef0b3ca 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.css @@ -87,3 +87,11 @@ .related-articles-tab { -fx-padding: 20 20 20 20; } + +#bibtexSourceCodeArea .search { + -fx-fill: red; +} + +.bibtexSourceCodeArea .text { + -fx-fill: -fx-text-background-color; +} \ No newline at end of file diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index d1b3f9a2876..eb65cdc0cff 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -27,6 +27,7 @@ import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.GUIGlobals; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.ActionFactory; import org.jabref.gui.actions.StandardActions; import org.jabref.gui.bibtexkeypattern.GenerateBibtexKeySingleAction; @@ -93,8 +94,9 @@ public class EntryEditor extends BorderPane { private final DialogService dialogService; private final ExternalFilesEntryLinker fileLinker; private final TaskExecutor taskExecutor; + private final StateManager stateManager; - public EntryEditor(BasePanel panel, EntryEditorPreferences preferences, FileUpdateMonitor fileMonitor, DialogService dialogService, ExternalFileTypes externalFileTypes, TaskExecutor taskExecutor) { + public EntryEditor(BasePanel panel, EntryEditorPreferences preferences, FileUpdateMonitor fileMonitor, DialogService dialogService, ExternalFileTypes externalFileTypes, TaskExecutor taskExecutor, StateManager stateManager) { this.panel = panel; this.databaseContext = panel.getBibDatabaseContext(); this.undoManager = panel.getUndoManager(); @@ -102,6 +104,7 @@ public EntryEditor(BasePanel panel, EntryEditorPreferences preferences, FileUpda this.fileMonitor = fileMonitor; this.dialogService = dialogService; this.taskExecutor = taskExecutor; + this.stateManager = stateManager; fileLinker = new ExternalFilesEntryLinker(externalFileTypes, Globals.prefs.getFilePreferences(), databaseContext); @@ -296,7 +299,7 @@ private List createTabs() { tabs.add(new RelatedArticlesTab(preferences, dialogService)); // Source tab - sourceTab = new SourceTab(databaseContext, undoManager, preferences.getLatexFieldFormatterPreferences(), preferences.getImportFormatPreferences(), fileMonitor, dialogService); + sourceTab = new SourceTab(databaseContext, undoManager, preferences.getLatexFieldFormatterPreferences(), preferences.getImportFormatPreferences(), fileMonitor, dialogService, stateManager); tabs.add(sourceTab); return tabs; } diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index 4f4275d5dba..7c04527c3e1 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -16,8 +16,8 @@ import javafx.scene.control.Tooltip; import javafx.scene.input.InputMethodRequests; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.StateManager; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.undo.CountingUndoManager; import org.jabref.gui.undo.NamedCompound; @@ -59,9 +59,11 @@ public class SourceTab extends EntryEditorTab { private final ImportFormatPreferences importFormatPreferences; private final FileUpdateMonitor fileMonitor; private final DialogService dialogService; + private final StateManager stateManager; + private CodeArea codeArea; - public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager, LatexFieldFormatterPreferences fieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor, DialogService dialogService) { + public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager, LatexFieldFormatterPreferences fieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor, DialogService dialogService, StateManager stateManager) { this.mode = bibDatabaseContext.getMode(); this.setText(Localization.lang("%0 source", mode.getFormattedName())); this.setTooltip(new Tooltip(Localization.lang("Show/edit %0 source", mode.getFormattedName()))); @@ -71,8 +73,9 @@ public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undo this.importFormatPreferences = importFormatPreferences; this.fileMonitor = fileMonitor; this.dialogService = dialogService; + this.stateManager = stateManager; - Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { + stateManager.addSearchQueryHighlightListener(highlightPattern -> { if (highlightPattern.isPresent() && codeArea != null) { codeArea.setStyleClass(0, codeArea.getLength(), "text"); Matcher matcher = highlightPattern.get().matcher(codeArea.getText()); @@ -130,8 +133,6 @@ private CodeArea createSourceEditor() { } }); codeArea.setId("bibtexSourceCodeArea"); - codeArea.getStylesheets().add(SourceTab.class.getResource("BibtexSourceCodeArea.css").toExternalForm()); - return codeArea; } @@ -169,7 +170,7 @@ protected void bindToEntry(BibEntry entry) { codeArea.clear(); try { codeArea.appendText(getSourceString(entry, mode, fieldFormatterPreferences)); - Globals.stateManager.fireSearchQueryHighlightEvent(); + stateManager.fireSearchQueryHighlightEvent(); } catch (IOException ex) { codeArea.setEditable(false); diff --git a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java index 8792e579628..1de3ca16169 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java @@ -4,7 +4,6 @@ import java.util.Optional; import javafx.beans.binding.Bindings; -import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; import javafx.collections.transformation.SortedList; @@ -33,10 +32,7 @@ public MainTableDataModel(BibDatabaseContext context) { Globals.stateManager.activeGroupProperty(), Globals.stateManager.activeSearchQueryProperty()) ); - entriesFiltered.addListener((ListChangeListener) c -> { - Globals.stateManager.setSearchResultSize(entriesFiltered.size()); - }); - + Globals.stateManager.searchResultSizeProperty().bind(Bindings.size(entriesFiltered)); // We need to wrap the list since otherwise sorting in the table does not work entriesSorted = new SortedList<>(entriesFiltered); } diff --git a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogView.java b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogView.java index cec9e6a9048..778758961f3 100644 --- a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogView.java +++ b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogView.java @@ -11,6 +11,7 @@ import javafx.scene.control.TableView; import javafx.scene.layout.VBox; +import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.preview.PreviewViewer; @@ -68,11 +69,11 @@ public StyleSelectDialogView(StyleLoader loader) { private void initialize() { viewModel = new StyleSelectDialogViewModel(dialogService, loader, preferencesService); - previewArticle = new PreviewViewer(new BibDatabaseContext(), dialogService); + previewArticle = new PreviewViewer(new BibDatabaseContext(), dialogService, Globals.stateManager); previewArticle.setEntry(TestEntry.getTestEntry()); vbox.getChildren().add(previewArticle); - previewBook = new PreviewViewer(new BibDatabaseContext(), dialogService); + previewBook = new PreviewViewer(new BibDatabaseContext(), dialogService, Globals.stateManager); previewBook.setEntry(TestEntry.getTestEntryBook()); vbox.getChildren().add(previewBook); diff --git a/src/main/java/org/jabref/gui/preferences/PreviewPreferencesTab.java b/src/main/java/org/jabref/gui/preferences/PreviewPreferencesTab.java index da23285e2e8..ec4c6348a23 100644 --- a/src/main/java/org/jabref/gui/preferences/PreviewPreferencesTab.java +++ b/src/main/java/org/jabref/gui/preferences/PreviewPreferencesTab.java @@ -118,7 +118,7 @@ private void setupLogic() { btnTest.setOnAction(event -> { try { - PreviewViewer testPane = new PreviewViewer(new BibDatabaseContext(), dialogService); + PreviewViewer testPane = new PreviewViewer(new BibDatabaseContext(), dialogService, Globals.stateManager); testPane.setEntry(TestEntry.getTestEntry()); PreviewLayout layout = chosen.getSelectionModel().getSelectedItem(); diff --git a/src/main/java/org/jabref/gui/preview/PreviewPanel.java b/src/main/java/org/jabref/gui/preview/PreviewPanel.java index 08db01a8a88..790aae4c1d6 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewPanel.java +++ b/src/main/java/org/jabref/gui/preview/PreviewPanel.java @@ -4,7 +4,6 @@ import java.nio.file.Path; import java.util.List; import java.util.Optional; -import java.util.regex.Pattern; import java.util.stream.Collectors; import javafx.scene.control.ContextMenu; @@ -27,7 +26,6 @@ import org.jabref.gui.keyboard.KeyBindingRepository; import org.jabref.logic.citationstyle.PreviewLayout; import org.jabref.logic.l10n.Localization; -import org.jabref.logic.search.SearchQueryHighlightListener; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.preferences.PreviewPreferences; @@ -35,7 +33,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PreviewPanel extends VBox implements SearchQueryHighlightListener { +public class PreviewPanel extends VBox { private static final Logger LOGGER = LoggerFactory.getLogger(PreviewPanel.class); @@ -52,7 +50,7 @@ public PreviewPanel(BibDatabaseContext database, BasePanel basePanel, DialogServ this.dialogService = dialogService; fileLinker = new ExternalFilesEntryLinker(externalFileTypes, Globals.prefs.getFilePreferences(), database); - previewView = new PreviewViewer(database, dialogService); + previewView = new PreviewViewer(database, dialogService, Globals.stateManager); previewView.setLayout(preferences.getCurrentPreviewStyle()); previewView.setContextMenu(createPopupMenu()); previewView.setOnDragDetected(event -> { @@ -107,11 +105,6 @@ public void close() { basePanel.closeBottomPane(); } - @Override - public void highlightPattern(Optional newPattern) { - // TODO: Implement that search phrases are highlighted - } - public void updateLayout(PreviewPreferences previewPreferences) { updateLayout(previewPreferences, false); } diff --git a/src/main/java/org/jabref/gui/preview/PreviewViewer.java b/src/main/java/org/jabref/gui/preview/PreviewViewer.java index d61cc819c07..bbc14907cec 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewViewer.java +++ b/src/main/java/org/jabref/gui/preview/PreviewViewer.java @@ -15,6 +15,7 @@ import org.jabref.Globals; import org.jabref.gui.ClipBoardManager; import org.jabref.gui.DialogService; +import org.jabref.gui.StateManager; import org.jabref.gui.util.BackgroundTask; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.citationstyle.PreviewLayout; @@ -60,7 +61,7 @@ public class PreviewViewer extends ScrollPane implements InvalidationListener { /** * @param database Used for resolving strings and pdf directories for links. */ - public PreviewViewer(BibDatabaseContext database, DialogService dialogService) { + public PreviewViewer(BibDatabaseContext database, DialogService dialogService, StateManager stateManager) { this.database = Objects.requireNonNull(database); this.dialogService = dialogService; this.clipBoardManager = Globals.clipboardManager; @@ -77,7 +78,7 @@ public PreviewViewer(BibDatabaseContext database, DialogService dialogService) { if (newValue != Worker.State.SUCCEEDED) { return; } - Globals.stateManager.addSearchQueryHighlightListener(highlightPattern -> { + stateManager.addSearchQueryHighlightListener(highlightPattern -> { if (highlightPattern.isPresent()) { String pattern = highlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index cdd04c7e1da..33a99a55961 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -212,7 +212,7 @@ public void performSearch() { updateResults(Globals.stateManager.searchResultSizeProperty().get(), SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), searchQuery.isGrammarBasedSearch()); - Globals.stateManager.fireSearchQueryHighlightEvent(); + } diff --git a/src/main/java/org/jabref/logic/search/SearchQuery.java b/src/main/java/org/jabref/logic/search/SearchQuery.java index d33fa4f90ff..12b0639d6da 100644 --- a/src/main/java/org/jabref/logic/search/SearchQuery.java +++ b/src/main/java/org/jabref/logic/search/SearchQuery.java @@ -63,9 +63,9 @@ private String getRegularExpressionDescription() { public String localize() { return String.format("\"%s\" (%s, %s)", - getQuery(), - getLocalizedCaseSensitiveDescription(), - getLocalizedRegularExpressionDescription()); + getQuery(), + getLocalizedCaseSensitiveDescription(), + getLocalizedRegularExpressionDescription()); } private String getLocalizedCaseSensitiveDescription() { diff --git a/src/test/java/org/jabref/gui/entryeditor/SourceTabTest.java b/src/test/java/org/jabref/gui/entryeditor/SourceTabTest.java index c3f50e3c853..20d11612483 100644 --- a/src/test/java/org/jabref/gui/entryeditor/SourceTabTest.java +++ b/src/test/java/org/jabref/gui/entryeditor/SourceTabTest.java @@ -7,6 +7,7 @@ import javafx.stage.Stage; import org.jabref.gui.DialogService; +import org.jabref.gui.StateManager; import org.jabref.gui.undo.CountingUndoManager; import org.jabref.logic.bibtex.LatexFieldFormatterPreferences; import org.jabref.logic.importer.ImportFormatPreferences; @@ -38,7 +39,7 @@ public class SourceTabTest { public void onStart(Stage stage) { area = new CodeArea(); area.appendText("some example\n text to go here\n across a couple of \n lines...."); - sourceTab = new SourceTab(new BibDatabaseContext(), new CountingUndoManager(), new LatexFieldFormatterPreferences(), mock(ImportFormatPreferences.class), new DummyFileUpdateMonitor(), mock(DialogService.class)); + sourceTab = new SourceTab(new BibDatabaseContext(), new CountingUndoManager(), new LatexFieldFormatterPreferences(), mock(ImportFormatPreferences.class), new DummyFileUpdateMonitor(), mock(DialogService.class), mock(StateManager.class)); pane = new TabPane( new Tab("main area", area), new Tab("other tab", new Label("some text")), From d0c5f2ebbd1c7664332b6a95a5bb93767f8bc1b2 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sun, 19 May 2019 22:18:59 +0200 Subject: [PATCH 19/24] Get rid of SearchQueryHighlightObservable Use SearchQuery directly TODO: fix updating of search results --- .../java/org/jabref/gui/StateManager.java | 23 ----- .../jabref/gui/entryeditor/EntryEditor.java | 8 -- .../org/jabref/gui/entryeditor/SourceTab.java | 32 ++++--- .../org/jabref/gui/preview/PreviewViewer.java | 38 ++++++--- .../jabref/gui/search/GlobalSearchBar.java | 20 ++--- .../org/jabref/logic/search/SearchQuery.java | 25 ++++++ .../search/SearchQueryHighlightListener.java | 20 ----- .../SearchQueryHighlightObservable.java | 85 ------------------- .../SearchQueryHighlightObservableTest.java | 59 ------------- .../jabref/logic/search/SearchQueryTest.java | 13 ++- 10 files changed, 95 insertions(+), 228 deletions(-) delete mode 100644 src/main/java/org/jabref/logic/search/SearchQueryHighlightListener.java delete mode 100644 src/main/java/org/jabref/logic/search/SearchQueryHighlightObservable.java delete mode 100644 src/test/java/org/jabref/logic/search/SearchQueryHighlightObservableTest.java diff --git a/src/main/java/org/jabref/gui/StateManager.java b/src/main/java/org/jabref/gui/StateManager.java index a73886d43a8..37e4bb68e52 100644 --- a/src/main/java/org/jabref/gui/StateManager.java +++ b/src/main/java/org/jabref/gui/StateManager.java @@ -16,8 +16,6 @@ import org.jabref.gui.util.OptionalObjectProperty; import org.jabref.logic.search.SearchQuery; -import org.jabref.logic.search.SearchQueryHighlightListener; -import org.jabref.logic.search.SearchQueryHighlightObservable; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.groups.GroupTreeNode; @@ -39,7 +37,6 @@ public class StateManager { private final ObservableMap> selectedGroups = FXCollections.observableHashMap(); private final OptionalObjectProperty activeSearchQuery = OptionalObjectProperty.empty(); private final IntegerProperty searchResultSize = new SimpleIntegerProperty(); - private final SearchQueryHighlightObservable searchQueryHighlightObservable = new SearchQueryHighlightObservable(); public StateManager() { activeGroups.bind(Bindings.valueAt(selectedGroups, activeDatabase.orElse(null))); @@ -99,24 +96,4 @@ public void setSearchQuery(SearchQuery searchQuery) { public IntegerProperty searchResultSizeProperty() { return searchResultSize; } - - public SearchQueryHighlightObservable getSearchQueryHighlightObservable() { - return searchQueryHighlightObservable; - } - - public void fireSearchQueryHighlightEvent() { - if (activeSearchQuery.get().isPresent()) { - searchQueryHighlightObservable.fireSearchlistenerEvent(activeSearchQuery.getValue().get()); - } - } - - public void resetSearchQueryHighlightObservable() - { - searchQueryHighlightObservable.reset(); - } - - public void addSearchQueryHighlightListener(SearchQueryHighlightListener listener) { - searchQueryHighlightObservable.removeSearchListener(listener); - searchQueryHighlightObservable.addSearchListener(listener); - } } diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index eb65cdc0cff..962d26832c4 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -46,7 +46,6 @@ import org.jabref.logic.help.HelpFile; import org.jabref.logic.importer.EntryBasedFetcher; import org.jabref.logic.importer.WebFetchers; -import org.jabref.logic.search.SearchQueryHighlightListener; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.util.FileUpdateMonitor; @@ -74,7 +73,6 @@ public class EntryEditor extends BorderPane { private final BibDatabaseContext databaseContext; private final CountingUndoManager undoManager; private final BasePanel panel; - private final List searchListeners = new ArrayList<>(); private Subscription typeSubscription; private final List tabs; private final FileUpdateMonitor fileMonitor; @@ -403,12 +401,6 @@ private void fetchAndMerge(EntryBasedFetcher fetcher) { new FetchAndMergeEntry(panel, taskExecutor).fetchAndMerge(entry, fetcher); } - void addSearchListener(SearchQueryHighlightListener listener) { - // TODO: Highlight search text in entry editors - searchListeners.add(listener); - - } - public void setFocusToField(String fieldName) { DefaultTaskExecutor.runInJavaFXThread(() -> { for (Tab tab : tabbed.getTabs()) { diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index 7c04527c3e1..8c967f132de 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -5,12 +5,16 @@ import java.io.StringWriter; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.swing.undo.UndoManager; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.geometry.Point2D; import javafx.scene.control.Tooltip; @@ -33,6 +37,7 @@ import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.fileformat.BibtexParser; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.search.SearchQuery; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.database.BibDatabaseMode; @@ -61,6 +66,7 @@ public class SourceTab extends EntryEditorTab { private final DialogService dialogService; private final StateManager stateManager; + private Optional searchHighlightPattern = Optional.empty(); private CodeArea codeArea; public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager, LatexFieldFormatterPreferences fieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor, DialogService dialogService, StateManager stateManager) { @@ -75,17 +81,23 @@ public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undo this.dialogService = dialogService; this.stateManager = stateManager; - stateManager.addSearchQueryHighlightListener(highlightPattern -> { - if (highlightPattern.isPresent() && codeArea != null) { - codeArea.setStyleClass(0, codeArea.getLength(), "text"); - Matcher matcher = highlightPattern.get().matcher(codeArea.getText()); - while (matcher.find()) { - for (int i = 0; i <= matcher.groupCount(); i++) { - codeArea.setStyleClass(matcher.start(), matcher.end(), "search"); - } + stateManager.activeSearchQueryProperty().addListener((observable, oldValue, newValue) -> { + searchHighlightPattern = newValue.flatMap(SearchQuery::getPatternForWords); + highlightSearchPattern(); + }); + + } + + private void highlightSearchPattern() { + if (searchHighlightPattern.isPresent() && codeArea != null) { + codeArea.setStyleClass(0, codeArea.getLength(), "text"); + Matcher matcher = searchHighlightPattern.get().matcher(codeArea.getText()); + while (matcher.find()) { + for (int i = 0; i <= matcher.groupCount(); i++) { + codeArea.setStyleClass(matcher.start(), matcher.end(), "search"); } } - }); + } } private static String getSourceString(BibEntry entry, BibDatabaseMode type, LatexFieldFormatterPreferences fieldFormatterPreferences) throws IOException { @@ -170,7 +182,7 @@ protected void bindToEntry(BibEntry entry) { codeArea.clear(); try { codeArea.appendText(getSourceString(entry, mode, fieldFormatterPreferences)); - stateManager.fireSearchQueryHighlightEvent(); + highlightSearchPattern(); } catch (IOException ex) { codeArea.setEditable(false); diff --git a/src/main/java/org/jabref/gui/preview/PreviewViewer.java b/src/main/java/org/jabref/gui/preview/PreviewViewer.java index bbc14907cec..bdac1d40cab 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewViewer.java +++ b/src/main/java/org/jabref/gui/preview/PreviewViewer.java @@ -2,10 +2,11 @@ import java.util.Objects; import java.util.Optional; +import java.util.regex.Pattern; import javafx.beans.InvalidationListener; import javafx.beans.Observable; -import javafx.beans.value.ObservableValue; +import javafx.beans.value.ChangeListener; import javafx.concurrent.Worker; import javafx.print.PrinterJob; import javafx.scene.control.ScrollPane; @@ -21,6 +22,7 @@ import org.jabref.logic.citationstyle.PreviewLayout; import org.jabref.logic.exporter.ExporterFactory; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.search.SearchQuery; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; @@ -57,6 +59,9 @@ public class PreviewViewer extends ScrollPane implements InvalidationListener { */ private Optional entry = Optional.empty(); private BibDatabaseContext database; + private boolean registered; + + private Optional searchHighlightPattern = Optional.empty(); /** * @param database Used for resolving strings and pdf directories for links. @@ -72,22 +77,31 @@ public PreviewViewer(BibDatabaseContext database, DialogService dialogService, S setContent(previewView); previewView.setContextMenuEnabled(false); - previewView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue observable, - Worker.State oldValue, - Worker.State newValue) -> { + previewView.getEngine().getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> { + if (newValue != Worker.State.SUCCEEDED) { return; } - stateManager.addSearchQueryHighlightListener(highlightPattern -> { - if (highlightPattern.isPresent()) { - String pattern = highlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); + if (!registered) { + stateManager.activeSearchQueryProperty().addListener(listener); + registered = true; + } + highlightSearchPattern(); + }); + + } - previewView.getEngine().executeScript("highlight('" + pattern + "');"); + private ChangeListener> listener = (queryObservable, queryOldValue, queryNewValue) -> { + searchHighlightPattern = queryNewValue.flatMap(SearchQuery::getPatternForWords); + highlightSearchPattern(); + }; - } - }); - }); + private void highlightSearchPattern() { + if (searchHighlightPattern.isPresent()) { + String pattern = searchHighlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); + previewView.getEngine().executeScript("highlight('" + pattern + "');"); + } } public void setLayout(PreviewLayout newLayout) { @@ -109,8 +123,8 @@ public void setEntry(BibEntry newEntry) { for (Observable observable : newEntry.getObservables()) { observable.addListener(this); } - update(); + } private void update() { diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 33a99a55961..8ab2a67e4c2 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -46,7 +46,6 @@ import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.l10n.Localization; import org.jabref.logic.search.SearchQuery; -import org.jabref.logic.search.SearchQueryHighlightObservable; import org.jabref.model.entry.Author; import org.jabref.preferences.SearchPreferences; @@ -73,7 +72,6 @@ public class GlobalSearchBar extends HBox { private final ToggleButton regularExp; private final Button searchModeButton = new Button(); private final Label currentResults = new Label(""); - private final SearchQueryHighlightObservable searchQueryHighlightObservable = new SearchQueryHighlightObservable(); private SearchDisplayMode searchDisplayMode; public GlobalSearchBar(JabRefFrame frame) { @@ -149,6 +147,16 @@ public GlobalSearchBar(JabRefFrame frame) { currentResults); this.setAlignment(Pos.CENTER_LEFT); + + //TODO Needs fixing, not yet working correctly + EasyBind.subscribe(Globals.stateManager.searchResultSizeProperty(), matchedResults -> { + + Globals.stateManager.activeSearchQueryProperty().getValue().ifPresent(searchQuery -> { + updateResults(matchedResults.intValue(), SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), + searchQuery.isGrammarBasedSearch()); + }); + + }); } private void toggleSearchModeAndSearch() { @@ -186,7 +194,6 @@ public void focus() { private void clearSearch() { currentResults.setText(""); searchField.setText(""); - Globals.stateManager.resetSearchQueryHighlightObservable(); Globals.stateManager.clearSearchQuery(); } @@ -209,18 +216,11 @@ public void performSearch() { Globals.stateManager.setSearchQuery(searchQuery); - updateResults(Globals.stateManager.searchResultSizeProperty().get(), - SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), - searchQuery.isGrammarBasedSearch()); - - } private void informUserAboutInvalidSearchQuery() { searchField.pseudoClassStateChanged(CLASS_NO_RESULTS, true); - searchQueryHighlightObservable.reset(); - Globals.stateManager.clearSearchQuery(); String illegalSearch = Localization.lang("Search failed: illegal search expression"); diff --git a/src/main/java/org/jabref/logic/search/SearchQuery.java b/src/main/java/org/jabref/logic/search/SearchQuery.java index 12b0639d6da..e6e35486767 100644 --- a/src/main/java/org/jabref/logic/search/SearchQuery.java +++ b/src/main/java/org/jabref/logic/search/SearchQuery.java @@ -3,6 +3,9 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Optional; +import java.util.StringJoiner; +import java.util.regex.Pattern; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; @@ -119,6 +122,28 @@ public List getSearchWords() { } } + // Returns a regular expression pattern in the form (w1)|(w2)| ... wi are escaped if no regular expression search is enabled + public Optional getPatternForWords() { + List words = getSearchWords(); + + if ((words == null) || words.isEmpty() || words.get(0).isEmpty()) { + return Optional.empty(); + } + + // compile the words to a regular expression in the form (w1)|(w2)|(w3) + StringJoiner joiner = new StringJoiner(")|(", "(", ")"); + for (String word : words) { + joiner.add(regularExpression ? word : Pattern.quote(word)); + } + String searchPattern = joiner.toString(); + + if (caseSensitive) { + return Optional.of(Pattern.compile(searchPattern)); + } else { + return Optional.of(Pattern.compile(searchPattern, Pattern.CASE_INSENSITIVE)); + } + } + public SearchRule getRule() { return rule; } diff --git a/src/main/java/org/jabref/logic/search/SearchQueryHighlightListener.java b/src/main/java/org/jabref/logic/search/SearchQueryHighlightListener.java deleted file mode 100644 index 5f88be0ae0a..00000000000 --- a/src/main/java/org/jabref/logic/search/SearchQueryHighlightListener.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.jabref.logic.search; - -import java.util.Optional; -import java.util.regex.Pattern; - -import com.google.common.eventbus.Subscribe; - -/** - * Every Listener that wants to receive events from a search needs to - * implement this interface - */ -@FunctionalInterface -public interface SearchQueryHighlightListener { - - /** - * Pattern with which one can determine what to highlight - */ - @Subscribe - void highlightPattern(Optional highlightPattern); -} diff --git a/src/main/java/org/jabref/logic/search/SearchQueryHighlightObservable.java b/src/main/java/org/jabref/logic/search/SearchQueryHighlightObservable.java deleted file mode 100644 index 1665e1b3294..00000000000 --- a/src/main/java/org/jabref/logic/search/SearchQueryHighlightObservable.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.jabref.logic.search; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.StringJoiner; -import java.util.regex.Pattern; - -import com.google.common.eventbus.EventBus; - -public class SearchQueryHighlightObservable { - - private final EventBus eventBus = new EventBus(); - - private Optional pattern = Optional.empty(); - - /** - * Adds a SearchQueryHighlightListener to the search bar. The added listener is immediately informed about the current search. - * Subscribers will be notified about searches. - * - * @param newListener SearchQueryHighlightListener to be added - */ - public void addSearchListener(SearchQueryHighlightListener newListener) { - Objects.requireNonNull(newListener); - - eventBus.register(newListener); - newListener.highlightPattern(pattern); - } - - public void removeSearchListener(SearchQueryHighlightListener listener) { - Objects.requireNonNull(listener); - - try { - eventBus.unregister(listener); - } catch (IllegalArgumentException e) { - // occurs if the event source has not been registered, should not prevent shutdown - } - } - /** - * Fires an event if a search was started (or cleared) - * - * @param searchQuery the search query - */ - - public void fireSearchlistenerEvent(SearchQuery searchQuery) { - Objects.requireNonNull(searchQuery); - - // Parse the search string to words - pattern = getPatternForWords(searchQuery.getSearchWords(), searchQuery.isRegularExpression(), - searchQuery.isCaseSensitive()); - - update(); - } - - public void reset() { - pattern = Optional.empty(); - update(); - } - - private void update() { - // Fire an event for every listener - eventBus.post(pattern); - } - - // Returns a regular expression pattern in the form (w1)|(w2)| ... wi are escaped if no regular expression search is enabled - public static Optional getPatternForWords(List words, boolean useRegex, boolean isCaseSensitive) { - if ((words == null) || words.isEmpty() || words.get(0).isEmpty()) { - return Optional.empty(); - } - - // compile the words to a regular expression in the form (w1)|(w2)|(w3) - StringJoiner joiner = new StringJoiner(")|(", "(", ")"); - for (String word : words) { - joiner.add(useRegex ? word : Pattern.quote(word)); - } - String searchPattern = joiner.toString(); - - if (isCaseSensitive) { - return Optional.of(Pattern.compile(searchPattern)); - } else { - return Optional.of(Pattern.compile(searchPattern, Pattern.CASE_INSENSITIVE)); - } - } - -} diff --git a/src/test/java/org/jabref/logic/search/SearchQueryHighlightObservableTest.java b/src/test/java/org/jabref/logic/search/SearchQueryHighlightObservableTest.java deleted file mode 100644 index fbe998e8a85..00000000000 --- a/src/test/java/org/jabref/logic/search/SearchQueryHighlightObservableTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.jabref.logic.search; - -import java.util.Optional; -import java.util.regex.Pattern; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.verify; - -class SearchQueryHighlightObservableTest { - - @Captor ArgumentCaptor> captor; - @Mock private SearchQueryHighlightListener listener; - private SearchQueryHighlightObservable observable; - - @BeforeEach - void setUp() throws Exception { - observable = new SearchQueryHighlightObservable(); - MockitoAnnotations.initMocks(this); - } - - @Test - void addSearchListenerNotifiesListenerAboutPreviousPattern() throws Exception { - observable.fireSearchlistenerEvent(new SearchQuery("test", false, false)); - - observable.addSearchListener(listener); - - verify(listener).highlightPattern(captor.capture()); - assertEquals("(\\Qtest\\E)", captor.getValue().get().pattern()); - } - - @Test - void addSearchListenerNotifiesRegisteredListener() throws Exception { - observable.addSearchListener(listener); - - observable.fireSearchlistenerEvent(new SearchQuery("test", false, false)); - - verify(listener, atLeastOnce()).highlightPattern(captor.capture()); - assertEquals("(\\Qtest\\E)", captor.getValue().get().pattern()); - } - - @Test - void addSearchListenerNotifiesRegisteredListenerAboutGrammarBasedSearches() throws Exception { - observable.addSearchListener(listener); - - observable.fireSearchlistenerEvent(new SearchQuery("author=harrer", false, false)); - - verify(listener, atLeastOnce()).highlightPattern(captor.capture()); - // TODO: We would expect "harrer" here - assertEquals("(\\Qauthor=harrer\\E)", captor.getValue().get().pattern()); - } -} diff --git a/src/test/java/org/jabref/logic/search/SearchQueryTest.java b/src/test/java/org/jabref/logic/search/SearchQueryTest.java index e4463f75155..34593c55d85 100644 --- a/src/test/java/org/jabref/logic/search/SearchQueryTest.java +++ b/src/test/java/org/jabref/logic/search/SearchQueryTest.java @@ -1,5 +1,8 @@ package org.jabref.logic.search; +import java.util.Optional; +import java.util.regex.Pattern; + import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibtexEntryTypes; import org.jabref.model.entry.FieldName; @@ -189,7 +192,15 @@ public void testSimpleTerm() { String query = "progress"; SearchQuery result = new SearchQuery(query, false, false); - assertFalse(result.isGrammarBasedSearch()); } + + @Test + public void testGetPattern() { + String query = "progress"; + SearchQuery result = new SearchQuery(query, false, false); + Pattern pattern = Pattern.compile("(\\Qprogress\\E)"); + //We can't directly compare the pattern objects + assertEquals(Optional.of(pattern.toString()), result.getPatternForWords().map(Pattern::toString)); + } } From 6db6073d554323fc5de2bc9c190ab02f2a3950cd Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 25 May 2019 13:32:03 +0200 Subject: [PATCH 20/24] update on search --- .../jabref/gui/maintable/MainTableDataModel.java | 1 + .../java/org/jabref/gui/search/GlobalSearchBar.java | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java index 1de3ca16169..0cd72de0e1f 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java @@ -35,6 +35,7 @@ public MainTableDataModel(BibDatabaseContext context) { Globals.stateManager.searchResultSizeProperty().bind(Bindings.size(entriesFiltered)); // We need to wrap the list since otherwise sorting in the table does not work entriesSorted = new SortedList<>(entriesFiltered); + } private boolean isMatched(BibEntryTableViewModel entry) { diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 7bf244224ff..41bbf9da8e1 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -159,14 +159,15 @@ public GlobalSearchBar(JabRefFrame frame) { this.setAlignment(Pos.CENTER_LEFT); //TODO Needs fixing, not yet working correctly - EasyBind.subscribe(Globals.stateManager.searchResultSizeProperty(), matchedResults -> { - - Globals.stateManager.activeSearchQueryProperty().getValue().ifPresent(searchQuery -> { - updateResults(matchedResults.intValue(), SearchDescribers.getSearchDescriberFor(searchQuery).getDescription(), - searchQuery.isGrammarBasedSearch()); + EasyBind.subscribe(Globals.stateManager.activeSearchQueryProperty(), searchQuery -> { + searchQuery.ifPresent(query -> { + + updateResults(Globals.stateManager.searchResultSizeProperty().intValue(), SearchDescribers.getSearchDescriberFor(query).getDescription(), + query.isGrammarBasedSearch()); }); }); + } private void toggleSearchModeAndSearch() { @@ -271,6 +272,8 @@ private SearchQuery getSearchQuery() { } public void updateResults(int matched, TextFlow description, boolean grammarBasedSearch) { + System.out.println("matched" + matched); + if (matched == 0) { currentResults.setText(Localization.lang("No results found.")); searchField.pseudoClassStateChanged(CLASS_NO_RESULTS, true); From da17d06ebacffb6485de643d96c74dd4d9f93f9b Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 25 May 2019 14:17:53 +0200 Subject: [PATCH 21/24] fix checkstyle --- .../jabref/gui/entryeditor/EntryEditor.java | 39 ++++++------------- .../org/jabref/gui/entryeditor/SourceTab.java | 2 - .../org/jabref/gui/preview/PreviewViewer.java | 4 +- 3 files changed, 14 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index 3ba9d14a26b..72fdf53f104 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -2,7 +2,6 @@ import java.io.File; import java.nio.file.Path; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -28,8 +27,6 @@ import org.jabref.gui.DialogService; import org.jabref.gui.GUIGlobals; import org.jabref.gui.StateManager; -import org.jabref.gui.actions.ActionFactory; -import org.jabref.gui.actions.StandardActions; import org.jabref.gui.bibtexkeypattern.GenerateBibtexKeySingleAction; import org.jabref.gui.entryeditor.fileannotationtab.FileAnnotationTab; import org.jabref.gui.externalfiles.ExternalFilesEntryLinker; @@ -111,9 +108,9 @@ public EntryEditor(BasePanel panel, EntryEditorPreferences preferences, FileUpda if (GUIGlobals.currentFont != null) { setStyle( - "text-area-background: " + ColorUtil.toHex(GUIGlobals.validFieldBackgroundColor) + ";" - + "text-area-foreground: " + ColorUtil.toHex(GUIGlobals.editorTextColor) + ";" - + "text-area-highlight: " + ColorUtil.toHex(GUIGlobals.activeBackgroundColor) + ";"); + "text-area-background: " + ColorUtil.toHex(GUIGlobals.validFieldBackgroundColor) + ";" + + "text-area-foreground: " + ColorUtil.toHex(GUIGlobals.editorTextColor) + ";" + + "text-area-highlight: " + ColorUtil.toHex(GUIGlobals.activeBackgroundColor) + ";"); } EasyBind.subscribe(tabbed.getSelectionModel().selectedItemProperty(), tab -> { @@ -142,58 +139,46 @@ public EntryEditor(BasePanel panel, EntryEditorPreferences preferences, FileUpda FileDragDropPreferenceType dragDropPreferencesType = Globals.prefs.getEntryEditorFileLinkPreference(); - if (dragDropPreferencesType == FileDragDropPreferenceType.MOVE) - { + if (dragDropPreferencesType == FileDragDropPreferenceType.MOVE) { if (event.getTransferMode() == TransferMode.LINK) //alt on win { LOGGER.debug("Mode LINK"); fileLinker.addFilesToEntry(entry, files); - } - else if (event.getTransferMode() == TransferMode.COPY) //ctrl on win, no modifier on Xubuntu + } else if (event.getTransferMode() == TransferMode.COPY) //ctrl on win, no modifier on Xubuntu { LOGGER.debug("Mode COPY"); fileLinker.copyFilesToFileDirAndAddToEntry(entry, files); - } - else - { + } else { LOGGER.debug("Mode MOVE"); //shift on win or no modifier fileLinker.moveFilesToFileDirAndAddToEntry(entry, files); } } - if (dragDropPreferencesType == FileDragDropPreferenceType.COPY) - { + if (dragDropPreferencesType == FileDragDropPreferenceType.COPY) { if (event.getTransferMode() == TransferMode.COPY) //ctrl on win, no modifier on Xubuntu { LOGGER.debug("Mode MOVE"); fileLinker.moveFilesToFileDirAndAddToEntry(entry, files); - } - else if (event.getTransferMode() == TransferMode.LINK) //alt on win + } else if (event.getTransferMode() == TransferMode.LINK) //alt on win { LOGGER.debug("Mode LINK"); fileLinker.addFilesToEntry(entry, files); - } - else - { + } else { LOGGER.debug("Mode COPY"); //shift on win or no modifier fileLinker.copyFilesToFileDirAndAddToEntry(entry, files); } } - if (dragDropPreferencesType == FileDragDropPreferenceType.LINK) - { + if (dragDropPreferencesType == FileDragDropPreferenceType.LINK) { if (event.getTransferMode() == TransferMode.COPY) //ctrl on win, no modifier on Xubuntu { LOGGER.debug("Mode COPY"); fileLinker.copyFilesToFileDirAndAddToEntry(entry, files); - } - else if (event.getTransferMode() == TransferMode.LINK) //alt on win + } else if (event.getTransferMode() == TransferMode.LINK) //alt on win { LOGGER.debug("Mode MOVE"); fileLinker.moveFilesToFileDirAndAddToEntry(entry, files); - } - else - { + } else { LOGGER.debug("Mode LINK"); //shift on win or no modifier fileLinker.addFilesToEntry(entry, files); } diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index 8c967f132de..c8fa3c87b37 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -13,8 +13,6 @@ import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.geometry.Point2D; import javafx.scene.control.Tooltip; diff --git a/src/main/java/org/jabref/gui/preview/PreviewViewer.java b/src/main/java/org/jabref/gui/preview/PreviewViewer.java index bdac1d40cab..5dadf8632fc 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewViewer.java +++ b/src/main/java/org/jabref/gui/preview/PreviewViewer.java @@ -37,8 +37,6 @@ */ public class PreviewViewer extends ScrollPane implements InvalidationListener { - private static final Logger LOGGER = LoggerFactory.getLogger(PreviewViewer.class); - private static final String JS_HIGHLIGHT_FUNCTION = " "; + private static final Logger LOGGER = LoggerFactory.getLogger(PreviewViewer.class); + private final ClipBoardManager clipBoardManager; private final DialogService dialogService; From 63678c239b07637ee5f7aec422d88ec93872f979 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 25 May 2019 14:29:05 +0200 Subject: [PATCH 22/24] try again with checkstyle declaration order --- .../org/jabref/gui/preview/PreviewViewer.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jabref/gui/preview/PreviewViewer.java b/src/main/java/org/jabref/gui/preview/PreviewViewer.java index 5dadf8632fc..8811d398b88 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewViewer.java +++ b/src/main/java/org/jabref/gui/preview/PreviewViewer.java @@ -37,6 +37,8 @@ */ public class PreviewViewer extends ScrollPane implements InvalidationListener { + private static final Logger LOGGER = LoggerFactory.getLogger(PreviewViewer.class); + private static final String JS_HIGHLIGHT_FUNCTION = " "; - private static final Logger LOGGER = LoggerFactory.getLogger(PreviewViewer.class); - private final ClipBoardManager clipBoardManager; private final DialogService dialogService; @@ -58,10 +58,15 @@ public class PreviewViewer extends ScrollPane implements InvalidationListener { * The entry currently shown */ private Optional entry = Optional.empty(); + private Optional searchHighlightPattern = Optional.empty(); + private BibDatabaseContext database; private boolean registered; - private Optional searchHighlightPattern = Optional.empty(); + private ChangeListener> listener = (queryObservable, queryOldValue, queryNewValue) -> { + searchHighlightPattern = queryNewValue.flatMap(SearchQuery::getPatternForWords); + highlightSearchPattern(); + }; /** * @param database Used for resolving strings and pdf directories for links. @@ -91,11 +96,6 @@ public PreviewViewer(BibDatabaseContext database, DialogService dialogService, S } - private ChangeListener> listener = (queryObservable, queryOldValue, queryNewValue) -> { - searchHighlightPattern = queryNewValue.flatMap(SearchQuery::getPatternForWords); - highlightSearchPattern(); - }; - private void highlightSearchPattern() { if (searchHighlightPattern.isPresent()) { String pattern = searchHighlightPattern.get().pattern().replace("\\Q", "").replace("\\E", ""); From 6a220bd44691750d81d01e6d1942ac460455a92b Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Mon, 27 May 2019 20:51:54 +0200 Subject: [PATCH 23/24] Finally fix the number of search results on multiple libs --- src/main/java/org/jabref/gui/StateManager.java | 18 ++++++++++-------- .../gui/maintable/MainTableDataModel.java | 9 +++++++-- .../org/jabref/gui/search/GlobalSearchBar.java | 12 ++---------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/jabref/gui/StateManager.java b/src/main/java/org/jabref/gui/StateManager.java index 37e4bb68e52..f9a0076d70f 100644 --- a/src/main/java/org/jabref/gui/StateManager.java +++ b/src/main/java/org/jabref/gui/StateManager.java @@ -9,7 +9,6 @@ import javafx.beans.property.IntegerProperty; import javafx.beans.property.ReadOnlyListProperty; import javafx.beans.property.ReadOnlyListWrapper; -import javafx.beans.property.SimpleIntegerProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.ObservableMap; @@ -25,9 +24,8 @@ * This class manages the GUI-state of JabRef, including: * - currently selected database * - currently selected group - * Coming soon: - * - open databases * - active search + * - active number of search results */ public class StateManager { @@ -36,7 +34,7 @@ public class StateManager { private final ObservableList selectedEntries = FXCollections.observableArrayList(); private final ObservableMap> selectedGroups = FXCollections.observableHashMap(); private final OptionalObjectProperty activeSearchQuery = OptionalObjectProperty.empty(); - private final IntegerProperty searchResultSize = new SimpleIntegerProperty(); + private final ObservableMap searchResultMap = FXCollections.observableHashMap(); public StateManager() { activeGroups.bind(Bindings.valueAt(selectedGroups, activeDatabase.orElse(null))); @@ -50,6 +48,14 @@ public OptionalObjectProperty activeSearchQueryProperty() { return activeSearchQuery; } + public void setActiveSearchResultSize(BibDatabaseContext database, IntegerProperty resultSize) { + searchResultMap.put(database, resultSize); + } + + public IntegerProperty getSearchResultSize() { + return searchResultMap.get(activeDatabase.getValue().orElse(new BibDatabaseContext())); + } + public ReadOnlyListProperty activeGroupProperty() { return activeGroups.getReadOnlyProperty(); } @@ -92,8 +98,4 @@ public void clearSearchQuery() { public void setSearchQuery(SearchQuery searchQuery) { activeSearchQuery.setValue(Optional.of(searchQuery)); } - - public IntegerProperty searchResultSizeProperty() { - return searchResultSize; - } } diff --git a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java index 0cd72de0e1f..5adc82434c9 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java @@ -4,6 +4,8 @@ import java.util.Optional; import javafx.beans.binding.Bindings; +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; import javafx.collections.transformation.SortedList; @@ -17,6 +19,7 @@ import org.jabref.model.search.matchers.MatcherSet; import org.jabref.model.search.matchers.MatcherSets; + public class MainTableDataModel { private final FilteredList entriesFiltered; private final SortedList entriesSorted; @@ -32,10 +35,12 @@ public MainTableDataModel(BibDatabaseContext context) { Globals.stateManager.activeGroupProperty(), Globals.stateManager.activeSearchQueryProperty()) ); - Globals.stateManager.searchResultSizeProperty().bind(Bindings.size(entriesFiltered)); + + IntegerProperty resultSize = new SimpleIntegerProperty(); + resultSize.bind(Bindings.size(entriesFiltered)); + Globals.stateManager.setActiveSearchResultSize(context, resultSize); // We need to wrap the list since otherwise sorting in the table does not work entriesSorted = new SortedList<>(entriesFiltered); - } private boolean isMatched(BibEntryTableViewModel entry) { diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 41bbf9da8e1..efd2aab5258 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -152,22 +152,16 @@ public GlobalSearchBar(JabRefFrame frame) { } }); - this.getChildren().addAll( - searchField, - currentResults); + this.getChildren().addAll(searchField, currentResults); this.setAlignment(Pos.CENTER_LEFT); - //TODO Needs fixing, not yet working correctly EasyBind.subscribe(Globals.stateManager.activeSearchQueryProperty(), searchQuery -> { searchQuery.ifPresent(query -> { - - updateResults(Globals.stateManager.searchResultSizeProperty().intValue(), SearchDescribers.getSearchDescriberFor(query).getDescription(), + updateResults(Globals.stateManager.getSearchResultSize().intValue(), SearchDescribers.getSearchDescriberFor(query).getDescription(), query.isGrammarBasedSearch()); }); - }); - } private void toggleSearchModeAndSearch() { @@ -272,8 +266,6 @@ private SearchQuery getSearchQuery() { } public void updateResults(int matched, TextFlow description, boolean grammarBasedSearch) { - System.out.println("matched" + matched); - if (matched == 0) { currentResults.setText(Localization.lang("No results found.")); searchField.pseudoClassStateChanged(CLASS_NO_RESULTS, true); From 752e433ec7dc5d34878388ac933d63a561402289 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Mon, 27 May 2019 20:56:16 +0200 Subject: [PATCH 24/24] fix checkstyle --- src/main/java/org/jabref/gui/maintable/MainTableDataModel.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java index 5adc82434c9..da3c0724790 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java +++ b/src/main/java/org/jabref/gui/maintable/MainTableDataModel.java @@ -19,7 +19,6 @@ import org.jabref.model.search.matchers.MatcherSet; import org.jabref.model.search.matchers.MatcherSets; - public class MainTableDataModel { private final FilteredList entriesFiltered; private final SortedList entriesSorted;