Autopsy  3.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 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.beans.property.SimpleBooleanProperty;
24 import javafx.collections.FXCollections;
25 import javafx.collections.ObservableMap;
26 import javafx.fxml.FXML;
27 import javafx.scene.control.Button;
28 import javafx.scene.control.CheckBox;
29 import javafx.scene.control.ContextMenu;
30 import javafx.scene.control.Menu;
31 import javafx.scene.control.MenuItem;
32 import javafx.scene.control.TreeItem;
33 import javafx.scene.control.TreeTableCell;
34 import javafx.scene.control.TreeTableColumn;
35 import javafx.scene.control.TreeTableRow;
36 import javafx.scene.control.TreeTableView;
37 import javafx.scene.layout.BorderPane;
38 import org.controlsfx.control.action.Action;
39 import org.openide.util.NbBundle;
47 
53 public class FilterSetPanel extends BorderPane implements TimeLineView {
54 
55  @FXML
56  private Button applyButton;
57 
58  @FXML
59  private Button defaultButton;
60 
61  @FXML
62  private TreeTableView<Filter> filterTreeTable;
63 
64  @FXML
65  private TreeTableColumn<AbstractFilter, AbstractFilter> treeColumn;
66 
67  @FXML
68  private TreeTableColumn<AbstractFilter, AbstractFilter> legendColumn;
69 
71 
73 
74  private final ObservableMap<String, Boolean> expansionMap = FXCollections.observableHashMap();
75 
76  @FXML
77  void initialize() {
78  assert applyButton != null : "fx:id=\"applyButton\" was not injected: check your FXML file 'FilterSetPanel.fxml'."; // NON-NLS
79 
80  applyButton.setOnAction(e -> {
81  controller.pushFilters(filterTreeTable.getRoot().getValue().copyOf());
82  });
83  applyButton.setText(NbBundle.getMessage(this.getClass(), "FilterSetPanel.applyButton.text"));
84  defaultButton.setText(NbBundle.getMessage(this.getClass(), "FilterSetPanel.defaultButton.text"));
85 
86  //remove column headers via css.
87  filterTreeTable.getStylesheets().addAll(getClass().getResource("FilterTable.css").toExternalForm()); // NON-NLS
88 
89  //use row factory as hook to attach context menus to.
90  filterTreeTable.setRowFactory((TreeTableView<Filter> param) -> {
91  final TreeTableRow<Filter> row = new TreeTableRow<>();
92 
93  MenuItem all = new MenuItem(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.all"));
94  all.setOnAction(e -> {
95  row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
96  t.getValue().setActive(Boolean.TRUE);
97  });
98  });
99  MenuItem none = new MenuItem(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.none"));
100  none.setOnAction(e -> {
101  row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
102  t.getValue().setActive(Boolean.FALSE);
103  });
104  });
105 
106  MenuItem only = new MenuItem(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.only"));
107  only.setOnAction(e -> {
108  row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
109  if (t == row.getTreeItem()) {
110  t.getValue().setActive(Boolean.TRUE);
111  } else {
112  t.getValue().setActive(Boolean.FALSE);
113  }
114  });
115  });
116  MenuItem others = new MenuItem(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.others"));
117  others.setOnAction(e -> {
118  row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
119  if (t == row.getTreeItem()) {
120  t.getValue().setActive(Boolean.FALSE);
121  } else {
122  t.getValue().setActive(Boolean.TRUE);
123  }
124  });
125  });
126  final ContextMenu rowMenu = new ContextMenu();
127  Menu select = new Menu(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.select"));
128  select.setOnAction(e -> {
129  row.getItem().setActive(!row.getItem().isActive());
130  });
131  select.getItems().addAll(all, none, only, others);
132  rowMenu.getItems().addAll(select);
133  row.setContextMenu(rowMenu);
134 
135  return row;
136  });
137 
138  //configure tree column to show name of filter and checkbox
139  treeColumn.setCellValueFactory(param -> param.getValue().valueProperty());
140  treeColumn.setCellFactory(col -> new FilterCheckBoxCell());
141  treeColumn.setText(NbBundle.getMessage(this.getClass(), "FilterSetPanel.treeColumn.text"));
142 
143  //configure legend column to show legend (or othe supplamantal ui, eg, text field for text filter)
144  legendColumn.setCellValueFactory(param -> param.getValue().valueProperty());
145  legendColumn.setCellFactory(col -> new LegendCell(this.controller));
146  legendColumn.setText(NbBundle.getMessage(this.getClass(), "FilterSetPanel.legendColumn.text"));
147  }
148 
149  public FilterSetPanel() {
150  FXMLConstructor.construct(this, "FilterSetPanel.fxml"); // NON-NLS
151  expansionMap.put(NbBundle.getMessage(this.getClass(), "FilterSetPanel.eventTypeFilter.title"), Boolean.TRUE);
152  }
153 
154  @Override
155  public void setController(TimeLineController timeLineController) {
156  this.controller = timeLineController;
157  Action defaultFiltersAction = new DefaultFilters(controller);
158  defaultButton.setOnAction(defaultFiltersAction);
159  defaultButton.disableProperty().bind(defaultFiltersAction.disabledProperty());
160  this.setModel(timeLineController.getEventsModel());
161  }
162 
163  @Override
164  public void setModel(FilteredEventsModel filteredEvents) {
165  this.filteredEvents = filteredEvents;
166  refresh();
167  this.filteredEvents.filter().addListener((Observable o) -> {
168  refresh();
169  });
170  }
171 
172  private void refresh() {
173  filterTreeTable.setRoot(new FilterTreeItem(this.filteredEvents.filter().get().copyOf(), expansionMap));
174  }
175 
180  private static class FilterCheckBoxCell extends TreeTableCell<AbstractFilter, AbstractFilter> {
181 
182  private final CheckBox checkBox = new CheckBox();
183  private SimpleBooleanProperty activeProperty;
184 
185  @Override
186  protected void updateItem(AbstractFilter item, boolean empty) {
187  super.updateItem(item, empty);
188  Platform.runLater(() -> {
189  if (activeProperty != null) {
190  checkBox.selectedProperty().unbindBidirectional(activeProperty);
191  }
192  checkBox.disableProperty().unbind();
193  if (item == null) {
194  setText(null);
195  setGraphic(null);
196 
197  } else {
198  setText(item.getDisplayName());
199  activeProperty = item.getActiveProperty();
200  checkBox.selectedProperty().bindBidirectional(activeProperty);
201  checkBox.disableProperty().bind(item.getDisabledProperty());
202  setGraphic(checkBox);
203  }
204  });
205  }
206 
207  }
208 }
final ObservableMap< String, Boolean > expansionMap
synchronized ReadOnlyObjectProperty< Filter > filter()
static void construct(Node n, String fxmlFileName)
void setController(TimeLineController timeLineController)
void setModel(FilteredEventsModel filteredEvents)
TreeTableColumn< AbstractFilter, AbstractFilter > treeColumn
TreeTableColumn< AbstractFilter, AbstractFilter > legendColumn

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