9
9
10
10
import javax .swing .undo .UndoManager ;
11
11
12
- import javafx .application .Platform ;
13
12
import javafx .beans .binding .Bindings ;
14
13
import javafx .beans .binding .BooleanBinding ;
15
14
import javafx .beans .property .BooleanProperty ;
16
15
import javafx .beans .property .SimpleBooleanProperty ;
17
16
import javafx .collections .ListChangeListener ;
18
- import javafx .collections .ObservableList ;
17
+ import javafx .collections .SetChangeListener ;
19
18
import javafx .css .PseudoClass ;
20
19
import javafx .event .Event ;
21
20
import javafx .geometry .Insets ;
55
54
import org .jabref .gui .keyboard .KeyBindingRepository ;
56
55
import org .jabref .gui .search .rules .describer .SearchDescribers ;
57
56
import org .jabref .gui .util .BindingsHelper ;
58
- import org .jabref .gui .util .IconValidationDecorator ;
59
57
import org .jabref .gui .util .OptionalObjectProperty ;
60
58
import org .jabref .gui .util .TooltipTextUtil ;
61
59
import org .jabref .gui .util .UiTaskExecutor ;
66
64
import org .jabref .preferences .PreferencesService ;
67
65
import org .jabref .preferences .SearchPreferences ;
68
66
69
- import de .saxsys .mvvmfx .utils .validation .FunctionBasedValidator ;
70
- import de .saxsys .mvvmfx .utils .validation .ValidationMessage ;
71
- import de .saxsys .mvvmfx .utils .validation .Validator ;
72
- import de .saxsys .mvvmfx .utils .validation .visualization .ControlsFxVisualizer ;
73
67
import impl .org .controlsfx .skin .AutoCompletePopup ;
74
68
import org .controlsfx .control .textfield .AutoCompletionBinding ;
75
69
import org .controlsfx .control .textfield .CustomTextField ;
@@ -99,7 +93,6 @@ public class GlobalSearchBar extends HBox {
99
93
100
94
private final StateManager stateManager ;
101
95
private final PreferencesService preferencesService ;
102
- private final Validator regexValidator ;
103
96
private final UndoManager undoManager ;
104
97
private final LibraryTabContainer tabContainer ;
105
98
@@ -145,32 +138,22 @@ public GlobalSearchBar(LibraryTabContainer tabContainer,
145
138
146
139
searchField .addEventFilter (KeyEvent .KEY_PRESSED , event -> {
147
140
if (keyBindingRepository .matches (event , KeyBinding .CLEAR_SEARCH )) {
148
- // Clear search and select first entry, if available
149
141
searchField .clear ();
150
142
if (searchType == SearchType .NORMAL_SEARCH ) {
151
- tabContainer .getCurrentLibraryTab ().getMainTable ().getSelectionModel (). selectFirst ();
143
+ tabContainer .getCurrentLibraryTab ().getMainTable ().requestFocus ();
152
144
}
153
145
event .consume ();
154
146
}
155
147
});
156
148
157
- searchField .setContextMenu (SearchFieldRightClickMenu .create (
158
- stateManager ,
159
- searchField ,
160
- tabContainer ,
161
- undoManager ));
162
-
163
- ObservableList <String > search = stateManager .getWholeSearchHistory ();
164
- search .addListener ((ListChangeListener .Change <? extends String > change ) ->
165
- searchField .setContextMenu (SearchFieldRightClickMenu .create (
166
- stateManager ,
167
- searchField ,
168
- tabContainer ,
169
- undoManager ))
170
- );
171
-
172
149
ClipBoardManager .addX11Support (searchField );
173
150
151
+ searchField .setContextMenu (SearchFieldRightClickMenu .create (stateManager , searchField ));
152
+ stateManager .getWholeSearchHistory ().addListener ((ListChangeListener .Change <? extends String > change ) -> {
153
+ searchField .getContextMenu ().getItems ().removeLast ();
154
+ searchField .getContextMenu ().getItems ().add (SearchFieldRightClickMenu .createSearchFromHistorySubMenu (stateManager , searchField ));
155
+ });
156
+
174
157
regularExpressionButton = IconTheme .JabRefIcons .REG_EX .asToggleButton ();
175
158
caseSensitiveButton = IconTheme .JabRefIcons .CASE_SENSITIVE .asToggleButton ();
176
159
fulltextButton = IconTheme .JabRefIcons .FULLTEXT .asToggleButton ();
@@ -184,8 +167,7 @@ public GlobalSearchBar(LibraryTabContainer tabContainer,
184
167
.or (caseSensitiveButton .focusedProperty ())
185
168
.or (fulltextButton .focusedProperty ())
186
169
.or (keepSearchString .focusedProperty ())
187
- .or (searchField .textProperty ()
188
- .isNotEmpty ());
170
+ .or (searchField .textProperty ().isNotEmpty ());
189
171
190
172
regularExpressionButton .visibleProperty ().unbind ();
191
173
regularExpressionButton .visibleProperty ().bind (focusedOrActive );
@@ -205,18 +187,10 @@ public GlobalSearchBar(LibraryTabContainer tabContainer,
205
187
206
188
modifierButtons .setAlignment (Pos .CENTER );
207
189
searchField .setRight (new HBox (searchField .getRight (), modifierButtons ));
208
- searchField .getStyleClass ().add ("search-field " );
190
+ searchField .getStyleClass ().add ("global- search-bar " );
209
191
searchField .setMinWidth (100 );
210
192
HBox .setHgrow (searchField , Priority .ALWAYS );
211
193
212
- regexValidator = new FunctionBasedValidator <>(
213
- searchField .textProperty (),
214
- query -> !(regularExpressionButton .isSelected () && !validRegex ()),
215
- ValidationMessage .error (Localization .lang ("Invalid regular expression" )));
216
- ControlsFxVisualizer visualizer = new ControlsFxVisualizer ();
217
- visualizer .setDecoration (new IconValidationDecorator (Pos .CENTER_LEFT ));
218
- Platform .runLater (() -> visualizer .initVisualization (regexValidator .getValidationStatus (), searchField ));
219
-
220
194
if (searchType == SearchType .NORMAL_SEARCH ) {
221
195
this .getChildren ().addAll (searchField , openGlobalSearchButton , currentResults );
222
196
} else {
@@ -261,52 +235,64 @@ private void initSearchModifierButtons() {
261
235
regularExpressionButton .setSelected (searchPreferences .isRegularExpression ());
262
236
regularExpressionButton .setTooltip (new Tooltip (Localization .lang ("regular expression" )));
263
237
initSearchModifierButton (regularExpressionButton );
264
- regularExpressionButton .setOnAction ( event -> {
265
- searchPreferences .setSearchFlag (SearchRules .SearchFlags .REGULAR_EXPRESSION , regularExpressionButton . isSelected () );
238
+ regularExpressionButton .selectedProperty (). addListener (( obs , oldVal , newVal ) -> {
239
+ searchPreferences .setSearchFlag (SearchRules .SearchFlags .REGULAR_EXPRESSION , newVal );
266
240
updateSearchQuery ();
267
241
});
268
242
269
243
caseSensitiveButton .setSelected (searchPreferences .isCaseSensitive ());
270
244
caseSensitiveButton .setTooltip (new Tooltip (Localization .lang ("Case sensitive" )));
271
245
initSearchModifierButton (caseSensitiveButton );
272
- caseSensitiveButton .setOnAction ( event -> {
273
- searchPreferences .setSearchFlag (SearchRules .SearchFlags .CASE_SENSITIVE , caseSensitiveButton . isSelected () );
246
+ caseSensitiveButton .selectedProperty (). addListener (( obs , oldVal , newVal ) -> {
247
+ searchPreferences .setSearchFlag (SearchRules .SearchFlags .CASE_SENSITIVE , newVal );
274
248
updateSearchQuery ();
275
249
});
276
250
277
251
fulltextButton .setSelected (searchPreferences .isFulltext ());
278
252
fulltextButton .setTooltip (new Tooltip (Localization .lang ("Fulltext search" )));
279
253
initSearchModifierButton (fulltextButton );
280
- fulltextButton .setOnAction ( event -> {
281
- searchPreferences .setSearchFlag (SearchRules .SearchFlags .FULLTEXT , fulltextButton . isSelected () );
254
+ fulltextButton .selectedProperty (). addListener (( obs , oldVal , newVal ) -> {
255
+ searchPreferences .setSearchFlag (SearchRules .SearchFlags .FULLTEXT , newVal );
282
256
updateSearchQuery ();
283
257
});
284
258
285
259
keepSearchString .setSelected (searchPreferences .shouldKeepSearchString ());
286
260
keepSearchString .setTooltip (new Tooltip (Localization .lang ("Keep search string across libraries" )));
287
261
initSearchModifierButton (keepSearchString );
288
- keepSearchString .setOnAction ( evt -> {
289
- searchPreferences .setSearchFlag (SearchRules .SearchFlags .KEEP_SEARCH_STRING , keepSearchString . isSelected () );
262
+ keepSearchString .selectedProperty (). addListener (( obs , oldVal , newVal ) -> {
263
+ searchPreferences .setSearchFlag (SearchRules .SearchFlags .KEEP_SEARCH_STRING , newVal );
290
264
updateSearchQuery ();
291
265
});
292
266
293
267
openGlobalSearchButton .disableProperty ().bindBidirectional (globalSearchActive );
294
268
openGlobalSearchButton .setTooltip (new Tooltip (Localization .lang ("Search across libraries in a new window" )));
295
269
initSearchModifierButton (openGlobalSearchButton );
296
- openGlobalSearchButton .setOnAction (evt -> {
297
- globalSearchActive .setValue (true );
298
- if (globalSearchResultDialog == null ) {
299
- globalSearchResultDialog = new GlobalSearchResultDialog (undoManager , tabContainer );
300
- }
301
- stateManager .activeGlobalSearchQueryProperty ().setValue (searchQueryProperty .get ());
302
- updateSearchQuery ();
303
- dialogService .showCustomDialogAndWait (globalSearchResultDialog );
304
- globalSearchActive .setValue (false );
270
+ openGlobalSearchButton .setOnAction (evt -> openGlobalSearchDialog ());
271
+
272
+ searchPreferences .getObservableSearchFlags ().addListener ((SetChangeListener .Change <? extends SearchRules .SearchFlags > change ) -> {
273
+ regularExpressionButton .setSelected (searchPreferences .isRegularExpression ());
274
+ caseSensitiveButton .setSelected (searchPreferences .isCaseSensitive ());
275
+ fulltextButton .setSelected (searchPreferences .isFulltext ());
276
+ keepSearchString .setSelected (searchPreferences .shouldKeepSearchString ());
305
277
});
306
278
}
307
279
280
+ public void openGlobalSearchDialog () {
281
+ if (globalSearchActive .get ()) {
282
+ return ;
283
+ }
284
+ globalSearchActive .setValue (true );
285
+ if (globalSearchResultDialog == null ) {
286
+ globalSearchResultDialog = new GlobalSearchResultDialog (undoManager , tabContainer );
287
+ }
288
+ stateManager .activeGlobalSearchQueryProperty ().setValue (searchQueryProperty .get ());
289
+ updateSearchQuery ();
290
+ dialogService .showCustomDialogAndWait (globalSearchResultDialog );
291
+ globalSearchActive .setValue (false );
292
+ }
293
+
308
294
private void initSearchModifierButton (ButtonBase searchButton ) {
309
- searchButton .setCursor (Cursor .DEFAULT );
295
+ searchButton .setCursor (Cursor .HAND );
310
296
searchButton .setMinHeight (28 );
311
297
searchButton .setMaxHeight (28 );
312
298
searchButton .setMinWidth (28 );
@@ -319,7 +305,8 @@ private void initSearchModifierButton(ButtonBase searchButton) {
319
305
/**
320
306
* Focuses the search field if it is not focused.
321
307
*/
322
- public void focus () {
308
+ @ Override
309
+ public void requestFocus () {
323
310
if (!searchField .isFocused ()) {
324
311
searchField .requestFocus ();
325
312
}
@@ -339,7 +326,7 @@ public void updateSearchQuery() {
339
326
}
340
327
341
328
// Invalid regular expression
342
- if (! regexValidator . getValidationStatus (). isValid ()) {
329
+ if (regularExpressionButton . isSelected () && ! validRegex ()) {
343
330
currentResults .setText (Localization .lang ("Invalid regular expression" ));
344
331
return ;
345
332
}
0 commit comments