Autopsy  4.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
FilterSetPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2013-16 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.timeline.ui.filtering;
20 
21 import java.util.Arrays;
22 import javafx.application.Platform;
23 import javafx.beans.Observable;
24 import javafx.beans.binding.Bindings;
25 import javafx.collections.FXCollections;
26 import javafx.collections.ObservableMap;
27 import javafx.fxml.FXML;
28 import javafx.scene.control.Button;
29 import javafx.scene.control.Cell;
30 import javafx.scene.control.ListCell;
31 import javafx.scene.control.ListView;
32 import javafx.scene.control.SplitPane;
33 import javafx.scene.control.TitledPane;
34 import javafx.scene.control.TreeTableColumn;
35 import javafx.scene.control.TreeTableView;
36 import javafx.scene.image.Image;
37 import javafx.scene.image.ImageView;
38 import javafx.scene.layout.BorderPane;
39 import org.controlsfx.control.action.Action;
40 import org.controlsfx.control.action.ActionUtils;
41 import org.openide.util.NbBundle;
50 
57 final public class FilterSetPanel extends BorderPane {
58 
59  private static final Image TICK = new Image("org/sleuthkit/autopsy/timeline/images/tick.png"); //NON-NLS
60 
61  @FXML
62  private Button applyButton;
63 
64  @FXML
65  private Button defaultButton;
66 
67  @FXML
68  private TreeTableView<Filter> filterTreeTable;
69 
70  @FXML
71  private TreeTableColumn<AbstractFilter, AbstractFilter> treeColumn;
72 
73  @FXML
74  private TreeTableColumn<AbstractFilter, AbstractFilter> legendColumn;
75 
76  @FXML
77  private ListView<DescriptionFilter> hiddenDescriptionsListView;
78  @FXML
79  private TitledPane hiddenDescriptionsPane;
80  @FXML
81  private SplitPane splitPane;
82 
85 
90  private final ObservableMap<Filter, Boolean> expansionMap = FXCollections.observableHashMap();
91  private double dividerPosition;
92 
93  @NbBundle.Messages({
94  "FilterSetPanel.defaultButton.text=Default",
95  "FilsetSetPanel.hiddenDescriptionsPane.displayName=Hidden Descriptions"})
96  @FXML
97  void initialize() {
98  assert applyButton != null : "fx:id=\"applyButton\" was not injected: check your FXML file 'FilterSetPanel.fxml'."; // NON-NLS
99 
100  ActionUtils.configureButton(new ApplyFiltersAction(), applyButton);
101  ActionUtils.configureButton(new ResetFilters(Bundle.FilterSetPanel_defaultButton_text(), controller), defaultButton);
102 
103  hiddenDescriptionsPane.setText(Bundle.FilsetSetPanel_hiddenDescriptionsPane_displayName());
104  //remove column headers via css.
105  filterTreeTable.getStylesheets().addAll(FilterSetPanel.class.getResource("FilterTable.css").toExternalForm()); // NON-NLS
106 
107  //use row factory as hook to attach context menus to.
108  filterTreeTable.setRowFactory(ttv -> new FilterTreeTableRow());
109 
110  //configure tree column to show name of filter and checkbox
111  treeColumn.setCellValueFactory(cellDataFeatures -> cellDataFeatures.getValue().valueProperty());
112  treeColumn.setCellFactory(col -> new FilterCheckBoxCellFactory<>().forTreeTable(col));
113 
114  //configure legend column to show legend (or othe supplamantal ui, eg, text field for text filter)
115  legendColumn.setCellValueFactory(cellDataFeatures -> cellDataFeatures.getValue().valueProperty());
116  legendColumn.setCellFactory(col -> new LegendCell(this.controller));
117 
118  //type is the only filter expanded initialy
119  expansionMap.put(controller.getEventsModel().getFilter().getTypeFilter(), true);
120 
121  this.filteredEvents.eventTypeZoomProperty().addListener((Observable observable) -> applyFilters());
122  this.filteredEvents.descriptionLODProperty().addListener((Observable observable1) -> applyFilters());
123  this.filteredEvents.timeRangeProperty().addListener((Observable observable2) -> applyFilters());
124 
125  this.filteredEvents.filterProperty().addListener((Observable o) -> refresh());
126  refresh();
127 
128  hiddenDescriptionsListView.setItems(controller.getQuickHideFilters());
129  hiddenDescriptionsListView.setCellFactory(listView -> getNewDiscriptionFilterListCell());
130 
131  //show and hide the "hidden descriptions" panel depending on the current view mode
132  controller.viewModeProperty().addListener(observable -> {
133  applyFilters();
134  switch (controller.getViewMode()) {
135  case COUNTS:
136  case LIST:
137  //hide for counts and lists, but remember divider position
138  dividerPosition = splitPane.getDividerPositions()[0];
139  splitPane.setDividerPositions(1);
140  hiddenDescriptionsPane.setExpanded(false);
141  hiddenDescriptionsPane.setCollapsible(false);
142  hiddenDescriptionsPane.setDisable(true);
143  break;
144  case DETAIL:
145  //show and restore divider position.
146  splitPane.setDividerPositions(dividerPosition);
147  hiddenDescriptionsPane.setDisable(false);
148  hiddenDescriptionsPane.setCollapsible(true);
149  hiddenDescriptionsPane.setExpanded(true);
150  hiddenDescriptionsPane.setCollapsible(false);
151  break;
152  default:
153  throw new UnsupportedOperationException("Unknown ViewMode: " + controller.getViewMode());
154  }
155  });
156  }
157 
158  public FilterSetPanel(TimeLineController controller) {
159  this.controller = controller;
160  this.filteredEvents = controller.getEventsModel();
161  FXMLConstructor.construct(this, "FilterSetPanel.fxml"); // NON-NLS
162  }
163 
164  private void refresh() {
165  Platform.runLater(() -> {
166  filterTreeTable.setRoot(new FilterTreeItem(filteredEvents.getFilter().copyOf(), expansionMap));
167  });
168  }
169 
170  private void applyFilters() {
171  Platform.runLater(() -> {
172  controller.pushFilters((RootFilter) filterTreeTable.getRoot().getValue());
173  });
174  }
175 
176  private ListCell<DescriptionFilter> getNewDiscriptionFilterListCell() {
177  final ListCell<DescriptionFilter> cell = new FilterCheckBoxCellFactory<DescriptionFilter>().forList();
178  cell.itemProperty().addListener(itemProperty -> {
179  if (cell.getItem() == null) {
180  cell.setContextMenu(null);
181  } else {
182  cell.setContextMenu(ActionUtils.createContextMenu(Arrays.asList(
183  new RemoveDescriptionFilterAction(controller, cell))
184  ));
185  }
186  });
187  return cell;
188  }
189 
190  @NbBundle.Messages({"FilterSetPanel.applyButton.text=Apply",
191  "FilterSetPanel.applyButton.longText=(Re)Apply filters"})
192  private class ApplyFiltersAction extends Action {
193 
195  super(Bundle.FilterSetPanel_applyButton_text());
196  setLongText(Bundle.FilterSetPanel_applyButton_longText());
197  setGraphic(new ImageView(TICK));
198  setEventHandler(actionEvent -> applyFilters());
199  }
200  }
201 
202  @NbBundle.Messages({
203  "FilterSetPanel.hiddenDescriptionsListView.unhideAndRemove=Unhide and remove from list",
204  "FilterSetPanel.hiddenDescriptionsListView.remove=Remove from list",})
205  private static class RemoveDescriptionFilterAction extends Action {
206 
207  private static final Image SHOW = new Image("/org/sleuthkit/autopsy/timeline/images/eye--plus.png"); // NON-NLS
208 
209  RemoveDescriptionFilterAction(TimeLineController controller, Cell<DescriptionFilter> cell) {
210  super(actionEvent -> controller.getQuickHideFilters().remove(cell.getItem()));
211  setGraphic(new ImageView(SHOW));
212  textProperty().bind(
213  Bindings.when(cell.getItem().selectedProperty())
214  .then(Bundle.FilterSetPanel_hiddenDescriptionsListView_unhideAndRemove())
215  .otherwise(Bundle.FilterSetPanel_hiddenDescriptionsListView_remove()));
216  }
217  }
218 }
synchronized ReadOnlyObjectProperty< EventTypeZoomLevel > eventTypeZoomProperty()
synchronized ReadOnlyObjectProperty< RootFilter > filterProperty()
synchronized void pushFilters(RootFilter filter)
synchronized ReadOnlyObjectProperty< ViewMode > viewModeProperty()
synchronized ReadOnlyObjectProperty< DescriptionLoD > descriptionLODProperty()
static void construct(Node node, String fxmlFileName)
synchronized ReadOnlyObjectProperty< Interval > timeRangeProperty()
TreeTableColumn< AbstractFilter, AbstractFilter > treeColumn
ObservableList< DescriptionFilter > getQuickHideFilters()
final ObservableMap< Filter, Boolean > expansionMap
TreeTableColumn< AbstractFilter, AbstractFilter > legendColumn

Copyright © 2012-2016 Basis Technology. Generated on: Tue Oct 25 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.