diff --git a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java index 47885f35bc..e2b8771ad2 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java @@ -276,11 +276,11 @@ public class TimeLineController { } } - synchronized public ReadOnlyBooleanProperty getCanAdvance() { + synchronized public ReadOnlyBooleanProperty canAdvanceProperty() { return historyManager.getCanAdvance(); } - synchronized public ReadOnlyBooleanProperty getCanRetreat() { + synchronized public ReadOnlyBooleanProperty canRetreatProperty() { return historyManager.getCanRetreat(); } private final ReadOnlyBooleanWrapper eventsDBStale = new ReadOnlyBooleanWrapper(true); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineTopComponent.java b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineTopComponent.java index 97821ce8e2..ab52c1cbb5 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineTopComponent.java @@ -46,6 +46,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.timeline.actions.Back; import org.sleuthkit.autopsy.timeline.actions.Forward; +import org.sleuthkit.autopsy.timeline.ui.HistoryToolBar; import org.sleuthkit.autopsy.timeline.ui.StatusBar; import org.sleuthkit.autopsy.timeline.ui.TimeLineResultView; import org.sleuthkit.autopsy.timeline.ui.TimeZonePanel; @@ -118,12 +119,13 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer } }); + HistoryToolBar historyToolBar = new HistoryToolBar(controller); final TimeZonePanel timeZonePanel = new TimeZonePanel(); VBox.setVgrow(timeZonePanel, Priority.SOMETIMES); final ZoomSettingsPane zoomSettingsPane = new ZoomSettingsPane(controller); - final VBox leftVBox = new VBox(5, timeZonePanel, zoomSettingsPane, leftTabPane); + final VBox leftVBox = new VBox(5, timeZonePanel,historyToolBar, zoomSettingsPane, leftTabPane); SplitPane.setResizableWithParent(leftVBox, Boolean.FALSE); final SplitPane mainSplitPane = new SplitPane(leftVBox, visualizationPanel); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/actions/Back.java b/Core/src/org/sleuthkit/autopsy/timeline/actions/Back.java index 1313b18483..8ee6aa3cd2 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/actions/Back.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/actions/Back.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.timeline.actions; -import javafx.event.ActionEvent; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.KeyCode; @@ -28,26 +27,27 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.timeline.TimeLineController; /** - * + * An action that navigates back through the history stack. */ //TODO: This and the corresponding imageanalyzer action are identical except for the type of the controller... abstract something! -jm 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); // NON-NLS private final TimeLineController controller; - + @NbBundle.Messages({"Back.text=Back", - "Back.longText=Go back to the last view settings."}) + "# {0} - action accelerator keys ", + "Back.longText=Back: {0}\nGo back to the last view settings."}) public Back(TimeLineController controller) { super(Bundle.Back_text()); - setLongText(Bundle.Back_longText()); + this.controller = controller; + setGraphic(new ImageView(BACK_IMAGE)); setAccelerator(new KeyCodeCombination(KeyCode.LEFT, KeyCodeCombination.ALT_DOWN)); - this.controller = controller; - disabledProperty().bind(controller.getCanRetreat().not()); - setEventHandler((ActionEvent t) -> { - controller.retreat(); - }); + setLongText(Bundle.Back_longText(getAccelerator().getDisplayText())); + setEventHandler(actionEvent -> controller.retreat()); + + disabledProperty().bind(controller.canRetreatProperty().not()); } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/actions/Forward.java b/Core/src/org/sleuthkit/autopsy/timeline/actions/Forward.java index b0b7e3e29b..851731528b 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/actions/Forward.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/actions/Forward.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.timeline.actions; -import javafx.event.ActionEvent; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.KeyCode; @@ -28,24 +27,27 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.timeline.TimeLineController; /** - * + * An action that navigates forward through the history. */ //TODO: This and the corresponding imageanalyzer action are identical except for the type of the controller... abstract something! -jm 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); // NON-NLS + private static final Image FORWARD_IMAGE = new Image("/org/sleuthkit/autopsy/timeline/images/arrow.png", 16, 16, true, true, true); // NON-NLS private final TimeLineController controller; - @NbBundle.Messages("Forward.text=Forward") + @NbBundle.Messages({"Forward.text=Forward", + "# {0} - action accelerator keys ", + "Forward.longText=Forward: {0}\nGo forward to the next view settings."}) public Forward(TimeLineController controller) { super(Bundle.Forward_text()); - setGraphic(new ImageView(BACK_IMAGE)); - setAccelerator(new KeyCodeCombination(KeyCode.RIGHT, KeyCodeCombination.ALT_DOWN)); this.controller = controller; - disabledProperty().bind(controller.getCanAdvance().not()); - setEventHandler((ActionEvent t) -> { - controller.advance(); - }); + + setGraphic(new ImageView(FORWARD_IMAGE)); + setAccelerator(new KeyCodeCombination(KeyCode.RIGHT, KeyCodeCombination.ALT_DOWN)); + setLongText(Bundle.Forward_longText(getAccelerator().getDisplayText())); + setEventHandler(actionEvent -> controller.advance()); + + disabledProperty().bind(controller.canAdvanceProperty().not()); } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/timeline/ui/Bundle.properties index 8241d48305..b08bf41e42 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/Bundle.properties @@ -45,4 +45,4 @@ VisualizationPanel.noEventsDialogLabel.text=There are no events visible with the VisualizationPanel.zoomButton.text=Zoom to events TimeZonePanel.localRadio.text=Local Time Zone TimeZonePanel.otherRadio.text=GMT / UTC -VisualizationPanel.resetFiltersButton.text=Reset all filters \ No newline at end of file +VisualizationPanel.resetFiltersButton.text=Reset all filters diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/HistoryToolBar.fxml b/Core/src/org/sleuthkit/autopsy/timeline/ui/HistoryToolBar.fxml new file mode 100644 index 0000000000..303ea9ecfe --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/HistoryToolBar.fxml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/HistoryToolBar.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/HistoryToolBar.java new file mode 100644 index 0000000000..7baf79f686 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/HistoryToolBar.java @@ -0,0 +1,68 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2016 Basis Technology Corp. + * Contact: carrier sleuthkit 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.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ToolBar; +import org.controlsfx.control.action.ActionUtils; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.timeline.FXMLConstructor; +import org.sleuthkit.autopsy.timeline.TimeLineController; +import org.sleuthkit.autopsy.timeline.actions.Back; +import org.sleuthkit.autopsy.timeline.actions.Forward; + +/** + * Toolbar with buttons to go back and forward in the history. + */ +public class HistoryToolBar extends ToolBar { + + @FXML + private Label historyLabel; + @FXML + private Button backButton; + @FXML + private Button forwardButton; + + private final TimeLineController controller; + + /** + * Constructor + * + * @param controller the TimeLineController this ToolBar interacts with. + */ + public HistoryToolBar(TimeLineController controller) { + this.controller = controller; + FXMLConstructor.construct(this, "HistoryToolBar.fxml"); + } + + @FXML + @NbBundle.Messages({"HistoryToolBar.historyLabel.text=Zoom & Filters History"}) + void initialize() { + assert historyLabel != null : "fx:id=\"historyLabel\" was not injected: check your FXML file 'HistoryToolBar.fxml'."; + assert backButton != null : "fx:id=\"backButton\" was not injected: check your FXML file 'HistoryToolBar.fxml'."; + assert forwardButton != null : "fx:id=\"forwardButton\" was not injected: check your FXML file 'HistoryToolBar.fxml'."; + + historyLabel.setText(Bundle.HistoryToolBar_historyLabel_text()); + + ActionUtils.configureButton(new Back(controller), backButton); + ActionUtils.configureButton(new Forward(controller), forwardButton); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/timeline/zooming/Bundle.properties b/Core/src/org/sleuthkit/autopsy/timeline/zooming/Bundle.properties index 7b6253d8c6..4e6e8c45bf 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/zooming/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/timeline/zooming/Bundle.properties @@ -4,10 +4,3 @@ DescriptionLOD.full=Full EventTypeZoomLevel.rootType=Root Type EventTypeZoomLevel.baseType=Base Type EventTypeZoomLevel.subType=Sub Type -ZoomSettingsPane.backButton.toolTip.text=Back\: {0} -ZoomSettingsPane.forwardButton.toolTip.text=Forward\: {0} -ZoomSettingsPane.descrLODLabel.text=Description Detail\: -ZoomSettingsPane.typeZoomLabel.text=Event Type\: -ZoomSettingsPane.timeUnitLabel.text=Time Units\: -ZoomSettingsPane.zoomLabel.text=Zoom -ZoomSettingsPane.historyLabel.text=History\: \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/timeline/zooming/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/timeline/zooming/Bundle_ja.properties index 6708e6f9ba..29c96aaa13 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/zooming/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/timeline/zooming/Bundle_ja.properties @@ -1,13 +1,10 @@ -EventTypeZoomLevel.baseType=\u30D9\u30FC\u30B9\u30BF\u30A4\u30D7 -EventTypeZoomLevel.rootType=\u30EB\u30FC\u30C8\u30BF\u30A4\u30D7 -EventTypeZoomLevel.subType=\u30B5\u30D6\u30BF\u30A4\u30D7 -ZoomSettingsPane.backButton.toolTip.text=\u623B\u308B\uFF1A{0} -ZoomSettingsPane.forwardButton.toolTip.text=\u9032\u3080\uFF1A{0} -DescriptionLOD.short=\u7C21\u6F54 +EventTypeZoomLevel.baseType=\u30d9\u30fc\u30b9\u30bf\u30a4\u30d7 +EventTypeZoomLevel.rootType=\u30eb\u30fc\u30c8\u30bf\u30a4\u30d7 +EventTypeZoomLevel.subType=\u30b5\u30d6\u30bf\u30a4\u30d7 +DescriptionLOD.short=\u7c21\u6f54 DescriptionLOD.medium=\u6982\u8981 -DescriptionLOD.full=\u8A73\u7D30 -ZoomSettingsPane.descrLODLabel.text=\u8A73\u7D30\u8AAC\u660E\uFF1A -ZoomSettingsPane.historyLabel.text=\u5C65\u6B74\uFF1A -ZoomSettingsPane.timeUnitLabel.text=\u6642\u9593\u5358\u4F4D\uFF1A -ZoomSettingsPane.typeZoomLabel.text=\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\uFF1A -ZoomSettingsPane.zoomLabel.text=\u30BA\u30FC\u30E0 \ No newline at end of file +DescriptionLOD.full=\u8a73\u7d30 +ZoomSettingsPane.descrLODLabel.text=\u8a73\u7d30\u8aac\u660e\uff1a +ZoomSettingsPane.historyLabel.text=\u5c65\u6b74\uff1a +ZoomSettingsPane.timeUnitLabel.text=\u6642\u9593\u5358\u4f4d\uff1a +ZoomSettingsPane.typeZoomLabel.text=\u30a4\u30d9\u30f3\u30c8\u30bf\u30a4\u30d7\uff1a \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/timeline/zooming/TimeUnits.java b/Core/src/org/sleuthkit/autopsy/timeline/zooming/TimeUnits.java index b59df7edbb..8ac7ba69f4 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/zooming/TimeUnits.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/zooming/TimeUnits.java @@ -87,4 +87,8 @@ public enum TimeUnits { this.p = p; this.cu = cu; } + + String getDisplayName() { + return toString(); + } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/zooming/ZoomSettingsPane.fxml b/Core/src/org/sleuthkit/autopsy/timeline/zooming/ZoomSettingsPane.fxml index 15b8f58734..eeb81efecd 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/zooming/ZoomSettingsPane.fxml +++ b/Core/src/org/sleuthkit/autopsy/timeline/zooming/ZoomSettingsPane.fxml @@ -1,13 +1,17 @@ - - - - - - + + + + + + + + + + - + @@ -54,6 +58,9 @@ + + + @@ -62,51 +69,14 @@ - - - - - - - - - - - - - - - - + diff --git a/Core/src/org/sleuthkit/autopsy/timeline/zooming/ZoomSettingsPane.java b/Core/src/org/sleuthkit/autopsy/timeline/zooming/ZoomSettingsPane.java index ec10689bd9..a8f5b77e4c 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/zooming/ZoomSettingsPane.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/zooming/ZoomSettingsPane.java @@ -23,36 +23,26 @@ import javafx.application.Platform; import javafx.beans.InvalidationListener; import javafx.beans.property.ReadOnlyObjectProperty; import javafx.fxml.FXML; -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 org.openide.util.NbBundle; import org.sleuthkit.autopsy.timeline.FXMLConstructor; import org.sleuthkit.autopsy.timeline.TimeLineController; import org.sleuthkit.autopsy.timeline.VisualizationMode; -import org.sleuthkit.autopsy.timeline.actions.Back; -import org.sleuthkit.autopsy.timeline.actions.Forward; import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel; import org.sleuthkit.autopsy.timeline.utils.IntervalUtils; import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo; /** - * FXML Controller class for the ZoomSettingsPane.fxml - * - * has sliders to provide context/control over three axes of zooming (timescale, - * event hierarchy, and description detail). + * A Panel that acts as a view for a given + * TimeLineController/FilteredEventsModel. It has sliders to provide + * context/control over three axes of zooming (timescale, event hierarchy, and + * description detail). */ public class ZoomSettingsPane extends TitledPane { - @FXML - private Button backButton; - - @FXML - private Button forwardButton; - @FXML private Slider descrLODSlider; @@ -74,18 +64,26 @@ public class ZoomSettingsPane extends TitledPane { @FXML private Label zoomLabel; - @FXML - private Label historyLabel; - - private TimeLineController controller; - - private FilteredEventsModel filteredEvents; + private final TimeLineController controller; + private final FilteredEventsModel filteredEvents; /** - * Initializes the controller class. + * Constructor + * + * @param controller TimeLineController this panel functions as a view for. */ - public void initialize() { + public ZoomSettingsPane(TimeLineController controller) { + this.controller = controller; + this.filteredEvents = controller.getEventsModel(); + FXMLConstructor.construct(this, "ZoomSettingsPane.fxml"); // NON-NLS + } + @NbBundle.Messages({ + "ZoomSettingsPane.descrLODLabel.text=Description Detail:", + "ZoomSettingsPane.typeZoomLabel.text=Event Type:", + "ZoomSettingsPane.timeUnitLabel.text=Time Units:", + "ZoomSettingsPane.zoomLabel.text=Zoom"}) + public void initialize() { timeUnitSlider.setMax(TimeUnits.values().length - 2); timeUnitSlider.setLabelFormatter(new TimeUnitConverter()); @@ -94,34 +92,32 @@ public class ZoomSettingsPane extends TitledPane { typeZoomSlider.setLabelFormatter(new TypeZoomConverter()); descrLODSlider.setMax(DescriptionLoD.values().length - 1); descrLODSlider.setLabelFormatter(new DescrLODConverter()); - descrLODLabel.setText( - NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.descrLODLabel.text")); - typeZoomLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.typeZoomLabel.text")); - timeUnitLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.timeUnitLabel.text")); - zoomLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.zoomLabel.text")); - historyLabel.setText(NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.historyLabel.text")); + descrLODLabel.setText(Bundle.ZoomSettingsPane_descrLODLabel_text()); + typeZoomLabel.setText(Bundle.ZoomSettingsPane_typeZoomLabel_text()); + timeUnitLabel.setText(Bundle.ZoomSettingsPane_timeUnitLabel_text()); + zoomLabel.setText(Bundle.ZoomSettingsPane_zoomLabel_text()); initializeSlider(timeUnitSlider, () -> { - TimeUnits requestedUnit = TimeUnits.values()[new Double(timeUnitSlider.getValue()).intValue()]; - if (requestedUnit == TimeUnits.FOREVER) { - controller.showFullRange(); - } else { - controller.pushTimeRange(IntervalUtils.getIntervalAround(IntervalUtils.middleOf(ZoomSettingsPane.this.filteredEvents.timeRangeProperty().get()), requestedUnit.getPeriod())); - } - }, + TimeUnits requestedUnit = TimeUnits.values()[new Double(timeUnitSlider.getValue()).intValue()]; + if (requestedUnit == TimeUnits.FOREVER) { + controller.showFullRange(); + } else { + controller.pushTimeRange(IntervalUtils.getIntervalAround(IntervalUtils.middleOf(ZoomSettingsPane.this.filteredEvents.timeRangeProperty().get()), requestedUnit.getPeriod())); + } + }, this.filteredEvents.timeRangeProperty(), () -> { - RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(this.filteredEvents.timeRangeProperty().get()); - ChronoUnit chronoUnit = rangeInfo.getPeriodSize().getChronoUnit(); - timeUnitSlider.setValue(TimeUnits.fromChronoUnit(chronoUnit).ordinal() - 1); - }); + RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(this.filteredEvents.timeRangeProperty().get()); + ChronoUnit chronoUnit = rangeInfo.getPeriodSize().getChronoUnit(); + timeUnitSlider.setValue(TimeUnits.fromChronoUnit(chronoUnit).ordinal() - 1); + }); initializeSlider(descrLODSlider, () -> controller.pushDescrLOD(DescriptionLoD.values()[Math.round(descrLODSlider.valueProperty().floatValue())]), this.filteredEvents.descriptionLODProperty(), () -> { - descrLODSlider.setValue(this.filteredEvents.descriptionLODProperty().get().ordinal()); - }); + descrLODSlider.setValue(this.filteredEvents.descriptionLODProperty().get().ordinal()); + }); initializeSlider(typeZoomSlider, () -> controller.pushEventTypeZoom(EventTypeZoomLevel.values()[Math.round(typeZoomSlider.valueProperty().floatValue())]), @@ -129,25 +125,6 @@ public class ZoomSettingsPane extends TitledPane { () -> 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 } /** @@ -195,7 +172,7 @@ public class ZoomSettingsPane extends TitledPane { @Override public String toString(Double object) { - return TimeUnits.values()[Math.min(TimeUnits.values().length - 1, object.intValue() + 1)].toString(); + return TimeUnits.values()[Math.min(TimeUnits.values().length - 1, object.intValue() + 1)].getDisplayName(); } @Override