Add search to Ignore list
This commit is contained in:
parent
32036f9027
commit
6a7db51663
|
@ -6,9 +6,13 @@ import ctbrec.Config;
|
||||||
import ctbrec.io.json.ObjectMapperFactory;
|
import ctbrec.io.json.ObjectMapperFactory;
|
||||||
import ctbrec.ui.AutosizeAlert;
|
import ctbrec.ui.AutosizeAlert;
|
||||||
import ctbrec.ui.controls.Dialogs;
|
import ctbrec.ui.controls.Dialogs;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.collections.transformation.FilteredList;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Alert.AlertType;
|
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.control.Alert.AlertType;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
|
@ -31,7 +35,9 @@ import static javafx.scene.control.ButtonType.YES;
|
||||||
public class IgnoreList extends GridPane {
|
public class IgnoreList extends GridPane {
|
||||||
|
|
||||||
private ListView<String> ignoreListView;
|
private ListView<String> ignoreListView;
|
||||||
|
private TextField searchField;
|
||||||
|
private ObservableList<String> masterList;
|
||||||
|
private FilteredList<String> filteredList;
|
||||||
private final ObjectMapper mapper = ObjectMapperFactory.getMapper();
|
private final ObjectMapper mapper = ObjectMapperFactory.getMapper();
|
||||||
|
|
||||||
public IgnoreList() {
|
public IgnoreList() {
|
||||||
|
@ -43,7 +49,12 @@ public class IgnoreList extends GridPane {
|
||||||
setHgap(10);
|
setHgap(10);
|
||||||
setVgap(10);
|
setVgap(10);
|
||||||
setPadding(new Insets(20, 10, 10, 10));
|
setPadding(new Insets(20, 10, 10, 10));
|
||||||
|
// Create search field with clear button
|
||||||
|
HBox searchBox = createSearchField();
|
||||||
|
add(searchBox, 0, 0);
|
||||||
|
GridPane.setHgrow(searchBox, Priority.ALWAYS);
|
||||||
|
|
||||||
|
// Initialize ListView
|
||||||
ignoreListView = new ListView<>();
|
ignoreListView = new ListView<>();
|
||||||
ignoreListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
ignoreListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||||
ignoreListView.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
|
ignoreListView.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
|
||||||
|
@ -51,9 +62,28 @@ public class IgnoreList extends GridPane {
|
||||||
removeSelectedModels();
|
removeSelectedModels();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
add(ignoreListView, 0, 0);
|
// Set custom cell factory for highlighting
|
||||||
|
ignoreListView.setCellFactory(listView -> new ListCell<>() {
|
||||||
|
@Override
|
||||||
|
protected void updateItem(String item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
if (empty || item == null) {
|
||||||
|
setText(null);
|
||||||
|
setStyle("");
|
||||||
|
} else {
|
||||||
|
setText(item);
|
||||||
|
// Highlight if the item matches the search text
|
||||||
|
String searchText = searchField.getText().trim().toLowerCase();
|
||||||
|
if (searchText.isEmpty() || !item.toLowerCase().contains(searchText)) {
|
||||||
|
setStyle("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
add(ignoreListView, 0, 1);
|
||||||
GridPane.setHgrow(ignoreListView, Priority.ALWAYS);
|
GridPane.setHgrow(ignoreListView, Priority.ALWAYS);
|
||||||
|
|
||||||
|
// Buttons
|
||||||
var remove = new Button("Remove");
|
var remove = new Button("Remove");
|
||||||
remove.setOnAction(evt -> removeSelectedModels());
|
remove.setOnAction(evt -> removeSelectedModels());
|
||||||
var exportIgnoreList = new Button("Export");
|
var exportIgnoreList = new Button("Export");
|
||||||
|
@ -65,12 +95,52 @@ public class IgnoreList extends GridPane {
|
||||||
buttons.setStyle("-fx-background-color: -fx-background"); // workaround so that the buttons don't shrink
|
buttons.setStyle("-fx-background-color: -fx-background"); // workaround so that the buttons don't shrink
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HBox createSearchField() {
|
||||||
|
HBox searchBox = new HBox(5);
|
||||||
|
searchField = new TextField();
|
||||||
|
searchField.setPromptText("Search ignore list...");
|
||||||
|
HBox.setHgrow(searchField, Priority.ALWAYS);
|
||||||
|
|
||||||
|
// Create clear button
|
||||||
|
Button clearButton = new Button("✖");
|
||||||
|
clearButton.setStyle("-fx-font-size: 12px; -fx-padding: 2px 5px; -fx-background-radius: 50%;");
|
||||||
|
clearButton.setVisible(false); // Initially hidden
|
||||||
|
clearButton.setOnAction(event -> {
|
||||||
|
searchField.clear();
|
||||||
|
searchField.requestFocus(); // Return focus to the TextField
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bind clear button visibility to text presence
|
||||||
|
clearButton.visibleProperty().bind(
|
||||||
|
Bindings.createBooleanBinding(
|
||||||
|
() -> !searchField.getText().trim().isEmpty(),
|
||||||
|
searchField.textProperty()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Bind the filter to the search field text property
|
||||||
|
searchField.textProperty().addListener((obs, oldValue, newValue) -> {
|
||||||
|
filteredList.setPredicate(item -> {
|
||||||
|
if (newValue == null || newValue.trim().isEmpty()) {
|
||||||
|
return true; // Show all items if search is empty
|
||||||
|
}
|
||||||
|
return item.toLowerCase().contains(newValue.trim().toLowerCase());
|
||||||
|
});
|
||||||
|
// Force ListView to refresh to update highlighting
|
||||||
|
ignoreListView.refresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
searchBox.getChildren().addAll(searchField, clearButton);
|
||||||
|
searchBox.setAlignment(javafx.geometry.Pos.CENTER_LEFT);
|
||||||
|
return searchBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void removeSelectedModels() {
|
private void removeSelectedModels() {
|
||||||
List<String> selectedModels = ignoreListView.getSelectionModel().getSelectedItems();
|
List<String> selectedModels = ignoreListView.getSelectionModel().getSelectedItems();
|
||||||
if (!selectedModels.isEmpty()) {
|
if (!selectedModels.isEmpty()) {
|
||||||
Config.getInstance().getSettings().ignoredModels.removeAll(selectedModels);
|
Config.getInstance().getSettings().ignoredModels.removeAll(selectedModels);
|
||||||
ignoreListView.getItems().removeAll(selectedModels);
|
masterList.removeAll(selectedModels); // Update master list
|
||||||
log.debug(Config.getInstance().getSettings().ignoredModels.toString());
|
|
||||||
try {
|
try {
|
||||||
Config.getInstance().save();
|
Config.getInstance().save();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -81,9 +151,10 @@ public class IgnoreList extends GridPane {
|
||||||
|
|
||||||
private void loadIgnoredModels() {
|
private void loadIgnoredModels() {
|
||||||
List<String> ignored = Config.getInstance().getSettings().ignoredModels;
|
List<String> ignored = Config.getInstance().getSettings().ignoredModels;
|
||||||
ignoreListView.getItems().clear();
|
masterList = FXCollections.observableArrayList(ignored);
|
||||||
ignoreListView.getItems().addAll(ignored);
|
Collections.sort(masterList);
|
||||||
Collections.sort(ignoreListView.getItems());
|
filteredList = new FilteredList<>(masterList, p -> true);
|
||||||
|
ignoreListView.setItems(filteredList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
|
|
Loading…
Reference in New Issue