Skip to content

Commit 446a593

Browse files
Merge pull request #332 from JabRef/uisearchhistory
Better search
2 parents a9790d8 + f453017 commit 446a593

File tree

62 files changed

+1829
-1666
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1829
-1666
lines changed

CHANGELOG.md

+14
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ to [sourceforge feature requests](https://sourceforge.net/p/jabref/features/) by
2828
- Feature: Merge information from both entries on duplication detection
2929
- Always use import inspection dialog on import from file
3030
- All duplicate whitespaces / tabs / newlines are now removed from non-multiline fields
31+
- Improvements to search:
32+
- Search bar is now at the top
33+
- A summary of the search result is shown in textual form in the search bar
34+
- The search text field changes its color based on the search result (red if nothing is found, green if at least one entry is found)
35+
- Autocompletion suggestions are shown in a popup
36+
- Search options are available via a drop-down list, this implements Feature Request #853
37+
- "Clear search" button also clears search field, this implements Feature Request #601
38+
- Every search is done automatically (live) as soon as the search text is changed
39+
- Search is local by default. To do a global search, one has to do a local search and then this search can be done globally as well, opening a new window.
40+
- The local search results can be shown in a new window.
3141
- Feature: Merge information from a DOI generated BibTex entry to an entry
3242
- Added more characters to HTML/Unicode converter
3343
- Feature: Push citations to Texmaker ([bug 318](https://sourceforge.net/p/jabref/bugs/318/), [bug 582](https://sourceforge.net/p/jabref/bugs/582/))
@@ -101,6 +111,10 @@ to [sourceforge feature requests](https://sourceforge.net/p/jabref/features/) by
101111
- Remove support for key bindings per external application by allowing only the key binding "push to application" for the currently selected external application.
102112
- Remove "edit preamble" from toolbar
103113
- Remove support to the move-to-SysTray action
114+
- Remove incremental search
115+
- Remove option to disable autocompleters for search and make this always one
116+
- Remove option to highlight matches and make this always one when not using regex or grammar-based search
117+
104118
- Remove option Tools -> Open PDF or PS which is replaced by Tools -> Open File
105119

106120
## 2.80 - never released

src/main/java/net/sf/jabref/JabRef.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public void start(String[] args) {
154154
return;
155155
}
156156

157-
openWindow(loaded);
157+
SwingUtilities.invokeLater(() -> openWindow(loaded));
158158
}
159159

160160
private void setupLogHandlerForErrorConsole() {

src/main/java/net/sf/jabref/JabRefPreferences.java

+14-30
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,8 @@ public class JabRefPreferences {
130130
public static final String SIDE_PANE_COMPONENT_NAMES = "sidePaneComponentNames";
131131
public static final String XMP_PRIVACY_FILTERS = "xmpPrivacyFilters";
132132
public static final String USE_XMP_PRIVACY_FILTER = "useXmpPrivacyFilter";
133-
public static final String SEARCH_AUTO_COMPLETE = "searchAutoComplete";
134-
public static final String INCREMENT_S = "incrementS";
135-
public static final String SEARCH_ALL = "searchAll";
136-
public static final String SEARCH_GEN = "searchGen";
137-
public static final String SEARCH_OPT = "searchOpt";
138-
public static final String SEARCH_REQ = "searchReq";
139-
public static final String CASE_SENSITIVE_SEARCH = "caseSensitiveSearch";
133+
public static final String SEARCH_MODE_FILTER = "searchModeFilter";
134+
public static final String SEARCH_CASE_SENSITIVE = "caseSensitiveSearch";
140135
public static final String DEFAULT_AUTO_SORT = "defaultAutoSort";
141136
public static final String DEFAULT_SHOW_SOURCE = "defaultShowSource";
142137
public static final String STRINGS_SIZE_Y = "stringsSizeY";
@@ -169,9 +164,9 @@ public class JabRefPreferences {
169164
public static final String AUTO_COMP_FIRST_LAST = "autoCompFF";
170165
public static final String AUTO_COMPLETE_FIELDS = "autoCompleteFields";
171166
public static final String AUTO_COMPLETE = "autoComplete";
172-
public static final String HIGH_LIGHT_WORDS = "highLightWords";
173-
public static final String REG_EXP_SEARCH = "regExpSearch";
174-
public static final String SELECT_S = "selectS";
167+
public static final String SEARCH_PANE_POS_Y = "searchPanePosY";
168+
public static final String SEARCH_PANE_POS_X = "searchPanePosX";
169+
public static final String SEARCH_REG_EXP = "regExpSearch";
175170
public static final String EDITOR_EMACS_KEYBINDINGS = "editorEMACSkeyBindings";
176171
public static final String EDITOR_EMACS_KEYBINDINGS_REBIND_CA = "editorEMACSkeyBindingsRebindCA";
177172
public static final String EDITOR_EMACS_KEYBINDINGS_REBIND_CF = "editorEMACSkeyBindingsRebindCF";
@@ -233,7 +228,6 @@ public class JabRefPreferences {
233228
public static final String DEFAULT_OWNER = "defaultOwner";
234229
public static final String GROUPS_VISIBLE_ROWS = "groupsVisibleRows";
235230
public static final String DEFAULT_ENCODING = "defaultEncoding";
236-
public static final String SEARCH_PANEL_VISIBLE = "searchPanelVisible";
237231
public static final String TOOLBAR_VISIBLE = "toolbarVisible";
238232
public static final String HIGHLIGHT_GROUPS_MATCHING_ALL = "highlightGroupsMatchingAll";
239233
public static final String HIGHLIGHT_GROUPS_MATCHING_ANY = "highlightGroupsMatchingAny";
@@ -262,9 +256,7 @@ public class JabRefPreferences {
262256
// When this should be made possible, the code to inspect is net.sf.jabref.gui.preftabs.LabelPatternPrefTab.storeSettings() -> LabelPattern keypatterns = getLabelPattern(); etc
263257
public static final String DEFAULT_LABEL_PATTERN = "defaultLabelPattern";
264258

265-
public static final String SEARCH_ALL_BASES = "searchAllBases";
266-
public static final String SHOW_SEARCH_IN_DIALOG = "showSearchInDialog";
267-
public static final String FLOAT_SEARCH = "floatSearch";
259+
public static final String SEARCH_MODE_FLOAT = "floatSearch";
268260
public static final String GRAY_OUT_NON_HITS = "grayOutNonHits";
269261
public static final String CONFIRM_DELETE = "confirmDelete";
270262
public static final String WARN_BEFORE_OVERWRITING_KEY = "warnBeforeOverwritingKey";
@@ -553,25 +545,20 @@ private JabRefPreferences() {
553545
defaults.put(MERGEENTRIES_SIZE_Y, 600);
554546
defaults.put(DEFAULT_SHOW_SOURCE, Boolean.FALSE);
555547
defaults.put(DEFAULT_AUTO_SORT, Boolean.FALSE);
556-
defaults.put(CASE_SENSITIVE_SEARCH, Boolean.FALSE);
557-
defaults.put(SEARCH_REQ, Boolean.TRUE);
558-
defaults.put(SEARCH_OPT, Boolean.TRUE);
559-
defaults.put(SEARCH_GEN, Boolean.TRUE);
560-
defaults.put(SEARCH_ALL, Boolean.FALSE);
561-
defaults.put(INCREMENT_S, Boolean.FALSE);
562-
defaults.put(SEARCH_AUTO_COMPLETE, Boolean.TRUE);
563-
564-
defaults.put(SELECT_S, Boolean.FALSE);
565-
defaults.put(REG_EXP_SEARCH, Boolean.TRUE);
566-
defaults.put(HIGH_LIGHT_WORDS, Boolean.TRUE);
548+
defaults.put(SEARCH_CASE_SENSITIVE, Boolean.FALSE);
549+
defaults.put(SEARCH_MODE_FILTER, Boolean.TRUE);
550+
551+
defaults.put(SEARCH_REG_EXP, Boolean.FALSE);
552+
defaults.put(SEARCH_PANE_POS_X, 0);
553+
defaults.put(SEARCH_PANE_POS_Y, 0);
567554
defaults.put(EDITOR_EMACS_KEYBINDINGS, Boolean.FALSE);
568555
defaults.put(EDITOR_EMACS_KEYBINDINGS_REBIND_CA, Boolean.TRUE);
569556
defaults.put(EDITOR_EMACS_KEYBINDINGS_REBIND_CF, Boolean.TRUE);
570557
defaults.put(AUTO_COMPLETE, Boolean.TRUE);
571558
defaults.put(AUTO_COMPLETE_FIELDS, "author;editor;title;journal;publisher;keywords;crossref");
572559
defaults.put(AUTO_COMP_FIRST_LAST, Boolean.FALSE); // "Autocomplete names in 'Firstname Lastname' format only"
573560
defaults.put(AUTO_COMP_LAST_FIRST, Boolean.FALSE); // "Autocomplete names in 'Lastname, Firstname' format only"
574-
defaults.put(SHORTEST_TO_COMPLETE, 2);
561+
defaults.put(SHORTEST_TO_COMPLETE, 1);
575562
defaults.put(AUTOCOMPLETE_FIRSTNAME_MODE, JabRefPreferences.AUTOCOMPLETE_FIRSTNAME_MODE_BOTH);
576563
defaults.put(GROUP_FLOAT_SELECTIONS, Boolean.TRUE);
577564
defaults.put(GROUP_INTERSECT_SELECTIONS, Boolean.TRUE);
@@ -591,7 +578,6 @@ private JabRefPreferences() {
591578
defaults.put(HIGHLIGHT_GROUPS_MATCHING_ANY, Boolean.FALSE);
592579
defaults.put(HIGHLIGHT_GROUPS_MATCHING_ALL, Boolean.FALSE);
593580
defaults.put(TOOLBAR_VISIBLE, Boolean.TRUE);
594-
defaults.put(SEARCH_PANEL_VISIBLE, Boolean.FALSE);
595581
defaults.put(DEFAULT_ENCODING, "UTF-8");
596582
defaults.put(GROUPS_VISIBLE_ROWS, 8);
597583
defaults.put(DEFAULT_OWNER, System.getProperty("user.name"));
@@ -665,9 +651,7 @@ private JabRefPreferences() {
665651
defaults.put(WARN_BEFORE_OVERWRITING_KEY, Boolean.TRUE);
666652
defaults.put(CONFIRM_DELETE, Boolean.TRUE);
667653
defaults.put(GRAY_OUT_NON_HITS, Boolean.TRUE);
668-
defaults.put(FLOAT_SEARCH, Boolean.TRUE);
669-
defaults.put(SHOW_SEARCH_IN_DIALOG, Boolean.FALSE);
670-
defaults.put(SEARCH_ALL_BASES, Boolean.FALSE);
654+
defaults.put(SEARCH_MODE_FLOAT, Boolean.FALSE);
671655
defaults.put(DEFAULT_LABEL_PATTERN, "[authors3][year]");
672656
defaults.put(PREVIEW_ENABLED, Boolean.TRUE);
673657
defaults.put(ACTIVE_PREVIEW, 0);

src/main/java/net/sf/jabref/SearchManagerNoGUI.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Collection;
1919
import java.util.Vector;
2020

21+
import net.sf.jabref.logic.search.SearchQuery;
2122
import org.apache.commons.logging.Log;
2223
import org.apache.commons.logging.LogFactory;
2324

@@ -49,19 +50,18 @@ public BibtexDatabase getDBfromMatches() {
4950
searchTerm = fieldYear();
5051
}
5152

52-
SearchRule searchRule = SearchRules.getSearchRuleByQuery(searchTerm,
53-
Globals.prefs.getBoolean(JabRefPreferences.CASE_SENSITIVE_SEARCH),
54-
Globals.prefs.getBoolean(JabRefPreferences.REG_EXP_SEARCH));
53+
SearchQuery searchQuery = new SearchQuery(searchTerm, Globals.prefs.getBoolean(JabRefPreferences.SEARCH_CASE_SENSITIVE),
54+
Globals.prefs.getBoolean(JabRefPreferences.SEARCH_REG_EXP));
5555

56-
if (!searchRule.validateSearchStrings(searchTerm)) {
56+
if (!searchQuery.isValidQuery()) {
5757
LOGGER.warn("Search failed: illegal search expression");
5858
return base;
5959
}
6060

6161
Collection<BibtexEntry> entries = database.getEntries();
6262
Vector<BibtexEntry> matchEntries = new Vector<>();
6363
for (BibtexEntry entry : entries) {
64-
boolean hit = searchRule.applyRule(searchTerm, entry);
64+
boolean hit = searchQuery.isMatch(entry);
6565
entry.setSearchHit(hit);
6666
if (hit) {
6767
matchEntries.add(entry);

src/main/java/net/sf/jabref/exporter/layout/Layout.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.commons.logging.LogFactory;
2222

2323
import java.util.ArrayList;
24+
import java.util.List;
2425

2526
import net.sf.jabref.model.database.BibtexDatabase;
2627
import net.sf.jabref.model.entry.BibtexEntry;
@@ -36,7 +37,7 @@ public class Layout {
3637

3738
private static final Log LOGGER = LogFactory.getLog(Layout.class);
3839

39-
public Layout(Vector<StringInt> parsedEntries, String classPrefix) throws Exception {
40+
public Layout(Vector<StringInt> parsedEntries, String classPrefix) {
4041
StringInt si;
4142
Vector<LayoutEntry> tmpEntries = new Vector<>(parsedEntries.size());
4243

@@ -121,8 +122,7 @@ public String doLayout(BibtexEntry bibtex, BibtexDatabase database) {
121122
* string references will be replaced by the strings' contents. Even
122123
* recursive string references are resolved.
123124
*/
124-
public String doLayout(BibtexEntry bibtex, BibtexDatabase database, ArrayList<String> wordsToHighlight)
125-
{
125+
public String doLayout(BibtexEntry bibtex, BibtexDatabase database, List<String> wordsToHighlight) {
126126
StringBuilder sb = new StringBuilder(100);
127127

128128
for (LayoutEntry layoutEntry : layoutEntries) {

src/main/java/net/sf/jabref/exporter/layout/LayoutEntry.java

+10-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
import java.io.File;
1919
import java.util.ArrayList;
20+
import java.util.HashMap;
21+
import java.util.List;
2022
import java.util.Map;
2123
import java.util.Vector;
2224
import java.util.regex.Matcher;
@@ -58,7 +60,7 @@ class LayoutEntry {
5860
private static final Log LOGGER = LogFactory.getLog(LayoutEntry.class);
5961

6062

61-
public LayoutEntry(StringInt si, String classPrefix_) throws Exception {
63+
public LayoutEntry(StringInt si, String classPrefix_) {
6264
type = si.i;
6365
classPrefix = classPrefix_;
6466

@@ -94,7 +96,7 @@ public LayoutEntry(StringInt si, String classPrefix_) throws Exception {
9496
}
9597
}
9698

97-
public LayoutEntry(Vector<StringInt> parsedEntries, String classPrefix_, int layoutType) throws Exception {
99+
public LayoutEntry(Vector<StringInt> parsedEntries, String classPrefix_, int layoutType) {
98100
classPrefix = classPrefix_;
99101
String blockStart;
100102
String blockEnd;
@@ -177,7 +179,7 @@ private String doLayout(BibtexEntry bibtex, BibtexDatabase database) {
177179
return doLayout(bibtex, database, null);
178180
}
179181

180-
public String doLayout(BibtexEntry bibtex, BibtexDatabase database, ArrayList<String> wordsToHighlight) {
182+
public String doLayout(BibtexEntry bibtex, BibtexDatabase database, List<String> wordsToHighlight) {
181183
switch (type) {
182184
case LayoutHelper.IS_LAYOUT_TEXT:
183185
return text;
@@ -479,16 +481,16 @@ public ArrayList<String> getInvalidFormatters() {
479481
* This check is a quick hack to avoid highlighting of HTML tags It does not always work, but it does its job mostly
480482
*
481483
* @param text This is a String in which we search for different words
482-
* @param toHighlight List of all words which must be highlighted
483-
*
484+
* @param wordsToHighlight List of all words which must be highlighted
485+
*
484486
* @return String that was called by the method, with HTML Tags if a word was found
485487
*/
486-
private String highlightWords(String text, ArrayList<String> toHighlight) {
487-
if (toHighlight == null) {
488+
private String highlightWords(String text, List<String> wordsToHighlight) {
489+
if (wordsToHighlight == null) {
488490
return text;
489491
}
490492

491-
Matcher matcher = Util.getPatternForWords(toHighlight).matcher(text);
493+
Matcher matcher = Util.getPatternForWords(wordsToHighlight).matcher(text);
492494

493495
if (Character.isLetterOrDigit(text.charAt(0))) {
494496
String hlColor = HIGHLIGHT_COLOR;

src/main/java/net/sf/jabref/exporter/layout/LayoutHelper.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public LayoutHelper(Reader in) {
5858
_in = new PushbackReader(in);
5959
}
6060

61-
public Layout getLayoutFromText(String classPrefix) throws Exception {
61+
public Layout getLayoutFromText(String classPrefix) throws IOException {
6262
parse();
6363

6464
StringInt si;

src/main/java/net/sf/jabref/groups/GroupSelector.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ public void valueChanged(TreeSelectionEvent e) {
710710
final TreePath[] selection = groupsTree.getSelectionPaths();
711711
if ((selection == null) || (selection.length == 0) || ((selection.length == 1)
712712
&& (((GroupTreeNode) selection[0].getLastPathComponent()).getGroup() instanceof AllEntriesGroup))) {
713-
panel.stopShowingGroup();
713+
panel.getFilterGroupToggle().stop();
714714
panel.mainTable.stopShowingFloatGrouping();
715715
if (showOverlappingGroups.isSelected()) {
716716
groupsTree.setHighlight2Cells(null);
@@ -784,11 +784,11 @@ public void update() {
784784
// Show the result in the chosen way:
785785
if (hideNonHits.isSelected()) {
786786
panel.mainTable.stopShowingFloatGrouping(); // Turn off shading, if active.
787-
panel.setGroupMatcher(GroupMatcher.INSTANCE); // Turn on filtering.
787+
panel.getFilterGroupToggle().start(); // Turn on filtering.
788788

789789
} else if (grayOut.isSelected()) {
790-
panel.stopShowingGroup(); // Turn off filtering, if active.
791-
panel.mainTable.showFloatGrouping(GroupMatcher.INSTANCE); // Turn on shading.
790+
panel.getFilterGroupToggle().stop(); // Turn off filtering, if active.
791+
panel.mainTable.showFloatGrouping(); // Turn on shading.
792792
}
793793

794794
if (showOverlappingGroupsP) {
@@ -889,7 +889,7 @@ public void componentOpening() {
889889
@Override
890890
public void componentClosing() {
891891
if (panel != null) {// panel may be null if no file is open any more
892-
panel.stopShowingGroup();
892+
panel.getFilterGroupToggle().stop();
893893
panel.mainTable.stopShowingFloatGrouping();
894894
}
895895
frame.groupToggle.setSelected(false);

0 commit comments

Comments
 (0)