mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 01:07:42 +00:00
Resolve merge conflict for com.sun.javafx.Utils
This commit is contained in:
commit
ee396f3271
@ -24,10 +24,7 @@ TimelinePanel.jButton7.text=3d
|
|||||||
TimelinePanel.jButton2.text=1m
|
TimelinePanel.jButton2.text=1m
|
||||||
TimelinePanel.jButton3.text=3m
|
TimelinePanel.jButton3.text=3m
|
||||||
TimelinePanel.jButton4.text=2w
|
TimelinePanel.jButton4.text=2w
|
||||||
TimeLineTopComponent.eventsTab.name=Events
|
|
||||||
TimeLineTopComponent.filterTab.name=Filters
|
|
||||||
OpenTimelineAction.title=Timeline
|
OpenTimelineAction.title=Timeline
|
||||||
OpenTimeLineAction.msgdlg.text=Could not create timeline, there are no data sources.
|
OpenTimeLineAction.msgdlg.text=Could not create timeline, there are no data sources.
|
||||||
TimeLineTopComponent.timeZonePanel.text=Display Times In\:
|
|
||||||
ProgressWindow.progressHeader.text=\
|
ProgressWindow.progressHeader.text=\
|
||||||
|
|
||||||
|
@ -316,8 +316,10 @@ public class TimeLineController {
|
|||||||
LOGGER.log(Level.INFO, "Beginning generation of timeline"); // NON-NLS
|
LOGGER.log(Level.INFO, "Beginning generation of timeline"); // NON-NLS
|
||||||
try {
|
try {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
if (isWindowOpen()) {
|
synchronized (TimeLineController.this) {
|
||||||
mainFrame.close();
|
if (isWindowOpen()) {
|
||||||
|
mainFrame.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final SleuthkitCase sleuthkitCase = Case.getCurrentCase().getSleuthkitCase();
|
final SleuthkitCase sleuthkitCase = Case.getCurrentCase().getSleuthkitCase();
|
||||||
@ -362,8 +364,10 @@ public class TimeLineController {
|
|||||||
void rebuildTagsTable() {
|
void rebuildTagsTable() {
|
||||||
LOGGER.log(Level.INFO, "starting to rebuild tags table"); // NON-NLS
|
LOGGER.log(Level.INFO, "starting to rebuild tags table"); // NON-NLS
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
if (isWindowOpen()) {
|
synchronized (TimeLineController.this) {
|
||||||
mainFrame.close();
|
if (isWindowOpen()) {
|
||||||
|
mainFrame.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
synchronized (eventsRepository) {
|
synchronized (eventsRepository) {
|
||||||
@ -388,16 +392,19 @@ public class TimeLineController {
|
|||||||
IngestManager.getInstance().removeIngestModuleEventListener(ingestModuleListener);
|
IngestManager.getInstance().removeIngestModuleEventListener(ingestModuleListener);
|
||||||
IngestManager.getInstance().removeIngestJobEventListener(ingestJobListener);
|
IngestManager.getInstance().removeIngestJobEventListener(ingestJobListener);
|
||||||
Case.removePropertyChangeListener(caseListener);
|
Case.removePropertyChangeListener(caseListener);
|
||||||
mainFrame.close();
|
SwingUtilities.invokeLater(() -> {
|
||||||
mainFrame.setVisible(false);
|
synchronized (TimeLineController.this) {
|
||||||
mainFrame = null;
|
mainFrame.close();
|
||||||
|
mainFrame = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show the timeline window and prompt for rebuilding database if necessary.
|
* show the timeline window and prompt for rebuilding database if necessary.
|
||||||
*/
|
*/
|
||||||
synchronized void openTimeLine() {
|
void openTimeLine() {
|
||||||
// listen for case changes (specifically images being added, and case changes).
|
// listen for case changes (specifically images being added, and case changes).
|
||||||
if (Case.isCaseOpen() && !listeningToAutopsy) {
|
if (Case.isCaseOpen() && !listeningToAutopsy) {
|
||||||
IngestManager.getInstance().addIngestModuleEventListener(ingestModuleListener);
|
IngestManager.getInstance().addIngestModuleEventListener(ingestModuleListener);
|
||||||
@ -539,20 +546,20 @@ public class TimeLineController {
|
|||||||
/**
|
/**
|
||||||
* private method to build gui if necessary and make it visible.
|
* private method to build gui if necessary and make it visible.
|
||||||
*/
|
*/
|
||||||
synchronized private void showWindow() {
|
private void showWindow() {
|
||||||
if (mainFrame == null) {
|
|
||||||
LOGGER.log(Level.WARNING, "Tried to show timeline with invalid window. Rebuilding GUI."); // NON-NLS
|
|
||||||
mainFrame = (TimeLineTopComponent) WindowManager.getDefault().findTopComponent(
|
|
||||||
NbBundle.getMessage(TimeLineController.class, "CTL_TimeLineTopComponentAction"));
|
|
||||||
if (mainFrame == null) {
|
|
||||||
mainFrame = new TimeLineTopComponent();
|
|
||||||
}
|
|
||||||
mainFrame.setController(this);
|
|
||||||
}
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
mainFrame.open();
|
synchronized (TimeLineController.this) {
|
||||||
mainFrame.setVisible(true);
|
if (mainFrame == null) {
|
||||||
mainFrame.toFront();
|
LOGGER.log(Level.WARNING, "Tried to show timeline with invalid window. Rebuilding GUI."); // NON-NLS
|
||||||
|
mainFrame = (TimeLineTopComponent) WindowManager.getDefault().findTopComponent(
|
||||||
|
NbBundle.getMessage(TimeLineController.class, "CTL_TimeLineTopComponentAction"));
|
||||||
|
if (mainFrame == null) {
|
||||||
|
mainFrame = new TimeLineTopComponent(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mainFrame.open();
|
||||||
|
mainFrame.toFront();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.embed.swing.JFXPanel;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.SplitPane;
|
import javafx.scene.control.SplitPane;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
@ -34,7 +34,6 @@ import javafx.scene.input.KeyCodeCombination;
|
|||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.layout.Priority;
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import org.netbeans.api.settings.ConvertAsProperties;
|
|
||||||
import org.openide.explorer.ExplorerManager;
|
import org.openide.explorer.ExplorerManager;
|
||||||
import org.openide.explorer.ExplorerUtils;
|
import org.openide.explorer.ExplorerUtils;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
@ -51,135 +50,103 @@ import org.sleuthkit.autopsy.timeline.ui.StatusBar;
|
|||||||
import org.sleuthkit.autopsy.timeline.ui.TimeLineResultView;
|
import org.sleuthkit.autopsy.timeline.ui.TimeLineResultView;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.TimeZonePanel;
|
import org.sleuthkit.autopsy.timeline.ui.TimeZonePanel;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.VisualizationPanel;
|
import org.sleuthkit.autopsy.timeline.ui.VisualizationPanel;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.detailview.tree.NavPanel;
|
import org.sleuthkit.autopsy.timeline.ui.detailview.tree.EventsTree;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.filtering.FilterSetPanel;
|
import org.sleuthkit.autopsy.timeline.ui.filtering.FilterSetPanel;
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.ZoomSettingsPane;
|
import org.sleuthkit.autopsy.timeline.zooming.ZoomSettingsPane;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TopComponent for the timeline feature.
|
* TopComponent for the timeline feature.
|
||||||
*/
|
*/
|
||||||
@ConvertAsProperties(
|
|
||||||
dtd = "-//org.sleuthkit.autopsy.timeline//TimeLine//EN",
|
|
||||||
autostore = false)
|
|
||||||
@TopComponent.Description(
|
@TopComponent.Description(
|
||||||
preferredID = "TimeLineTopComponent",
|
preferredID = "TimeLineTopComponent",
|
||||||
//iconBase="SET/PATH/TO/ICON/HERE",
|
//iconBase="SET/PATH/TO/ICON/HERE",
|
||||||
persistenceType = TopComponent.PERSISTENCE_NEVER)
|
persistenceType = TopComponent.PERSISTENCE_NEVER)
|
||||||
@TopComponent.Registration(mode = "timeline", openAtStartup = false)
|
@TopComponent.Registration(mode = "timeline", openAtStartup = false)
|
||||||
public final class TimeLineTopComponent extends TopComponent implements ExplorerManager.Provider, TimeLineUI {
|
public final class TimeLineTopComponent extends TopComponent implements ExplorerManager.Provider {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(TimeLineTopComponent.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(TimeLineTopComponent.class.getName());
|
||||||
|
|
||||||
private DataContentPanel dataContentPanel;
|
private final DataContentPanel dataContentPanel;
|
||||||
|
|
||||||
private TimeLineResultView tlrv;
|
private final TimeLineResultView tlrv;
|
||||||
|
|
||||||
private final ExplorerManager em = new ExplorerManager();
|
private final ExplorerManager em = new ExplorerManager();
|
||||||
|
|
||||||
private TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
|
|
||||||
////jfx componenets that make up the interface
|
public TimeLineTopComponent(TimeLineController controller) {
|
||||||
private final FilterSetPanel filtersPanel = new FilterSetPanel();
|
|
||||||
|
|
||||||
private final Tab eventsTab = new Tab(
|
|
||||||
NbBundle.getMessage(TimeLineTopComponent.class, "TimeLineTopComponent.eventsTab.name"));
|
|
||||||
|
|
||||||
private final Tab filterTab = new Tab(
|
|
||||||
NbBundle.getMessage(TimeLineTopComponent.class, "TimeLineTopComponent.filterTab.name"));
|
|
||||||
|
|
||||||
private final VBox leftVBox = new VBox(5);
|
|
||||||
|
|
||||||
private final NavPanel navPanel = new NavPanel();
|
|
||||||
|
|
||||||
private final StatusBar statusBar = new StatusBar();
|
|
||||||
|
|
||||||
private final TabPane tabPane = new TabPane();
|
|
||||||
|
|
||||||
private final ZoomSettingsPane zoomSettingsPane = new ZoomSettingsPane();
|
|
||||||
|
|
||||||
private final VisualizationPanel visualizationPanel = new VisualizationPanel(navPanel);
|
|
||||||
|
|
||||||
private final SplitPane splitPane = new SplitPane();
|
|
||||||
|
|
||||||
private final TimeZonePanel timeZonePanel = new TimeZonePanel();
|
|
||||||
|
|
||||||
public TimeLineTopComponent() {
|
|
||||||
initComponents();
|
initComponents();
|
||||||
|
this.controller = controller;
|
||||||
associateLookup(ExplorerUtils.createLookup(em, getActionMap()));
|
associateLookup(ExplorerUtils.createLookup(em, getActionMap()));
|
||||||
|
|
||||||
setName(NbBundle.getMessage(TimeLineTopComponent.class, "CTL_TimeLineTopComponent"));
|
setName(NbBundle.getMessage(TimeLineTopComponent.class, "CTL_TimeLineTopComponent"));
|
||||||
setToolTipText(NbBundle.getMessage(TimeLineTopComponent.class, "HINT_TimeLineTopComponent"));
|
setToolTipText(NbBundle.getMessage(TimeLineTopComponent.class, "HINT_TimeLineTopComponent"));
|
||||||
setIcon(WindowManager.getDefault().getMainWindow().getIconImage()); //use the same icon as main application
|
setIcon(WindowManager.getDefault().getMainWindow().getIconImage()); //use the same icon as main application
|
||||||
|
|
||||||
timeZonePanel.setText(NbBundle.getMessage(this.getClass(), "TimeLineTopComponent.timeZonePanel.text"));
|
|
||||||
customizeComponents();
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized private void customizeComponents() {
|
|
||||||
|
|
||||||
dataContentPanel = DataContentPanel.createInstance();
|
dataContentPanel = DataContentPanel.createInstance();
|
||||||
this.contentViewerContainerPanel.add(dataContentPanel, BorderLayout.CENTER);
|
this.contentViewerContainerPanel.add(dataContentPanel, BorderLayout.CENTER);
|
||||||
tlrv = new TimeLineResultView(dataContentPanel);
|
tlrv = new TimeLineResultView(controller, dataContentPanel);
|
||||||
DataResultPanel dataResultPanel = tlrv.getDataResultPanel();
|
DataResultPanel dataResultPanel = tlrv.getDataResultPanel();
|
||||||
this.resultContainerPanel.add(dataResultPanel, BorderLayout.CENTER);
|
this.resultContainerPanel.add(dataResultPanel, BorderLayout.CENTER);
|
||||||
dataResultPanel.open();
|
dataResultPanel.open();
|
||||||
|
customizeFXComponents();
|
||||||
Platform.runLater(() -> {
|
|
||||||
//assemble ui componenets together
|
|
||||||
jFXstatusPanel.setScene(new Scene(statusBar));
|
|
||||||
jFXVizPanel.setScene(new Scene(splitPane));
|
|
||||||
|
|
||||||
splitPane.setDividerPositions(0);
|
|
||||||
|
|
||||||
filterTab.setClosable(false);
|
|
||||||
filterTab.setContent(filtersPanel);
|
|
||||||
filterTab.setGraphic(new ImageView("org/sleuthkit/autopsy/timeline/images/funnel.png")); // NON-NLS
|
|
||||||
|
|
||||||
eventsTab.setClosable(false);
|
|
||||||
eventsTab.setContent(navPanel);
|
|
||||||
eventsTab.setGraphic(new ImageView("org/sleuthkit/autopsy/timeline/images/timeline_marker.png")); // NON-NLS
|
|
||||||
|
|
||||||
tabPane.getTabs().addAll(filterTab, eventsTab);
|
|
||||||
VBox.setVgrow(tabPane, Priority.ALWAYS);
|
|
||||||
|
|
||||||
VBox.setVgrow(timeZonePanel, Priority.SOMETIMES);
|
|
||||||
leftVBox.getChildren().addAll(timeZonePanel, zoomSettingsPane, tabPane);
|
|
||||||
|
|
||||||
SplitPane.setResizableWithParent(leftVBox, Boolean.FALSE);
|
|
||||||
splitPane.getItems().addAll(leftVBox, visualizationPanel);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@NbBundle.Messages({"TimeLineTopComponent.eventsTab.name=Events",
|
||||||
public synchronized void setController(TimeLineController controller) {
|
"TimeLineTopComponent.filterTab.name=Filters"})
|
||||||
this.controller = controller;
|
void customizeFXComponents() {
|
||||||
|
|
||||||
tlrv.setController(controller);
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
jFXVizPanel.getScene().addEventFilter(KeyEvent.KEY_PRESSED,
|
|
||||||
(KeyEvent event) -> {
|
//create and wire up jfx componenets that make up the interface
|
||||||
if (new KeyCodeCombination(KeyCode.LEFT, KeyCodeCombination.ALT_DOWN).match(event)) {
|
final Tab filterTab = new Tab(Bundle.TimeLineTopComponent_filterTab_name(), new FilterSetPanel(controller));
|
||||||
new Back(controller).handle(new ActionEvent());
|
filterTab.setClosable(false);
|
||||||
} else if (new KeyCodeCombination(KeyCode.BACK_SPACE).match(event)) {
|
filterTab.setGraphic(new ImageView("org/sleuthkit/autopsy/timeline/images/funnel.png")); // NON-NLS
|
||||||
new Back(controller).handle(new ActionEvent());
|
|
||||||
} else if (new KeyCodeCombination(KeyCode.RIGHT, KeyCodeCombination.ALT_DOWN).match(event)) {
|
final EventsTree eventsTree = new EventsTree(controller);
|
||||||
new Forward(controller).handle(new ActionEvent());
|
final VisualizationPanel visualizationPanel = new VisualizationPanel(controller, eventsTree);
|
||||||
} else if (new KeyCodeCombination(KeyCode.BACK_SPACE, KeyCodeCombination.SHIFT_DOWN).match(event)) {
|
final Tab eventsTreeTab = new Tab(Bundle.TimeLineTopComponent_eventsTab_name(), eventsTree);
|
||||||
new Forward(controller).handle(new ActionEvent());
|
eventsTreeTab.setClosable(false);
|
||||||
}
|
eventsTreeTab.setGraphic(new ImageView("org/sleuthkit/autopsy/timeline/images/timeline_marker.png")); // NON-NLS
|
||||||
});
|
eventsTreeTab.disableProperty().bind(controller.viewModeProperty().isEqualTo(VisualizationMode.COUNTS));
|
||||||
|
|
||||||
|
final TabPane leftTabPane = new TabPane(filterTab, eventsTreeTab);
|
||||||
|
VBox.setVgrow(leftTabPane, Priority.ALWAYS);
|
||||||
controller.viewModeProperty().addListener((Observable observable) -> {
|
controller.viewModeProperty().addListener((Observable observable) -> {
|
||||||
if (controller.viewModeProperty().get().equals(VisualizationMode.COUNTS)) {
|
if (controller.viewModeProperty().get().equals(VisualizationMode.COUNTS)) {
|
||||||
tabPane.getSelectionModel().select(filterTab);
|
//if view mode is counts, make sure events tabd is not active
|
||||||
|
leftTabPane.getSelectionModel().select(filterTab);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
eventsTab.disableProperty().bind(controller.viewModeProperty().isEqualTo(VisualizationMode.COUNTS));
|
|
||||||
visualizationPanel.setController(controller);
|
final TimeZonePanel timeZonePanel = new TimeZonePanel();
|
||||||
navPanel.setController(controller);
|
VBox.setVgrow(timeZonePanel, Priority.SOMETIMES);
|
||||||
filtersPanel.setController(controller);
|
|
||||||
zoomSettingsPane.setController(controller);
|
final ZoomSettingsPane zoomSettingsPane = new ZoomSettingsPane(controller);
|
||||||
statusBar.setController(controller);
|
|
||||||
|
final VBox leftVBox = new VBox(5, timeZonePanel, zoomSettingsPane, leftTabPane);
|
||||||
|
SplitPane.setResizableWithParent(leftVBox, Boolean.FALSE);
|
||||||
|
|
||||||
|
final SplitPane mainSplitPane = new SplitPane(leftVBox, visualizationPanel);
|
||||||
|
mainSplitPane.setDividerPositions(0);
|
||||||
|
|
||||||
|
final Scene scene = new Scene(mainSplitPane);
|
||||||
|
scene.addEventFilter(KeyEvent.KEY_PRESSED,
|
||||||
|
(KeyEvent event) -> {
|
||||||
|
if (new KeyCodeCombination(KeyCode.LEFT, KeyCodeCombination.ALT_DOWN).match(event)) {
|
||||||
|
new Back(controller).handle(null);
|
||||||
|
} else if (new KeyCodeCombination(KeyCode.BACK_SPACE).match(event)) {
|
||||||
|
new Back(controller).handle(null);
|
||||||
|
} else if (new KeyCodeCombination(KeyCode.RIGHT, KeyCodeCombination.ALT_DOWN).match(event)) {
|
||||||
|
new Forward(controller).handle(null);
|
||||||
|
} else if (new KeyCodeCombination(KeyCode.BACK_SPACE, KeyCodeCombination.SHIFT_DOWN).match(event)) {
|
||||||
|
new Forward(controller).handle(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//add ui componenets to JFXPanels
|
||||||
|
jFXVizPanel.setScene(scene);
|
||||||
|
jFXstatusPanel.setScene(new Scene(new StatusBar(controller)));
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,9 +163,9 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
|||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
jFXstatusPanel = new javafx.embed.swing.JFXPanel();
|
jFXstatusPanel = new JFXPanel();
|
||||||
splitYPane = new javax.swing.JSplitPane();
|
splitYPane = new javax.swing.JSplitPane();
|
||||||
jFXVizPanel = new javafx.embed.swing.JFXPanel();
|
jFXVizPanel = new JFXPanel();
|
||||||
lowerSplitXPane = new javax.swing.JSplitPane();
|
lowerSplitXPane = new javax.swing.JSplitPane();
|
||||||
resultContainerPanel = new javax.swing.JPanel();
|
resultContainerPanel = new javax.swing.JPanel();
|
||||||
contentViewerContainerPanel = new javax.swing.JPanel();
|
contentViewerContainerPanel = new javax.swing.JPanel();
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2014 Basis Technology Corp.
|
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.sleuthkit.autopsy.timeline;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface TimeLineUI {
|
|
||||||
|
|
||||||
void setController(TimeLineController controller);
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2013 Basis Technology Corp.
|
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.sleuthkit.autopsy.timeline;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface to be implemented by views of the data.
|
|
||||||
*
|
|
||||||
* Most implementations should install the relevant listeners in their
|
|
||||||
* {@link #setController} and {@link #setModel} methods
|
|
||||||
*/
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
|
||||||
|
|
||||||
public interface TimeLineView extends TimeLineUI {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void setController(TimeLineController controller);
|
|
||||||
|
|
||||||
void setModel(final FilteredEventsModel filteredEvents);
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
Back.actions.name.text=Back
|
Back.actions.name.text=Back
|
||||||
DefaultFilters.action.name.text=apply default filters
|
DefaultFilters.action.name.text=apply default filters
|
||||||
Forward.action.name.text=Forward
|
Forward.action.name.text=Forward
|
||||||
ZoomOut.action.name.text=apply default filters
|
|
||||||
|
@ -53,7 +53,8 @@ public class SaveSnapshotAsReport extends Action {
|
|||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(SaveSnapshotAsReport.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(SaveSnapshotAsReport.class.getName());
|
||||||
|
|
||||||
@NbBundle.Messages({"SaveSnapshot.action.name.text=save snapshot", "SaveSnapshot.fileChoose.title.text=Save snapshot to"})
|
@NbBundle.Messages({"SaveSnapshot.action.name.text=save snapshot",
|
||||||
|
"SaveSnapshot.fileChoose.title.text=Save snapshot to"})
|
||||||
public SaveSnapshotAsReport(TimeLineController controller, WritableImage snapshot) {
|
public SaveSnapshotAsReport(TimeLineController controller, WritableImage snapshot) {
|
||||||
super(Bundle.SaveSnapshot_action_name_text());
|
super(Bundle.SaveSnapshot_action_name_text());
|
||||||
setEventHandler(new Consumer<ActionEvent>() {
|
setEventHandler(new Consumer<ActionEvent>() {
|
||||||
|
44
Core/src/org/sleuthkit/autopsy/timeline/actions/ZoomIn.java
Normal file
44
Core/src/org/sleuthkit/autopsy/timeline/actions/ZoomIn.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2015 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.timeline.actions;
|
||||||
|
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import org.controlsfx.control.action.Action;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ZoomIn extends Action {
|
||||||
|
|
||||||
|
private static final Image MAGNIFIER_IN = new Image("/org/sleuthkit/autopsy/timeline/images/magnifier-zoom-in-green.png"); //NOI18N
|
||||||
|
|
||||||
|
@NbBundle.Messages({"ZoomIn.longText=Zoom in to view half as much time.",
|
||||||
|
"ZoomIn.action.text=Zoom in"})
|
||||||
|
public ZoomIn(TimeLineController controller) {
|
||||||
|
super(Bundle.ZoomIn_action_text());
|
||||||
|
setLongText(Bundle.ZoomIn_longText());
|
||||||
|
setGraphic(new ImageView(MAGNIFIER_IN));
|
||||||
|
setEventHandler(actionEvent -> {
|
||||||
|
controller.pushZoomInTime();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2015 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,7 +19,8 @@
|
|||||||
package org.sleuthkit.autopsy.timeline.actions;
|
package org.sleuthkit.autopsy.timeline.actions;
|
||||||
|
|
||||||
import javafx.beans.binding.BooleanBinding;
|
import javafx.beans.binding.BooleanBinding;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
@ -30,15 +31,22 @@ import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
|||||||
*/
|
*/
|
||||||
public class ZoomOut extends Action {
|
public class ZoomOut extends Action {
|
||||||
|
|
||||||
private final TimeLineController controller;
|
private static final Image MAGNIFIER_OUT = new Image("/org/sleuthkit/autopsy/timeline/images/magnifier-zoom-out-red.png"); //NOI18N
|
||||||
|
|
||||||
private final FilteredEventsModel eventsModel;
|
@NbBundle.Messages({"ZoomOut.longText=Zoom out to view 50% more time.",
|
||||||
|
"ZoomOut.action.text=Zoom out"})
|
||||||
|
public ZoomOut(TimeLineController controller) {
|
||||||
|
super(Bundle.ZoomOut_action_text());
|
||||||
|
setLongText(Bundle.ZoomOut_longText());
|
||||||
|
setGraphic(new ImageView(MAGNIFIER_OUT));
|
||||||
|
setEventHandler(actionEvent -> {
|
||||||
|
controller.pushZoomOutTime();
|
||||||
|
});
|
||||||
|
|
||||||
public ZoomOut(final TimeLineController controller) {
|
//disable action when the current time range already encompases the entire case.
|
||||||
super(NbBundle.getMessage(ZoomOut.class, "ZoomOut.action.name.text"));
|
|
||||||
this.controller = controller;
|
|
||||||
eventsModel = controller.getEventsModel();
|
|
||||||
disabledProperty().bind(new BooleanBinding() {
|
disabledProperty().bind(new BooleanBinding() {
|
||||||
|
private final FilteredEventsModel eventsModel = controller.getEventsModel();
|
||||||
|
|
||||||
{
|
{
|
||||||
bind(eventsModel.zoomParametersProperty());
|
bind(eventsModel.zoomParametersProperty());
|
||||||
}
|
}
|
||||||
@ -48,8 +56,5 @@ public class ZoomOut extends Action {
|
|||||||
return eventsModel.zoomParametersProperty().getValue().getTimeRange().contains(eventsModel.getSpanningInterval());
|
return eventsModel.zoomParametersProperty().getValue().getTimeRange().contains(eventsModel.getSpanningInterval());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setEventHandler((ActionEvent t) -> {
|
|
||||||
controller.zoomOutToActivity();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2014-15 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.timeline.actions;
|
||||||
|
|
||||||
|
import javafx.beans.binding.BooleanBinding;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import org.controlsfx.control.action.Action;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
|
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ZoomToEvents extends Action {
|
||||||
|
|
||||||
|
private static final Image MAGNIFIER_OUT = new Image("/org/sleuthkit/autopsy/timeline/images/magnifier-zoom-out-red.png", 16, 16, true, true); //NOI18N
|
||||||
|
|
||||||
|
@NbBundle.Messages({"ZoomToEvents.action.text=Zoom to events",
|
||||||
|
"ZoomToEvents.longText=Zoom out to show the nearest events."})
|
||||||
|
public ZoomToEvents(final TimeLineController controller) {
|
||||||
|
super(Bundle.ZoomToEvents_action_text());
|
||||||
|
setLongText(Bundle.ZoomToEvents_longText());
|
||||||
|
setGraphic(new ImageView(MAGNIFIER_OUT));
|
||||||
|
setEventHandler(actionEvent -> {
|
||||||
|
controller.zoomOutToActivity();
|
||||||
|
});
|
||||||
|
|
||||||
|
//disable action when the current time range already encompases the entire case.
|
||||||
|
disabledProperty().bind(new BooleanBinding() {
|
||||||
|
private final FilteredEventsModel eventsModel = controller.getEventsModel();
|
||||||
|
|
||||||
|
{
|
||||||
|
bind(eventsModel.zoomParametersProperty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean computeValue() {
|
||||||
|
//TODO: do a db query to see if using this action will actually result in viewable events
|
||||||
|
return eventsModel.zoomParametersProperty().getValue().getTimeRange().contains(eventsModel.getSpanningInterval());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -41,7 +41,6 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
|||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent.DeletedContentTagInfo;
|
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent.DeletedContentTagInfo;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.RootEventType;
|
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.RootEventType;
|
||||||
import org.sleuthkit.autopsy.timeline.db.EventsRepository;
|
import org.sleuthkit.autopsy.timeline.db.EventsRepository;
|
||||||
|
@ -51,13 +51,11 @@ import javafx.scene.text.Font;
|
|||||||
import javafx.scene.text.FontWeight;
|
import javafx.scene.text.FontWeight;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.scene.text.TextAlignment;
|
import javafx.scene.text.TextAlignment;
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||||
import org.sleuthkit.autopsy.timeline.events.RefreshRequestedEvent;
|
import org.sleuthkit.autopsy.timeline.events.RefreshRequestedEvent;
|
||||||
|
|
||||||
@ -75,7 +73,7 @@ import org.sleuthkit.autopsy.timeline.events.RefreshRequestedEvent;
|
|||||||
* {@link XYChart} doing the rendering. Is this a good idea? -jm TODO: pull up
|
* {@link XYChart} doing the rendering. Is this a good idea? -jm TODO: pull up
|
||||||
* common history context menu items out of derived classes? -jm
|
* common history context menu items out of derived classes? -jm
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y> & TimeLineChart<X>> extends BorderPane implements TimeLineView {
|
public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y> & TimeLineChart<X>> extends BorderPane {
|
||||||
|
|
||||||
@NbBundle.Messages("AbstractVisualization.Drag_Tooltip.text=Drag the mouse to select a time interval to zoom into.")
|
@NbBundle.Messages("AbstractVisualization.Drag_Tooltip.text=Drag the mouse to select a time interval to zoom into.")
|
||||||
private static final Tooltip DRAG_TOOLTIP = new Tooltip(Bundle.AbstractVisualization_Drag_Tooltip_text());
|
private static final Tooltip DRAG_TOOLTIP = new Tooltip(Bundle.AbstractVisualization_Drag_Tooltip_text());
|
||||||
@ -102,11 +100,15 @@ public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y>
|
|||||||
*/
|
*/
|
||||||
private Task<Boolean> updateTask;
|
private Task<Boolean> updateTask;
|
||||||
|
|
||||||
protected TimeLineController controller;
|
final protected TimeLineController controller;
|
||||||
|
|
||||||
protected FilteredEventsModel filteredEvents;
|
final protected FilteredEventsModel filteredEvents;
|
||||||
|
|
||||||
protected ReadOnlyListWrapper<N> selectedNodes = new ReadOnlyListWrapper<>(FXCollections.observableArrayList());
|
final protected ReadOnlyListWrapper<N> selectedNodes = new ReadOnlyListWrapper<>(FXCollections.observableArrayList());
|
||||||
|
|
||||||
|
private InvalidationListener invalidationListener = (Observable observable) -> {
|
||||||
|
update();
|
||||||
|
};
|
||||||
|
|
||||||
public ReadOnlyListProperty<N> getSelectedNodes() {
|
public ReadOnlyListProperty<N> getSelectedNodes() {
|
||||||
return selectedNodes.getReadOnlyProperty();
|
return selectedNodes.getReadOnlyProperty();
|
||||||
@ -186,7 +188,7 @@ public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y>
|
|||||||
* Primarily this invokes the background {@link Task} returned by
|
* Primarily this invokes the background {@link Task} returned by
|
||||||
* {@link #getUpdateTask()} which derived classes must implement.
|
* {@link #getUpdateTask()} which derived classes must implement.
|
||||||
*/
|
*/
|
||||||
synchronized public void update() {
|
final synchronized public void update() {
|
||||||
if (updateTask != null) {
|
if (updateTask != null) {
|
||||||
updateTask.cancel(true);
|
updateTask.cancel(true);
|
||||||
updateTask = null;
|
updateTask = null;
|
||||||
@ -212,7 +214,7 @@ public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y>
|
|||||||
controller.monitorTask(updateTask);
|
controller.monitorTask(updateTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void dispose() {
|
final synchronized public void dispose() {
|
||||||
if (updateTask != null) {
|
if (updateTask != null) {
|
||||||
updateTask.cancel(true);
|
updateTask.cancel(true);
|
||||||
}
|
}
|
||||||
@ -220,7 +222,12 @@ public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y>
|
|||||||
invalidationListener = null;
|
invalidationListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractVisualizationPane(Pane partPane, Pane contextPane, Region spacer) {
|
protected AbstractVisualizationPane(TimeLineController controller, Pane partPane, Pane contextPane, Region spacer) {
|
||||||
|
this.controller = controller;
|
||||||
|
|
||||||
|
this.filteredEvents = controller.getEventsModel();
|
||||||
|
this.filteredEvents.registerForEvents(this);
|
||||||
|
this.filteredEvents.zoomParametersProperty().addListener(invalidationListener);
|
||||||
this.leafPane = partPane;
|
this.leafPane = partPane;
|
||||||
this.branchPane = contextPane;
|
this.branchPane = contextPane;
|
||||||
this.spacer = spacer;
|
this.spacer = spacer;
|
||||||
@ -235,18 +242,9 @@ public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized public void setController(TimeLineController controller) {
|
|
||||||
this.controller = controller;
|
|
||||||
chart.setController(controller);
|
|
||||||
|
|
||||||
setModel(controller.getEventsModel());
|
|
||||||
TimeLineController.getTimeZone().addListener((Observable observable) -> {
|
|
||||||
update();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
TimeLineController.getTimeZone().addListener(invalidationListener);
|
||||||
|
|
||||||
//show tooltip text in status bar
|
//show tooltip text in status bar
|
||||||
hoverProperty().addListener((observable, oldActivated, newActivated) -> {
|
hoverProperty().addListener((observable, oldActivated, newActivated) -> {
|
||||||
if (newActivated) {
|
if (newActivated) {
|
||||||
@ -255,21 +253,7 @@ public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y>
|
|||||||
controller.setStatus("");
|
controller.setStatus("");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized public void setModel(@Nonnull FilteredEventsModel filteredEvents) {
|
|
||||||
|
|
||||||
if (this.filteredEvents != null && this.filteredEvents != filteredEvents) {
|
|
||||||
this.filteredEvents.unRegisterForEvents(this);
|
|
||||||
this.filteredEvents.zoomParametersProperty().removeListener(invalidationListener);
|
|
||||||
}
|
|
||||||
if (this.filteredEvents != filteredEvents) {
|
|
||||||
filteredEvents.registerForEvents(this);
|
|
||||||
filteredEvents.zoomParametersProperty().addListener(invalidationListener);
|
|
||||||
}
|
|
||||||
this.filteredEvents = filteredEvents;
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,10 +262,6 @@ public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y>
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InvalidationListener invalidationListener = (Observable observable) -> {
|
|
||||||
update();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iterate through the list of tick-marks building a two level structure of
|
* iterate through the list of tick-marks building a two level structure of
|
||||||
* replacement tick marl labels. (Visually) upper level has most
|
* replacement tick marl labels. (Visually) upper level has most
|
||||||
|
@ -28,13 +28,12 @@ import javafx.scene.layout.Region;
|
|||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineUI;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* simple status bar that only shows one possible message determined by
|
* simple status bar that only shows one possible message determined by
|
||||||
* {@link TimeLineController#newEventsFlag}
|
* {@link TimeLineController#newEventsFlag}
|
||||||
*/
|
*/
|
||||||
public class StatusBar extends ToolBar implements TimeLineUI {
|
public class StatusBar extends ToolBar {
|
||||||
|
|
||||||
private TimeLineController controller;
|
private TimeLineController controller;
|
||||||
|
|
||||||
@ -56,7 +55,8 @@ public class StatusBar extends ToolBar implements TimeLineUI {
|
|||||||
@FXML
|
@FXML
|
||||||
private Label messageLabel;
|
private Label messageLabel;
|
||||||
|
|
||||||
public StatusBar() {
|
public StatusBar(TimeLineController controller) {
|
||||||
|
this.controller = controller;
|
||||||
FXMLConstructor.construct(this, "StatusBar.fxml"); // NON-NLS
|
FXMLConstructor.construct(this, "StatusBar.fxml"); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,11 +73,7 @@ public class StatusBar extends ToolBar implements TimeLineUI {
|
|||||||
taskLabel.setText(NbBundle.getMessage(this.getClass(), "StatusBar.taskLabel.text"));
|
taskLabel.setText(NbBundle.getMessage(this.getClass(), "StatusBar.taskLabel.text"));
|
||||||
taskLabel.setVisible(false);
|
taskLabel.setVisible(false);
|
||||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setController(TimeLineController controller) {
|
|
||||||
this.controller = controller;
|
|
||||||
refreshLabel.visibleProperty().bind(this.controller.getNewEventsFlag());
|
refreshLabel.visibleProperty().bind(this.controller.getNewEventsFlag());
|
||||||
refreshLabel.managedProperty().bind(this.controller.getNewEventsFlag());
|
refreshLabel.managedProperty().bind(this.controller.getNewEventsFlag());
|
||||||
taskLabel.textProperty().bind(this.controller.getTaskTitle());
|
taskLabel.textProperty().bind(this.controller.getTaskTitle());
|
||||||
|
@ -29,7 +29,6 @@ import javafx.scene.input.MouseEvent;
|
|||||||
import org.controlsfx.control.action.ActionGroup;
|
import org.controlsfx.control.action.ActionGroup;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.actions.Back;
|
import org.sleuthkit.autopsy.timeline.actions.Back;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.Forward;
|
import org.sleuthkit.autopsy.timeline.actions.Forward;
|
||||||
|
|
||||||
@ -38,8 +37,9 @@ import org.sleuthkit.autopsy.timeline.actions.Forward;
|
|||||||
*
|
*
|
||||||
* @param <X> the type of values along the horizontal axis
|
* @param <X> the type of values along the horizontal axis
|
||||||
*/
|
*/
|
||||||
public interface TimeLineChart<X> extends TimeLineView {
|
public interface TimeLineChart<X> {
|
||||||
|
|
||||||
|
// void setController(TimeLineController controller);
|
||||||
IntervalSelector<? extends X> getIntervalSelector();
|
IntervalSelector<? extends X> getIntervalSelector();
|
||||||
|
|
||||||
void setIntervalSelector(IntervalSelector<? extends X> newIntervalSelector);
|
void setIntervalSelector(IntervalSelector<? extends X> newIntervalSelector);
|
||||||
@ -139,6 +139,17 @@ public interface TimeLineChart<X> extends TimeLineView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum to represent whether the drag is a left/right-edge modification or a
|
||||||
|
* horizontal slide triggered by dragging the center
|
||||||
|
*/
|
||||||
|
enum DragPosition {
|
||||||
|
|
||||||
|
LEFT,
|
||||||
|
CENTER,
|
||||||
|
RIGHT
|
||||||
|
}
|
||||||
|
|
||||||
@NbBundle.Messages({"TimeLineChart.zoomHistoryActionGroup.name=Zoom History"})
|
@NbBundle.Messages({"TimeLineChart.zoomHistoryActionGroup.name=Zoom History"})
|
||||||
static ActionGroup newZoomHistoyActionGroup(TimeLineController controller) {
|
static ActionGroup newZoomHistoyActionGroup(TimeLineController controller) {
|
||||||
return new ActionGroup(Bundle.TimeLineChart_zoomHistoryActionGroup_name(),
|
return new ActionGroup(Bundle.TimeLineChart_zoomHistoryActionGroup_name(),
|
||||||
|
@ -25,12 +25,11 @@ import javax.swing.SwingUtilities;
|
|||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
|
||||||
import org.sleuthkit.autopsy.timeline.explorernodes.EventRootNode;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
||||||
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
|
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||||
|
import org.sleuthkit.autopsy.timeline.explorernodes.EventRootNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Since it was too hard to derive from {@link DataResultPanel}, this class
|
* Since it was too hard to derive from {@link DataResultPanel}, this class
|
||||||
@ -39,16 +38,16 @@ import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
|||||||
* {@link DataResultPanel}. That is, this class acts as a sort of bridge/adapter
|
* {@link DataResultPanel}. That is, this class acts as a sort of bridge/adapter
|
||||||
* between a FilteredEventsModel instance and a DataResultPanel instance.
|
* between a FilteredEventsModel instance and a DataResultPanel instance.
|
||||||
*/
|
*/
|
||||||
public class TimeLineResultView implements TimeLineView {
|
public class TimeLineResultView {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the {@link DataResultPanel} that is the real view proxied by this class
|
* the {@link DataResultPanel} that is the real view proxied by this class
|
||||||
*/
|
*/
|
||||||
private final DataResultPanel dataResultPanel;
|
private final DataResultPanel dataResultPanel;
|
||||||
|
|
||||||
private TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
|
|
||||||
private FilteredEventsModel filteredEvents;
|
private final FilteredEventsModel filteredEvents;
|
||||||
|
|
||||||
private Set<Long> selectedEventIDs = new HashSet<>();
|
private Set<Long> selectedEventIDs = new HashSet<>();
|
||||||
|
|
||||||
@ -56,19 +55,11 @@ public class TimeLineResultView implements TimeLineView {
|
|||||||
return dataResultPanel;
|
return dataResultPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeLineResultView(DataContent dataContent) {
|
public TimeLineResultView(TimeLineController controller, DataContent dataContent) {
|
||||||
dataResultPanel = DataResultPanel.createInstanceUninitialized("", "", Node.EMPTY, 0, dataContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the Controller for this class. Also sets the model provided by the
|
|
||||||
* controller as the model for this view.
|
|
||||||
*
|
|
||||||
* @param controller
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setController(TimeLineController controller) {
|
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
|
this.filteredEvents = controller.getEventsModel();
|
||||||
|
dataResultPanel = DataResultPanel.createInstanceUninitialized("", "", Node.EMPTY, 0, dataContent);
|
||||||
|
|
||||||
//set up listeners on relevant properties
|
//set up listeners on relevant properties
|
||||||
TimeLineController.getTimeZone().addListener((Observable observable) -> {
|
TimeLineController.getTimeZone().addListener((Observable observable) -> {
|
||||||
@ -78,18 +69,7 @@ public class TimeLineResultView implements TimeLineView {
|
|||||||
controller.getSelectedEventIDs().addListener((Observable o) -> {
|
controller.getSelectedEventIDs().addListener((Observable o) -> {
|
||||||
refresh();
|
refresh();
|
||||||
});
|
});
|
||||||
|
refresh();
|
||||||
setModel(controller.getEventsModel());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the Model for this View
|
|
||||||
*
|
|
||||||
* @param filteredEvents
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
synchronized public void setModel(final FilteredEventsModel filteredEvents) {
|
|
||||||
this.filteredEvents = filteredEvents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +23,10 @@ import java.util.Date;
|
|||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.RadioButton;
|
||||||
|
import javafx.scene.control.TitledPane;
|
||||||
|
import javafx.scene.control.Toggle;
|
||||||
|
import javafx.scene.control.ToggleGroup;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
@ -50,8 +53,9 @@ public class TimeZonePanel extends TitledPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@NbBundle.Messages({"TimeZonePanel.title=Display Times In:"})
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
setText(Bundle.TimeZonePanel_title());
|
||||||
// localRadio.setText("Local Time Zone: " + getTimeZoneString(TimeZone.getDefault()));
|
// localRadio.setText("Local Time Zone: " + getTimeZoneString(TimeZone.getDefault()));
|
||||||
localRadio.setText(NbBundle.getMessage(this.getClass(), "TimeZonePanel.localRadio.text"));
|
localRadio.setText(NbBundle.getMessage(this.getClass(), "TimeZonePanel.localRadio.text"));
|
||||||
otherRadio.setText(NbBundle.getMessage(this.getClass(), "TimeZonePanel.otherRadio.text"));
|
otherRadio.setText(NbBundle.getMessage(this.getClass(), "TimeZonePanel.otherRadio.text"));
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<?import jfxtras.scene.control.*?>
|
<?import jfxtras.scene.control.*?>
|
||||||
<?import org.controlsfx.control.*?>
|
<?import org.controlsfx.control.*?>
|
||||||
|
|
||||||
<fx:root prefHeight="-1.0" prefWidth="-1.0" type="javafx.scene.layout.BorderPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
<fx:root prefHeight="-1.0" prefWidth="-1.0" type="javafx.scene.layout.BorderPane" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
|
||||||
<top>
|
<top>
|
||||||
<ToolBar fx:id="toolBar" prefWidth="200.0" BorderPane.alignment="CENTER">
|
<ToolBar fx:id="toolBar" prefWidth="200.0" BorderPane.alignment="CENTER">
|
||||||
<items>
|
<items>
|
||||||
@ -115,7 +115,7 @@
|
|||||||
</Separator>
|
</Separator>
|
||||||
<HBox>
|
<HBox>
|
||||||
<children>
|
<children>
|
||||||
<Button fx:id="zoomOutButton" mnemonicParsing="false">
|
<Button fx:id="zoomOutButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false">
|
||||||
<graphic>
|
<graphic>
|
||||||
<ImageView pickOnBounds="true" preserveRatio="true">
|
<ImageView pickOnBounds="true" preserveRatio="true">
|
||||||
<image>
|
<image>
|
||||||
@ -127,7 +127,7 @@
|
|||||||
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
|
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
|
||||||
</HBox.margin>
|
</HBox.margin>
|
||||||
</Button>
|
</Button>
|
||||||
<Button fx:id="zoomInButton" mnemonicParsing="false">
|
<Button fx:id="zoomInButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false">
|
||||||
<graphic>
|
<graphic>
|
||||||
<ImageView pickOnBounds="true" preserveRatio="true">
|
<ImageView pickOnBounds="true" preserveRatio="true">
|
||||||
<image>
|
<image>
|
||||||
@ -143,7 +143,7 @@
|
|||||||
</HBox>
|
</HBox>
|
||||||
<MenuButton fx:id="zoomMenuButton" mnemonicParsing="false">
|
<MenuButton fx:id="zoomMenuButton" mnemonicParsing="false">
|
||||||
<graphic>
|
<graphic>
|
||||||
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
<ImageView pickOnBounds="true" preserveRatio="true">
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../images/magnifier-left.png" />
|
<Image url="@../images/magnifier-left.png" />
|
||||||
</image>
|
</image>
|
||||||
|
@ -63,6 +63,7 @@ import jfxtras.scene.control.LocalDateTimeTextField;
|
|||||||
import org.controlsfx.control.NotificationPane;
|
import org.controlsfx.control.NotificationPane;
|
||||||
import org.controlsfx.control.RangeSlider;
|
import org.controlsfx.control.RangeSlider;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
|
import org.controlsfx.control.action.ActionUtils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
import org.joda.time.Interval;
|
import org.joda.time.Interval;
|
||||||
@ -71,11 +72,12 @@ import org.sleuthkit.autopsy.coreutils.LoggedTask;
|
|||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.VisualizationMode;
|
import org.sleuthkit.autopsy.timeline.VisualizationMode;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.ResetFilters;
|
import org.sleuthkit.autopsy.timeline.actions.ResetFilters;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.SaveSnapshotAsReport;
|
import org.sleuthkit.autopsy.timeline.actions.SaveSnapshotAsReport;
|
||||||
|
import org.sleuthkit.autopsy.timeline.actions.ZoomIn;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.ZoomOut;
|
import org.sleuthkit.autopsy.timeline.actions.ZoomOut;
|
||||||
|
import org.sleuthkit.autopsy.timeline.actions.ZoomToEvents;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||||
import org.sleuthkit.autopsy.timeline.events.TagsUpdatedEvent;
|
import org.sleuthkit.autopsy.timeline.events.TagsUpdatedEvent;
|
||||||
import org.sleuthkit.autopsy.timeline.filters.TagsFilter;
|
import org.sleuthkit.autopsy.timeline.filters.TagsFilter;
|
||||||
@ -83,7 +85,7 @@ import static org.sleuthkit.autopsy.timeline.ui.Bundle.VisualizationPanel_refres
|
|||||||
import static org.sleuthkit.autopsy.timeline.ui.Bundle.VisualizationPanel_tagsAddedOrDeleted;
|
import static org.sleuthkit.autopsy.timeline.ui.Bundle.VisualizationPanel_tagsAddedOrDeleted;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.countsview.CountsViewPane;
|
import org.sleuthkit.autopsy.timeline.ui.countsview.CountsViewPane;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewPane;
|
import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewPane;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.detailview.tree.NavPanel;
|
import org.sleuthkit.autopsy.timeline.ui.detailview.tree.EventsTree;
|
||||||
import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;
|
import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,7 +96,7 @@ import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;
|
|||||||
*
|
*
|
||||||
* TODO: refactor common code out of histogram and CountsView? -jm
|
* TODO: refactor common code out of histogram and CountsView? -jm
|
||||||
*/
|
*/
|
||||||
public class VisualizationPanel extends BorderPane implements TimeLineView {
|
final public class VisualizationPanel extends BorderPane {
|
||||||
|
|
||||||
private static final Image INFORMATION = new Image("org/sleuthkit/autopsy/timeline/images/information.png", 16, 16, true, true); // NON-NLS
|
private static final Image INFORMATION = new Image("org/sleuthkit/autopsy/timeline/images/information.png", 16, 16, true, true); // NON-NLS
|
||||||
private static final Image REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/arrow-circle-double-135.png"); // NON-NLS
|
private static final Image REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/arrow-circle-double-135.png"); // NON-NLS
|
||||||
@ -104,7 +106,7 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
|||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private LoggedTask<Void> histogramTask;
|
private LoggedTask<Void> histogramTask;
|
||||||
|
|
||||||
private final NavPanel navPanel;
|
private final EventsTree eventsTree;
|
||||||
|
|
||||||
private AbstractVisualizationPane<?, ?, ?, ?> visualization;
|
private AbstractVisualizationPane<?, ?, ?, ?> visualization;
|
||||||
|
|
||||||
@ -204,14 +206,15 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
|||||||
|
|
||||||
static private final Lighting lighting = new Lighting();
|
static private final Lighting lighting = new Lighting();
|
||||||
|
|
||||||
public VisualizationPanel(NavPanel navPanel) {
|
public VisualizationPanel(TimeLineController controller, EventsTree eventsTree) {
|
||||||
this.navPanel = navPanel;
|
this.controller = controller;
|
||||||
|
this.eventsTree = eventsTree;
|
||||||
FXMLConstructor.construct(this, "VisualizationPanel.fxml"); // NON-NLS
|
FXMLConstructor.construct(this, "VisualizationPanel.fxml"); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML // This method is called by the FXMLLoader when initialization is complete
|
@FXML // This method is called by the FXMLLoader when initialization is complete
|
||||||
@NbBundle.Messages("VisualizationPanel.refresh=refresh")
|
@NbBundle.Messages("VisualizationPanel.refresh=refresh")
|
||||||
protected void initialize() {
|
void initialize() {
|
||||||
assert endPicker != null : "fx:id=\"endPicker\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS
|
assert endPicker != null : "fx:id=\"endPicker\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS
|
||||||
assert histogramBox != null : "fx:id=\"histogramBox\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS
|
assert histogramBox != null : "fx:id=\"histogramBox\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS
|
||||||
assert startPicker != null : "fx:id=\"startPicker\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS
|
assert startPicker != null : "fx:id=\"startPicker\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS
|
||||||
@ -286,13 +289,6 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
|||||||
}
|
}
|
||||||
zoomMenuButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomMenuButton.text")); // NON-NLS
|
zoomMenuButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomMenuButton.text")); // NON-NLS
|
||||||
|
|
||||||
zoomOutButton.setOnAction(e -> {
|
|
||||||
controller.pushZoomOutTime();
|
|
||||||
});
|
|
||||||
zoomInButton.setOnAction(e -> {
|
|
||||||
controller.pushZoomInTime();
|
|
||||||
});
|
|
||||||
|
|
||||||
snapShotButton.setOnAction(event ->
|
snapShotButton.setOnAction(event ->
|
||||||
this.snapshot(snapShotResult -> {
|
this.snapshot(snapShotResult -> {
|
||||||
new SaveSnapshotAsReport(controller, snapShotResult.getImage()).handle(event);
|
new SaveSnapshotAsReport(controller, snapShotResult.getImage()).handle(event);
|
||||||
@ -301,12 +297,22 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
|||||||
);
|
);
|
||||||
|
|
||||||
snapShotButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.snapShotButton.text")); // NON-NLS
|
snapShotButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.snapShotButton.text")); // NON-NLS
|
||||||
}
|
if (this.filteredEvents != null && this.filteredEvents != controller.getEventsModel()) {
|
||||||
|
this.filteredEvents.unRegisterForEvents(this);
|
||||||
|
this.filteredEvents.timeRangeProperty().removeListener(timeRangeInvalidationListener);
|
||||||
|
this.filteredEvents.zoomParametersProperty().removeListener(zoomListener);
|
||||||
|
}
|
||||||
|
if (this.filteredEvents != controller.getEventsModel()) {
|
||||||
|
controller.getEventsModel().registerForEvents(this);
|
||||||
|
controller.getEventsModel().timeRangeProperty().addListener(timeRangeInvalidationListener);
|
||||||
|
controller.getEventsModel().zoomParametersProperty().addListener(zoomListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.filteredEvents = controller.getEventsModel();
|
||||||
|
refreshTimeUI(controller.getEventsModel().timeRangeProperty().get());
|
||||||
|
ActionUtils.configureButton(new ZoomOut(controller), zoomOutButton);
|
||||||
|
ActionUtils.configureButton(new ZoomIn(controller), zoomInButton);
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void setController(TimeLineController controller) {
|
|
||||||
this.controller = controller;
|
|
||||||
setModel(controller.getEventsModel());
|
|
||||||
setViewMode(controller.viewModeProperty().get());
|
setViewMode(controller.viewModeProperty().get());
|
||||||
controller.getNeedsHistogramRebuild().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
|
controller.getNeedsHistogramRebuild().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
@ -321,33 +327,14 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
|||||||
refreshHistorgram();
|
refreshHistorgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setModel(FilteredEventsModel filteredEvents) {
|
|
||||||
if (this.filteredEvents != null && this.filteredEvents != filteredEvents) {
|
|
||||||
this.filteredEvents.unRegisterForEvents(this);
|
|
||||||
this.filteredEvents.timeRangeProperty().removeListener(timeRangeInvalidationListener);
|
|
||||||
this.filteredEvents.zoomParametersProperty().removeListener(zoomListener);
|
|
||||||
}
|
|
||||||
if (this.filteredEvents != filteredEvents) {
|
|
||||||
filteredEvents.registerForEvents(this);
|
|
||||||
filteredEvents.timeRangeProperty().addListener(timeRangeInvalidationListener);
|
|
||||||
filteredEvents.zoomParametersProperty().addListener(zoomListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.filteredEvents = filteredEvents;
|
|
||||||
|
|
||||||
refreshTimeUI(filteredEvents.timeRangeProperty().get());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setViewMode(VisualizationMode visualizationMode) {
|
private void setViewMode(VisualizationMode visualizationMode) {
|
||||||
switch (visualizationMode) {
|
switch (visualizationMode) {
|
||||||
case COUNTS:
|
case COUNTS:
|
||||||
setVisualization(new CountsViewPane(partPane, contextPane, spacer));
|
setVisualization(new CountsViewPane(controller, partPane, contextPane, spacer));
|
||||||
countsToggle.setSelected(true);
|
countsToggle.setSelected(true);
|
||||||
break;
|
break;
|
||||||
case DETAIL:
|
case DETAIL:
|
||||||
setVisualization(new DetailViewPane(partPane, contextPane, spacer));
|
setVisualization(new DetailViewPane(controller, partPane, contextPane, spacer));
|
||||||
detailsToggle.setSelected(true);
|
detailsToggle.setSelected(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -362,24 +349,25 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
visualization = newViz;
|
visualization = newViz;
|
||||||
|
visualization.update();
|
||||||
toolBar.getItems().addAll(newViz.getSettingsNodes());
|
toolBar.getItems().addAll(newViz.getSettingsNodes());
|
||||||
|
|
||||||
visualization.setController(controller);
|
|
||||||
notificationPane.setContent(visualization);
|
notificationPane.setContent(visualization);
|
||||||
if (visualization instanceof DetailViewPane) {
|
if (visualization instanceof DetailViewPane) {
|
||||||
navPanel.setDetailViewPane((DetailViewPane) visualization);
|
eventsTree.setDetailViewPane((DetailViewPane) visualization);
|
||||||
}
|
}
|
||||||
visualization.hasEvents.addListener((observable, oldValue, newValue) -> {
|
visualization.hasEvents.addListener((observable, oldValue, newValue) -> {
|
||||||
if (newValue == false) {
|
if (newValue == false) {
|
||||||
|
|
||||||
notificationPane.setContent(new StackPane(visualization, new Region() {
|
notificationPane.setContent(
|
||||||
{
|
new StackPane(visualization,
|
||||||
setBackground(new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)));
|
new Region() {
|
||||||
setOpacity(.3);
|
{
|
||||||
}
|
setBackground(new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||||
}, new NoEventsDialog(() -> {
|
setOpacity(.3);
|
||||||
notificationPane.setContent(visualization);
|
}
|
||||||
})));
|
},
|
||||||
|
new NoEventsDialog(() -> notificationPane.setContent(visualization))));
|
||||||
} else {
|
} else {
|
||||||
notificationPane.setContent(visualization);
|
notificationPane.setContent(visualization);
|
||||||
}
|
}
|
||||||
@ -544,7 +532,6 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
|||||||
private NoEventsDialog(Runnable closeCallback) {
|
private NoEventsDialog(Runnable closeCallback) {
|
||||||
this.closeCallback = closeCallback;
|
this.closeCallback = closeCallback;
|
||||||
FXMLConstructor.construct(this, "NoEventsDialog.fxml"); // NON-NLS
|
FXMLConstructor.construct(this, "NoEventsDialog.fxml"); // NON-NLS
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@ -554,15 +541,9 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
|||||||
assert zoomButton != null : "fx:id=\"zoomButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS
|
assert zoomButton != null : "fx:id=\"zoomButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS
|
||||||
|
|
||||||
noEventsDialogLabel.setText(NbBundle.getMessage(NoEventsDialog.class, "VisualizationPanel.noEventsDialogLabel.text")); // NON-NLS
|
noEventsDialogLabel.setText(NbBundle.getMessage(NoEventsDialog.class, "VisualizationPanel.noEventsDialogLabel.text")); // NON-NLS
|
||||||
zoomButton.setText(NbBundle.getMessage(NoEventsDialog.class, "VisualizationPanel.zoomButton.text")); // NON-NLS
|
ActionUtils.configureButton(new ZoomToEvents(controller), zoomButton);
|
||||||
|
|
||||||
Action zoomOutAction = new ZoomOut(controller);
|
dismissButton.setOnAction(actionEvent -> closeCallback.run());
|
||||||
zoomButton.setOnAction(zoomOutAction);
|
|
||||||
zoomButton.disableProperty().bind(zoomOutAction.disabledProperty());
|
|
||||||
|
|
||||||
dismissButton.setOnAction(e -> {
|
|
||||||
closeCallback.run();
|
|
||||||
});
|
|
||||||
Action defaultFiltersAction = new ResetFilters(controller);
|
Action defaultFiltersAction = new ResetFilters(controller);
|
||||||
resetFiltersButton.setOnAction(defaultFiltersAction);
|
resetFiltersButton.setOnAction(defaultFiltersAction);
|
||||||
resetFiltersButton.disableProperty().bind(defaultFiltersAction.disabledProperty());
|
resetFiltersButton.disableProperty().bind(defaultFiltersAction.disabledProperty());
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013 Basis Technology Corp.
|
* Copyright 2013-15 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -66,7 +66,6 @@ import org.sleuthkit.autopsy.coreutils.LoggedTask;
|
|||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.VisualizationMode;
|
import org.sleuthkit.autopsy.timeline.VisualizationMode;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.Back;
|
import org.sleuthkit.autopsy.timeline.actions.Back;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.Forward;
|
import org.sleuthkit.autopsy.timeline.actions.Forward;
|
||||||
@ -279,9 +278,9 @@ public class CountsViewPane extends AbstractVisualizationPane<String, Number, No
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public CountsViewPane(Pane partPane, Pane contextPane, Region spacer) {
|
public CountsViewPane(TimeLineController controller, Pane partPane, Pane contextPane, Region spacer) {
|
||||||
super(partPane, contextPane, spacer);
|
super(controller, partPane, contextPane, spacer);
|
||||||
chart = new EventCountsChart(dateAxis, countAxis);
|
chart = new EventCountsChart(controller, dateAxis, countAxis);
|
||||||
setChartClickHandler();
|
setChartClickHandler();
|
||||||
chart.setData(dataSets);
|
chart.setData(dataSets);
|
||||||
setCenter(chart);
|
setCenter(chart);
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
package org.sleuthkit.autopsy.timeline.ui.countsview;
|
package org.sleuthkit.autopsy.timeline.ui.countsview;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
import javafx.scene.chart.CategoryAxis;
|
import javafx.scene.chart.CategoryAxis;
|
||||||
import javafx.scene.chart.NumberAxis;
|
import javafx.scene.chart.NumberAxis;
|
||||||
@ -32,7 +31,6 @@ import org.joda.time.DateTime;
|
|||||||
import org.joda.time.Interval;
|
import org.joda.time.Interval;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
|
||||||
import org.sleuthkit.autopsy.timeline.ui.IntervalSelector;
|
import org.sleuthkit.autopsy.timeline.ui.IntervalSelector;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
||||||
import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;
|
import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;
|
||||||
@ -45,11 +43,12 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
|||||||
|
|
||||||
private ContextMenu chartContextMenu;
|
private ContextMenu chartContextMenu;
|
||||||
|
|
||||||
|
@Override
|
||||||
public ContextMenu getChartContextMenu() {
|
public ContextMenu getChartContextMenu() {
|
||||||
return chartContextMenu;
|
return chartContextMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
|
|
||||||
private IntervalSelector<? extends String> intervalSelector;
|
private IntervalSelector<? extends String> intervalSelector;
|
||||||
|
|
||||||
@ -60,8 +59,9 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
|||||||
*/
|
*/
|
||||||
private RangeDivisionInfo rangeInfo;
|
private RangeDivisionInfo rangeInfo;
|
||||||
|
|
||||||
EventCountsChart(CategoryAxis dateAxis, NumberAxis countAxis) {
|
EventCountsChart(TimeLineController controller, CategoryAxis dateAxis, NumberAxis countAxis) {
|
||||||
super(dateAxis, countAxis);
|
super(dateAxis, countAxis);
|
||||||
|
this.controller = controller;
|
||||||
//configure constant properties on axes and chart
|
//configure constant properties on axes and chart
|
||||||
dateAxis.setAnimated(true);
|
dateAxis.setAnimated(true);
|
||||||
dateAxis.setLabel(null);
|
dateAxis.setLabel(null);
|
||||||
@ -87,6 +87,7 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
|||||||
setOnMouseDragged(chartDragHandler);
|
setOnMouseDragged(chartDragHandler);
|
||||||
|
|
||||||
setOnMouseClicked(new MouseClickedHandler<>(this));
|
setOnMouseClicked(new MouseClickedHandler<>(this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -95,6 +96,7 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
|||||||
intervalSelector = null;
|
intervalSelector = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ContextMenu getChartContextMenu(MouseEvent clickEvent) throws MissingResourceException {
|
public ContextMenu getChartContextMenu(MouseEvent clickEvent) throws MissingResourceException {
|
||||||
if (chartContextMenu != null) {
|
if (chartContextMenu != null) {
|
||||||
chartContextMenu.hide();
|
chartContextMenu.hide();
|
||||||
@ -112,12 +114,6 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
|||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void setController(TimeLineController controller) {
|
|
||||||
this.controller = controller;
|
|
||||||
setModel(this.controller.getEventsModel());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IntervalSelector<? extends String> getIntervalSelector() {
|
public IntervalSelector<? extends String> getIntervalSelector() {
|
||||||
return intervalSelector;
|
return intervalSelector;
|
||||||
@ -129,14 +125,6 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
|||||||
getChartChildren().add(getIntervalSelector());
|
getChartChildren().add(getIntervalSelector());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setModel(FilteredEventsModel filteredEvents) {
|
|
||||||
filteredEvents.zoomParametersProperty().addListener(o -> {
|
|
||||||
clearIntervalSelector();
|
|
||||||
controller.selectEventIDs(Collections.emptyList());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CountsIntervalSelector newIntervalSelector() {
|
public CountsIntervalSelector newIntervalSelector() {
|
||||||
return new CountsIntervalSelector(this);
|
return new CountsIntervalSelector(this);
|
||||||
@ -179,7 +167,7 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
|||||||
* Interval Selector for the counts chart, adjusts interval based on
|
* Interval Selector for the counts chart, adjusts interval based on
|
||||||
* rangeInfo to include final period
|
* rangeInfo to include final period
|
||||||
*/
|
*/
|
||||||
static private class CountsIntervalSelector extends IntervalSelector<String> {
|
final static private class CountsIntervalSelector extends IntervalSelector<String> {
|
||||||
|
|
||||||
private final EventCountsChart countsChart;
|
private final EventCountsChart countsChart;
|
||||||
|
|
||||||
|
@ -113,9 +113,10 @@ public class DetailViewPane extends AbstractVisualizationPane<DateTime, EventClu
|
|||||||
return chart.getEventBundles();
|
return chart.getEventBundles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DetailViewPane(Pane partPane, Pane contextPane, Region spacer) {
|
|
||||||
super(partPane, contextPane, spacer);
|
public DetailViewPane(TimeLineController controller, Pane partPane, Pane contextPane, Region spacer) {
|
||||||
chart = new EventDetailsChart(dateAxis, verticalAxis, selectedNodes);
|
super(controller, partPane, contextPane, spacer);
|
||||||
|
chart = new EventDetailsChart(controller, dateAxis, verticalAxis, selectedNodes);
|
||||||
setChartClickHandler();
|
setChartClickHandler();
|
||||||
chart.setData(dataSets);
|
chart.setData(dataSets);
|
||||||
setCenter(chart);
|
setCenter(chart);
|
||||||
@ -211,11 +212,6 @@ public class DetailViewPane extends AbstractVisualizationPane<DateTime, EventClu
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void setModel(FilteredEventsModel filteredEvents) {
|
|
||||||
super.setModel(filteredEvents);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void incrementScrollValue(int factor) {
|
private void incrementScrollValue(int factor) {
|
||||||
vertScrollBar.valueProperty().set(Math.max(0, Math.min(100, vertScrollBar.getValue() + factor * (chart.getHeight() / chart.maxVScrollProperty().get()))));
|
vertScrollBar.valueProperty().set(Math.max(0, Math.min(100, vertScrollBar.getValue() + factor * (chart.getHeight() / chart.maxVScrollProperty().get()))));
|
||||||
}
|
}
|
||||||
|
@ -102,16 +102,19 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
private static final int PROJECTED_LINE_Y_OFFSET = 5;
|
private static final int PROJECTED_LINE_Y_OFFSET = 5;
|
||||||
private static final int PROJECTED_LINE_STROKE_WIDTH = 5;
|
private static final int PROJECTED_LINE_STROKE_WIDTH = 5;
|
||||||
private static final int MINIMUM_EVENT_NODE_GAP = 4;
|
private static final int MINIMUM_EVENT_NODE_GAP = 4;
|
||||||
|
|
||||||
|
|
||||||
|
private final TimeLineController controller;
|
||||||
|
private final FilteredEventsModel filteredEvents;
|
||||||
|
|
||||||
private ContextMenu chartContextMenu;
|
private ContextMenu chartContextMenu;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ContextMenu getChartContextMenu() {
|
public ContextMenu getChartContextMenu() {
|
||||||
return chartContextMenu;
|
return chartContextMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeLineController controller;
|
|
||||||
|
|
||||||
private FilteredEventsModel filteredEvents;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a user positionable vertical line to help compare events
|
* a user positionable vertical line to help compare events
|
||||||
*/
|
*/
|
||||||
@ -187,10 +190,21 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
*/
|
*/
|
||||||
final SimpleDoubleProperty truncateWidth = new SimpleDoubleProperty(200.0);
|
final SimpleDoubleProperty truncateWidth = new SimpleDoubleProperty(200.0);
|
||||||
|
|
||||||
EventDetailsChart(DateAxis dateAxis, final Axis<EventCluster> verticalAxis, ObservableList<EventBundleNodeBase<?, ?, ?>> selectedNodes) {
|
EventDetailsChart(TimeLineController controller, DateAxis dateAxis, final Axis<EventCluster> verticalAxis, ObservableList<EventBundleNodeBase<?, ?, ?>> selectedNodes) {
|
||||||
super(dateAxis, verticalAxis);
|
super(dateAxis, verticalAxis);
|
||||||
|
this.controller = controller;
|
||||||
|
this.filteredEvents = this.controller.getEventsModel();
|
||||||
|
|
||||||
|
filteredEvents.zoomParametersProperty().addListener(o -> {
|
||||||
|
clearGuideLine();
|
||||||
|
clearIntervalSelector();
|
||||||
|
selectedNodes.clear();
|
||||||
|
projectionMap.clear();
|
||||||
|
controller.selectEventIDs(Collections.emptyList());
|
||||||
|
});
|
||||||
Tooltip.install(this, AbstractVisualizationPane.getDragTooltip());
|
Tooltip.install(this, AbstractVisualizationPane.getDragTooltip());
|
||||||
|
|
||||||
|
|
||||||
dateAxis.setAutoRanging(false);
|
dateAxis.setAutoRanging(false);
|
||||||
|
|
||||||
verticalAxis.setVisible(false);//TODO: why doesn't this hide the vertical axis, instead we have to turn off all parts individually? -jm
|
verticalAxis.setVisible(false);//TODO: why doesn't this hide the vertical axis, instead we have to turn off all parts individually? -jm
|
||||||
@ -210,6 +224,7 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
truncateAll.addListener(layoutInvalidationListener);
|
truncateAll.addListener(layoutInvalidationListener);
|
||||||
truncateWidth.addListener(layoutInvalidationListener);
|
truncateWidth.addListener(layoutInvalidationListener);
|
||||||
descrVisibility.addListener(layoutInvalidationListener);
|
descrVisibility.addListener(layoutInvalidationListener);
|
||||||
|
getController().getQuickHideFilters().addListener(layoutInvalidationListener);
|
||||||
|
|
||||||
//this is needed to allow non circular binding of the guideline and timerangeRect heights to the height of the chart
|
//this is needed to allow non circular binding of the guideline and timerangeRect heights to the height of the chart
|
||||||
//TODO: seems like a hack, can we remove? -jm
|
//TODO: seems like a hack, can we remove? -jm
|
||||||
@ -260,30 +275,6 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
|
|||||||
return bandByType;
|
return bandByType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void setController(TimeLineController controller) {
|
|
||||||
this.controller = controller;
|
|
||||||
setModel(this.controller.getEventsModel());
|
|
||||||
getController().getQuickHideFilters().addListener(layoutInvalidationListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setModel(FilteredEventsModel filteredEvents) {
|
|
||||||
|
|
||||||
if (this.filteredEvents != filteredEvents) {
|
|
||||||
filteredEvents.zoomParametersProperty().addListener(o -> {
|
|
||||||
clearGuideLine();
|
|
||||||
clearIntervalSelector();
|
|
||||||
|
|
||||||
selectedNodes.clear();
|
|
||||||
projectionMap.clear();
|
|
||||||
controller.selectEventIDs(Collections.emptyList());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.filteredEvents = filteredEvents;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IntervalSelector<DateTime> newIntervalSelector() {
|
public IntervalSelector<DateTime> newIntervalSelector() {
|
||||||
return new DetailIntervalSelector(this);
|
return new DetailIntervalSelector(this);
|
||||||
|
@ -1 +0,0 @@
|
|||||||
NavPanel.eventsTreeLabel.text=Sort By\:
|
|
@ -1 +1 @@
|
|||||||
NavPanel.eventsTreeLabel.text=\u4E0B\u8A18\u306B\u5F93\u3044\u4E26\u3079\u66FF\u3048\uFF1A
|
EventsTree.Label.text=\u4e0b\u8a18\u306b\u5f93\u3044\u4e26\u3079\u66ff\u3048\uff1a
|
@ -46,9 +46,7 @@ import org.openide.util.NbBundle;
|
|||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.EventBundle;
|
import org.sleuthkit.autopsy.timeline.datamodel.EventBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
|
||||||
import org.sleuthkit.autopsy.timeline.filters.AbstractFilter;
|
import org.sleuthkit.autopsy.timeline.filters.AbstractFilter;
|
||||||
import org.sleuthkit.autopsy.timeline.filters.DescriptionFilter;
|
import org.sleuthkit.autopsy.timeline.filters.DescriptionFilter;
|
||||||
import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewPane;
|
import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewPane;
|
||||||
@ -59,11 +57,9 @@ import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewPane;
|
|||||||
* out. Right clicking on a item in the tree shows a context menu to show/hide
|
* out. Right clicking on a item in the tree shows a context menu to show/hide
|
||||||
* it.
|
* it.
|
||||||
*/
|
*/
|
||||||
public class NavPanel extends BorderPane implements TimeLineView {
|
final public class EventsTree extends BorderPane {
|
||||||
|
|
||||||
private TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
|
|
||||||
private FilteredEventsModel filteredEvents;
|
|
||||||
|
|
||||||
private DetailViewPane detailViewPane;
|
private DetailViewPane detailViewPane;
|
||||||
|
|
||||||
@ -76,8 +72,10 @@ public class NavPanel extends BorderPane implements TimeLineView {
|
|||||||
@FXML
|
@FXML
|
||||||
private ComboBox<Comparator<TreeItem<EventBundle<?>>>> sortByBox;
|
private ComboBox<Comparator<TreeItem<EventBundle<?>>>> sortByBox;
|
||||||
|
|
||||||
public NavPanel() {
|
public EventsTree(TimeLineController controller) {
|
||||||
FXMLConstructor.construct(this, "NavPanel.fxml"); // NON-NLS
|
this.controller = controller;
|
||||||
|
|
||||||
|
FXMLConstructor.construct(this, "EventsTree.fxml"); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDetailViewPane(DetailViewPane detailViewPane) {
|
public void setDetailViewPane(DetailViewPane detailViewPane) {
|
||||||
@ -112,19 +110,8 @@ public class NavPanel extends BorderPane implements TimeLineView {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setController(TimeLineController controller) {
|
|
||||||
this.controller = controller;
|
|
||||||
setModel(controller.getEventsModel());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setModel(FilteredEventsModel filteredEvents) {
|
|
||||||
this.filteredEvents = filteredEvents;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@NbBundle.Messages("EventsTree.Label.text=Sort By:")
|
||||||
void initialize() {
|
void initialize() {
|
||||||
assert sortByBox != null : "fx:id=\"sortByBox\" was not injected: check your FXML file 'NavPanel.fxml'."; // NON-NLS
|
assert sortByBox != null : "fx:id=\"sortByBox\" was not injected: check your FXML file 'NavPanel.fxml'."; // NON-NLS
|
||||||
|
|
||||||
@ -137,7 +124,7 @@ public class NavPanel extends BorderPane implements TimeLineView {
|
|||||||
eventsTree.setCellFactory((TreeView<EventBundle<?>> p) -> new EventBundleTreeCell());
|
eventsTree.setCellFactory((TreeView<EventBundle<?>> p) -> new EventBundleTreeCell());
|
||||||
eventsTree.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
eventsTree.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||||
|
|
||||||
eventsTreeLabel.setText(NbBundle.getMessage(this.getClass(), "NavPanel.eventsTreeLabel.text"));
|
eventsTreeLabel.setText(Bundle.EventsTree_Label_text());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,6 +219,5 @@ public class NavPanel extends BorderPane implements TimeLineView {
|
|||||||
setContextMenu(null);
|
setContextMenu(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -44,7 +44,6 @@ import org.controlsfx.control.action.ActionUtils;
|
|||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.VisualizationMode;
|
import org.sleuthkit.autopsy.timeline.VisualizationMode;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.ResetFilters;
|
import org.sleuthkit.autopsy.timeline.actions.ResetFilters;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||||
@ -64,7 +63,7 @@ import static org.sleuthkit.autopsy.timeline.ui.filtering.Bundle.Timeline_ui_fil
|
|||||||
* This also implements {@link TimeLineView} since it dynamically updates its
|
* This also implements {@link TimeLineView} since it dynamically updates its
|
||||||
* filters based on the contents of a {@link FilteredEventsModel}
|
* filters based on the contents of a {@link FilteredEventsModel}
|
||||||
*/
|
*/
|
||||||
final public class FilterSetPanel extends BorderPane implements TimeLineView {
|
final public class FilterSetPanel extends BorderPane {
|
||||||
|
|
||||||
private static final Image TICK = new Image("org/sleuthkit/autopsy/timeline/images/tick.png");
|
private static final Image TICK = new Image("org/sleuthkit/autopsy/timeline/images/tick.png");
|
||||||
|
|
||||||
@ -171,20 +170,25 @@ final public class FilterSetPanel extends BorderPane implements TimeLineView {
|
|||||||
legendColumn.setCellValueFactory(param -> param.getValue().valueProperty());
|
legendColumn.setCellValueFactory(param -> param.getValue().valueProperty());
|
||||||
legendColumn.setCellFactory(col -> new LegendCell(this.controller));
|
legendColumn.setCellFactory(col -> new LegendCell(this.controller));
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterSetPanel() {
|
|
||||||
FXMLConstructor.construct(this, "FilterSetPanel.fxml"); // NON-NLS
|
|
||||||
expansionMap.put(new TypeFilter(RootEventType.getInstance()).getDisplayName(), true);
|
expansionMap.put(new TypeFilter(RootEventType.getInstance()).getDisplayName(), true);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setController(TimeLineController timeLineController) {
|
|
||||||
this.controller = timeLineController;
|
|
||||||
Action defaultFiltersAction = new ResetFilters(controller);
|
Action defaultFiltersAction = new ResetFilters(controller);
|
||||||
defaultButton.setOnAction(defaultFiltersAction);
|
defaultButton.setOnAction(defaultFiltersAction);
|
||||||
defaultButton.disableProperty().bind(defaultFiltersAction.disabledProperty());
|
defaultButton.disableProperty().bind(defaultFiltersAction.disabledProperty());
|
||||||
this.setModel(timeLineController.getEventsModel());
|
|
||||||
|
this.filteredEvents.eventTypeZoomProperty().addListener((Observable observable) -> {
|
||||||
|
applyFilters();
|
||||||
|
});
|
||||||
|
this.filteredEvents.descriptionLODProperty().addListener((Observable observable1) -> {
|
||||||
|
applyFilters();
|
||||||
|
});
|
||||||
|
this.filteredEvents.timeRangeProperty().addListener((Observable observable2) -> {
|
||||||
|
applyFilters();
|
||||||
|
});
|
||||||
|
this.filteredEvents.filterProperty().addListener((Observable o) -> {
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
refresh();
|
||||||
|
|
||||||
hiddenDescriptionsListView.setItems(controller.getQuickHideFilters());
|
hiddenDescriptionsListView.setItems(controller.getQuickHideFilters());
|
||||||
hiddenDescriptionsListView.setCellFactory((ListView<DescriptionFilter> param) -> {
|
hiddenDescriptionsListView.setCellFactory((ListView<DescriptionFilter> param) -> {
|
||||||
@ -237,25 +241,13 @@ final public class FilterSetPanel extends BorderPane implements TimeLineView {
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public FilterSetPanel(TimeLineController controller) {
|
||||||
|
this.controller = controller;
|
||||||
public void setModel(FilteredEventsModel filteredEvents) {
|
this.filteredEvents = controller.getEventsModel();
|
||||||
this.filteredEvents = filteredEvents;
|
FXMLConstructor.construct(this, "FilterSetPanel.fxml"); // NON-NLS
|
||||||
this.filteredEvents.eventTypeZoomProperty().addListener((Observable observable) -> {
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
this.filteredEvents.descriptionLODProperty().addListener((Observable observable) -> {
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
this.filteredEvents.timeRangeProperty().addListener((Observable observable) -> {
|
|
||||||
applyFilters();
|
|
||||||
});
|
|
||||||
this.filteredEvents.filterProperty().addListener((Observable o) -> {
|
|
||||||
refresh();
|
|
||||||
});
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ import javafx.scene.paint.Color;
|
|||||||
import javafx.scene.shape.Rectangle;
|
import javafx.scene.shape.Rectangle;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
|
||||||
import org.sleuthkit.autopsy.timeline.filters.AbstractFilter;
|
import org.sleuthkit.autopsy.timeline.filters.AbstractFilter;
|
||||||
import org.sleuthkit.autopsy.timeline.filters.TextFilter;
|
import org.sleuthkit.autopsy.timeline.filters.TextFilter;
|
||||||
@ -40,18 +39,19 @@ import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
|||||||
* A TreeTableCell that shows an icon and color corresponding to the represented
|
* A TreeTableCell that shows an icon and color corresponding to the represented
|
||||||
* filter
|
* filter
|
||||||
*/
|
*/
|
||||||
class LegendCell extends TreeTableCell<AbstractFilter, AbstractFilter> implements TimeLineView {
|
final class LegendCell extends TreeTableCell<AbstractFilter, AbstractFilter> {
|
||||||
|
|
||||||
private static final Color CLEAR = Color.rgb(0, 0, 0, 0);
|
private static final Color CLEAR = Color.rgb(0, 0, 0, 0);
|
||||||
|
|
||||||
private TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
|
|
||||||
private FilteredEventsModel filteredEvents;
|
private final FilteredEventsModel filteredEvents;
|
||||||
|
|
||||||
//We need a controller so we can listen to changes in EventTypeZoom to show/hide legends
|
//We need a controller so we can listen to changes in EventTypeZoom to show/hide legends
|
||||||
public LegendCell(TimeLineController controller) {
|
LegendCell(TimeLineController controller) {
|
||||||
setEditable(false);
|
setEditable(false);
|
||||||
setController(controller);
|
this.controller = controller;
|
||||||
|
this.filteredEvents = this.controller.getEventsModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -119,15 +119,4 @@ class LegendCell extends TreeTableCell<AbstractFilter, AbstractFilter> implement
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized public final void setController(TimeLineController controller) {
|
|
||||||
this.controller = controller;
|
|
||||||
setModel(this.controller.getEventsModel());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setModel(FilteredEventsModel filteredEvents) {
|
|
||||||
this.filteredEvents = filteredEvents;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,19 +18,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline.zooming;
|
package org.sleuthkit.autopsy.timeline.zooming;
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.InvalidationListener;
|
import javafx.beans.InvalidationListener;
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Slider;
|
||||||
|
import javafx.scene.control.TitledPane;
|
||||||
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
|
||||||
import org.sleuthkit.autopsy.timeline.VisualizationMode;
|
import org.sleuthkit.autopsy.timeline.VisualizationMode;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.Back;
|
import org.sleuthkit.autopsy.timeline.actions.Back;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.Forward;
|
import org.sleuthkit.autopsy.timeline.actions.Forward;
|
||||||
@ -44,13 +45,7 @@ import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;
|
|||||||
* has sliders to provide context/control over three axes of zooming (timescale,
|
* has sliders to provide context/control over three axes of zooming (timescale,
|
||||||
* event hierarchy, and description detail).
|
* event hierarchy, and description detail).
|
||||||
*/
|
*/
|
||||||
public class ZoomSettingsPane extends TitledPane implements TimeLineView {
|
public class ZoomSettingsPane extends TitledPane {
|
||||||
|
|
||||||
@FXML
|
|
||||||
private ResourceBundle resources;
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private URL location;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button backButton;
|
private Button backButton;
|
||||||
@ -105,35 +100,6 @@ public class ZoomSettingsPane extends TitledPane implements TimeLineView {
|
|||||||
timeUnitLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.timeUnitLabel.text"));
|
timeUnitLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.timeUnitLabel.text"));
|
||||||
zoomLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.zoomLabel.text"));
|
zoomLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.zoomLabel.text"));
|
||||||
historyLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.historyLabel.text"));
|
historyLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.historyLabel.text"));
|
||||||
}
|
|
||||||
|
|
||||||
public ZoomSettingsPane() {
|
|
||||||
FXMLConstructor.construct(this, "ZoomSettingsPane.fxml"); // NON-NLS
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized public void setController(TimeLineController controller) {
|
|
||||||
this.controller = controller;
|
|
||||||
setModel(controller.getEventsModel());
|
|
||||||
descrLODSlider.disableProperty().bind(controller.viewModeProperty().isEqualTo(VisualizationMode.COUNTS));
|
|
||||||
Back back = new Back(controller);
|
|
||||||
backButton.disableProperty().bind(back.disabledProperty());
|
|
||||||
backButton.setOnAction(back);
|
|
||||||
backButton.setTooltip(new Tooltip(
|
|
||||||
NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.backButton.toolTip.text",
|
|
||||||
back.getAccelerator().getName())));
|
|
||||||
Forward forward = new Forward(controller);
|
|
||||||
forwardButton.disableProperty().bind(forward.disabledProperty());
|
|
||||||
forwardButton.setOnAction(forward);
|
|
||||||
forwardButton.setTooltip(new Tooltip(
|
|
||||||
NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.forwardButton.toolTip.text",
|
|
||||||
forward.getAccelerator().getName())));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setModel(FilteredEventsModel filteredEvents) {
|
|
||||||
this.filteredEvents = filteredEvents;
|
|
||||||
|
|
||||||
initializeSlider(timeUnitSlider,
|
initializeSlider(timeUnitSlider,
|
||||||
() -> {
|
() -> {
|
||||||
@ -151,18 +117,14 @@ public class ZoomSettingsPane extends TitledPane implements TimeLineView {
|
|||||||
|
|
||||||
timeUnitSlider.setValue(TimeUnits.fromChronoUnit(chronoUnit).ordinal() - 1);
|
timeUnitSlider.setValue(TimeUnits.fromChronoUnit(chronoUnit).ordinal() - 1);
|
||||||
});
|
});
|
||||||
|
initializeSlider(descrLODSlider, () -> {
|
||||||
initializeSlider(descrLODSlider,
|
DescriptionLoD newLOD = DescriptionLoD.values()[Math.round(descrLODSlider.valueProperty().floatValue())];
|
||||||
() -> {
|
if (controller.pushDescrLOD(newLOD) == false) {
|
||||||
DescriptionLoD newLOD = DescriptionLoD.values()[Math.round(descrLODSlider.valueProperty().floatValue())];
|
descrLODSlider.setValue(new DescrLODConverter().fromString(controller.getEventsModel().getDescriptionLOD().toString()));
|
||||||
if (controller.pushDescrLOD(newLOD) == false) {
|
}
|
||||||
descrLODSlider.setValue(new DescrLODConverter().fromString(filteredEvents.getDescriptionLOD().toString()));
|
}, this.filteredEvents.descriptionLODProperty(), () -> {
|
||||||
}
|
descrLODSlider.setValue(this.filteredEvents.descriptionLODProperty().get().ordinal());
|
||||||
}, this.filteredEvents.descriptionLODProperty(),
|
});
|
||||||
() -> {
|
|
||||||
descrLODSlider.setValue(this.filteredEvents.descriptionLODProperty().get().ordinal());
|
|
||||||
});
|
|
||||||
|
|
||||||
initializeSlider(typeZoomSlider,
|
initializeSlider(typeZoomSlider,
|
||||||
() -> {
|
() -> {
|
||||||
EventTypeZoomLevel newZoomLevel = EventTypeZoomLevel.values()[Math.round(typeZoomSlider.valueProperty().floatValue())];
|
EventTypeZoomLevel newZoomLevel = EventTypeZoomLevel.values()[Math.round(typeZoomSlider.valueProperty().floatValue())];
|
||||||
@ -172,6 +134,26 @@ public class ZoomSettingsPane extends TitledPane implements TimeLineView {
|
|||||||
() -> {
|
() -> {
|
||||||
typeZoomSlider.setValue(this.filteredEvents.eventTypeZoomProperty().get().ordinal());
|
typeZoomSlider.setValue(this.filteredEvents.eventTypeZoomProperty().get().ordinal());
|
||||||
});
|
});
|
||||||
|
descrLODSlider.disableProperty().bind(controller.viewModeProperty().isEqualTo(VisualizationMode.COUNTS));
|
||||||
|
Back back = new Back(controller);
|
||||||
|
backButton.disableProperty().bind(back.disabledProperty());
|
||||||
|
backButton.setOnAction(back);
|
||||||
|
backButton.setTooltip(new Tooltip(
|
||||||
|
NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.backButton.toolTip.text",
|
||||||
|
back.getAccelerator().getName())));
|
||||||
|
Forward forward = new Forward(controller);
|
||||||
|
forwardButton.disableProperty().bind(forward.disabledProperty());
|
||||||
|
forwardButton.setOnAction(forward);
|
||||||
|
forwardButton.setTooltip(new Tooltip(
|
||||||
|
NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.forwardButton.toolTip.text",
|
||||||
|
forward.getAccelerator().getName())));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZoomSettingsPane(TimeLineController controller) {
|
||||||
|
this.controller = controller;
|
||||||
|
this.filteredEvents = controller.getEventsModel();
|
||||||
|
FXMLConstructor.construct(this, "ZoomSettingsPane.fxml"); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user