move DB update notification out of status bar and parallel to tag notification

This commit is contained in:
jmillman 2016-05-10 09:55:45 -04:00
parent e176109dde
commit b43ef31cbb
8 changed files with 62 additions and 88 deletions

View File

@ -29,9 +29,9 @@ import org.sleuthkit.autopsy.timeline.TimeLineController;
* ingest. * ingest.
*/ */
public class RebuildDataBase extends Action { public class RebuildDataBase extends Action {
private static final Image DB_REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/database_refresh.png"); private static final Image DB_REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/database_refresh.png");
@NbBundle.Messages({ @NbBundle.Messages({
"RebuildDataBase.text=Update DB", "RebuildDataBase.text=Update DB",
"RebuildDataBase.longText=Update the DB to include new events."}) "RebuildDataBase.longText=Update the DB to include new events."})
@ -40,5 +40,6 @@ public class RebuildDataBase extends Action {
setLongText(Bundle.RebuildDataBase_longText()); setLongText(Bundle.RebuildDataBase_longText());
setGraphic(new ImageView(DB_REFRESH)); setGraphic(new ImageView(DB_REFRESH));
setEventHandler(actionEvent -> controller.rebuildRepo()); setEventHandler(actionEvent -> controller.rebuildRepo());
disabledProperty().bind(controller.eventsDBStaleProperty().not());
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,52 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?> <?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?> <?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.Separator?> <?import javafx.scene.control.Separator?>
<?import javafx.scene.control.ToolBar?> <?import javafx.scene.control.ToolBar?>
<?import javafx.scene.image.Image?> <?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?> <?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.StackPane?> <?import javafx.scene.layout.StackPane?>
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" type="ToolBar" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1"> <fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" type="ToolBar" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
<items> <items>
<HBox fx:id="refreshBox" alignment="CENTER" spacing="5.0"> <Label fx:id="statusLabel" layoutX="10.0" layoutY="11.0" HBox.hgrow="ALWAYS">
<children> <graphic>
<Label fx:id="refreshLabel"> <ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
<graphic> <image>
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> <Image url="@../images/information-white.png" />
<image> </image>
<Image url="@../images/information-frame.png" /> </ImageView>
</image> </graphic>
</ImageView> </Label>
</graphic> <Separator halignment="RIGHT" orientation="VERTICAL" />
</Label>
<Button fx:id="updateDBButton" mnemonicParsing="false" text="Update DB">
<graphic>
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../images/database_refresh.png" />
</image>
</ImageView>
</graphic>
</Button>
</children>
</HBox>
<Separator orientation="VERTICAL" />
<Label fx:id="statusLabel" layoutX="10.0" layoutY="11.0">
<graphic>
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../images/information-white.png" />
</image>
</ImageView>
</graphic>
</Label>
<Region fx:id="spacer" maxWidth="1.7976931348623157E308" />
<Separator orientation="VERTICAL" />
<Label fx:id="taskLabel" contentDisplay="RIGHT"> <Label fx:id="taskLabel" contentDisplay="RIGHT">
<graphic> <graphic>
<StackPane> <StackPane>

View File

@ -19,41 +19,26 @@
package org.sleuthkit.autopsy.timeline.ui; package org.sleuthkit.autopsy.timeline.ui;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar; import javafx.scene.control.ProgressBar;
import javafx.scene.control.ToolBar; import javafx.scene.control.ToolBar;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import org.controlsfx.control.action.ActionUtils;
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.actions.RebuildDataBase;
/** /**
* Simple status bar that shows a possible message determined by * Simple status bar that shows a possible message determined by
* TimeLineController.eventsDBStaleProperty() and the warning/button to update * TimeLineController.getStatusProperty() and progress of background tasks.
* the db if it is stale
*/ */
public class StatusBar extends ToolBar { public class StatusBar extends ToolBar {
private final TimeLineController controller; private final TimeLineController controller;
@FXML
private Label refreshLabel;
@FXML
private HBox refreshBox;
@FXML
private Button updateDBButton;
@FXML @FXML
private Label statusLabel; private Label statusLabel;
@FXML @FXML
private ProgressBar progressBar; private ProgressBar progressBar;
@FXML @FXML
private Region spacer;
@FXML
private Label taskLabel; private Label taskLabel;
@FXML @FXML
private Label messageLabel; private Label messageLabel;
@ -64,28 +49,19 @@ public class StatusBar extends ToolBar {
} }
@FXML @FXML
@NbBundle.Messages({"StatusBar.refreshLabel.text=The timeline DB may be out of date."})
void initialize() { void initialize() {
assert refreshLabel != null : "fx:id=\"refreshLabel\" was not injected: check your FXML file 'StatusBar.fxml'."; // NON-NLS
assert progressBar != null : "fx:id=\"progressBar\" was not injected: check your FXML file 'StatusBar.fxml'."; // NON-NLS assert progressBar != null : "fx:id=\"progressBar\" was not injected: check your FXML file 'StatusBar.fxml'."; // NON-NLS
assert spacer != null : "fx:id=\"spacer\" was not injected: check your FXML file 'StatusBar.fxml'."; // NON-NLS
assert taskLabel != null : "fx:id=\"taskLabel\" was not injected: check your FXML file 'StatusBar.fxml'."; // NON-NLS assert taskLabel != null : "fx:id=\"taskLabel\" was not injected: check your FXML file 'StatusBar.fxml'."; // NON-NLS
assert messageLabel != null : "fx:id=\"messageLabel\" was not injected: check your FXML file 'StatusBar.fxml'."; // NON-NLS assert messageLabel != null : "fx:id=\"messageLabel\" was not injected: check your FXML file 'StatusBar.fxml'."; // NON-NLS
HBox.setHgrow(spacer, Priority.ALWAYS);
refreshLabel.setText(Bundle.StatusBar_refreshLabel_text());
refreshBox.visibleProperty().bind(this.controller.eventsDBStaleProperty());
refreshBox.managedProperty().bind(this.controller.eventsDBStaleProperty());
taskLabel.setVisible(false); taskLabel.setVisible(false);
taskLabel.textProperty().bind(this.controller.taskTitleProperty()); taskLabel.textProperty().bind(this.controller.taskTitleProperty());
taskLabel.visibleProperty().bind(this.controller.getTasks().emptyProperty().not());
messageLabel.textProperty().bind(this.controller.taskMessageProperty()); messageLabel.textProperty().bind(this.controller.taskMessageProperty());
progressBar.progressProperty().bind(this.controller.taskProgressProperty()); progressBar.progressProperty().bind(this.controller.taskProgressProperty());
taskLabel.visibleProperty().bind(this.controller.getTasks().emptyProperty().not());
statusLabel.textProperty().bind(this.controller.getStatusProperty()); statusLabel.textProperty().bind(this.controller.getStatusProperty());
statusLabel.visibleProperty().bind(statusLabel.textProperty().isNotEmpty()); statusLabel.visibleProperty().bind(statusLabel.textProperty().isNotEmpty());
ActionUtils.configureButton(new RebuildDataBase(controller), updateDBButton);
} }
} }

View File

@ -19,13 +19,13 @@
<fx:root prefHeight="-1.0" prefWidth="-1.0" type="javafx.scene.layout.BorderPane" xmlns="http://javafx.com/javafx/8.0.65" 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.65" xmlns:fx="http://javafx.com/fxml/1">
<top> <top>
<HBox BorderPane.alignment="CENTER"> <HBox alignment="CENTER_LEFT" BorderPane.alignment="CENTER">
<children> <children>
<ToolBar fx:id="toolBar" HBox.hgrow="ALWAYS"> <ToolBar fx:id="toolBar" HBox.hgrow="NEVER">
<items> <items>
<HBox alignment="CENTER" BorderPane.alignment="CENTER"> <HBox alignment="CENTER_LEFT" BorderPane.alignment="CENTER" HBox.hgrow="ALWAYS">
<children> <children>
<Label fx:id="visualizationModeLabel" text="Visualisation Mode:"> <Label fx:id="visualizationModeLabel" text="Visualisation Mode:" textAlignment="CENTER" wrapText="true" HBox.hgrow="NEVER">
<HBox.margin> <HBox.margin>
<Insets right="5.0" /> <Insets right="5.0" />
</HBox.margin> </HBox.margin>
@ -34,7 +34,7 @@
</font> </font>
</Label> </Label>
<SegmentedButton maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"> <SegmentedButton maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" HBox.hgrow="NEVER">
<buttons> <buttons>
<ToggleButton fx:id="countsToggle" alignment="TOP_LEFT" mnemonicParsing="false" selected="true"> <ToggleButton fx:id="countsToggle" alignment="TOP_LEFT" mnemonicParsing="false" selected="true">
<graphic> <graphic>
@ -74,10 +74,10 @@
<Separator orientation="VERTICAL" /> <Separator orientation="VERTICAL" />
</items> </items>
</ToolBar> </ToolBar>
<ToolBar maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"> <ToolBar maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" HBox.hgrow="ALWAYS">
<items> <items>
<Separator orientation="VERTICAL" /> <Separator halignment="RIGHT" orientation="VERTICAL" HBox.hgrow="ALWAYS" />
<Button fx:id="snapShotButton" mnemonicParsing="false"> <Button fx:id="snapShotButton" mnemonicParsing="false" text="Snapshot Report">
<graphic> <graphic>
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> <ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
<image> <image>
@ -86,8 +86,8 @@
</ImageView> </ImageView>
</graphic> </graphic>
</Button> </Button>
<Separator halignment="LEFT" maxWidth="1.7976931348623157E308" orientation="VERTICAL" /> <Separator maxWidth="1.7976931348623157E308" orientation="VERTICAL" />
<Button fx:id="refreshButton" alignment="CENTER_RIGHT" mnemonicParsing="false" text="Refresh"> <Button fx:id="refreshButton" alignment="CENTER_RIGHT" mnemonicParsing="false" text="Refresh Vis.">
<graphic> <graphic>
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> <ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
<image> <image>
@ -96,6 +96,15 @@
</ImageView> </ImageView>
</graphic> </graphic>
</Button> </Button>
<Button fx:id="updateDBButton" mnemonicParsing="false" text="Update DB">
<graphic>
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../images/database_refresh.png" />
</image>
</ImageView>
</graphic>
</Button>
</items> </items>
</ToolBar> </ToolBar>
</children> </children>

View File

@ -74,6 +74,7 @@ import org.sleuthkit.autopsy.timeline.FXMLConstructor;
import org.sleuthkit.autopsy.timeline.TimeLineController; import org.sleuthkit.autopsy.timeline.TimeLineController;
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.RebuildDataBase;
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.ZoomIn;
@ -99,6 +100,7 @@ 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 WARNING = new Image("org/sleuthkit/autopsy/timeline/images/warning_triangle.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 GRAY_BACKGROUND = new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)); private static final Background GRAY_BACKGROUND = new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY));
@ -164,6 +166,8 @@ final public class VisualizationPanel extends BorderPane {
private Button snapShotButton; private Button snapShotButton;
@FXML @FXML
private Button refreshButton; private Button refreshButton;
@FXML
private Button updateDBButton;
/* /*
* Wraps contained visualization so that we can show notifications over it. * Wraps contained visualization so that we can show notifications over it.
@ -260,7 +264,8 @@ final public class VisualizationPanel extends BorderPane {
"VisualizationPanel.countsToggle.text=Counts", "VisualizationPanel.countsToggle.text=Counts",
"VisualizationPanel.detailsToggle.text=Details", "VisualizationPanel.detailsToggle.text=Details",
"VisualizationPanel.zoomMenuButton.text=Zoom in/out to", "VisualizationPanel.zoomMenuButton.text=Zoom in/out to",
"VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date."}) "VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date.",
"StatusBar.refreshLabel.text=The timeline DB may be out of date."})
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
@ -275,12 +280,32 @@ final public class VisualizationPanel extends BorderPane {
setCenter(notificationPane); setCenter(notificationPane);
needsRefresh.addListener(observable -> { needsRefresh.addListener(observable -> {
if (needsRefresh.get()) { if (needsRefresh.get()) {
notificationPane.getActions().setAll(new Refresh());
notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION)); notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION));
} else { } else {
notificationPane.hide(); notificationPane.hide();
} }
}); });
//this should use an event(EventBus) , not this weird observable pattern
controller.eventsDBStaleProperty().addListener(staleProperty -> {
Platform.runLater(() -> {
if (controller.isEventsDBStale()) {
notificationPane.getActions().setAll(new RebuildDataBase(controller));
notificationPane.show(Bundle.StatusBar_refreshLabel_text(), new ImageView(WARNING));
} else {
VisualizationPanel.this.refreshHistorgram();
notificationPane.hide();
}
});
});
//configure snapshor button / action
ActionUtils.configureButton(new SaveSnapshotAsReport(controller, notificationPane::getContent), snapShotButton);
ActionUtils.configureButton(new Refresh(), refreshButton);
ActionUtils.configureButton(new RebuildDataBase(controller), updateDBButton);
//configure visualization mode toggle //configure visualization mode toggle
visualizationModeLabel.setText(Bundle.VisualizationPanel_visualizationModeLabel_text()); visualizationModeLabel.setText(Bundle.VisualizationPanel_visualizationModeLabel_text());
countsToggle.setText(Bundle.VisualizationPanel_countsToggle_text()); countsToggle.setText(Bundle.VisualizationPanel_countsToggle_text());
@ -306,10 +331,6 @@ final public class VisualizationPanel extends BorderPane {
controller.visualizationModeProperty().addListener(visualizationMode -> syncVisualizationMode()); controller.visualizationModeProperty().addListener(visualizationMode -> syncVisualizationMode());
syncVisualizationMode(); syncVisualizationMode();
//configure snapshor button / action
ActionUtils.configureButton(new SaveSnapshotAsReport(controller, notificationPane::getContent), snapShotButton);
ActionUtils.configureButton(new Refresh(), refreshButton);
/////configure start and end pickers /////configure start and end pickers
startLabel.setText(Bundle.VisualizationPanel_startLabel_text()); startLabel.setText(Bundle.VisualizationPanel_startLabel_text());
endLabel.setText(Bundle.VisualizationPanel_endLabel_text()); endLabel.setText(Bundle.VisualizationPanel_endLabel_text());
@ -366,12 +387,6 @@ final public class VisualizationPanel extends BorderPane {
filteredEvents.zoomParametersProperty().addListener(zoomListener); filteredEvents.zoomParametersProperty().addListener(zoomListener);
refreshTimeUI(); //populate the viz refreshTimeUI(); //populate the viz
//this should use an event(EventBus) , not this weird observable pattern
controller.eventsDBStaleProperty().addListener(staleProperty -> {
if (controller.isEventsDBStale()) {
Platform.runLater(VisualizationPanel.this::refreshHistorgram);
}
});
refreshHistorgram(); refreshHistorgram();
} }