mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 11:07:43 +00:00
always show tag notification
This commit is contained in:
parent
076ee69394
commit
dfce250309
@ -1,7 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
* Autopsy Forensic Browser
|
||||||
* To change this template file, choose Tools | Templates
|
*
|
||||||
* and open the template in the editor.
|
* Copyright 2014-2016 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.events;
|
package org.sleuthkit.autopsy.timeline.events;
|
||||||
|
|
||||||
|
@ -36,6 +36,5 @@ abstract public class TagsUpdatedEvent {
|
|||||||
|
|
||||||
public TagsUpdatedEvent(Set<Long> updatedEventIDs) {
|
public TagsUpdatedEvent(Set<Long> updatedEventIDs) {
|
||||||
this.updatedEventIDs = updatedEventIDs;
|
this.updatedEventIDs = updatedEventIDs;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ import javafx.beans.InvalidationListener;
|
|||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.event.ActionEvent;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
@ -81,8 +80,8 @@ 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.actions.ZoomToEvents;
|
||||||
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.TagsUpdatedEvent;
|
import org.sleuthkit.autopsy.timeline.events.TagsUpdatedEvent;
|
||||||
import org.sleuthkit.autopsy.timeline.filters.TagsFilter;
|
|
||||||
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.EventsTree;
|
import org.sleuthkit.autopsy.timeline.ui.detailview.tree.EventsTree;
|
||||||
@ -97,16 +96,16 @@ 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
|
||||||
*/
|
*/
|
||||||
final public class VisualizationPanel extends BorderPane {
|
final public class VisualizationPanel extends BorderPane {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(VisualizationPanel.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(VisualizationPanel.class.getName());
|
||||||
|
|
||||||
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
|
||||||
private static final Background background = new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY));
|
private static final Background background = new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY));
|
||||||
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private LoggedTask<Void> histogramTask;
|
private LoggedTask<Void> histogramTask;
|
||||||
|
|
||||||
private final EventsTree eventsTree;
|
private final EventsTree eventsTree;
|
||||||
private AbstractVisualizationPane<?, ?, ?, ?> visualization;
|
private AbstractVisualizationPane<?, ?, ?, ?> visualization;
|
||||||
//// range slider and histogram componenets
|
//// range slider and histogram componenets
|
||||||
@ -121,13 +120,13 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private StackPane rangeHistogramStack;
|
private StackPane rangeHistogramStack;
|
||||||
|
|
||||||
private final RangeSlider rangeSlider = new RangeSlider(0, 1.0, .25, .75);
|
private final RangeSlider rangeSlider = new RangeSlider(0, 1.0, .25, .75);
|
||||||
|
|
||||||
//// time range selection components
|
//// time range selection components
|
||||||
@FXML
|
@FXML
|
||||||
private MenuButton zoomMenuButton;
|
private MenuButton zoomMenuButton;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button zoomOutButton;
|
private Button zoomOutButton;
|
||||||
@FXML
|
@FXML
|
||||||
@ -165,7 +164,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
* wraps contained visualization so that we can show notifications over it.
|
* wraps contained visualization so that we can show notifications over it.
|
||||||
*/
|
*/
|
||||||
private final NotificationPane notificationPane = new NotificationPane();
|
private final NotificationPane notificationPane = new NotificationPane();
|
||||||
|
|
||||||
private final TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
private final FilteredEventsModel filteredEvents;
|
private final FilteredEventsModel filteredEvents;
|
||||||
|
|
||||||
@ -216,26 +215,26 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* convert the given epoch millis to a LocalDateTime USING THE CURERNT
|
* Convert the given epoch millis to a LocalDateTime USING THE CURERNT
|
||||||
* TIMEZONE FROM TIMELINECONTROLLER
|
* TIMEZONE FROM TIMELINECONTROLLER
|
||||||
*
|
*
|
||||||
* @param millis
|
* @param millis The milliseconds to convert.
|
||||||
*
|
*
|
||||||
* @return the given epoch millis as a LocalDateTime
|
* @return The given epoch millis as a LocalDateTime
|
||||||
*/
|
*/
|
||||||
private static LocalDateTime epochMillisToLocalDateTime(long millis) {
|
private static LocalDateTime epochMillisToLocalDateTime(long millis) {
|
||||||
return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), TimeLineController.getTimeZoneID());
|
return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), TimeLineController.getTimeZoneID());
|
||||||
}
|
}
|
||||||
|
|
||||||
public VisualizationPanel(@Nonnull TimeLineController controller, @Nonnull EventsTree eventsTree) {
|
public VisualizationPanel(@Nonnull TimeLineController controller, @Nonnull EventsTree eventsTree) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
this.filteredEvents = controller.getEventsModel();
|
this.filteredEvents = controller.getEventsModel();
|
||||||
this.eventsTree = eventsTree;
|
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.visualizationModeLabel.text=Visualization Mode:",
|
"VisualizationPanel.visualizationModeLabel.text=Visualization Mode:",
|
||||||
"VisualizationPanel.startLabel.text=Start:",
|
"VisualizationPanel.startLabel.text=Start:",
|
||||||
"VisualizationPanel.endLabel.text=End:",
|
"VisualizationPanel.endLabel.text=End:",
|
||||||
@ -252,15 +251,6 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
|
|
||||||
//configure notification pane
|
//configure notification pane
|
||||||
notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK);
|
notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK);
|
||||||
notificationPane.getActions().setAll(new Action(Bundle.VisualizationPanel_refresh()) {
|
|
||||||
{
|
|
||||||
setGraphic(new ImageView(REFRESH));
|
|
||||||
setEventHandler((ActionEvent t) -> {
|
|
||||||
filteredEvents.refresh();
|
|
||||||
notificationPane.hide();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setCenter(notificationPane);
|
setCenter(notificationPane);
|
||||||
|
|
||||||
//configure visualization mode toggle
|
//configure visualization mode toggle
|
||||||
@ -276,7 +266,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
controller.setViewMode(VisualizationMode.DETAIL);
|
controller.setViewMode(VisualizationMode.DETAIL);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (countsToggle.getToggleGroup() != null) {
|
if (countsToggle.getToggleGroup() != null) {
|
||||||
countsToggle.getToggleGroup().selectedToggleProperty().addListener(toggleListener);
|
countsToggle.getToggleGroup().selectedToggleProperty().addListener(toggleListener);
|
||||||
} else {
|
} else {
|
||||||
@ -353,9 +343,9 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
refreshHistorgram();
|
refreshHistorgram();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setViewMode(VisualizationMode visualizationMode) {
|
private void setViewMode(VisualizationMode visualizationMode) {
|
||||||
switch (visualizationMode) {
|
switch (visualizationMode) {
|
||||||
case COUNTS:
|
case COUNTS:
|
||||||
@ -368,7 +358,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void setVisualization(final AbstractVisualizationPane<?, ?, ?, ?> newViz) {
|
private synchronized void setVisualization(final AbstractVisualizationPane<?, ?, ?, ?> newViz) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
synchronized (VisualizationPanel.this) {
|
synchronized (VisualizationPanel.this) {
|
||||||
@ -376,11 +366,11 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
toolBar.getItems().removeAll(visualization.getSettingsNodes());
|
toolBar.getItems().removeAll(visualization.getSettingsNodes());
|
||||||
visualization.dispose();
|
visualization.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
visualization = newViz;
|
visualization = newViz;
|
||||||
visualization.update();
|
visualization.update();
|
||||||
toolBar.getItems().addAll(newViz.getSettingsNodes());
|
toolBar.getItems().addAll(newViz.getSettingsNodes());
|
||||||
|
|
||||||
notificationPane.setContent(visualization);
|
notificationPane.setContent(visualization);
|
||||||
if (visualization instanceof DetailViewPane) {
|
if (visualization instanceof DetailViewPane) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
@ -390,7 +380,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
}
|
}
|
||||||
visualization.hasEvents.addListener((observable, oldValue, newValue) -> {
|
visualization.hasEvents.addListener((observable, oldValue, newValue) -> {
|
||||||
if (newValue == false) {
|
if (newValue == false) {
|
||||||
|
|
||||||
notificationPane.setContent(
|
notificationPane.setContent(
|
||||||
new StackPane(visualization,
|
new StackPane(visualization,
|
||||||
new Region() {
|
new Region() {
|
||||||
@ -407,75 +397,79 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@NbBundle.Messages("VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date.")
|
@NbBundle.Messages("VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date.")
|
||||||
public void handleTimeLineTagEvent(TagsUpdatedEvent event) {
|
public void handleTimeLineTagEvent(TagsUpdatedEvent event) {
|
||||||
TagsFilter tagsFilter = filteredEvents.getFilter().getTagsFilter();
|
Platform.runLater(() -> {
|
||||||
if (tagsFilter.isSelected() && tagsFilter.isDisabled() == false) {
|
notificationPane.setCloseButtonVisible(false);
|
||||||
Platform.runLater(() -> {
|
notificationPane.getActions().setAll(new Refresh());
|
||||||
notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION));
|
notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION));
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void handleRefreshRequestedEvent(RefreshRequestedEvent event) {
|
||||||
|
Platform.runLater(notificationPane::hide);
|
||||||
|
}
|
||||||
|
|
||||||
synchronized private void refreshHistorgram() {
|
synchronized private void refreshHistorgram() {
|
||||||
|
|
||||||
if (histogramTask != null) {
|
if (histogramTask != null) {
|
||||||
histogramTask.cancel(true);
|
histogramTask.cancel(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
histogramTask = new LoggedTask<Void>(
|
histogramTask = new LoggedTask<Void>(
|
||||||
NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.title"), true) { // NON-NLS
|
NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.title"), true) { // NON-NLS
|
||||||
private final Lighting lighting = new Lighting();
|
private final Lighting lighting = new Lighting();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void call() throws Exception {
|
protected Void call() throws Exception {
|
||||||
|
|
||||||
|
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.preparing")); // NON-NLS
|
||||||
|
|
||||||
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.preparing")); // NON-NLS
|
long max = 0;
|
||||||
|
final RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval());
|
||||||
|
final long lowerBound = rangeInfo.getLowerBound();
|
||||||
|
final long upperBound = rangeInfo.getUpperBound();
|
||||||
|
Interval timeRange = new Interval(new DateTime(lowerBound, TimeLineController.getJodaTimeZone()), new DateTime(upperBound, TimeLineController.getJodaTimeZone()));
|
||||||
|
|
||||||
long max = 0;
|
//extend range to block bounderies (ie day, month, year)
|
||||||
final RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval());
|
int p = 0; // progress counter
|
||||||
final long lowerBound = rangeInfo.getLowerBound();
|
|
||||||
final long upperBound = rangeInfo.getUpperBound();
|
|
||||||
Interval timeRange = new Interval(new DateTime(lowerBound, TimeLineController.getJodaTimeZone()), new DateTime(upperBound, TimeLineController.getJodaTimeZone()));
|
|
||||||
|
|
||||||
//extend range to block bounderies (ie day, month, year)
|
//clear old data, and reset ranges and series
|
||||||
int p = 0; // progress counter
|
Platform.runLater(() -> {
|
||||||
|
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.resetUI")); // NON-NLS
|
||||||
|
|
||||||
//clear old data, and reset ranges and series
|
});
|
||||||
Platform.runLater(() -> {
|
|
||||||
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.resetUI")); // NON-NLS
|
ArrayList<Long> bins = new ArrayList<>();
|
||||||
|
|
||||||
|
DateTime start = timeRange.getStart();
|
||||||
|
while (timeRange.contains(start)) {
|
||||||
|
if (isCancelled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
DateTime end = start.plus(rangeInfo.getPeriodSize().getPeriod());
|
||||||
|
final Interval interval = new Interval(start, end);
|
||||||
|
//increment for next iteration
|
||||||
|
|
||||||
});
|
start = end;
|
||||||
|
|
||||||
ArrayList<Long> bins = new ArrayList<>();
|
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.queryDb")); // NON-NLS
|
||||||
|
//query for current range
|
||||||
DateTime start = timeRange.getStart();
|
long count = filteredEvents.getEventCounts(interval).values().stream().mapToLong(Long::valueOf).sum();
|
||||||
while (timeRange.contains(start)) {
|
bins.add(count);
|
||||||
if (isCancelled()) {
|
|
||||||
return null;
|
max = Math.max(count, max);
|
||||||
}
|
|
||||||
DateTime end = start.plus(rangeInfo.getPeriodSize().getPeriod());
|
final double fMax = Math.log(max);
|
||||||
final Interval interval = new Interval(start, end);
|
final ArrayList<Long> fbins = new ArrayList<>(bins);
|
||||||
//increment for next iteration
|
Platform.runLater(() -> {
|
||||||
|
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.updateUI2")); // NON-NLS
|
||||||
start = end;
|
|
||||||
|
|
||||||
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.queryDb")); // NON-NLS
|
|
||||||
//query for current range
|
|
||||||
long count = filteredEvents.getEventCounts(interval).values().stream().mapToLong(Long::valueOf).sum();
|
|
||||||
bins.add(count);
|
|
||||||
|
|
||||||
max = Math.max(count, max);
|
|
||||||
|
|
||||||
final double fMax = Math.log(max);
|
|
||||||
final ArrayList<Long> fbins = new ArrayList<>(bins);
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.updateUI2")); // NON-NLS
|
|
||||||
|
|
||||||
histogramBox.getChildren().clear();
|
|
||||||
|
|
||||||
|
histogramBox.getChildren().clear();
|
||||||
|
|
||||||
for (Long bin : fbins) {
|
for (Long bin : fbins) {
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
break;
|
break;
|
||||||
@ -498,41 +492,41 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
new Thread(histogramTask).start();
|
new Thread(histogramTask).start();
|
||||||
controller.monitorTask(histogramTask);
|
controller.monitorTask(histogramTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshTimeUI() {
|
private void refreshTimeUI() {
|
||||||
refreshTimeUI(filteredEvents.timeRangeProperty().get());
|
refreshTimeUI(filteredEvents.timeRangeProperty().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshTimeUI(Interval interval) {
|
private void refreshTimeUI(Interval interval) {
|
||||||
|
|
||||||
RangeDivisionInfo rangeDivisionInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval());
|
RangeDivisionInfo rangeDivisionInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval());
|
||||||
|
|
||||||
final long minTime = rangeDivisionInfo.getLowerBound();
|
final long minTime = rangeDivisionInfo.getLowerBound();
|
||||||
final long maxTime = rangeDivisionInfo.getUpperBound();
|
final long maxTime = rangeDivisionInfo.getUpperBound();
|
||||||
|
|
||||||
long startMillis = interval.getStartMillis();
|
long startMillis = interval.getStartMillis();
|
||||||
long endMillis = interval.getEndMillis();
|
long endMillis = interval.getEndMillis();
|
||||||
|
|
||||||
if (minTime > 0 && maxTime > minTime) {
|
if (minTime > 0 && maxTime > minTime) {
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
startPicker.localDateTimeProperty().removeListener(startListener);
|
startPicker.localDateTimeProperty().removeListener(startListener);
|
||||||
endPicker.localDateTimeProperty().removeListener(endListener);
|
endPicker.localDateTimeProperty().removeListener(endListener);
|
||||||
rangeSlider.highValueChangingProperty().removeListener(rangeSliderListener);
|
rangeSlider.highValueChangingProperty().removeListener(rangeSliderListener);
|
||||||
rangeSlider.lowValueChangingProperty().removeListener(rangeSliderListener);
|
rangeSlider.lowValueChangingProperty().removeListener(rangeSliderListener);
|
||||||
|
|
||||||
rangeSlider.setMax((maxTime - minTime));
|
rangeSlider.setMax((maxTime - minTime));
|
||||||
|
|
||||||
rangeSlider.setLowValue(startMillis - minTime);
|
rangeSlider.setLowValue(startMillis - minTime);
|
||||||
rangeSlider.setHighValue(endMillis - minTime);
|
rangeSlider.setHighValue(endMillis - minTime);
|
||||||
startPicker.setLocalDateTime(epochMillisToLocalDateTime(startMillis));
|
startPicker.setLocalDateTime(epochMillisToLocalDateTime(startMillis));
|
||||||
endPicker.setLocalDateTime(epochMillisToLocalDateTime(endMillis));
|
endPicker.setLocalDateTime(epochMillisToLocalDateTime(endMillis));
|
||||||
|
|
||||||
rangeSlider.highValueChangingProperty().addListener(rangeSliderListener);
|
rangeSlider.highValueChangingProperty().addListener(rangeSliderListener);
|
||||||
rangeSlider.lowValueChangingProperty().addListener(rangeSliderListener);
|
rangeSlider.lowValueChangingProperty().addListener(rangeSliderListener);
|
||||||
startPicker.localDateTimeProperty().addListener(startListener);
|
startPicker.localDateTimeProperty().addListener(startListener);
|
||||||
@ -540,10 +534,10 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages("NoEventsDialog.titledPane.text=No Visible Events")
|
@NbBundle.Messages("NoEventsDialog.titledPane.text=No Visible Events")
|
||||||
private class NoEventsDialog extends StackPane {
|
private class NoEventsDialog extends StackPane {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TitledPane titledPane;
|
private TitledPane titledPane;
|
||||||
@FXML
|
@FXML
|
||||||
@ -556,14 +550,14 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
private Button zoomButton;
|
private Button zoomButton;
|
||||||
@FXML
|
@FXML
|
||||||
private Label noEventsDialogLabel;
|
private Label noEventsDialogLabel;
|
||||||
|
|
||||||
private final Runnable closeCallback;
|
private final Runnable closeCallback;
|
||||||
|
|
||||||
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
|
||||||
void initialize() {
|
void initialize() {
|
||||||
assert resetFiltersButton != null : "fx:id=\"resetFiltersButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS
|
assert resetFiltersButton != null : "fx:id=\"resetFiltersButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS
|
||||||
@ -574,7 +568,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
noEventsDialogLabel.setText(NbBundle.getMessage(NoEventsDialog.class, "VisualizationPanel.noEventsDialogLabel.text")); // NON-NLS
|
noEventsDialogLabel.setText(NbBundle.getMessage(NoEventsDialog.class, "VisualizationPanel.noEventsDialogLabel.text")); // NON-NLS
|
||||||
|
|
||||||
dismissButton.setOnAction(actionEvent -> closeCallback.run());
|
dismissButton.setOnAction(actionEvent -> closeCallback.run());
|
||||||
|
|
||||||
ActionUtils.configureButton(new ZoomToEvents(controller), zoomButton);
|
ActionUtils.configureButton(new ZoomToEvents(controller), zoomButton);
|
||||||
ActionUtils.configureButton(new Back(controller), backButton);
|
ActionUtils.configureButton(new Back(controller), backButton);
|
||||||
ActionUtils.configureButton(new ResetFilters(controller), resetFiltersButton);
|
ActionUtils.configureButton(new ResetFilters(controller), resetFiltersButton);
|
||||||
@ -586,15 +580,15 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
* the selected LocalDateTime as start/end to the timelinecontroller.
|
* the selected LocalDateTime as start/end to the timelinecontroller.
|
||||||
*/
|
*/
|
||||||
private class PickerListener implements InvalidationListener {
|
private class PickerListener implements InvalidationListener {
|
||||||
|
|
||||||
private final BiFunction< Interval, Long, Interval> intervalMapper;
|
private final BiFunction< Interval, Long, Interval> intervalMapper;
|
||||||
private final Supplier<LocalDateTimeTextField> pickerSupplier;
|
private final Supplier<LocalDateTimeTextField> pickerSupplier;
|
||||||
|
|
||||||
PickerListener(Supplier<LocalDateTimeTextField> pickerSupplier, BiFunction<Interval, Long, Interval> intervalMapper) {
|
PickerListener(Supplier<LocalDateTimeTextField> pickerSupplier, BiFunction<Interval, Long, Interval> intervalMapper) {
|
||||||
this.pickerSupplier = pickerSupplier;
|
this.pickerSupplier = pickerSupplier;
|
||||||
this.intervalMapper = intervalMapper;
|
this.intervalMapper = intervalMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidated(Observable observable) {
|
public void invalidated(Observable observable) {
|
||||||
LocalDateTime pickerTime = pickerSupplier.get().getLocalDateTime();
|
LocalDateTime pickerTime = pickerSupplier.get().getLocalDateTime();
|
||||||
@ -609,7 +603,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
* callback that disabled date/times outside the span of the current case.
|
* callback that disabled date/times outside the span of the current case.
|
||||||
*/
|
*/
|
||||||
private class LocalDateDisabler implements Callback<LocalDateTimePicker.LocalDateTimeRange, Void> {
|
private class LocalDateDisabler implements Callback<LocalDateTimePicker.LocalDateTimeRange, Void> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void call(LocalDateTimePicker.LocalDateTimeRange viewedRange) {
|
public Void call(LocalDateTimePicker.LocalDateTimeRange viewedRange) {
|
||||||
startPicker.disabledLocalDateTimes().clear();
|
startPicker.disabledLocalDateTimes().clear();
|
||||||
@ -619,7 +613,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
Interval spanningInterval = filteredEvents.getSpanningInterval();
|
Interval spanningInterval = filteredEvents.getSpanningInterval();
|
||||||
long spanStartMillis = spanningInterval.getStartMillis();
|
long spanStartMillis = spanningInterval.getStartMillis();
|
||||||
long spaneEndMillis = spanningInterval.getEndMillis();
|
long spaneEndMillis = spanningInterval.getEndMillis();
|
||||||
|
|
||||||
LocalDate rangeStartLocalDate = viewedRange.getStartLocalDateTime().toLocalDate();
|
LocalDate rangeStartLocalDate = viewedRange.getStartLocalDateTime().toLocalDate();
|
||||||
LocalDate rangeEndLocalDate = viewedRange.getEndLocalDateTime().toLocalDate().plusDays(1);
|
LocalDate rangeEndLocalDate = viewedRange.getEndLocalDateTime().toLocalDate().plusDays(1);
|
||||||
//iterate over days of the displayed range and disable ones not in spanning interval
|
//iterate over days of the displayed range and disable ones not in spanning interval
|
||||||
@ -647,11 +641,11 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
* picker to reset if invalid info was entered
|
* picker to reset if invalid info was entered
|
||||||
*/
|
*/
|
||||||
private final LocalDateTimeTextField picker;
|
private final LocalDateTimeTextField picker;
|
||||||
|
|
||||||
LocalDateTimeValidator(LocalDateTimeTextField picker) {
|
LocalDateTimeValidator(LocalDateTimeTextField picker) {
|
||||||
this.picker = picker;
|
this.picker = picker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean call(LocalDateTime param) {
|
public Boolean call(LocalDateTime param) {
|
||||||
long epochMilli = localDateTimeToEpochMilli(param);
|
long epochMilli = localDateTimeToEpochMilli(param);
|
||||||
@ -666,4 +660,15 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class Refresh extends Action {
|
||||||
|
|
||||||
|
@NbBundle.Messages({"VisualizationPanel.refresh=refresh"})
|
||||||
|
Refresh() {
|
||||||
|
super(Bundle.VisualizationPanel_refresh());
|
||||||
|
|
||||||
|
setGraphic(new ImageView(REFRESH));
|
||||||
|
setEventHandler(actionEvent -> filteredEvents.refresh());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user