mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge branch 'millmanorama-release-3.1.1' into release-3.1.1
This commit is contained in:
commit
152d984554
@ -41,7 +41,7 @@ public abstract class LoggedTask<T> extends Task<T> implements Cancellable {
|
||||
protected void cancelled() {
|
||||
super.cancelled();
|
||||
if (logStateChanges) {
|
||||
LOGGER.log(Level.WARNING, "{0} cancelled!", getTitle());
|
||||
// LOGGER.log(Level.WARNING, "{0} cancelled!", getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ public abstract class LoggedTask<T> extends Task<T> implements Cancellable {
|
||||
protected void scheduled() {
|
||||
super.scheduled();
|
||||
if (logStateChanges) {
|
||||
LOGGER.log(Level.INFO, "{0} scheduled", getTitle());
|
||||
// LOGGER.log(Level.INFO, "{0} scheduled", getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ public abstract class LoggedTask<T> extends Task<T> implements Cancellable {
|
||||
LOGGER.log(Level.SEVERE, getTitle() + " threw unexpected exception: ", ex);
|
||||
}
|
||||
if (logStateChanges) {
|
||||
LOGGER.log(Level.INFO, "{0} succeeded", getTitle());
|
||||
// LOGGER.log(Level.INFO, "{0} succeeded", getTitle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,14 +23,14 @@ import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyCodeCombination;
|
||||
import org.controlsfx.control.action.AbstractAction;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
//TODO: This and the corresponding imageanalyzer action are identical except for the type of the controller... abstract something! -jm
|
||||
public class Back extends AbstractAction {
|
||||
public class Back extends Action {
|
||||
|
||||
private static final Image BACK_IMAGE = new Image("/org/sleuthkit/autopsy/timeline/images/arrow-180.png", 16, 16, true, true, true);
|
||||
|
||||
@ -42,10 +42,8 @@ public class Back extends AbstractAction {
|
||||
setAccelerator(new KeyCodeCombination(KeyCode.LEFT, KeyCodeCombination.ALT_DOWN));
|
||||
this.controller = controller;
|
||||
disabledProperty().bind(controller.getCanRetreat().not());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent ae) {
|
||||
controller.retreat();
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
controller.retreat();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.timeline.actions;
|
||||
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.event.ActionEvent;
|
||||
import org.controlsfx.control.action.AbstractAction;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.events.FilteredEventsModel;
|
||||
import org.sleuthkit.autopsy.timeline.filters.Filter;
|
||||
@ -28,7 +28,7 @@ import org.sleuthkit.autopsy.timeline.filters.Filter;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DefaultFilters extends AbstractAction {
|
||||
public class DefaultFilters extends Action {
|
||||
|
||||
private final TimeLineController controller;
|
||||
|
||||
@ -48,10 +48,8 @@ public class DefaultFilters extends AbstractAction {
|
||||
return eventsModel.getRequestedZoomParamters().getValue().getFilter().equals(Filter.getDefaultFilter());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
controller.applyDefaultFilters();
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
controller.applyDefaultFilters();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -23,14 +23,14 @@ import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyCodeCombination;
|
||||
import org.controlsfx.control.action.AbstractAction;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
//TODO: This and the corresponding imageanalyzer action are identical except for the type of the controller... abstract something! -jm
|
||||
public class Forward extends AbstractAction {
|
||||
public class Forward extends Action {
|
||||
|
||||
private static final Image BACK_IMAGE = new Image("/org/sleuthkit/autopsy/timeline/images/arrow.png", 16, 16, true, true, true);
|
||||
|
||||
@ -42,10 +42,8 @@ public class Forward extends AbstractAction {
|
||||
setAccelerator(new KeyCodeCombination(KeyCode.RIGHT, KeyCodeCombination.ALT_DOWN));
|
||||
this.controller = controller;
|
||||
disabledProperty().bind(controller.getCanAdvance().not());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent ae) {
|
||||
controller.advance();
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
controller.advance();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import javafx.embed.swing.SwingFXUtils;
|
||||
import javafx.event.ActionEvent;
|
||||
@ -35,7 +36,7 @@ import javafx.scene.image.WritableImage;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.util.Pair;
|
||||
import javax.imageio.ImageIO;
|
||||
import org.controlsfx.control.action.AbstractAction;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
@ -44,7 +45,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class SaveSnapshot extends AbstractAction {
|
||||
public class SaveSnapshot extends Action {
|
||||
|
||||
private static final String HTML_EXT = ".html";
|
||||
|
||||
@ -60,75 +61,77 @@ public class SaveSnapshot extends AbstractAction {
|
||||
super("save snapshot");
|
||||
this.controller = controller;
|
||||
this.snapshot = snapshot;
|
||||
}
|
||||
setEventHandler(new Consumer<ActionEvent>() {
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
//choose location/name
|
||||
DirectoryChooser fileChooser = new DirectoryChooser();
|
||||
fileChooser.setTitle("Save snapshot to");
|
||||
fileChooser.setInitialDirectory(new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Reports"));
|
||||
File outFolder = fileChooser.showDialog(null);
|
||||
if (outFolder == null) {
|
||||
return;
|
||||
}
|
||||
outFolder.mkdir();
|
||||
String name = outFolder.getName();
|
||||
@Override
|
||||
public void accept(ActionEvent t) {
|
||||
//choose location/name
|
||||
DirectoryChooser fileChooser = new DirectoryChooser();
|
||||
fileChooser.setTitle("Save snapshot to");
|
||||
fileChooser.setInitialDirectory(new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Reports"));
|
||||
File outFolder = fileChooser.showDialog(null);
|
||||
if (outFolder == null) {
|
||||
return;
|
||||
}
|
||||
outFolder.mkdir();
|
||||
String name = outFolder.getName();
|
||||
|
||||
//gather metadata
|
||||
List<Pair<String, String>> reportMetaData = new ArrayList<>();
|
||||
//gather metadata
|
||||
List<Pair<String, String>> reportMetaData = new ArrayList<>();
|
||||
|
||||
reportMetaData.add(new Pair<>("Case", Case.getCurrentCase().getName()));
|
||||
reportMetaData.add(new Pair<>("Case", Case.getCurrentCase().getName()));
|
||||
|
||||
ZoomParams get = controller.getEventsModel().getRequestedZoomParamters().get();
|
||||
reportMetaData.add(new Pair<>("Time Range", get.getTimeRange().toString()));
|
||||
reportMetaData.add(new Pair<>("Description Level of Detail", get.getDescrLOD().getDisplayName()));
|
||||
reportMetaData.add(new Pair<>("Event Type Zoom Level", get.getTypeZoomLevel().getDisplayName()));
|
||||
reportMetaData.add(new Pair<>("Filters", get.getFilter().getHTMLReportString()));
|
||||
ZoomParams get = controller.getEventsModel().getRequestedZoomParamters().get();
|
||||
reportMetaData.add(new Pair<>("Time Range", get.getTimeRange().toString()));
|
||||
reportMetaData.add(new Pair<>("Description Level of Detail", get.getDescrLOD().getDisplayName()));
|
||||
reportMetaData.add(new Pair<>("Event Type Zoom Level", get.getTypeZoomLevel().getDisplayName()));
|
||||
reportMetaData.add(new Pair<>("Filters", get.getFilter().getHTMLReportString()));
|
||||
|
||||
//save snapshot as png
|
||||
try {
|
||||
ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "png", new File(outFolder.getPath() + File.separator + outFolder.getName() + REPORT_IMAGE_EXTENSION));
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to write snapshot to disk", ex);
|
||||
return;
|
||||
}
|
||||
//save snapshot as png
|
||||
try {
|
||||
ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "png", new File(outFolder.getPath() + File.separator + outFolder.getName() + REPORT_IMAGE_EXTENSION));
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to write snapshot to disk", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
//build html string
|
||||
StringBuilder wrapper = new StringBuilder();
|
||||
wrapper.append("<html>\n<head>\n\t<title>").append("timeline snapshot").append("</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"index.css\" />\n</head>\n<body>\n");
|
||||
wrapper.append("<div id=\"content\">\n<h1>").append(outFolder.getName()).append("</h1>\n");
|
||||
wrapper.append("<img src = \"").append(outFolder.getName()).append(REPORT_IMAGE_EXTENSION + "\" alt = \"snaphot\">");
|
||||
wrapper.append("<table>\n");
|
||||
for (Pair<String, String> pair : reportMetaData) {
|
||||
wrapper.append("<tr><td>").append(pair.getKey()).append(": </td><td>").append(pair.getValue()).append("</td></tr>\n");
|
||||
}
|
||||
wrapper.append("</table>\n");
|
||||
wrapper.append("</div>\n</body>\n</html>");
|
||||
//build html string
|
||||
StringBuilder wrapper = new StringBuilder();
|
||||
wrapper.append("<html>\n<head>\n\t<title>").append("timeline snapshot").append("</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"index.css\" />\n</head>\n<body>\n");
|
||||
wrapper.append("<div id=\"content\">\n<h1>").append(outFolder.getName()).append("</h1>\n");
|
||||
wrapper.append("<img src = \"").append(outFolder.getName()).append(REPORT_IMAGE_EXTENSION + "\" alt = \"snaphot\">");
|
||||
wrapper.append("<table>\n");
|
||||
for (Pair<String, String> pair : reportMetaData) {
|
||||
wrapper.append("<tr><td>").append(pair.getKey()).append(": </td><td>").append(pair.getValue()).append("</td></tr>\n");
|
||||
}
|
||||
wrapper.append("</table>\n");
|
||||
wrapper.append("</div>\n</body>\n</html>");
|
||||
|
||||
//write html wrapper
|
||||
try (Writer htmlWriter = new FileWriter(new File(outFolder, name + HTML_EXT))) {
|
||||
htmlWriter.write(wrapper.toString());
|
||||
} catch (FileNotFoundException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to open html wrapper file for writing ", ex);
|
||||
return;
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to write html wrapper file", ex);
|
||||
return;
|
||||
}
|
||||
//write html wrapper
|
||||
try (Writer htmlWriter = new FileWriter(new File(outFolder, name + HTML_EXT))) {
|
||||
htmlWriter.write(wrapper.toString());
|
||||
} catch (FileNotFoundException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to open html wrapper file for writing ", ex);
|
||||
return;
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to write html wrapper file", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
//copy css
|
||||
try (InputStream resource = this.getClass().getResourceAsStream("/org/sleuthkit/autopsy/timeline/index.css")) {
|
||||
Files.copy(resource, Paths.get(outFolder.getPath(), "index.css"));
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to copy css file", ex);
|
||||
}
|
||||
//copy css
|
||||
try (InputStream resource = this.getClass().getResourceAsStream("/org/sleuthkit/autopsy/timeline/index.css")) {
|
||||
Files.copy(resource, Paths.get(outFolder.getPath(), "index.css"));
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to copy css file", ex);
|
||||
}
|
||||
|
||||
//add html file as report to case
|
||||
try {
|
||||
Case.getCurrentCase().addReport(outFolder.getPath() + File.separator + outFolder.getName() + HTML_EXT, "Timeline", outFolder.getName() + HTML_EXT);
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed add html wrapper as a report", ex);
|
||||
}
|
||||
//add html file as report to case
|
||||
try {
|
||||
Case.getCurrentCase().addReport(outFolder.getPath() + File.separator + outFolder.getName() + HTML_EXT, "Timeline", outFolder.getName() + HTML_EXT);
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed add html wrapper as a report", ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -20,14 +20,14 @@ package org.sleuthkit.autopsy.timeline.actions;
|
||||
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.event.ActionEvent;
|
||||
import org.controlsfx.control.action.AbstractAction;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.events.FilteredEventsModel;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ZoomOut extends AbstractAction {
|
||||
public class ZoomOut extends Action {
|
||||
|
||||
private final TimeLineController controller;
|
||||
|
||||
@ -47,10 +47,8 @@ public class ZoomOut extends AbstractAction {
|
||||
return eventsModel.getRequestedZoomParamters().getValue().getTimeRange().contains(eventsModel.getSpanningInterval());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
controller.zoomOutToActivity();
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
controller.zoomOutToActivity();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ public class EventDB {
|
||||
return "1";
|
||||
}
|
||||
result = StringUtils.deleteWhitespace(result).equals("(1and1and1)") ? "1" : result;
|
||||
System.out.println(result);
|
||||
//System.out.println(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -402,7 +402,7 @@ public class EventDB {
|
||||
if (end2 == 0) {
|
||||
end2 = getMaxTime();
|
||||
}
|
||||
System.out.println(start2 + " " + start + " " + end + " " + end2);
|
||||
//System.out.println(start2 + " " + start + " " + end + " " + end2);
|
||||
return new Interval(start2 * 1000, (end2 + 1) * 1000, TimeLineController.getJodaTimeZone());
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@ -445,7 +445,7 @@ public class EventDB {
|
||||
|
||||
dbReadLock();
|
||||
final String query = "select event_id from events where time >= " + startTime + " and time <" + endTime + " and " + getSQLWhere(filter);
|
||||
System.out.println(query);
|
||||
//System.out.println(query);
|
||||
try (Statement stmt = con.createStatement();
|
||||
ResultSet rs = stmt.executeQuery(query)) {
|
||||
|
||||
@ -801,13 +801,13 @@ public class EventDB {
|
||||
|
||||
ResultSet rs = null;
|
||||
dbReadLock();
|
||||
System.out.println(queryString);
|
||||
//System.out.println(queryString);
|
||||
try (Statement stmt = con.createStatement();) {
|
||||
Stopwatch stopwatch = new Stopwatch();
|
||||
stopwatch.start();
|
||||
rs = stmt.executeQuery(queryString);
|
||||
stopwatch.stop();
|
||||
System.out.println(stopwatch.elapsedMillis() / 1000.0 + " seconds");
|
||||
// System.out.println(stopwatch.elapsedMillis() / 1000.0 + " seconds");
|
||||
while (rs.next()) {
|
||||
|
||||
EventType type = useSubTypes
|
||||
@ -880,7 +880,7 @@ public class EventDB {
|
||||
+ " from events where time >= " + start + " and time < " + end + " and " + getSQLWhere(filter)
|
||||
+ " group by interval, " + (useSubTypes ? SUB_TYPE_COLUMN : BASE_TYPE_COLUMN) + " , " + descriptionColumn
|
||||
+ " order by Min(time)";
|
||||
System.out.println(query);
|
||||
//System.out.println(query);
|
||||
ResultSet rs = null;
|
||||
try (Statement stmt = con.createStatement(); // scoop up requested events in groups organized by interval, type, and desription
|
||||
) {
|
||||
@ -890,7 +890,7 @@ public class EventDB {
|
||||
|
||||
rs = stmt.executeQuery(query);
|
||||
stopwatch.stop();
|
||||
System.out.println(stopwatch.elapsedMillis() / 1000.0 + " seconds");
|
||||
//System.out.println(stopwatch.elapsedMillis() / 1000.0 + " seconds");
|
||||
while (rs.next()) {
|
||||
EventType type = useSubTypes ? RootEventType.allTypes.get(rs.getInt(SUB_TYPE_COLUMN)) : BaseTypes.values()[rs.getInt(BASE_TYPE_COLUMN)];
|
||||
|
||||
|
@ -109,13 +109,13 @@ public class EventsRepository {
|
||||
this.eventDB = EventDB.getEventDB(Case.getCurrentCase().getCaseDirectory());
|
||||
|
||||
idToEventCache = CacheBuilder.newBuilder().maximumSize(5000L).expireAfterAccess(10, TimeUnit.MINUTES).removalListener((RemovalNotification<Long, TimeLineEvent> rn) -> {
|
||||
LOGGER.log(Level.INFO, "evicting event: {0}", rn.toString());
|
||||
//LOGGER.log(Level.INFO, "evicting event: {0}", rn.toString());
|
||||
}).build(CacheLoader.from(eventDB::getEventById));
|
||||
eventCountsCache = CacheBuilder.newBuilder().maximumSize(1000L).expireAfterAccess(10, TimeUnit.MINUTES).removalListener((RemovalNotification<ZoomParams, Map<EventType, Long>> rn) -> {
|
||||
LOGGER.log(Level.INFO, "evicting counts: {0}", rn.toString());
|
||||
//LOGGER.log(Level.INFO, "evicting counts: {0}", rn.toString());
|
||||
}).build(CacheLoader.from(eventDB::countEvents));
|
||||
aggregateEventsCache = CacheBuilder.newBuilder().maximumSize(1000L).expireAfterAccess(10, TimeUnit.MINUTES).removalListener((RemovalNotification<ZoomParams, List<AggregateEvent>> rn) -> {
|
||||
LOGGER.log(Level.INFO, "evicting aggregated events: {0}", rn.toString());
|
||||
//LOGGER.log(Level.INFO, "evicting aggregated events: {0}", rn.toString());
|
||||
}).build(CacheLoader.from(eventDB::getAggregatedEvents));
|
||||
maxCache = CacheBuilder.newBuilder().build(CacheLoader.from(eventDB::getMaxTime));
|
||||
minCache = CacheBuilder.newBuilder().build(CacheLoader.from(eventDB::getMinTime));
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.timeline.ui;
|
||||
|
||||
import impl.org.controlsfx.skin.RangeSliderSkin;
|
||||
import java.net.URL;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
@ -34,13 +33,11 @@ import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Rectangle2D;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.SnapshotParameters;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.MenuButton;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.Separator;
|
||||
import javafx.scene.control.Skin;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.control.Toggle;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
@ -63,13 +60,13 @@ import javafx.scene.paint.Color;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import jfxtras.scene.control.LocalDateTimeTextField;
|
||||
import org.controlsfx.control.RangeSlider;
|
||||
import org.controlsfx.control.action.AbstractAction;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.Interval;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.coreutils.LoggedTask;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
||||
import org.sleuthkit.autopsy.timeline.VisualizationMode;
|
||||
@ -235,19 +232,19 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
rangeSlider.setOpacity(.7);
|
||||
rangeSlider.setMin(0);
|
||||
|
||||
/** this is still needed to not get swamped by low/high value changes.
|
||||
* https://bitbucket.org/controlsfx/controlsfx/issue/241/rangeslider-high-low-properties
|
||||
* TODO: committ an appropriate version of this fix to the ControlsFX
|
||||
* repo on bitbucket, remove this after next release -jm */
|
||||
Skin<?> skin = rangeSlider.getSkin();
|
||||
if (skin != null) {
|
||||
attachDragListener((RangeSliderSkin) skin);
|
||||
} else {
|
||||
rangeSlider.skinProperty().addListener((Observable observable) -> {
|
||||
RangeSliderSkin skin1 = (RangeSliderSkin) rangeSlider.getSkin();
|
||||
attachDragListener(skin1);
|
||||
});
|
||||
}
|
||||
// /** this is still needed to not get swamped by low/high value changes.
|
||||
// * https://bitbucket.org/controlsfx/controlsfx/issue/241/rangeslider-high-low-properties
|
||||
// * TODO: committ an appropriate version of this fix to the ControlsFX
|
||||
// * repo on bitbucket, remove this after next release -jm */
|
||||
// Skin<?> skin = rangeSlider.getSkin();
|
||||
// if (skin != null) {
|
||||
// attachDragListener((RangeSliderSkin) skin);
|
||||
// } else {
|
||||
// rangeSlider.skinProperty().addListener((Observable observable) -> {
|
||||
// RangeSliderSkin skin1 = (RangeSliderSkin) rangeSlider.getSkin();
|
||||
// attachDragListener(skin1);
|
||||
// });
|
||||
// }
|
||||
|
||||
rangeSlider.setBlockIncrement(1);
|
||||
|
||||
@ -292,59 +289,59 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: committed an appropriate version of this fix to the ControlsFX repo
|
||||
* on bitbucket, remove this after next release -jm
|
||||
*
|
||||
* @param skin
|
||||
*/
|
||||
private void attachDragListener(RangeSliderSkin skin) {
|
||||
if (skin != null) {
|
||||
for (Node n : skin.getChildren()) {
|
||||
if (n.getStyleClass().contains("track")) {
|
||||
n.setOpacity(.3);
|
||||
}
|
||||
if (n.getStyleClass().contains("range-bar")) {
|
||||
StackPane rangeBar = (StackPane) n;
|
||||
rangeBar.setOnMousePressed((MouseEvent e) -> {
|
||||
rangeBar.requestFocus();
|
||||
preDragPos = e.getX();
|
||||
});
|
||||
|
||||
//don't mark as not changing until mouse is released
|
||||
rangeBar.setOnMouseReleased((MouseEvent event) -> {
|
||||
rangeSlider.setLowValueChanging(false);
|
||||
rangeSlider.setHighValueChanging(false);
|
||||
});
|
||||
rangeBar.setOnMouseDragged((MouseEvent event) -> {
|
||||
final double min = rangeSlider.getMin();
|
||||
final double max = rangeSlider.getMax();
|
||||
|
||||
///!!! compensate for range and width so that rangebar actualy stays with the slider
|
||||
double delta = (event.getX() - preDragPos) * (max - min) / rangeSlider.
|
||||
getWidth();
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
final double lowValue = rangeSlider.getLowValue();
|
||||
final double newLowValue = Math.min(Math.max(min, lowValue + delta),
|
||||
max);
|
||||
final double highValue = rangeSlider.getHighValue();
|
||||
final double newHighValue = Math.min(Math.max(min, highValue + delta),
|
||||
max);
|
||||
|
||||
if (newLowValue <= min || newHighValue >= max) {
|
||||
return;
|
||||
}
|
||||
|
||||
rangeSlider.setLowValueChanging(true);
|
||||
rangeSlider.setHighValueChanging(true);
|
||||
rangeSlider.setLowValue(newLowValue);
|
||||
rangeSlider.setHighValue(newHighValue);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * TODO: committed an appropriate version of this fix to the ControlsFX repo
|
||||
// * on bitbucket, remove this after next release -jm
|
||||
// *
|
||||
// * @param skin
|
||||
// */
|
||||
// private void attachDragListener(RangeSliderSkin skin) {
|
||||
// if (skin != null) {
|
||||
// for (Node n : skin.getChildren()) {
|
||||
// if (n.getStyleClass().contains("track")) {
|
||||
// n.setOpacity(.3);
|
||||
// }
|
||||
// if (n.getStyleClass().contains("range-bar")) {
|
||||
// StackPane rangeBar = (StackPane) n;
|
||||
// rangeBar.setOnMousePressed((MouseEvent e) -> {
|
||||
// rangeBar.requestFocus();
|
||||
// preDragPos = e.getX();
|
||||
// });
|
||||
//
|
||||
// //don't mark as not changing until mouse is released
|
||||
// rangeBar.setOnMouseReleased((MouseEvent event) -> {
|
||||
// rangeSlider.setLowValueChanging(false);
|
||||
// rangeSlider.setHighValueChanging(false);
|
||||
// });
|
||||
// rangeBar.setOnMouseDragged((MouseEvent event) -> {
|
||||
// final double min = rangeSlider.getMin();
|
||||
// final double max = rangeSlider.getMax();
|
||||
//
|
||||
// ///!!! compensate for range and width so that rangebar actualy stays with the slider
|
||||
// double delta = (event.getX() - preDragPos) * (max - min) / rangeSlider.
|
||||
// getWidth();
|
||||
// ////////////////////////////////////////////////////
|
||||
//
|
||||
// final double lowValue = rangeSlider.getLowValue();
|
||||
// final double newLowValue = Math.min(Math.max(min, lowValue + delta),
|
||||
// max);
|
||||
// final double highValue = rangeSlider.getHighValue();
|
||||
// final double newHighValue = Math.min(Math.max(min, highValue + delta),
|
||||
// max);
|
||||
//
|
||||
// if (newLowValue <= min || newHighValue >= max) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// rangeSlider.setLowValueChanging(true);
|
||||
// rangeSlider.setHighValueChanging(true);
|
||||
// rangeSlider.setLowValue(newLowValue);
|
||||
// rangeSlider.setHighValue(newHighValue);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public synchronized void setController(TimeLineController controller) {
|
||||
@ -568,14 +565,14 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
assert dismissButton != null : "fx:id=\"dismissButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'.";
|
||||
assert zoomButton != null : "fx:id=\"zoomButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'.";
|
||||
|
||||
AbstractAction zoomOutAction = new ZoomOut(controller);
|
||||
Action zoomOutAction = new ZoomOut(controller);
|
||||
zoomButton.setOnAction(zoomOutAction);
|
||||
zoomButton.disableProperty().bind(zoomOutAction.disabledProperty());
|
||||
|
||||
dismissButton.setOnAction(e -> {
|
||||
closeCallback.run();
|
||||
});
|
||||
AbstractAction defaultFiltersAction = new DefaultFilters(controller);
|
||||
Action defaultFiltersAction = new DefaultFilters(controller);
|
||||
resetFiltersButton.setOnAction(defaultFiltersAction);
|
||||
resetFiltersButton.disableProperty().bind(defaultFiltersAction.disabledProperty());
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ import javafx.scene.shape.Line;
|
||||
import javafx.scene.shape.StrokeLineCap;
|
||||
import javafx.util.Duration;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import org.controlsfx.control.action.AbstractAction;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.controlsfx.control.action.ActionGroup;
|
||||
import org.controlsfx.control.action.ActionUtils;
|
||||
import org.joda.time.DateTime;
|
||||
@ -108,13 +108,12 @@ public final class EventDetailChart extends XYChart<DateTime, AggregateEvent> im
|
||||
/** how much detail of the description to show in the ui */
|
||||
private final SimpleObjectProperty<DescriptionVisibility> descrVisibility = new SimpleObjectProperty<>(DescriptionVisibility.SHOWN);
|
||||
|
||||
|
||||
/** a user position-able vertical line to help the compare events */
|
||||
private Line guideLine;
|
||||
|
||||
/** * the user can drag out a time range to zoom into and this
|
||||
* {@link IntervalSelector} is the visual representation of it while
|
||||
* the user is dragging */
|
||||
* {@link IntervalSelector} is the visual representation of it while the
|
||||
* user is dragging */
|
||||
private IntervalSelector<? extends DateTime> intervalSelector;
|
||||
|
||||
/** listener that triggers layout pass */
|
||||
@ -220,34 +219,29 @@ public final class EventDetailChart extends XYChart<DateTime, AggregateEvent> im
|
||||
}
|
||||
if (clickEvent.getButton() == MouseButton.SECONDARY && clickEvent.isStillSincePress()) {
|
||||
|
||||
chartContextMenu = ActionUtils.createContextMenu(Arrays.asList(new AbstractAction("Place Marker") {
|
||||
chartContextMenu = ActionUtils.createContextMenu(Arrays.asList(new Action("Place Marker") {
|
||||
{
|
||||
setGraphic(new ImageView(new Image("/org/sleuthkit/autopsy/timeline/images/marker.png", 16, 16, true, true, true)));
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
if (guideLine == null) {
|
||||
guideLine = new GuideLine(0, 0, 0, getHeight(), dateAxis);
|
||||
guideLine.relocate(clickEvent.getX(), 0);
|
||||
guideLine.endYProperty().bind(heightProperty().subtract(dateAxis.heightProperty().subtract(dateAxis.tickLengthProperty())));
|
||||
|
||||
getChartChildren().add(guideLine);
|
||||
|
||||
guideLine.setOnMouseClicked((MouseEvent event) -> {
|
||||
if (event.getButton() == MouseButton.SECONDARY) {
|
||||
clearGuideLine();
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
guideLine.relocate(clickEvent.getX(), 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent ae) {
|
||||
//
|
||||
if (guideLine == null) {
|
||||
guideLine = new GuideLine(0, 0, 0, getHeight(), dateAxis);
|
||||
guideLine.relocate(clickEvent.getX(), 0);
|
||||
guideLine.endYProperty().bind(heightProperty().subtract(dateAxis.heightProperty().subtract(dateAxis.tickLengthProperty())));
|
||||
|
||||
getChartChildren().add(guideLine);
|
||||
|
||||
guideLine.setOnMouseClicked((MouseEvent event) -> {
|
||||
if (event.getButton() == MouseButton.SECONDARY) {
|
||||
clearGuideLine();
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
} else {
|
||||
|
||||
guideLine.relocate(clickEvent.getX(), 0);
|
||||
}
|
||||
}
|
||||
}, new ActionGroup("Zoom History", new Back(controller),
|
||||
new Forward(controller))));
|
||||
chartContextMenu.setAutoHide(true);
|
||||
@ -419,15 +413,15 @@ public final class EventDetailChart extends XYChart<DateTime, AggregateEvent> im
|
||||
*
|
||||
* we start with a list of nodes (each representing an event) - sort the
|
||||
* list of nodes by span start time of the underlying event - initialize
|
||||
* empty map (maxXatY) from y-position to max used x-value - for each
|
||||
* node: -- autosize the node (based on text label) -- get the event's start
|
||||
* and end positions from the dateaxis -- size the capsule representing
|
||||
* event duration -- starting from the top of the chart: --- (1)check if
|
||||
* maxXatY is to the left of the start position: -------if maxXatY less than
|
||||
* start position , good, put the current node here, mark end
|
||||
* position as maxXatY, go to next node -------if maxXatY greater than start
|
||||
* position, increment y position, do -------------check(1) again until
|
||||
* maxXatY less than start position
|
||||
* empty map (maxXatY) from y-position to max used x-value - for each node:
|
||||
* -- autosize the node (based on text label) -- get the event's start and
|
||||
* end positions from the dateaxis -- size the capsule representing event
|
||||
* duration -- starting from the top of the chart: --- (1)check if maxXatY
|
||||
* is to the left of the start position: -------if maxXatY less than start
|
||||
* position , good, put the current node here, mark end position as maxXatY,
|
||||
* go to next node -------if maxXatY greater than start position, increment
|
||||
* y position, do -------------check(1) again until maxXatY less than start
|
||||
* position
|
||||
*/
|
||||
@Override
|
||||
protected synchronized void layoutPlotChildren() {
|
||||
@ -649,8 +643,6 @@ public final class EventDetailChart extends XYChart<DateTime, AggregateEvent> im
|
||||
return chartContextMenu;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static class StartTimeComparator implements Comparator<Node> {
|
||||
|
||||
@Override
|
||||
@ -692,8 +684,7 @@ public final class EventDetailChart extends XYChart<DateTime, AggregateEvent> im
|
||||
|
||||
}
|
||||
|
||||
|
||||
synchronized void setRequiresLayout(boolean b) {
|
||||
synchronized void setRequiresLayout(boolean b) {
|
||||
requiresLayout = true;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ import javafx.scene.control.TreeTableColumn;
|
||||
import javafx.scene.control.TreeTableRow;
|
||||
import javafx.scene.control.TreeTableView;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import org.controlsfx.control.action.AbstractAction;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
||||
@ -149,7 +149,7 @@ public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
@Override
|
||||
public void setController(TimeLineController timeLineController) {
|
||||
this.controller = timeLineController;
|
||||
AbstractAction defaultFiltersAction = new DefaultFilters(controller);
|
||||
Action defaultFiltersAction = new DefaultFilters(controller);
|
||||
defaultButton.setOnAction(defaultFiltersAction);
|
||||
defaultButton.disableProperty().bind(defaultFiltersAction.disabledProperty());
|
||||
this.setModel(timeLineController.getEventsModel());
|
||||
|
@ -36,7 +36,7 @@
|
||||
<dependency conf="autopsy_core->*" org="org.imgscalr" name="imgscalr-lib" rev="4.2" />
|
||||
|
||||
<!-- timeline and image analyzer -->
|
||||
<dependency conf="autopsy_core->*" org="org.controlsfx" name="controlsfx" rev="8.0.6" />
|
||||
<dependency conf="autopsy_core->*" org="org.controlsfx" name="controlsfx" rev="8.20.8" />
|
||||
<!-- timeline and -->
|
||||
<dependency conf="autopsy_core->*" org="joda-time" name="joda-time" rev="2.4" />
|
||||
<dependency conf="autopsy_core->*" org="org.jfxtras" name="jfxtras-fxml" rev="8.0-r1" />
|
||||
|
@ -12,7 +12,7 @@ file.reference.commons-lang3-3.0.jar=release/modules/ext/commons-lang3-3.0.jar
|
||||
file.reference.commons-logging-1.1.2-javadoc.jar=release/modules/ext/commons-logging-1.1.2-javadoc.jar
|
||||
file.reference.commons-logging-1.1.2-sources.jar=release/modules/ext/commons-logging-1.1.2-sources.jar
|
||||
file.reference.commons-logging-1.1.2.jar=release/modules/ext/commons-logging-1.1.2.jar
|
||||
file.reference.controlsfx-8.0.6.jar=release/modules/ext/controlsfx-8.0.6.jar
|
||||
file.reference.controlsfx-8.20.8.jar=release/modules/ext/controlsfx-8.20.8.jar
|
||||
file.reference.dom4j-1.6.1.jar=release/modules/ext/dom4j-1.6.1.jar
|
||||
file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.1_spec-1.0.jar
|
||||
file.reference.gson-1.4.jar=release/modules/ext/gson-1.4.jar
|
||||
@ -41,6 +41,7 @@ file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar
|
||||
file.reference.log4j-1.2.17.jar=release/modules/ext/log4j-1.2.17.jar
|
||||
file.reference.logkit-1.0.1.jar=release/modules/ext/logkit-1.0.1.jar
|
||||
file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar
|
||||
file.reference.openjfx-dialogs-1.0.2.jar=release/modules/ext/openjfx-dialogs-1.0.2.jar
|
||||
file.reference.platform-3.4.0.jar=release/modules/ext/platform-3.4.0.jar
|
||||
file.reference.poi-3.8.jar=release/modules/ext/poi-3.8.jar
|
||||
file.reference.poi-excelant-3.8.jar=release/modules/ext/poi-excelant-3.8.jar
|
||||
@ -58,4 +59,6 @@ file.reference.xml-apis-1.0.b2.jar=release/modules/ext/xml-apis-1.0.b2.jar
|
||||
file.reference.xmlbeans-2.3.0.jar=release/modules/ext/xmlbeans-2.3.0.jar
|
||||
javac.source=1.7
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
javadoc.reference.controlsfx-8.20.8.jar=release/modules/ext/controlsfx-8.20.8-javadoc.jar
|
||||
nbm.needs.restart=true
|
||||
source.reference.controlsfx-8.20.8.jar=release/modules/ext/controlsfx-8.20.8-sources.jar
|
||||
|
@ -64,16 +64,6 @@
|
||||
<package>com.sun.mail.smtp</package>
|
||||
<package>com.sun.mail.util</package>
|
||||
<package>com.sun.mail.util.logging</package>
|
||||
<package>impl.org.controlsfx</package>
|
||||
<package>impl.org.controlsfx.autocompletion</package>
|
||||
<package>impl.org.controlsfx.behavior</package>
|
||||
<package>impl.org.controlsfx.i18n</package>
|
||||
<package>impl.org.controlsfx.skin</package>
|
||||
<package>impl.org.controlsfx.spreadsheet</package>
|
||||
<package>impl.org.controlsfx.tools</package>
|
||||
<package>impl.org.controlsfx.tools.rectangle</package>
|
||||
<package>impl.org.controlsfx.tools.rectangle.change</package>
|
||||
<package>impl.org.controlsfx.version</package>
|
||||
<package>javassist</package>
|
||||
<package>javassist.bytecode</package>
|
||||
<package>javassist.bytecode.analysis</package>
|
||||
@ -485,11 +475,14 @@
|
||||
<package>org.apache.xmlbeans.xml.stream.events</package>
|
||||
<package>org.apache.xmlbeans.xml.stream.utils</package>
|
||||
<package>org.apache.xmlcommons</package>
|
||||
<package>org.controlsfx</package>
|
||||
<package>org.controlsfx.control</package>
|
||||
<package>org.controlsfx.control.action</package>
|
||||
<package>org.controlsfx.control.cell</package>
|
||||
<package>org.controlsfx.control.decoration</package>
|
||||
<package>org.controlsfx.control.spreadsheet</package>
|
||||
<package>org.controlsfx.control.table</package>
|
||||
<package>org.controlsfx.control.table.model</package>
|
||||
<package>org.controlsfx.control.textfield</package>
|
||||
<package>org.controlsfx.dialog</package>
|
||||
<package>org.controlsfx.glyphfont</package>
|
||||
@ -622,6 +615,10 @@
|
||||
<runtime-relative-path>ext/logkit-1.0.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/logkit-1.0.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/openjfx-dialogs-1.0.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/openjfx-dialogs-1.0.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/imgscalr-lib-4.2-javadoc.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/imgscalr-lib-4.2-javadoc.jar</binary-origin>
|
||||
@ -682,10 +679,6 @@
|
||||
<runtime-relative-path>ext/mail-1.4.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/mail-1.4.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/controlsfx-8.0.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/controlsfx-8.0.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/slf4j-api-1.6.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/slf4j-api-1.6.1.jar</binary-origin>
|
||||
@ -754,6 +747,10 @@
|
||||
<runtime-relative-path>ext/jfxtras-fxml-8.0-r1-javadoc.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfxtras-fxml-8.0-r1-javadoc.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/controlsfx-8.20.8.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/controlsfx-8.20.8.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jfxtras-fxml-8.0-r1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfxtras-fxml-8.0-r1.jar</binary-origin>
|
||||
|
Loading…
x
Reference in New Issue
Block a user