19 package org.sleuthkit.autopsy.timeline.ui.filtering;
21 import java.util.Arrays;
22 import javafx.application.Platform;
23 import javafx.beans.InvalidationListener;
24 import javafx.beans.binding.Bindings;
25 import javafx.collections.FXCollections;
26 import javafx.collections.ObservableMap;
27 import javafx.event.EventHandler;
28 import javafx.fxml.FXML;
29 import javafx.scene.control.Button;
30 import javafx.scene.control.Cell;
31 import javafx.scene.control.ListCell;
32 import javafx.scene.control.ListView;
33 import javafx.scene.control.SplitPane;
34 import javafx.scene.control.TitledPane;
35 import javafx.scene.control.TreeTableColumn;
36 import javafx.scene.control.TreeTableView;
37 import javafx.scene.image.Image;
38 import javafx.scene.image.ImageView;
39 import javafx.scene.input.KeyEvent;
40 import javafx.scene.layout.BorderPane;
41 import org.controlsfx.control.action.Action;
42 import org.controlsfx.control.action.ActionUtils;
43 import org.openide.util.NbBundle;
60 private static final Image
TICK =
new Image(
"org/sleuthkit/autopsy/timeline/images/tick.png");
91 private final ObservableMap< Object, Boolean>
expansionMap = FXCollections.observableHashMap();
95 "FilterSetPanel.defaultButton.text=Reset",
96 "FilsetSetPanel.hiddenDescriptionsPane.displayName=Hidden Descriptions"})
99 assert applyButton != null :
"fx:id=\"applyButton\" was not injected: check your FXML file 'FilterSetPanel.fxml'.";
101 ActionUtils.configureButton(
new ApplyFiltersAction(), applyButton);
102 ActionUtils.configureButton(
new ResetFilters(Bundle.FilterSetPanel_defaultButton_text(),
controller), defaultButton);
104 hiddenDescriptionsPane.setText(Bundle.FilsetSetPanel_hiddenDescriptionsPane_displayName());
106 filterTreeTable.getStylesheets().addAll(
FilterSetPanel.class.getResource(
"FilterTable.css").toExternalForm());
109 filterTreeTable.setRowFactory(ttv ->
new FilterTreeTableRow());
112 treeColumn.setCellValueFactory(cellDataFeatures -> cellDataFeatures.getValue().valueProperty());
113 treeColumn.setCellFactory(col ->
new FilterCheckBoxCellFactory<>().forTreeTable(col));
116 legendColumn.setCellValueFactory(cellDataFeatures -> cellDataFeatures.getValue().valueProperty());
117 legendColumn.setCellFactory(col ->
new LegendCell(this.controller));
125 InvalidationListener applyFiltersListener = observable ->
applyFilters();
143 dividerPosition = splitPane.getDividerPositions()[0];
144 splitPane.setDividerPositions(1);
145 hiddenDescriptionsPane.setExpanded(
false);
146 hiddenDescriptionsPane.setCollapsible(
false);
147 hiddenDescriptionsPane.setDisable(
true);
151 splitPane.setDividerPositions(dividerPosition);
152 hiddenDescriptionsPane.setDisable(
false);
153 hiddenDescriptionsPane.setCollapsible(
true);
154 hiddenDescriptionsPane.setExpanded(
true);
155 hiddenDescriptionsPane.setCollapsible(
false);
158 throw new UnsupportedOperationException(
"Unknown ViewMode: " + controller.
getViewMode());
163 filterTreeTable.addEventFilter(KeyEvent.ANY,
new EventHandler<KeyEvent>() {
165 public void handle(KeyEvent event) {
172 this.controller = controller;
179 -> filterTreeTable.setRoot(
new FilterTreeItem(filteredEvents.
eventFilterProperty().get().copyOf(), expansionMap)));
183 Platform.runLater(() -> {
189 final ListCell<DescriptionFilterState> cell =
new FilterCheckBoxCellFactory< DescriptionFilterState>().forList();
190 cell.itemProperty().addListener(itemProperty -> {
191 if (cell.getItem() == null) {
192 cell.setContextMenu(null);
194 cell.setContextMenu(ActionUtils.createContextMenu(Arrays.asList(
202 @NbBundle.Messages({
"FilterSetPanel.applyButton.text=Apply",
203 "FilterSetPanel.applyButton.longText=(Re)Apply filters"})
207 super(Bundle.FilterSetPanel_applyButton_text());
208 setLongText(Bundle.FilterSetPanel_applyButton_longText());
209 setGraphic(
new ImageView(TICK));
210 setEventHandler(actionEvent -> applyFilters());
215 "FilterSetPanel.hiddenDescriptionsListView.unhideAndRemove=Unhide and remove from list",
216 "FilterSetPanel.hiddenDescriptionsListView.remove=Remove from list",})
219 private static final Image SHOW =
new Image(
"/org/sleuthkit/autopsy/timeline/images/eye--plus.png");
223 setGraphic(
new ImageView(SHOW));
225 Bindings.when(cell.getItem().selectedProperty())
226 .then(Bundle.FilterSetPanel_hiddenDescriptionsListView_unhideAndRemove())
227 .otherwise(Bundle.FilterSetPanel_hiddenDescriptionsListView_remove()));
final ReadOnlyObjectWrapper< TimelineEventType.HierarchyLevel > eventTypesHierarchyLevelProperty
final EventsModel filteredEvents
synchronized RootFilterState getEventFilterState()
ListCell< DescriptionFilterState > getNewDescriptionFilterListCell()
synchronized ViewMode getViewMode()
CompoundFilterState< FileTypeFilter, FileTypesFilter > getFileTypesFilterState()
FilterSetPanel(TimeLineController controller)
ListView< DescriptionFilterState > hiddenDescriptionsListView
TreeTableColumn< FilterState< ?>, FilterState<?> > treeColumn
final ReadOnlyObjectWrapper< Interval > timeRangeProperty
CompoundFilterState< EventTypeFilter, EventTypeFilter > getEventTypeFilterState()
synchronized void pushFilters(RootFilterState filter)
TitledPane hiddenDescriptionsPane
final TimeLineController controller
EventsModel getEventsModel()
synchronized ReadOnlyObjectProperty< ViewMode > viewModeProperty()
ObservableList< DescriptionFilterState > getQuickHideFilters()
synchronized ReadOnlyObjectProperty< TimelineLevelOfDetail > descriptionLODProperty()
CompoundFilterState< DataSourceFilter, DataSourcesFilter > getDataSourcesFilterState()
final ObservableMap< Object, Boolean > expansionMap
static void construct(Node node, String fxmlFileName)
TreeTableView< FilterState<?> > filterTreeTable
synchronized ReadOnlyObjectProperty< RootFilterState > eventFilterProperty()
TreeTableColumn< FilterState<?>, FilterState<?> > legendColumn