Autopsy  4.0
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-15 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 javafx.application.Platform;
22 import javafx.beans.Observable;
23 import javafx.collections.FXCollections;
24 import javafx.collections.ObservableMap;
25 import javafx.event.ActionEvent;
26 import javafx.fxml.FXML;
27 import javafx.scene.control.Button;
28 import javafx.scene.control.ContextMenu;
29 import javafx.scene.control.ListCell;
30 import javafx.scene.control.ListView;
31 import javafx.scene.control.Menu;
32 import javafx.scene.control.MenuItem;
33 import javafx.scene.control.SplitPane;
34 import javafx.scene.control.TitledPane;
35 import javafx.scene.control.TreeItem;
36 import javafx.scene.control.TreeTableColumn;
37 import javafx.scene.control.TreeTableRow;
38 import javafx.scene.control.TreeTableView;
39 import javafx.scene.image.Image;
40 import javafx.scene.image.ImageView;
41 import javafx.scene.layout.BorderPane;
42 import org.controlsfx.control.action.Action;
43 import org.controlsfx.control.action.ActionUtils;
44 import org.openide.util.NbBundle;
56 
63 final public class FilterSetPanel extends BorderPane {
64 
65  private static final Image TICK = new Image("org/sleuthkit/autopsy/timeline/images/tick.png"); //NON-NLS
66 
67  @FXML
68  private Button applyButton;
69 
70  @FXML
71  private Button defaultButton;
72 
73  @FXML
74  private TreeTableView<Filter> filterTreeTable;
75 
76  @FXML
77  private TreeTableColumn<AbstractFilter, AbstractFilter> treeColumn;
78 
79  @FXML
80  private TreeTableColumn<AbstractFilter, AbstractFilter> legendColumn;
81 
82  @FXML
83  private ListView<DescriptionFilter> hiddenDescriptionsListView;
84  @FXML
85  private TitledPane hiddenDescriptionsPane;
86  @FXML
87  private SplitPane splitPane;
88 
90 
92 
93  private final ObservableMap<String, Boolean> expansionMap = FXCollections.observableHashMap();
94  private double position;
95 
96  @FXML
97  @NbBundle.Messages({
98  "Timeline.ui.filtering.menuItem.all=all",
99  "FilterSetPanel.defaultButton.text=Default",
100  "Timeline.ui.filtering.menuItem.none=none",
101  "Timeline.ui.filtering.menuItem.only=only",
102  "Timeline.ui.filtering.menuItem.others=others",
103  "Timeline.ui.filtering.menuItem.select=select",
104  "FilterSetPanel.hiddenDescriptionsListView.unhideAndRm=Unhide and remove from list",
105  "FilterSetPanel.hiddenDescriptionsListView.remove=Remove from list",
106  "FilsetSetPanel.hiddenDescriptionsPane.displayName=Hidden Descriptions"})
107  void initialize() {
108  assert applyButton != null : "fx:id=\"applyButton\" was not injected: check your FXML file 'FilterSetPanel.fxml'."; // NON-NLS
109 
110  ActionUtils.configureButton(new ApplyFiltersAction(), applyButton);
111  defaultButton.setText(Bundle.FilterSetPanel_defaultButton_text());
112  hiddenDescriptionsPane.setText(Bundle.FilsetSetPanel_hiddenDescriptionsPane_displayName());
113  //remove column headers via css.
114  filterTreeTable.getStylesheets().addAll(FilterSetPanel.class.getResource("FilterTable.css").toExternalForm()); // NON-NLS
115 
116  //use row factory as hook to attach context menus to.
117  filterTreeTable.setRowFactory((TreeTableView<Filter> param) -> {
118  final TreeTableRow<Filter> row = new TreeTableRow<>();
119 
120  MenuItem all = new MenuItem(Bundle.Timeline_ui_filtering_menuItem_all());
121  all.setOnAction(e -> {
122  row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
123  t.getValue().setSelected(Boolean.TRUE);
124  });
125  });
126  MenuItem none = new MenuItem(Bundle.Timeline_ui_filtering_menuItem_none());
127  none.setOnAction(e -> {
128  row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
129  t.getValue().setSelected(Boolean.FALSE);
130  });
131  });
132 
133  MenuItem only = new MenuItem(Bundle.Timeline_ui_filtering_menuItem_only());
134  only.setOnAction(e -> {
135  row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
136  if (t == row.getTreeItem()) {
137  t.getValue().setSelected(Boolean.TRUE);
138  } else {
139  t.getValue().setSelected(Boolean.FALSE);
140  }
141  });
142  });
143  MenuItem others = new MenuItem(Bundle.Timeline_ui_filtering_menuItem_others());
144  others.setOnAction(e -> {
145  row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
146  if (t == row.getTreeItem()) {
147  t.getValue().setSelected(Boolean.FALSE);
148  } else {
149  t.getValue().setSelected(Boolean.TRUE);
150  }
151  });
152  });
153  final ContextMenu rowMenu = new ContextMenu();
154  Menu select = new Menu(Bundle.Timeline_ui_filtering_menuItem_select());
155  select.setOnAction(e -> {
156  row.getItem().setSelected(!row.getItem().isSelected());
157  });
158  select.getItems().addAll(all, none, only, others);
159  rowMenu.getItems().addAll(select);
160  row.setContextMenu(rowMenu);
161 
162  return row;
163  });
164 
165  //configure tree column to show name of filter and checkbox
166  treeColumn.setCellValueFactory(param -> param.getValue().valueProperty());
167  treeColumn.setCellFactory(col -> new FilterCheckBoxCellFactory<>().forTreeTable(col));
168 
169  //configure legend column to show legend (or othe supplamantal ui, eg, text field for text filter)
170  legendColumn.setCellValueFactory(param -> param.getValue().valueProperty());
171  legendColumn.setCellFactory(col -> new LegendCell(this.controller));
172 
173  expansionMap.put(new TypeFilter(RootEventType.getInstance()).getDisplayName(), true);
174 
175  Action defaultFiltersAction = new ResetFilters(controller);
176  defaultButton.setOnAction(defaultFiltersAction);
177  defaultButton.disableProperty().bind(defaultFiltersAction.disabledProperty());
178 
179  this.filteredEvents.eventTypeZoomProperty().addListener((Observable observable) -> {
180  applyFilters();
181  });
182  this.filteredEvents.descriptionLODProperty().addListener((Observable observable1) -> {
183  applyFilters();
184  });
185  this.filteredEvents.timeRangeProperty().addListener((Observable observable2) -> {
186  applyFilters();
187  });
188  this.filteredEvents.filterProperty().addListener((Observable o) -> {
189  refresh();
190  });
191  refresh();
192 
193  hiddenDescriptionsListView.setItems(controller.getQuickHideFilters());
194  hiddenDescriptionsListView.setCellFactory((ListView<DescriptionFilter> param) -> {
195  final ListCell<DescriptionFilter> forList = new FilterCheckBoxCellFactory<DescriptionFilter>().forList();
196 
197  forList.itemProperty().addListener((Observable observable) -> {
198  if (forList.getItem() == null) {
199  forList.setContextMenu(null);
200  } else {
201  forList.setContextMenu(new ContextMenu(new MenuItem() {
202  {
203  forList.getItem().selectedProperty().addListener((observable, wasSelected, isSelected) -> {
204  configureText(isSelected);
205  });
206 
207  configureText(forList.getItem().selectedProperty().get());
208  setOnAction((ActionEvent event) -> {
209  controller.getQuickHideFilters().remove(forList.getItem());
210  });
211  }
212 
213  private void configureText(Boolean newValue) {
214  if (newValue) {
215  setText(Bundle.FilterSetPanel_hiddenDescriptionsListView_unhideAndRm());
216  } else {
217  setText(Bundle.FilterSetPanel_hiddenDescriptionsListView_remove());
218  }
219  }
220  }));
221  }
222  });
223 
224  return forList;
225  });
226 
227  controller.viewModeProperty().addListener(observable -> {
228  applyFilters();
229  if (controller.viewModeProperty().get() == VisualizationMode.COUNTS) {
230  position = splitPane.getDividerPositions()[0];
231  splitPane.setDividerPositions(1);
232  hiddenDescriptionsPane.setExpanded(false);
233  hiddenDescriptionsPane.setCollapsible(false);
234  hiddenDescriptionsPane.setDisable(true);
235  } else {
236  splitPane.setDividerPositions(position);
237  hiddenDescriptionsPane.setDisable(false);
238  hiddenDescriptionsPane.setCollapsible(true);
239  hiddenDescriptionsPane.setExpanded(true);
240  hiddenDescriptionsPane.setCollapsible(false);
241 
242  }
243  });
244 
245  }
246 
247  public FilterSetPanel(TimeLineController controller) {
248  this.controller = controller;
249  this.filteredEvents = controller.getEventsModel();
250  FXMLConstructor.construct(this, "FilterSetPanel.fxml"); // NON-NLS
251 
252  }
253 
254  private void refresh() {
255  Platform.runLater(() -> {
256  filterTreeTable.setRoot(new FilterTreeItem(filteredEvents.getFilter().copyOf(), expansionMap));
257  });
258  }
259 
260  @NbBundle.Messages({"FilterSetPanel.applyButton.text=Apply",
261  "FilterSetPanel.applyButton.longText=(Re)Apply filters"})
262  private class ApplyFiltersAction extends Action {
263 
265  super(Bundle.FilterSetPanel_applyButton_text());
266  setLongText(Bundle.FilterSetPanel_applyButton_longText());
267  setGraphic(new ImageView(TICK));
268  setEventHandler((ActionEvent t) -> {
269  applyFilters();
270  });
271  }
272  }
273 
274  private void applyFilters() {
275  Platform.runLater(() -> {
276  controller.pushFilters((RootFilter) filterTreeTable.getRoot().getValue());
277  });
278  }
279 }
final ObservableMap< String, Boolean > expansionMap
synchronized ReadOnlyObjectProperty< VisualizationMode > viewModeProperty()
synchronized ReadOnlyObjectProperty< EventTypeZoomLevel > eventTypeZoomProperty()
synchronized ReadOnlyObjectProperty< RootFilter > filterProperty()
synchronized void pushFilters(RootFilter filter)
synchronized ReadOnlyObjectProperty< DescriptionLoD > descriptionLODProperty()
static void construct(Node node, String fxmlFileName)
synchronized ReadOnlyObjectProperty< Interval > timeRangeProperty()
TreeTableColumn< AbstractFilter, AbstractFilter > treeColumn
ObservableList< DescriptionFilter > getQuickHideFilters()
TreeTableColumn< AbstractFilter, AbstractFilter > legendColumn

Copyright © 2012-2015 Basis Technology. Generated on: Wed Apr 6 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.