From c31f025e88cf09959836741121b1175444c8dab3 Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Wed, 13 Mar 2024 11:22:06 +0100 Subject: [PATCH] Add country filter Signed-off-by: Florian Dupuy --- .../diagram/viewer/MainViewController.java | 32 ++++++++++++++++--- .../com/powsybl/diagram/viewer/Model.java | 10 ++++++ .../src/main/resources/mainView.fxml | 4 +++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/diagram-viewer/src/main/java/com/powsybl/diagram/viewer/MainViewController.java b/diagram-viewer/src/main/java/com/powsybl/diagram/viewer/MainViewController.java index 751ea78..0ba5120 100644 --- a/diagram-viewer/src/main/java/com/powsybl/diagram/viewer/MainViewController.java +++ b/diagram-viewer/src/main/java/com/powsybl/diagram/viewer/MainViewController.java @@ -105,6 +105,9 @@ public String toString() { @FXML public ChoiceBox componentTypeFilterChoice; + @FXML + public ComboBox countriesFilterComboBox; + @FXML public TreeView> vlTree; @FXML @@ -156,6 +159,7 @@ private void initialize() { // to avoid bug in TreeView: it does not calculate properly the selection shift, so clearing selection filterField.textProperty().addListener((observable, oldValue, newValue) -> clearSelection()); componentTypeFilterChoice.valueProperty().addListener((observable, oldValue, newValue) -> clearSelection()); + countriesFilterComboBox.valueProperty().addListener((observable, oldValue, newValue) -> clearSelection()); String casePathPropertyValue = preferences.get(CASE_PATH_PROPERTY, null); if (casePathPropertyValue != null) { @@ -171,6 +175,9 @@ private void initialize() { showNames.selectedProperty().addListener((observable, oldValue, newValue) -> vlTree.refresh()); + countriesFilterComboBox.itemsProperty().bind(Bindings.createObjectBinding(() -> model.getCountriesNames())); + countriesFilterComboBox.disableProperty().bind(Bindings.createBooleanBinding(() -> model.getCountriesNames().isEmpty(), model.networkProperty())); + vlTree.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { if (newValue != null) { Container c = newValue.getValue(); @@ -416,7 +423,8 @@ private void initSubstationsTree(Network network) { filteredList = new FilteredList<>(substationItems); filteredList.predicateProperty().bind(Bindings.createObjectBinding(() -> this::treeItemFilter, filterField.textProperty(), - componentTypeFilterChoice.valueProperty())); + componentTypeFilterChoice.valueProperty(), + countriesFilterComboBox.valueProperty())); var rootTreeItem = createCheckBoxTreeItem(network, containersChecked); Bindings.bindContent(rootTreeItem.getChildren(), filteredList); @@ -438,15 +446,31 @@ private CheckBoxTreeItem> createCheckBoxTreeItem(Container c, Se private boolean treeItemFilter(TreeItem> item) { String filter = filterField.getText(); ComponentFilterType idType = componentTypeFilterChoice.getValue(); + String countryValue = countriesFilterComboBox.getValue(); + Country country = countryValue != null ? Country.valueOf(countryValue) : null; var container = item.getValue(); if (StringUtils.isEmpty(filter)) { - return containsComponentType(idType, container); + return containsComponentType(idType, container) && locatedIn(country, container); } else { boolean filterOk = getIdentifiableStringSupplier().apply(container) .toLowerCase(Locale.getDefault()) .contains(filter.toLowerCase(Locale.getDefault())); return (filterOk || item.getChildren().stream().anyMatch(this::treeItemFilter)) - && containsComponentType(idType, container); + && containsComponentType(idType, container) + && locatedIn(country, container); + } + } + + private static boolean locatedIn(Country country, Container> container) { + if (country == null) { + return true; // no selection + } + if (container instanceof Substation s) { + return s.getCountry().map(c -> c == country).orElse(false); + } else if (container instanceof VoltageLevel v) { + return v.getSubstation().flatMap(Substation::getCountry).map(c -> c == country).orElse(false); + } else { + return true; // network } } @@ -465,7 +489,7 @@ private static boolean containsComponentType(ComponentFilterType type, Container default -> v.getConnectableStream(type.connectableClass).findFirst().isPresent(); }; } else { - return true; + return true; // network } } diff --git a/diagram-viewer/src/main/java/com/powsybl/diagram/viewer/Model.java b/diagram-viewer/src/main/java/com/powsybl/diagram/viewer/Model.java index 642d5e9..bbba54a 100644 --- a/diagram-viewer/src/main/java/com/powsybl/diagram/viewer/Model.java +++ b/diagram-viewer/src/main/java/com/powsybl/diagram/viewer/Model.java @@ -10,14 +10,19 @@ import com.powsybl.diagram.viewer.nad.NetworkAreaDiagramModel; import com.powsybl.diagram.viewer.sld.SingleLineDiagramModel; import com.powsybl.iidm.network.Container; +import com.powsybl.iidm.network.Country; import com.powsybl.iidm.network.Network; import javafx.beans.property.*; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; /** * @author Florian Dupuy */ public class Model { private final ObjectProperty network = new SimpleObjectProperty<>(); + private final ObservableList countriesNames = FXCollections.observableArrayList(); + private Container selectedContainer = null; private final NetworkAreaDiagramModel nadModel; @@ -32,6 +37,7 @@ public Model(BooleanProperty showNames, NetworkAreaDiagramModel nadModel, Single } public void setNetwork(Network network) { + this.countriesNames.setAll(network.getCountries().stream().map(Country::toString).toList()); this.network.setValue(network); } @@ -56,4 +62,8 @@ public void clean() { nadModel.clean(); sldModel.clean(); } + + public ObservableList getCountriesNames() { + return countriesNames; + } } diff --git a/diagram-viewer/src/main/resources/mainView.fxml b/diagram-viewer/src/main/resources/mainView.fxml index e449b05..f00e21e 100644 --- a/diagram-viewer/src/main/resources/mainView.fxml +++ b/diagram-viewer/src/main/resources/mainView.fxml @@ -30,6 +30,10 @@