2121import com .google .common .base .Strings ;
2222import javafx .application .Platform ;
2323import javafx .beans .property .SimpleBooleanProperty ;
24+ import javafx .beans .value .ChangeListener ;
2425import javafx .beans .value .ObservableValue ;
2526import javafx .fxml .FXML ;
26- import javafx .fxml .FXMLLoader ;
2727import javafx .geometry .Pos ;
2828import javafx .scene .control .Button ;
2929import javafx .scene .control .ComboBox ;
3030import javafx .scene .control .Label ;
3131import javafx .scene .control .RadioButton ;
3232import javafx .scene .control .TextField ;
33+ import javafx .scene .input .KeyCode ;
34+ import javafx .scene .input .KeyEvent ;
3335import javafx .scene .layout .AnchorPane ;
3436import javafx .scene .layout .GridPane ;
3537import javafx .scene .layout .HBox ;
3638import javafx .scene .layout .VBox ;
3739import org .phoebus .logbook .LogClient ;
3840import org .phoebus .logbook .Logbook ;
3941import org .phoebus .logbook .Tag ;
40- import org .phoebus .ui .dialog .ListSelectionController ;
42+ import org .phoebus .ui .dialog .ListSelectionPopOver ;
4143import org .phoebus .ui .dialog .PopOver ;
4244import org .phoebus .ui .time .TimeRelativeIntervalPane ;
4345import org .phoebus .util .time .TimeParser ;
4446import org .phoebus .util .time .TimeRelativeInterval ;
4547import org .phoebus .util .time .TimestampFormats ;
4648
47- import java .io .IOException ;
4849import java .util .Arrays ;
4950import java .util .Collections ;
5051import java .util .List ;
5152import java .util .Map ;
52- import java .util .logging .Level ;
5353import java .util .logging .Logger ;
5454import java .util .stream .Collectors ;
5555
@@ -84,23 +84,17 @@ public class AdvancedSearchViewController {
8484
8585 @ FXML
8686 TextField searchLogbooks ;
87- PopOver logbookSearchPopover ;
87+ ListSelectionPopOver logbookSearchPopover ;
8888
8989 @ FXML
9090 ComboBox <String > levelSelector ;
9191
9292 @ FXML
9393 TextField searchTags ;
94- PopOver tagSearchPopover ;
94+ ListSelectionPopOver tagSearchPopover ;
9595
9696 private final LogClient logClient ;
9797
98- private ListSelectionController tagController ;
99- private ListSelectionController logbookController ;
100-
101- List <String > logbookNames ;
102- List <String > tagNames ;
103-
10498 @ FXML
10599 private AnchorPane advancedSearchPane ;
106100
@@ -118,26 +112,45 @@ public class AdvancedSearchViewController {
118112 private final SimpleBooleanProperty sortAscending = new SimpleBooleanProperty (false );
119113 private final SimpleBooleanProperty requireAttachments = new SimpleBooleanProperty (false );
120114
115+ private Runnable searchCallback = () -> {
116+ throw new IllegalStateException ("Search callback is not set on AdvancedSearchViewConroller!" );
117+ };
118+
121119 public AdvancedSearchViewController (LogClient logClient , SearchParameters searchParameters ) {
122120 this .logClient = logClient ;
123121 this .searchParameters = searchParameters ;
124122 }
125123
124+ public void setSearchCallback (Runnable searchCallback ) {
125+ this .searchCallback = searchCallback ;
126+ }
127+
126128 @ FXML
127129 public void initialize () {
128130
129131 searchTitle .textProperty ().bindBidirectional (this .searchParameters .titleProperty ());
132+ searchTitle .setOnKeyReleased (this ::searchOnEnter );
130133 searchText .textProperty ().bindBidirectional (this .searchParameters .textProperty ());
134+ searchText .setOnKeyReleased (this ::searchOnEnter );
131135 searchAuthor .textProperty ().bindBidirectional (this .searchParameters .authorProperty ());
136+ searchAuthor .setOnKeyReleased (this ::searchOnEnter );
132137 levelSelector .valueProperty ().bindBidirectional (this .searchParameters .levelProperty ());
138+ levelSelector .setOnAction (e -> searchCallback .run ());
133139 searchTags .textProperty ().bindBidirectional (this .searchParameters .tagsProperty ());
140+ searchParameters .tagsProperty ().addListener (searchOnTextChange );
134141 searchLogbooks .textProperty ().bindBidirectional (this .searchParameters .logbooksProperty ());
142+ searchParameters .logbooksProperty ().addListener (searchOnTextChange );
135143 startTime .textProperty ().bindBidirectional (this .searchParameters .startTimeProperty ());
144+ startTime .setOnKeyReleased (this ::searchOnEnter );
136145 endTime .textProperty ().bindBidirectional (this .searchParameters .endTimeProperty ());
146+ endTime .setOnKeyReleased (this ::searchOnEnter );
137147 searchParameters .addListener ((observable , oldValue , newValue ) -> {
138148 updateControls (newValue );
139149 });
150+ sortAscending .addListener (searchOnSortChange );
151+
140152 attachmentTypes .textProperty ().bindBidirectional (this .searchParameters .attachmentsProperty ());
153+ attachmentTypes .setOnKeyReleased (this ::searchOnEnter );
141154
142155 levelLabel .setText (LogbookUIPreferences .level_field_name );
143156
@@ -173,6 +186,7 @@ public void initialize() {
173186 }
174187 if (timeSearchPopover .isShowing ())
175188 timeSearchPopover .hide ();
189+ searchCallback .run ();
176190 });
177191 });
178192 Button cancel = new Button ();
@@ -204,68 +218,50 @@ public void initialize() {
204218 }
205219 });
206220
207- FXMLLoader logbookSelectionLoader = new FXMLLoader ();
208- logbookSelectionLoader .setLocation (this .getClass ().getResource ("/org/phoebus/ui/dialog/ListSelection.fxml" ));
209- try {
210- logbookSelectionLoader .load ();
211- logbookController = logbookSelectionLoader .getController ();
212- logbookController .setOnApply ((List <String > t ) -> {
213- Platform .runLater (() -> {
214- if (t .isEmpty ()) {
215- searchParameters .logbooksProperty ().setValue (null );
216- } else {
217- searchParameters .logbooksProperty ().setValue (t .stream ().collect (Collectors .joining ("," )));
221+ logbookSearchPopover = ListSelectionPopOver .create (
222+ (logbooks , popover ) -> {
223+ String logbooksValue = String .join ("," , logbooks );
224+ searchParameters .logbooksProperty ().setValue (logbooksValue );
225+ if (popover .isShowing ()) {
226+ popover .hide ();
218227 }
219- if (logbookSearchPopover .isShowing ())
220- logbookSearchPopover .hide ();
221- });
222- return true ;
223- });
224- logbookController .setOnCancel ((List <String > t ) -> {
225- if (logbookSearchPopover .isShowing ())
226- logbookSearchPopover .hide ();
227- return true ;
228- });
229- logbookSearchPopover = new PopOver (logbookSelectionLoader .getRoot ());
230- } catch (IOException e ) {
231- logger .log (Level .WARNING , "failed to open logbook search dialog" , e );
232- }
228+ },
229+ (logbooks , popover ) -> {
230+ if (popover .isShowing ()) {
231+ popover .hide ();
232+ }
233+ }
234+ );
233235
234- FXMLLoader tagSelectionLoader = new FXMLLoader ();
235- tagSelectionLoader .setLocation (this .getClass ().getResource ("/org/phoebus/ui/dialog/ListSelection.fxml" ));
236- try {
237- tagSelectionLoader .load ();
238- tagController = tagSelectionLoader .getController ();
239- tagController .setOnApply ((List <String > t ) -> {
240- Platform .runLater (() -> {
241-
242- String tagsValue =
243- t .stream ().collect (Collectors .joining ("," ));
244- //searchParameters.put(Keys.TAGS, tagsValue);
236+ tagSearchPopover = ListSelectionPopOver .create (
237+ (tags , popover ) -> {
238+ String tagsValue = String .join ("," , tags );
245239 searchParameters .tagsProperty ().setValue (tagsValue );
246-
247- if (tagSearchPopover .isShowing ()) {
248- tagSearchPopover .hide ();
240+ if (popover .isShowing ()) {
241+ popover .hide ();
249242 }
250- });
251- return true ;
252- });
253- tagController .setOnCancel ((List <String > t ) -> {
254- if (tagSearchPopover .isShowing ())
255- tagSearchPopover .hide ();
256- return true ;
257- });
258- tagSearchPopover = new PopOver (tagSelectionLoader .getRoot ());
259- } catch (IOException e ) {
260- logger .log (Level .WARNING , "failed to open tag search dialog" , e );
261- }
243+ },
244+ (tags , popover ) -> {
245+ if (popover .isShowing ()) {
246+ popover .hide ();
247+ }
248+ }
249+ );
262250
263251 searchTags .setOnMouseClicked (mouseEvent -> {
264252 if (tagSearchPopover .isShowing ()) {
265253 tagSearchPopover .hide ();
266254 } else {
267- tagNames = logClient .listTags ().stream ().map (Tag ::getName ).sorted ().collect (Collectors .toList ());
268- tagController .setAvailable (tagNames );
255+ List <String > selectedTags = Arrays .stream ( searchParameters .tagsProperty ().getValueSafe ().split ("," ))
256+ .map (String ::trim )
257+ .filter (it -> !it .isEmpty ())
258+ .collect (Collectors .toList ());
259+ List <String > availableTags = logClient .listTags ().stream ()
260+ .map (Tag ::getName )
261+ .sorted ()
262+ .collect (Collectors .toList ());
263+ tagSearchPopover .setAvailable (availableTags , selectedTags );
264+ tagSearchPopover .setSelected (selectedTags );
269265 tagSearchPopover .show (searchTags );
270266 }
271267 });
@@ -274,8 +270,16 @@ public void initialize() {
274270 if (logbookSearchPopover .isShowing ()) {
275271 logbookSearchPopover .hide ();
276272 } else {
277- logbookNames = logClient .listLogbooks ().stream ().map (Logbook ::getName ).sorted ().collect (Collectors .toList ());
278- logbookController .setAvailable (logbookNames );
273+ List <String > selectedLogbooks = Arrays .stream ( searchParameters .logbooksProperty ().getValueSafe ().split ("," ))
274+ .map (String ::trim )
275+ .filter (it -> !it .isEmpty ())
276+ .collect (Collectors .toList ());
277+ List <String > availableLogbooks = logClient .listLogbooks ().stream ()
278+ .map (Logbook ::getName )
279+ .sorted ()
280+ .collect (Collectors .toList ());
281+ logbookSearchPopover .setAvailable (availableLogbooks , selectedLogbooks );
282+ logbookSearchPopover .setSelected (selectedLogbooks );
279283 logbookSearchPopover .show (searchLogbooks );
280284 }
281285 });
@@ -324,7 +328,7 @@ private void updateControls(String queryString) {
324328 validatedLogbookNames .stream ().collect (Collectors .joining ("," ));
325329 searchParameters .logbooksProperty ().setValue (selectedLogbooks );
326330 }
327- logbookController .setSelected (validatedLogbookNames );
331+ logbookSearchPopover .setSelected (validatedLogbookNames );
328332 } else if (keys .equals (Keys .TAGS )) {
329333 List <String > validatedTagsNames = getValidatedTagsSelection (entry .getValue ());
330334 if (validatedTagsNames .isEmpty ()) {
@@ -333,7 +337,7 @@ private void updateControls(String queryString) {
333337 String selectedTags = validatedTagsNames .stream ().collect (Collectors .joining ("," ));
334338 searchParameters .tagsProperty ().setValue (selectedTags );
335339 }
336- tagController .setSelected (validatedTagsNames );
340+ tagSearchPopover .setSelected (validatedTagsNames );
337341 }
338342 }
339343 });
@@ -368,4 +372,19 @@ protected List<String> getValidatedTagsSelection(String tags) {
368372 public SimpleBooleanProperty getSortAscending (){
369373 return sortAscending ;
370374 }
375+
376+ private void searchOnEnter (KeyEvent e ) {
377+ if (e .getCode () == KeyCode .ENTER ) {
378+ searchCallback .run ();
379+ }
380+ }
381+
382+ private final ChangeListener <? super String > searchOnTextChange = (options , oldValue , newValue ) -> {
383+ searchCallback .run ();
384+ };
385+
386+ private final ChangeListener <? super Boolean > searchOnSortChange = (options , oldValue , newValue ) -> {
387+ searchCallback .run ();
388+ };
389+
371390}
0 commit comments