mirror of
https://github.com/elisspace/autopsy.git
synced 2026-10-02 15:29:54 +00:00
Merge pull request #997 from mrtizmo/timeline_ja
Timeline module JA localization
This commit is contained in:
@@ -1,17 +1,14 @@
|
||||
OpenIDE-Module-Name=Timeline
|
||||
CTL_MakeTimeline="Timeline"
|
||||
CTL_TimeLineTopComponentAction=TimeLineTopComponent
|
||||
CTL_TimeLineTopComponent=Timeline Window
|
||||
HINT_TimeLineTopComponent=This is a Timeline window
|
||||
Timeline.frameName.text={0} - Autopsy Timeline
|
||||
Timeline.resultsPanel.title=Timeline Results
|
||||
Timeline.runJavaFxThread.progress.creating=Creating timeline . . .
|
||||
Timeline.zoomOutButton.text=Zoom Out
|
||||
Timeline.goToButton.text=Go To\:
|
||||
Timeline.yearBarChart.x.years=Years
|
||||
Timeline.yearBarChart.y.numEvents=Number of Events
|
||||
Timeline.MonthsBarChart.x.monthYY=Month ({0})
|
||||
Timeline.MonthsBarChart.y.numEvents=Number of Events
|
||||
Timeline.eventsByMoBarChart.x.dayOfMo=Day of Month
|
||||
Timeline.eventsByMoBarChart.y.numEvents=Number of Events
|
||||
Timeline.node.emptyRoot=Empty Root
|
||||
Timeline.resultPanel.loading=Loading...
|
||||
Timeline.node.root=Root
|
||||
Timeline.propChg.confDlg.timelineOOD.msg=The event data is out of date. Would you like to regenerate it?
|
||||
@@ -33,5 +30,16 @@ TimelinePanel.jButton2.text=1m
|
||||
TimelinePanel.jButton3.text=3m
|
||||
TimelinePanel.jButton4.text=2w
|
||||
ProgressWindow.progressHeader.text=\
|
||||
AggregateEvent.differentTypes="aggregate events are not compatible they have different types"
|
||||
AggregateEvent.differentDescriptions="aggregate events are not compatible they have different descriptions"
|
||||
TimeLineTopComponent.eventsTab.name=Events
|
||||
TimeLineTopComponent.filterTab.name=Filters
|
||||
Timeline.showLastPopulatedWhileIngestingConf.confDlg.details=re populate events?
|
||||
Timeline.do_repopulate.msg=The events database was previously populated while ingest was running.\nSome events may not have been populated or may have been populated inaccurately.\nDo you want to repopulate the events database now?
|
||||
Timeline.pushDescrLOD.confdlg.msg=You are about to show details for {0} events. This might be very slow or even crash Autopsy.\n\nDo you want to continue?
|
||||
Timeline.pushDescrLOD.confdlg.details=
|
||||
OpenTimelineAction.title=Timeline
|
||||
Timeline.ProgressWindow.cancel.confdlg.msg=Do you want to cancel time line creation?
|
||||
Timeline.ProgressWindow.cancel.confdlg.detail=Cancel timeline creation?
|
||||
Timeline.progressWindow.name=Timeline
|
||||
Timeline.progressWindow.title=Generating Timeline data
|
||||
OpenTimeLineAction.msgdlg.text=Error creating timeline, there are no data sources.
|
||||
TimeLineTopComponent.timeZonePanel.text=Display Times In\:
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
CTL_MakeTimeline=\u300C\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u300D
|
||||
CTL_TimeLineTopComponent=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30A6\u30A3\u30F3\u30C9\u30A6
|
||||
CTL_TimeLineTopComponentAction=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30C8\u30C3\u30D7\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8
|
||||
HINT_TimeLineTopComponent=\u3053\u308C\u306F\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30A6\u30A3\u30F3\u30C9\u30A6\u3067\u3059
|
||||
OpenIDE-Module-Name=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3
|
||||
OpenTimelineAction.title=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3
|
||||
Timeline.do_repopulate.msg=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u5B9F\u884C\u4E2D\u306B\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u4EE5\u524D\u57CB\u3081\u3089\u308C\u307E\u3057\u305F\u3002\n\u4E00\u90E8\u306E\u30A4\u30D9\u30F3\u30C8\u306F\u7A7A\u767D\u306E\u307E\u307E\u3082\u3057\u304F\u306F\u4E0D\u6B63\u78BA\u306A\u30C7\u30FC\u30BF\u3067\u57CB\u307E\u3063\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\n\u4ECA\u3059\u3050\u30A4\u30D9\u30F3\u30C8\u306E\u30C7\u30FC\u30BF\u3092\u518D\u5EA6\u57CB\u3081\u307E\u3059\u304B\uFF1F
|
||||
Timeline.frameName.text={0} - Autopsy\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3
|
||||
Timeline.goToButton.text=\u4E0B\u8A18\u3078\u79FB\u52D5\uFF1A
|
||||
Timeline.initTimeline.confDlg.genBeforeIngest.details=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3
|
||||
Timeline.initTimeline.confDlg.genBeforeIngest.msg=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u304C\u5B8C\u4E86\u3059\u308B\u524D\u306B\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u3092\u4F5C\u6210\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059\u3002\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u304C\u4E0D\u5B8C\u5168\u306B\u306A\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\u5B9F\u884C\u3057\u307E\u3059\u304B\uFF1F
|
||||
Timeline.node.root=\u30EB\u30FC\u30C8
|
||||
Timeline.ProgressWindow.cancel.confdlg.detail=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u4F5C\u6210\u3092\u30AD\u30E3\u30F3\u30BB\u30EB\u3057\u307E\u3059\u304B\uFF1F
|
||||
Timeline.ProgressWindow.cancel.confdlg.msg=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u4F5C\u6210\u3092\u30AD\u30E3\u30F3\u30BB\u30EB\u3057\u307E\u3059\u304B\uFF1F
|
||||
Timeline.progressWindow.name=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3
|
||||
Timeline.progressWindow.title=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u30C7\u30FC\u30BF\u4F5C\u6210\u4E2D
|
||||
Timeline.propChg.confDlg.timelineOOD.details=\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u9078\u629E
|
||||
Timeline.propChg.confDlg.timelineOOD.msg=\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF\u304C\u6700\u65B0\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u518D\u5EA6\u4F5C\u6210\u3057\u307E\u3059\u304B\uFF1F
|
||||
Timeline.pushDescrLOD.confdlg.msg=\u5B9F\u884C\u3059\u308B\u3068{0}\u30A4\u30D9\u30F3\u30C8\u306E\u8A73\u7D30\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\u3053\u306E\u51E6\u7406\u306F\u9577\u6642\u9593\u304B\u304B\u308B\u3082\u3057\u304F\u306FAutopsy\u3092\u30AF\u30E9\u30C3\u30B7\u30E5\u3059\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\n\n\u5B9F\u884C\u3057\u307E\u3059\u304B\uFF1F
|
||||
Timeline.resultPanel.loading=\u30ED\u30FC\u30C9\u4E2D\u30FB\u30FB\u30FB
|
||||
Timeline.resultsPanel.title=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u7D50\u679C
|
||||
Timeline.runJavaFxThread.progress.creating=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u4F5C\u6210\u4E2D\u30FB\u30FB\u30FB
|
||||
Timeline.showLastPopulatedWhileIngestingConf.confDlg.details=\u30A4\u30D9\u30F3\u30C8\u3092\u518D\u5EA6\u57CB\u3081\u307E\u3059\u304B\uFF1F
|
||||
Timeline.zoomOutButton.text=\u30BA\u30FC\u30E0\u30A2\u30A6\u30C8
|
||||
TimelineFrame.title=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3
|
||||
TimeLineTopComponent.eventsTab.name=\u30A4\u30D9\u30F3\u30C8
|
||||
TimeLineTopComponent.filterTab.name=\u30D5\u30A3\u30EB\u30BF
|
||||
OpenTimeLineAction.msgdlg.text=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u4F5C\u6210\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093\u3002
|
||||
TimeLineTopComponent.timeZonePanel.text=\u6642\u9593\u3092\u4E0B\u8A18\u3067\u8868\u793A\uFF1A
|
||||
@@ -40,7 +40,7 @@ import org.openide.util.Exceptions;
|
||||
public class FXMLConstructor {
|
||||
|
||||
static public void construct(Node n, String fxmlFileName) {
|
||||
final String name = "nbres:/" + StringUtils.replace(n.getClass().getPackage().getName(), ".", "/") + "/" + fxmlFileName;
|
||||
final String name = "nbres:/" + StringUtils.replace(n.getClass().getPackage().getName(), ".", "/") + "/" + fxmlFileName; // NON-NLS
|
||||
System.out.println(name);
|
||||
|
||||
try {
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionReferences;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
@@ -66,14 +67,15 @@ public class OpenTimelineAction extends CallableSystemAction {
|
||||
final Case currentCase = Case.getCurrentCase();
|
||||
|
||||
if (currentCase.hasData() == false) {
|
||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), "Error creating timeline, there are no data sources.");
|
||||
LOGGER.log(Level.INFO, "Error creating timeline, there are no data sources.");
|
||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
|
||||
NbBundle.getMessage(this.getClass(), "OpenTimeLineAction.msgdlg.text"));
|
||||
LOGGER.log(Level.INFO, "Error creating timeline, there are no data sources.");// NON-NLS
|
||||
return;
|
||||
}
|
||||
synchronized (OpenTimelineAction.class) {
|
||||
if (timeLineController == null) {
|
||||
timeLineController = new TimeLineController();
|
||||
LOGGER.log(Level.WARNING, "Failed to get TimeLineController from lookup. Instantiating one directly.S");
|
||||
LOGGER.log(Level.WARNING, "Failed to get TimeLineController from lookup. Instantiating one directly.S");// NON-NLS
|
||||
}
|
||||
}
|
||||
timeLineController.openTimeLine();
|
||||
@@ -81,7 +83,7 @@ public class OpenTimelineAction extends CallableSystemAction {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Timeline";
|
||||
return NbBundle.getMessage(TimeLineTopComponent.class, "OpenTimelineAction.title");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -65,10 +65,10 @@ public class ProgressWindow extends JFrame {
|
||||
});
|
||||
|
||||
//progressBar.setIndeterminate(true);
|
||||
setName("Timeline");
|
||||
setTitle("Generating Timeline data");
|
||||
setName(NbBundle.getMessage(TimeLineTopComponent.class, "Timeline.progressWindow.name"));
|
||||
setTitle(NbBundle.getMessage(TimeLineTopComponent.class, "Timeline.progressWindow.title"));
|
||||
// Close the dialog when Esc is pressed
|
||||
String cancelName = "cancel";
|
||||
String cancelName = "cancel"; // NON-NLS
|
||||
InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||
|
||||
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName);
|
||||
@@ -179,7 +179,12 @@ public class ProgressWindow extends JFrame {
|
||||
public void cancel() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (isVisible()) {
|
||||
int showConfirmDialog = JOptionPane.showConfirmDialog(ProgressWindow.this, "Do you want to cancel time line creation?", "Cancel timeline creation?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||
int showConfirmDialog = JOptionPane.showConfirmDialog(ProgressWindow.this,
|
||||
NbBundle.getMessage(TimeLineTopComponent.class,
|
||||
"Timeline.ProgressWindow.cancel.confdlg.msg"),
|
||||
NbBundle.getMessage(TimeLineTopComponent.class,
|
||||
"Timeline.ProgressWindow.cancel.confdlg.detail"),
|
||||
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||
if (showConfirmDialog == JOptionPane.YES_OPTION) {
|
||||
close();
|
||||
}
|
||||
|
||||
@@ -98,7 +98,8 @@ public class TimeLineController {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(TimeLineController.class.getName());
|
||||
|
||||
private static final String DO_REPOPULATE_MESSAGE = "The events databse was prevously populated while ingest was running.\n" + "Some events may not have been populated or may have been populated inaccurately.\n" + "Do you want to repopulate the events database now?";
|
||||
private static final String DO_REPOPULATE_MESSAGE = NbBundle.getMessage(TimeLineController.class,
|
||||
"Timeline.do_repopulate.msg");
|
||||
|
||||
private static final ReadOnlyObjectWrapper<TimeZone> timeZone = new ReadOnlyObjectWrapper<>(TimeZone.getDefault());
|
||||
|
||||
@@ -107,7 +108,7 @@ public class TimeLineController {
|
||||
}
|
||||
|
||||
public static DateTimeFormatter getZonedFormatter() {
|
||||
return DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss").withZone(getJodaTimeZone());
|
||||
return DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss").withZone(getJodaTimeZone()); // NON-NLS
|
||||
}
|
||||
|
||||
public static DateTimeZone getJodaTimeZone() {
|
||||
@@ -253,7 +254,7 @@ public class TimeLineController {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
LOGGER.log(Level.INFO, "Beginning generation of timeline");
|
||||
LOGGER.log(Level.INFO, "Beginning generation of timeline"); // NON-NLS
|
||||
try {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (mainFrame != null) {
|
||||
@@ -286,7 +287,7 @@ public class TimeLineController {
|
||||
});
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error when generating timeline, ", ex);
|
||||
LOGGER.log(Level.SEVERE, "Error when generating timeline, ", ex); // NON-NLS
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -347,18 +348,18 @@ public class TimeLineController {
|
||||
}
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error when generating timeline, ", ex);
|
||||
LOGGER.log(Level.SEVERE, "Error when generating timeline, ", ex); // NON-NLS
|
||||
} catch (HeadlessException | MissingResourceException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Unexpected error when generating timeline, ", ex);
|
||||
LOGGER.log(Level.SEVERE, "Unexpected error when generating timeline, ", ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private long getCaseLastArtifactID(final SleuthkitCase sleuthkitCase) {
|
||||
long caseLastArtfId = -1;
|
||||
try (ResultSet runQuery = sleuthkitCase.runQuery("select Max(artifact_id) as max_id from blackboard_artifacts")) {
|
||||
try (ResultSet runQuery = sleuthkitCase.runQuery("select Max(artifact_id) as max_id from blackboard_artifacts")) { // NON-NLS
|
||||
while (runQuery.next()) {
|
||||
caseLastArtfId = runQuery.getLong("max_id");
|
||||
caseLastArtfId = runQuery.getLong("max_id"); // NON-NLS
|
||||
}
|
||||
sleuthkitCase.closeRunQuery(runQuery);
|
||||
} catch (SQLException ex) {
|
||||
@@ -403,7 +404,7 @@ public class TimeLineController {
|
||||
}
|
||||
|
||||
public void selectEventIDs(Collection<Long> events) {
|
||||
final LoggedTask<Interval> selectEventIDsTask = new LoggedTask<Interval>("Select Event IDs", true) {
|
||||
final LoggedTask<Interval> selectEventIDsTask = new LoggedTask<Interval>("Select Event IDs", true) { // NON-NLS
|
||||
@Override
|
||||
protected Interval call() throws Exception {
|
||||
return filteredEvents.getSpanningInterval(events);
|
||||
@@ -419,10 +420,10 @@ public class TimeLineController {
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(FilteredEventsModel.class
|
||||
.getName()).log(Level.SEVERE, getTitle() + " interrupted unexpectedly", ex);
|
||||
.getName()).log(Level.SEVERE, getTitle() + " interrupted unexpectedly", ex); // NON-NLS
|
||||
} catch (ExecutionException ex) {
|
||||
Logger.getLogger(FilteredEventsModel.class
|
||||
.getName()).log(Level.SEVERE, getTitle() + " unexpectedly threw " + ex.getCause(), ex);
|
||||
.getName()).log(Level.SEVERE, getTitle() + " unexpectedly threw " + ex.getCause(), ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -435,8 +436,9 @@ public class TimeLineController {
|
||||
*/
|
||||
synchronized private void showWindow() {
|
||||
if (mainFrame == null) {
|
||||
LOGGER.log(Level.WARNING, "Tried to show timeline with invalid window. Rebuilding GUI.");
|
||||
mainFrame = (TimeLineTopComponent) WindowManager.getDefault().findTopComponent("TimeLineTopComponent");
|
||||
LOGGER.log(Level.WARNING, "Tried to show timeline with invalid window. Rebuilding GUI."); // NON-NLS
|
||||
mainFrame = (TimeLineTopComponent) WindowManager.getDefault().findTopComponent(
|
||||
NbBundle.getMessage(TimeLineTopComponent.class, "CTL_TimeLineTopComponentAction"));
|
||||
if (mainFrame == null) {
|
||||
mainFrame = new TimeLineTopComponent();
|
||||
}
|
||||
@@ -476,9 +478,12 @@ public class TimeLineController {
|
||||
if (newLOD == DescriptionLOD.FULL && count > 10_000) {
|
||||
|
||||
int showConfirmDialog = JOptionPane.showConfirmDialog(mainFrame,
|
||||
"You are about to show details for " + NumberFormat.getInstance().format(count) + " events. This might be very slow or even crash Autopsy.\n\nDo you want to continue?",
|
||||
"",
|
||||
JOptionPane.YES_NO_OPTION);
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"Timeline.pushDescrLOD.confdlg.msg",
|
||||
NumberFormat.getInstance().format(count)),
|
||||
NbBundle.getMessage(TimeLineTopComponent.class,
|
||||
"Timeline.pushDescrLOD.confdlg.details"),
|
||||
JOptionPane.YES_NO_OPTION);
|
||||
|
||||
shouldContinue = (showConfirmDialog == JOptionPane.YES_OPTION);
|
||||
}
|
||||
@@ -533,7 +538,7 @@ public class TimeLineController {
|
||||
public void selectTimeAndType(Interval interval, EventType type) {
|
||||
final Interval timeRange = filteredEvents.getSpanningInterval().overlap(interval);
|
||||
|
||||
final LoggedTask<Collection<Long>> selectTimeAndTypeTask = new LoggedTask<Collection<Long>>("Select Time and Type", true) {
|
||||
final LoggedTask<Collection<Long>> selectTimeAndTypeTask = new LoggedTask<Collection<Long>>("Select Time and Type", true) { // NON-NLS
|
||||
@Override
|
||||
protected Collection< Long> call() throws Exception {
|
||||
synchronized (TimeLineController.this) {
|
||||
@@ -551,10 +556,10 @@ public class TimeLineController {
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(FilteredEventsModel.class
|
||||
.getName()).log(Level.SEVERE, getTitle() + " interrupted unexpectedly", ex);
|
||||
.getName()).log(Level.SEVERE, getTitle() + " interrupted unexpectedly", ex);// NON-NLS
|
||||
} catch (ExecutionException ex) {
|
||||
Logger.getLogger(FilteredEventsModel.class
|
||||
.getName()).log(Level.SEVERE, getTitle() + " unexpectedly threw " + ex.getCause(), ex);
|
||||
.getName()).log(Level.SEVERE, getTitle() + " unexpectedly threw " + ex.getCause(), ex);// NON-NLS
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -625,7 +630,8 @@ public class TimeLineController {
|
||||
synchronized int showLastPopulatedWhileIngestingConfirmation() {
|
||||
return JOptionPane.showConfirmDialog(mainFrame,
|
||||
DO_REPOPULATE_MESSAGE,
|
||||
"re populate events?",
|
||||
NbBundle.getMessage(TimeLineTopComponent.class,
|
||||
"Timeline.showLastPopulatedWhileIngestingConf.confDlg.details"),
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE);
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ import javafx.scene.layout.VBox;
|
||||
import org.netbeans.api.settings.ConvertAsProperties;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.explorer.ExplorerUtils;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.windows.Mode;
|
||||
import org.openide.windows.TopComponent;
|
||||
import static org.openide.windows.TopComponent.PROP_UNDOCKING_DISABLED;
|
||||
@@ -66,11 +66,6 @@ import org.sleuthkit.autopsy.timeline.zooming.ZoomSettingsPane;
|
||||
//iconBase="SET/PATH/TO/ICON/HERE",
|
||||
persistenceType = TopComponent.PERSISTENCE_NEVER)
|
||||
@TopComponent.Registration(mode = "timeline", openAtStartup = false)
|
||||
@Messages({
|
||||
"CTL_TimeLineTopComponentAction=TimeLineTopComponent",
|
||||
"CTL_TimeLineTopComponent=Timeline Window",
|
||||
"HINT_TimeLineTopComponent=This is a Timeline window"
|
||||
})
|
||||
public final class TimeLineTopComponent extends TopComponent implements ExplorerManager.Provider, TimeLineUI {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(TimeLineTopComponent.class.getName());
|
||||
@@ -86,9 +81,11 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
////jfx componenets that make up the interface
|
||||
private final FilterSetPanel filtersPanel = new FilterSetPanel();
|
||||
|
||||
private final Tab eventsTab = new Tab("Events");
|
||||
private final Tab eventsTab = new Tab(
|
||||
NbBundle.getMessage(TimeLineTopComponent.class, "TimeLineTopComponent.eventsTab.name"));
|
||||
|
||||
private final Tab filterTab = new Tab("Filters");
|
||||
private final Tab filterTab = new Tab(
|
||||
NbBundle.getMessage(TimeLineTopComponent.class, "TimeLineTopComponent.filterTab.name"));
|
||||
|
||||
private final VBox leftVBox = new VBox(5);
|
||||
|
||||
@@ -111,10 +108,11 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
|
||||
associateLookup(ExplorerUtils.createLookup(em, getActionMap()));
|
||||
|
||||
setName(Bundle.CTL_TimeLineTopComponent());
|
||||
setToolTipText(Bundle.HINT_TimeLineTopComponent());
|
||||
setName(NbBundle.getMessage(TimeLineTopComponent.class, "CTL_TimeLineTopComponent"));
|
||||
setToolTipText(NbBundle.getMessage(TimeLineTopComponent.class, "HINT_TimeLineTopComponent"));
|
||||
setIcon(WindowManager.getDefault().getMainWindow().getIconImage()); //use the same icon as main application
|
||||
|
||||
timeZonePanel.setText(NbBundle.getMessage(this.getClass(), "TimeLineTopComponent.timeZonePanel.text"));
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
@@ -136,11 +134,11 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
|
||||
filterTab.setClosable(false);
|
||||
filterTab.setContent(filtersPanel);
|
||||
filterTab.setGraphic(new ImageView("org/sleuthkit/autopsy/timeline/images/funnel.png"));
|
||||
filterTab.setGraphic(new ImageView("org/sleuthkit/autopsy/timeline/images/funnel.png")); // NON-NLS
|
||||
|
||||
eventsTab.setClosable(false);
|
||||
eventsTab.setContent(navPanel);
|
||||
eventsTab.setGraphic(new ImageView("org/sleuthkit/autopsy/timeline/images/timeline_marker.png"));
|
||||
eventsTab.setGraphic(new ImageView("org/sleuthkit/autopsy/timeline/images/timeline_marker.png")); // NON-NLS
|
||||
|
||||
tabPane.getTabs().addAll(filterTab, eventsTab);
|
||||
VBox.setVgrow(tabPane, Priority.ALWAYS);
|
||||
|
||||
@@ -24,6 +24,7 @@ import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyCodeCombination;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
|
||||
/**
|
||||
@@ -32,12 +33,12 @@ 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 Action {
|
||||
|
||||
private static final Image BACK_IMAGE = new Image("/org/sleuthkit/autopsy/timeline/images/arrow-180.png", 16, 16, true, true, true);
|
||||
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;
|
||||
|
||||
public Back(TimeLineController controller) {
|
||||
super("Back");
|
||||
super(NbBundle.getMessage(Back.class, "Back.actions.name.text"));
|
||||
setGraphic(new ImageView(BACK_IMAGE));
|
||||
setAccelerator(new KeyCodeCombination(KeyCode.LEFT, KeyCodeCombination.ALT_DOWN));
|
||||
this.controller = controller;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Back.actions.name.text=Back
|
||||
DefaultFilters.action.name.text=apply default filters
|
||||
Forward.action.name.text=Forward
|
||||
SaveSnapshot.action.name.text=save snapshot
|
||||
SaveSnapshot.fileChoose.title.text=Save snapshot to
|
||||
ZoomOut.action.name.text=apply default filters
|
||||
@@ -0,0 +1,6 @@
|
||||
Back.actions.name.text=\u623B\u308B
|
||||
DefaultFilters.action.name.text=\u30C7\u30D5\u30A9\u30EB\u30C8\u30D5\u30A3\u30EB\u30BF\u3092\u9069\u7528
|
||||
Forward.action.name.text=\u9032\u3080
|
||||
SaveSnapshot.action.name.text=\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u3092\u4FDD\u5B58
|
||||
SaveSnapshot.fileChoose.title.text=\u4E0B\u8A18\u3078\u4FDD\u5B58
|
||||
ZoomOut.action.name.text=\u30C7\u30D5\u30A9\u30EB\u30C8\u30D5\u30A3\u30EB\u30BF\u3092\u9069\u7528
|
||||
@@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.timeline.actions;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.event.ActionEvent;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.events.FilteredEventsModel;
|
||||
import org.sleuthkit.autopsy.timeline.filters.Filter;
|
||||
@@ -35,7 +36,7 @@ public class DefaultFilters extends Action {
|
||||
private FilteredEventsModel eventsModel;
|
||||
|
||||
public DefaultFilters(final TimeLineController controller) {
|
||||
super("apply default filters");
|
||||
super(NbBundle.getMessage(DefaultFilters.class, "DefaultFilters.action.name.text"));
|
||||
this.controller = controller;
|
||||
eventsModel = controller.getEventsModel();
|
||||
disabledProperty().bind(new BooleanBinding() {
|
||||
|
||||
@@ -24,6 +24,7 @@ import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyCodeCombination;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
|
||||
/**
|
||||
@@ -32,12 +33,12 @@ 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 Action {
|
||||
|
||||
private static final Image BACK_IMAGE = new Image("/org/sleuthkit/autopsy/timeline/images/arrow.png", 16, 16, true, true, true);
|
||||
private static final Image BACK_IMAGE = new Image("/org/sleuthkit/autopsy/timeline/images/arrow.png", 16, 16, true, true, true); // NON-NLS
|
||||
|
||||
private final TimeLineController controller;
|
||||
|
||||
public Forward(TimeLineController controller) {
|
||||
super("Forward");
|
||||
super(NbBundle.getMessage(Forward.class, "Forward.action.name.text"));
|
||||
setGraphic(new ImageView(BACK_IMAGE));
|
||||
setAccelerator(new KeyCodeCombination(KeyCode.RIGHT, KeyCodeCombination.ALT_DOWN));
|
||||
this.controller = controller;
|
||||
|
||||
@@ -37,6 +37,7 @@ import javafx.stage.DirectoryChooser;
|
||||
import javafx.util.Pair;
|
||||
import javax.imageio.ImageIO;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
@@ -58,7 +59,7 @@ public class SaveSnapshot extends Action {
|
||||
private final WritableImage snapshot;
|
||||
|
||||
public SaveSnapshot(TimeLineController controller, WritableImage snapshot) {
|
||||
super("save snapshot");
|
||||
super(NbBundle.getMessage(SaveSnapshot.class, "SaveSnapshot.action.name.text"));
|
||||
this.controller = controller;
|
||||
this.snapshot = snapshot;
|
||||
setEventHandler(new Consumer<ActionEvent>() {
|
||||
@@ -67,8 +68,8 @@ public class SaveSnapshot extends Action {
|
||||
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"));
|
||||
fileChooser.setTitle(NbBundle.getMessage(this.getClass(), "SaveSnapshot.fileChoose.title.text"));
|
||||
fileChooser.setInitialDirectory(new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Reports")); // NON-NLS
|
||||
File outFolder = fileChooser.showDialog(null);
|
||||
if (outFolder == null) {
|
||||
return;
|
||||
@@ -79,57 +80,57 @@ public class SaveSnapshot extends Action {
|
||||
//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())); // NON-NLS
|
||||
|
||||
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()));
|
||||
reportMetaData.add(new Pair<>("Time Range", get.getTimeRange().toString())); // NON-NLS
|
||||
reportMetaData.add(new Pair<>("Description Level of Detail", get.getDescrLOD().getDisplayName())); // NON-NLS
|
||||
reportMetaData.add(new Pair<>("Event Type Zoom Level", get.getTypeZoomLevel().getDisplayName())); // NON-NLS
|
||||
reportMetaData.add(new Pair<>("Filters", get.getFilter().getHTMLReportString())); // NON-NLS
|
||||
|
||||
//save snapshot as png
|
||||
try {
|
||||
ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "png", new File(outFolder.getPath() + File.separator + outFolder.getName() + REPORT_IMAGE_EXTENSION));
|
||||
ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "png", new File(outFolder.getPath() + File.separator + outFolder.getName() + REPORT_IMAGE_EXTENSION)); // NON-NLS
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to write snapshot to disk", ex);
|
||||
LOGGER.log(Level.WARNING, "failed to write snapshot to disk", ex); // NON-NLS
|
||||
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");
|
||||
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"); // NON-NLS
|
||||
wrapper.append("<div id=\"content\">\n<h1>").append(outFolder.getName()).append("</h1>\n"); // NON-NLS
|
||||
wrapper.append("<img src = \"").append(outFolder.getName()).append(REPORT_IMAGE_EXTENSION + "\" alt = \"snaphot\">"); // NON-NLS
|
||||
wrapper.append("<table>\n"); // NON-NLS
|
||||
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("<tr><td>").append(pair.getKey()).append(": </td><td>").append(pair.getValue()).append("</td></tr>\n"); // NON-NLS
|
||||
}
|
||||
wrapper.append("</table>\n");
|
||||
wrapper.append("</div>\n</body>\n</html>");
|
||||
wrapper.append("</table>\n"); // NON-NLS
|
||||
wrapper.append("</div>\n</body>\n</html>"); // NON-NLS
|
||||
|
||||
//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);
|
||||
LOGGER.log(Level.WARNING, "failed to open html wrapper file for writing ", ex); // NON-NLS
|
||||
return;
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to write html wrapper file", ex);
|
||||
LOGGER.log(Level.WARNING, "failed to write html wrapper file", ex); // NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
//copy css
|
||||
try (InputStream resource = this.getClass().getResourceAsStream("/org/sleuthkit/autopsy/timeline/index.css")) {
|
||||
Files.copy(resource, Paths.get(outFolder.getPath(), "index.css"));
|
||||
try (InputStream resource = this.getClass().getResourceAsStream("/org/sleuthkit/autopsy/timeline/index.css")) { // NON-NLS
|
||||
Files.copy(resource, Paths.get(outFolder.getPath(), "index.css")); // NON-NLS
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed to copy css file", ex);
|
||||
LOGGER.log(Level.WARNING, "failed to copy css file", ex); // NON-NLS
|
||||
}
|
||||
|
||||
//add html file as report to case
|
||||
try {
|
||||
Case.getCurrentCase().addReport(outFolder.getPath() + File.separator + outFolder.getName() + HTML_EXT, "Timeline", outFolder.getName() + HTML_EXT);
|
||||
Case.getCurrentCase().addReport(outFolder.getPath() + File.separator + outFolder.getName() + HTML_EXT, "Timeline", outFolder.getName() + HTML_EXT); // NON-NLS
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.WARNING, "failed add html wrapper as a report", ex);
|
||||
LOGGER.log(Level.WARNING, "failed add html wrapper as a report", ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.timeline.actions;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.event.ActionEvent;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.events.FilteredEventsModel;
|
||||
|
||||
@@ -34,7 +35,7 @@ public class ZoomOut extends Action {
|
||||
private final FilteredEventsModel eventsModel;
|
||||
|
||||
public ZoomOut(final TimeLineController controller) {
|
||||
super("apply default filters");
|
||||
super(NbBundle.getMessage(ZoomOut.class, "ZoomOut.action.name.text"));
|
||||
this.controller = controller;
|
||||
eventsModel = controller.getEventsModel();
|
||||
disabledProperty().bind(new BooleanBinding() {
|
||||
|
||||
@@ -95,11 +95,11 @@ public class AggregateEvent {
|
||||
public static AggregateEvent merge(AggregateEvent ag1, AggregateEvent ag2) {
|
||||
|
||||
if (ag1.getType() != ag2.getType()) {
|
||||
throw new IllegalArgumentException(NbBundle.getMessage(AggregateEvent.class, "AggregateEvent.differentTypes"));
|
||||
throw new IllegalArgumentException("aggregate events are not compatible they have different types");
|
||||
}
|
||||
|
||||
if (!ag1.getDescription().equals(ag2.getDescription())) {
|
||||
throw new IllegalArgumentException(NbBundle.getMessage(AggregateEvent.class, "AggregateEvent.differentDescriptions"));
|
||||
throw new IllegalArgumentException("aggregate events are not compatible they have different descriptions");
|
||||
}
|
||||
HashSet<Long> ids = new HashSet<>(ag1.getEventIDs());
|
||||
ids.addAll(ag2.getEventIDs());
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
EventsRepository.progressWindow.msg.reinit_db=(re)initializing events database
|
||||
EventsRepository.progressWindow.msg.populateMacEventsFiles=populating mac events for files\:
|
||||
EventsRepository.progressWindow.msg.populateMacEventsFiles2=populating mac events for files\:
|
||||
EventsRepository.progressWindow.msg.commitingDb=committing events db
|
||||
EventsRepository.msgdlg.problem.text=There was a problem populating the timeline. Not all events may be present or accurate. See the log for details.
|
||||
EventsRepository.progressWindow.populatingXevents=populating {0} events
|
||||
@@ -0,0 +1,6 @@
|
||||
EventsRepository.msgdlg.problem.text=\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u4F5C\u6210\u4E2D\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u6B20\u843D\u3057\u3066\u3044\u308B\u307E\u305F\u306F\u4E0D\u6B63\u78BA\u306A\u30A4\u30D9\u30F3\u30C8\u304C\u3042\u308B\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002\u8A73\u7D30\u306F\u30ED\u30B0\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
||||
EventsRepository.progressWindow.msg.commitingDb=\u30A4\u30D9\u30F3\u30C8DB\u3092\u30B3\u30DF\u30C3\u30C8\u4E2D
|
||||
EventsRepository.progressWindow.msg.reinit_db=\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\uFF08\u518D\uFF09\u521D\u671F\u5316\u4E2D
|
||||
EventsRepository.progressWindow.msg.populateMacEventsFiles=\u4E0B\u8A18\u30D5\u30A1\u30A4\u30EB\u306EMAC time\u30A4\u30D9\u30F3\u30C8\u3092\u5165\u529B\u4E2D\uFF1A
|
||||
EventsRepository.progressWindow.msg.populateMacEventsFiles2=\u4E0B\u8A18\u30D5\u30A1\u30A4\u30EB\u306EMAC time\u30A4\u30D9\u30F3\u30C8\u3092\u5165\u529B\u4E2D\uFF1A
|
||||
EventsRepository.progressWindow.populatingXevents={0} \u30A4\u30D9\u30F3\u30C8\u3092\u5165\u529B\u4E2D
|
||||
@@ -79,41 +79,41 @@ import org.sqlite.SQLiteJDBCLoader;
|
||||
*/
|
||||
public class EventDB {
|
||||
|
||||
private static final String ARTIFACT_ID_COLUMN = "artifact_id";
|
||||
private static final String ARTIFACT_ID_COLUMN = "artifact_id"; // NON-NLS
|
||||
|
||||
private static final String BASE_TYPE_COLUMN = "base_type";
|
||||
private static final String BASE_TYPE_COLUMN = "base_type"; // NON-NLS
|
||||
|
||||
private static final String EVENT_ID_COLUMN = "event_id";
|
||||
private static final String EVENT_ID_COLUMN = "event_id"; // NON-NLS
|
||||
|
||||
//column name constants//////////////////////
|
||||
private static final String FILE_ID_COLUMN = "file_id";
|
||||
private static final String FILE_ID_COLUMN = "file_id"; // NON-NLS
|
||||
|
||||
private static final String FULL_DESCRIPTION_COLUMN = "full_description";
|
||||
private static final String FULL_DESCRIPTION_COLUMN = "full_description"; // NON-NLS
|
||||
|
||||
private static final String KNOWN_COLUMN = "known_state";
|
||||
private static final String KNOWN_COLUMN = "known_state"; // NON-NLS
|
||||
|
||||
private static final String LAST_ARTIFACT_ID_KEY = "last_artifact_id";
|
||||
private static final String LAST_ARTIFACT_ID_KEY = "last_artifact_id"; // NON-NLS
|
||||
|
||||
private static final String LAST_OBJECT_ID_KEY = "last_object_id";
|
||||
private static final String LAST_OBJECT_ID_KEY = "last_object_id"; // NON-NLS
|
||||
|
||||
private static final java.util.logging.Logger LOGGER = Logger.getLogger(EventDB.class.getName());
|
||||
|
||||
private static final String MED_DESCRIPTION_COLUMN = "med_description";
|
||||
private static final String MED_DESCRIPTION_COLUMN = "med_description"; // NON-NLS
|
||||
|
||||
private static final String SHORT_DESCRIPTION_COLUMN = "short_description";
|
||||
private static final String SHORT_DESCRIPTION_COLUMN = "short_description"; // NON-NLS
|
||||
|
||||
private static final String SUB_TYPE_COLUMN = "sub_type";
|
||||
private static final String SUB_TYPE_COLUMN = "sub_type"; // NON-NLS
|
||||
|
||||
private static final String TIME_COLUMN = "time";
|
||||
private static final String TIME_COLUMN = "time"; // NON-NLS
|
||||
|
||||
private static final String WAS_INGEST_RUNNING_KEY = "was_ingest_running";
|
||||
private static final String WAS_INGEST_RUNNING_KEY = "was_ingest_running"; // NON-NLS
|
||||
|
||||
static {
|
||||
//make sure sqlite driver is loaded // possibly redundant
|
||||
try {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
Class.forName("org.sqlite.JDBC"); // NON-NLS
|
||||
} catch (ClassNotFoundException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to load sqlite JDBC driver", ex);
|
||||
LOGGER.log(Level.SEVERE, "Failed to load sqlite JDBC driver", ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,14 +128,14 @@ public class EventDB {
|
||||
*/
|
||||
public static EventDB getEventDB(String dbPath) {
|
||||
try {
|
||||
EventDB eventDB = new EventDB(dbPath + File.separator + "events.db");
|
||||
EventDB eventDB = new EventDB(dbPath + File.separator + "events.db"); // NON-NLS
|
||||
|
||||
return eventDB;
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "sql error creating database connection", ex);
|
||||
LOGGER.log(Level.SEVERE, "sql error creating database connection", ex); // NON-NLS
|
||||
return null;
|
||||
} catch (Exception ex) {
|
||||
LOGGER.log(Level.SEVERE, "error creating database connection", ex);
|
||||
LOGGER.log(Level.SEVERE, "error creating database connection", ex); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -156,14 +156,14 @@ public class EventDB {
|
||||
return filter.getSubFilters().stream()
|
||||
.filter(Filter::isActive)
|
||||
.map(EventDB::getSQLWhere)
|
||||
.collect(Collectors.joining(" and ", "( ", ")"));
|
||||
.collect(Collectors.joining(" and ", "( ", ")")); // NON-NLS
|
||||
}
|
||||
|
||||
static String getSQLWhere(UnionFilter filter) {
|
||||
return filter.getSubFilters().stream()
|
||||
.filter(Filter::isActive)
|
||||
.map(EventDB::getSQLWhere)
|
||||
.collect(Collectors.joining(" or ", "( ", ")"));
|
||||
.collect(Collectors.joining(" or ", "( ", ")")); // NON-NLS
|
||||
}
|
||||
|
||||
private static String getSQLWhere(Filter filter) {
|
||||
@@ -185,14 +185,14 @@ public class EventDB {
|
||||
} else {
|
||||
return "1";
|
||||
}
|
||||
result = StringUtils.deleteWhitespace(result).equals("(1and1and1)") ? "1" : result;
|
||||
result = StringUtils.deleteWhitespace(result).equals("(1and1and1)") ? "1" : result; // NON-NLS
|
||||
//System.out.println(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String getSQLWhere(HideKnownFilter filter) {
|
||||
return (filter.isActive())
|
||||
? "(known_state is not '" + TskData.FileKnown.KNOWN.getFileKnownValue() + "')"
|
||||
? "(known_state is not '" + TskData.FileKnown.KNOWN.getFileKnownValue() + "')" // NON-NLS
|
||||
: "1";
|
||||
}
|
||||
|
||||
@@ -202,9 +202,9 @@ public class EventDB {
|
||||
return "1";
|
||||
}
|
||||
String strip = StringUtils.strip(filter.getText());
|
||||
return "((" + MED_DESCRIPTION_COLUMN + " like '%" + strip + "%') or ("
|
||||
+ FULL_DESCRIPTION_COLUMN + " like '%" + strip + "%') or ("
|
||||
+ SHORT_DESCRIPTION_COLUMN + " like '%" + strip + "%'))";
|
||||
return "((" + MED_DESCRIPTION_COLUMN + " like '%" + strip + "%') or (" // NON-NLS
|
||||
+ FULL_DESCRIPTION_COLUMN + " like '%" + strip + "%') or (" // NON-NLS
|
||||
+ SHORT_DESCRIPTION_COLUMN + " like '%" + strip + "%'))"; // NON-NLS
|
||||
} else {
|
||||
return "1";
|
||||
}
|
||||
@@ -228,7 +228,7 @@ public class EventDB {
|
||||
return "1"; //then collapse clause to true
|
||||
}
|
||||
}
|
||||
return "(" + SUB_TYPE_COLUMN + " in (" + StringUtils.join(getActiveSubTypes(filter), ",") + "))";
|
||||
return "(" + SUB_TYPE_COLUMN + " in (" + StringUtils.join(getActiveSubTypes(filter), ",") + "))"; // NON-NLS
|
||||
}
|
||||
|
||||
private volatile Connection con;
|
||||
@@ -274,13 +274,13 @@ public class EventDB {
|
||||
try (Statement stmt = con.createStatement();
|
||||
//You can't inject multiple values into one ? paramater in prepared statement,
|
||||
//so we make new statement each time...
|
||||
ResultSet rs = stmt.executeQuery("select Min(time), Max(time) from events where event_id in (" + StringUtils.join(eventIDs, ", ") + ")");) {
|
||||
ResultSet rs = stmt.executeQuery("select Min(time), Max(time) from events where event_id in (" + StringUtils.join(eventIDs, ", ") + ")");) { // NON-NLS
|
||||
while (rs.next()) {
|
||||
span = new Interval(rs.getLong("Min(time)"), rs.getLong("Max(time)") + 1, DateTimeZone.UTC);
|
||||
span = new Interval(rs.getLong("Min(time)"), rs.getLong("Max(time)") + 1, DateTimeZone.UTC); // NON-NLS
|
||||
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error executing get spanning interval query.", ex);
|
||||
LOGGER.log(Level.SEVERE, "Error executing get spanning interval query.", ex); // NON-NLS
|
||||
} finally {
|
||||
dbReadUnlock();
|
||||
}
|
||||
@@ -297,7 +297,7 @@ public class EventDB {
|
||||
closeStatements();
|
||||
con.close();
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.WARNING, "Failed to close connection to evetns.db", ex);
|
||||
LOGGER.log(Level.WARNING, "Failed to close connection to evetns.db", ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
con = null;
|
||||
@@ -305,7 +305,7 @@ public class EventDB {
|
||||
|
||||
void commitTransaction(EventTransaction tr, Boolean notify) {
|
||||
if (tr.isClosed()) {
|
||||
throw new IllegalArgumentException("can't close already closed transaction");
|
||||
throw new IllegalArgumentException("can't close already closed transaction"); // NON-NLS
|
||||
}
|
||||
tr.commit(notify);
|
||||
}
|
||||
@@ -314,9 +314,9 @@ public class EventDB {
|
||||
int result = -1;
|
||||
dbReadLock();
|
||||
//TODO convert this to prepared statement -jm
|
||||
try (ResultSet rs = con.createStatement().executeQuery("select count(*) as count from events")) {
|
||||
try (ResultSet rs = con.createStatement().executeQuery("select count(*) as count from events")) { // NON-NLS
|
||||
while (rs.next()) {
|
||||
result = rs.getInt("count");
|
||||
result = rs.getInt("count"); // NON-NLS
|
||||
break;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@@ -374,9 +374,9 @@ public class EventDB {
|
||||
//TODO: use prepared statement - jm
|
||||
dbWriteLock();
|
||||
try (Statement createStatement = con.createStatement()) {
|
||||
createStatement.execute("drop table if exists events");
|
||||
createStatement.execute("drop table if exists events"); // NON-NLS
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "could not drop old events table", ex);
|
||||
LOGGER.log(Level.SEVERE, "could not drop old events table", ex); // NON-NLS
|
||||
} finally {
|
||||
dbWriteUnlock();
|
||||
}
|
||||
@@ -393,11 +393,11 @@ public class EventDB {
|
||||
|
||||
dbReadLock();
|
||||
try (Statement stmt = con.createStatement(); //can't use prepared statement because of complex where clause
|
||||
ResultSet rs = stmt.executeQuery(" select (select Max(time) from events where time <=" + start + " and " + sqlWhere + ") as start,(select Min(time) from events where time >= " + end + " and " + sqlWhere + ") as end")) {
|
||||
ResultSet rs = stmt.executeQuery(" select (select Max(time) from events where time <=" + start + " and " + sqlWhere + ") as start,(select Min(time) from events where time >= " + end + " and " + sqlWhere + ") as end")) { // NON-NLS
|
||||
while (rs.next()) {
|
||||
|
||||
long start2 = rs.getLong("start");
|
||||
long end2 = rs.getLong("end");
|
||||
long start2 = rs.getLong("start"); // NON-NLS
|
||||
long end2 = rs.getLong("end"); // NON-NLS
|
||||
|
||||
if (end2 == 0) {
|
||||
end2 = getMaxTime();
|
||||
@@ -406,7 +406,7 @@ public class EventDB {
|
||||
return new Interval(start2 * 1000, (end2 + 1) * 1000, TimeLineController.getJodaTimeZone());
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to get MIN time.", ex);
|
||||
LOGGER.log(Level.SEVERE, "Failed to get MIN time.", ex); // NON-NLS
|
||||
} finally {
|
||||
dbReadUnlock();
|
||||
}
|
||||
@@ -426,7 +426,7 @@ public class EventDB {
|
||||
}
|
||||
}
|
||||
} catch (SQLException sqlEx) {
|
||||
LOGGER.log(Level.SEVERE, "exception while querying for event with id = " + eventID, sqlEx);
|
||||
LOGGER.log(Level.SEVERE, "exception while querying for event with id = " + eventID, sqlEx); // NON-NLS
|
||||
} finally {
|
||||
dbReadUnlock();
|
||||
}
|
||||
@@ -444,7 +444,7 @@ public class EventDB {
|
||||
Set<Long> resultIDs = new HashSet<>();
|
||||
|
||||
dbReadLock();
|
||||
final String query = "select event_id from events where time >= " + startTime + " and time <" + endTime + " and " + getSQLWhere(filter);
|
||||
final String query = "select event_id from events where time >= " + startTime + " and time <" + endTime + " and " + getSQLWhere(filter); // NON-NLS
|
||||
//System.out.println(query);
|
||||
try (Statement stmt = con.createStatement();
|
||||
ResultSet rs = stmt.executeQuery(query)) {
|
||||
@@ -454,7 +454,7 @@ public class EventDB {
|
||||
}
|
||||
|
||||
} catch (SQLException sqlEx) {
|
||||
LOGGER.log(Level.SEVERE, "failed to execute query for event ids in range", sqlEx);
|
||||
LOGGER.log(Level.SEVERE, "failed to execute query for event ids in range", sqlEx); // NON-NLS
|
||||
} finally {
|
||||
dbReadUnlock();
|
||||
}
|
||||
@@ -475,10 +475,10 @@ public class EventDB {
|
||||
dbReadLock();
|
||||
try (ResultSet rs = getMaxTimeStmt.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
return rs.getLong("max");
|
||||
return rs.getLong("max"); // NON-NLS
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to get MAX time.", ex);
|
||||
LOGGER.log(Level.SEVERE, "Failed to get MAX time.", ex); // NON-NLS
|
||||
} finally {
|
||||
dbReadUnlock();
|
||||
}
|
||||
@@ -490,10 +490,10 @@ public class EventDB {
|
||||
dbReadLock();
|
||||
try (ResultSet rs = getMinTimeStmt.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
return rs.getLong("min");
|
||||
return rs.getLong("min"); // NON-NLS
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to get MIN time.", ex);
|
||||
LOGGER.log(Level.SEVERE, "Failed to get MIN time.", ex); // NON-NLS
|
||||
} finally {
|
||||
dbReadUnlock();
|
||||
}
|
||||
@@ -519,49 +519,49 @@ public class EventDB {
|
||||
configureDB();
|
||||
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "problem accessing database", ex);
|
||||
LOGGER.log(Level.SEVERE, "problem accessing database", ex); // NON-NLS
|
||||
}
|
||||
|
||||
dbWriteLock();
|
||||
try {
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
String sql = "CREATE TABLE if not exists db_info "
|
||||
+ " ( key TEXT, "
|
||||
+ " value INTEGER, "
|
||||
+ "PRIMARY KEY (key))";
|
||||
String sql = "CREATE TABLE if not exists db_info " // NON-NLS
|
||||
+ " ( key TEXT, " // NON-NLS
|
||||
+ " value INTEGER, " // NON-NLS
|
||||
+ "PRIMARY KEY (key))"; // NON-NLS
|
||||
stmt.execute(sql);
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "problem creating db_info table", ex);
|
||||
LOGGER.log(Level.SEVERE, "problem creating db_info table", ex); // NON-NLS
|
||||
}
|
||||
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
String sql = "CREATE TABLE if not exists events "
|
||||
+ " (event_id INTEGER PRIMARY KEY, "
|
||||
+ " file_id INTEGER, "
|
||||
+ " artifact_id INTEGER, "
|
||||
+ " time INTEGER, "
|
||||
+ " sub_type INTEGER, "
|
||||
+ " base_type INTEGER, "
|
||||
+ " full_description TEXT, "
|
||||
+ " med_description TEXT, "
|
||||
+ " short_description TEXT, "
|
||||
+ " known_state INTEGER)";
|
||||
String sql = "CREATE TABLE if not exists events " // NON-NLS
|
||||
+ " (event_id INTEGER PRIMARY KEY, " // NON-NLS
|
||||
+ " file_id INTEGER, " // NON-NLS
|
||||
+ " artifact_id INTEGER, " // NON-NLS
|
||||
+ " time INTEGER, " // NON-NLS
|
||||
+ " sub_type INTEGER, " // NON-NLS
|
||||
+ " base_type INTEGER, " // NON-NLS
|
||||
+ " full_description TEXT, " // NON-NLS
|
||||
+ " med_description TEXT, " // NON-NLS
|
||||
+ " short_description TEXT, " // NON-NLS
|
||||
+ " known_state INTEGER)"; // NON-NLS
|
||||
stmt.execute(sql);
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "problem creating database table", ex);
|
||||
LOGGER.log(Level.SEVERE, "problem creating database table", ex); // NON-NLS
|
||||
}
|
||||
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
String sql = "CREATE INDEX if not exists file_idx ON events(file_id)";
|
||||
String sql = "CREATE INDEX if not exists file_idx ON events(file_id)"; // NON-NLS
|
||||
stmt.execute(sql);
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "problem creating file_idx", ex);
|
||||
LOGGER.log(Level.SEVERE, "problem creating file_idx", ex); // NON-NLS
|
||||
}
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
String sql = "CREATE INDEX if not exists artifact_idx ON events(artifact_id)";
|
||||
String sql = "CREATE INDEX if not exists artifact_idx ON events(artifact_id)"; // NON-NLS
|
||||
stmt.execute(sql);
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "problem creating artifact_idx", ex);
|
||||
LOGGER.log(Level.SEVERE, "problem creating artifact_idx", ex); // NON-NLS
|
||||
}
|
||||
|
||||
//for common queries the covering indexes below were better, but having the time index 'blocke' them
|
||||
@@ -572,38 +572,38 @@ public class EventDB {
|
||||
// LOGGER.log(Level.SEVERE, "problem creating time_idx", ex);
|
||||
// }
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
String sql = "CREATE INDEX if not exists sub_type_idx ON events(sub_type, time)";
|
||||
String sql = "CREATE INDEX if not exists sub_type_idx ON events(sub_type, time)"; // NON-NLS
|
||||
stmt.execute(sql);
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "problem creating sub_type_idx", ex);
|
||||
LOGGER.log(Level.SEVERE, "problem creating sub_type_idx", ex); // NON-NLS
|
||||
}
|
||||
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
String sql = "CREATE INDEX if not exists base_type_idx ON events(base_type, time)";
|
||||
String sql = "CREATE INDEX if not exists base_type_idx ON events(base_type, time)"; // NON-NLS
|
||||
stmt.execute(sql);
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "problem creating base_type_idx", ex);
|
||||
LOGGER.log(Level.SEVERE, "problem creating base_type_idx", ex); // NON-NLS
|
||||
}
|
||||
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
String sql = "CREATE INDEX if not exists known_idx ON events(known_state)";
|
||||
String sql = "CREATE INDEX if not exists known_idx ON events(known_state)"; // NON-NLS
|
||||
stmt.execute(sql);
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "problem creating known_idx", ex);
|
||||
LOGGER.log(Level.SEVERE, "problem creating known_idx", ex); // NON-NLS
|
||||
}
|
||||
|
||||
try {
|
||||
insertRowStmt = prepareStatement(
|
||||
"INSERT INTO events (file_id ,artifact_id, time, sub_type, base_type, full_description, med_description, short_description, known_state) "
|
||||
+ "VALUES (?,?,?,?,?,?,?,?,?)");
|
||||
"INSERT INTO events (file_id ,artifact_id, time, sub_type, base_type, full_description, med_description, short_description, known_state) " // NON-NLS
|
||||
+ "VALUES (?,?,?,?,?,?,?,?,?)"); // NON-NLS
|
||||
|
||||
getMaxTimeStmt = prepareStatement("select Max(time) as max from events");
|
||||
getMinTimeStmt = prepareStatement("select Min(time) as min from events");
|
||||
getEventByIDStmt = prepareStatement("select * from events where event_id = ?");
|
||||
recordDBInfoStmt = prepareStatement("insert or replace into db_info (key, value) values (?, ?)");
|
||||
getDBInfoStmt = prepareStatement("select value from db_info where key = ?");
|
||||
getMaxTimeStmt = prepareStatement("select Max(time) as max from events"); // NON-NLS
|
||||
getMinTimeStmt = prepareStatement("select Min(time) as min from events"); // NON-NLS
|
||||
getEventByIDStmt = prepareStatement("select * from events where event_id = ?"); // NON-NLS
|
||||
recordDBInfoStmt = prepareStatement("insert or replace into db_info (key, value) values (?, ?)"); // NON-NLS
|
||||
getDBInfoStmt = prepareStatement("select value from db_info where key = ?"); // NON-NLS
|
||||
} catch (SQLException sQLException) {
|
||||
LOGGER.log(Level.SEVERE, "failed to prepareStatment", sQLException);
|
||||
LOGGER.log(Level.SEVERE, "failed to prepareStatment", sQLException); // NON-NLS
|
||||
}
|
||||
|
||||
} finally {
|
||||
@@ -626,7 +626,7 @@ public class EventDB {
|
||||
*/
|
||||
void insertEvent(long time, EventType type, Long objID, Long artifactID, String fullDescription, String medDescription, String shortDescription, TskData.FileKnown known, EventTransaction tr) {
|
||||
if (tr.isClosed()) {
|
||||
throw new IllegalArgumentException("can't update database with closed transaction");
|
||||
throw new IllegalArgumentException("can't update database with closed transaction"); // NON-NLS
|
||||
}
|
||||
int typeNum;
|
||||
int superTypeNum;
|
||||
@@ -667,7 +667,7 @@ public class EventDB {
|
||||
insertRowStmt.executeUpdate();
|
||||
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "failed to insert event", ex);
|
||||
LOGGER.log(Level.SEVERE, "failed to insert event", ex); // NON-NLS
|
||||
} finally {
|
||||
dbWriteUnlock();
|
||||
}
|
||||
@@ -683,10 +683,10 @@ public class EventDB {
|
||||
void openDBCon() {
|
||||
try {
|
||||
if (con == null || con.isClosed()) {
|
||||
con = DriverManager.getConnection("jdbc:sqlite:" + dbPath);
|
||||
con = DriverManager.getConnection("jdbc:sqlite:" + dbPath); // NON-NLS
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.WARNING, "Failed to open connection to events.db", ex);
|
||||
LOGGER.log(Level.WARNING, "Failed to open connection to events.db", ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,8 +709,8 @@ public class EventDB {
|
||||
boolean tableExists() {
|
||||
//TODO: use prepared statement - jm
|
||||
try (Statement createStatement = con.createStatement();
|
||||
ResultSet executeQuery = createStatement.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='events'")) {
|
||||
if (executeQuery.getString("name").equals("events") == false) {
|
||||
ResultSet executeQuery = createStatement.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='events'")) { // NON-NLS
|
||||
if (executeQuery.getString("name").equals("events") == false) { // NON-NLS
|
||||
return false;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@@ -730,26 +730,26 @@ public class EventDB {
|
||||
//this should match Sleuthkit db setupt
|
||||
try (Statement statement = con.createStatement()) {
|
||||
//reduce i/o operations, we have no OS crash recovery anyway
|
||||
statement.execute("PRAGMA synchronous = OFF;");
|
||||
statement.execute("PRAGMA synchronous = OFF;"); // NON-NLS
|
||||
//we don't use this feature, so turn it off for minimal speed up on queries
|
||||
//this is deprecated and not recomended
|
||||
statement.execute("PRAGMA count_changes = OFF;");
|
||||
statement.execute("PRAGMA count_changes = OFF;"); // NON-NLS
|
||||
//this made a big difference to query speed
|
||||
statement.execute("PRAGMA temp_store = MEMORY");
|
||||
statement.execute("PRAGMA temp_store = MEMORY"); // NON-NLS
|
||||
//this made a modest improvement in query speeds
|
||||
statement.execute("PRAGMA cache_size = 50000");
|
||||
statement.execute("PRAGMA cache_size = 50000"); // NON-NLS
|
||||
//we never delete anything so...
|
||||
statement.execute("PRAGMA auto_vacuum = 0");
|
||||
statement.execute("PRAGMA auto_vacuum = 0"); // NON-NLS
|
||||
//allow to query while in transaction - no need read locks
|
||||
statement.execute("PRAGMA read_uncommitted = True;");
|
||||
statement.execute("PRAGMA read_uncommitted = True;"); // NON-NLS
|
||||
} finally {
|
||||
dbWriteUnlock();
|
||||
}
|
||||
|
||||
try {
|
||||
LOGGER.log(Level.INFO, String.format("sqlite-jdbc version %s loaded in %s mode",
|
||||
LOGGER.log(Level.INFO, String.format("sqlite-jdbc version %s loaded in %s mode", // NON-NLS
|
||||
SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode()
|
||||
? "native" : "pure-java"));
|
||||
? "native" : "pure-java")); // NON-NLS
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
}
|
||||
@@ -795,9 +795,9 @@ public class EventDB {
|
||||
final boolean useSubTypes = (zoomLevel == EventTypeZoomLevel.SUB_TYPE);
|
||||
|
||||
//get some info about the range of dates requested
|
||||
final String queryString = "select count(*), " + (useSubTypes ? SUB_TYPE_COLUMN : BASE_TYPE_COLUMN)
|
||||
+ " from events where time >= " + startTime + " and time < " + endTime + " and " + getSQLWhere(filter)
|
||||
+ " GROUP BY " + (useSubTypes ? SUB_TYPE_COLUMN : BASE_TYPE_COLUMN);
|
||||
final String queryString = "select count(*), " + (useSubTypes ? SUB_TYPE_COLUMN : BASE_TYPE_COLUMN) // NON-NLS
|
||||
+ " from events where time >= " + startTime + " and time < " + endTime + " and " + getSQLWhere(filter) // NON-NLS
|
||||
+ " GROUP BY " + (useSubTypes ? SUB_TYPE_COLUMN : BASE_TYPE_COLUMN); // NON-NLS
|
||||
|
||||
ResultSet rs = null;
|
||||
dbReadLock();
|
||||
@@ -814,11 +814,11 @@ public class EventDB {
|
||||
? RootEventType.allTypes.get(rs.getInt(SUB_TYPE_COLUMN))
|
||||
: BaseTypes.values()[rs.getInt(BASE_TYPE_COLUMN)];
|
||||
|
||||
typeMap.put(type, rs.getLong("count(*)"));
|
||||
typeMap.put(type, rs.getLong("count(*)")); // NON-NLS
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
LOGGER.log(Level.SEVERE, "error getting count of events from db.", ex);
|
||||
LOGGER.log(Level.SEVERE, "error getting count of events from db.", ex); // NON-NLS
|
||||
} finally {
|
||||
try {
|
||||
rs.close();
|
||||
@@ -876,10 +876,10 @@ public class EventDB {
|
||||
|
||||
//get all agregate events in this time unit
|
||||
dbReadLock();
|
||||
String query = "select strftime('" + strfTimeFormat + "',time , 'unixepoch'" + (TimeLineController.getTimeZone().get().equals(TimeZone.getDefault()) ? ", 'localtime'" : "") + ") as interval, group_concat(event_id) as event_ids, Min(time), Max(time), " + descriptionColumn + ", " + (useSubTypes ? SUB_TYPE_COLUMN : BASE_TYPE_COLUMN)
|
||||
+ " 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)";
|
||||
String query = "select strftime('" + strfTimeFormat + "',time , 'unixepoch'" + (TimeLineController.getTimeZone().get().equals(TimeZone.getDefault()) ? ", 'localtime'" : "") + ") as interval, group_concat(event_id) as event_ids, Min(time), Max(time), " + descriptionColumn + ", " + (useSubTypes ? SUB_TYPE_COLUMN : BASE_TYPE_COLUMN) // NON-NLS
|
||||
+ " from events where time >= " + start + " and time < " + end + " and " + getSQLWhere(filter) // NON-NLS
|
||||
+ " group by interval, " + (useSubTypes ? SUB_TYPE_COLUMN : BASE_TYPE_COLUMN) + " , " + descriptionColumn // NON-NLS
|
||||
+ " order by Min(time)"; // NON-NLS
|
||||
//System.out.println(query);
|
||||
ResultSet rs = null;
|
||||
try (Statement stmt = con.createStatement(); // scoop up requested events in groups organized by interval, type, and desription
|
||||
@@ -895,9 +895,9 @@ public class EventDB {
|
||||
EventType type = useSubTypes ? RootEventType.allTypes.get(rs.getInt(SUB_TYPE_COLUMN)) : BaseTypes.values()[rs.getInt(BASE_TYPE_COLUMN)];
|
||||
|
||||
AggregateEvent aggregateEvent = new AggregateEvent(
|
||||
new Interval(rs.getLong("Min(time)") * 1000, rs.getLong("Max(time)") * 1000, TimeLineController.getJodaTimeZone()),
|
||||
new Interval(rs.getLong("Min(time)") * 1000, rs.getLong("Max(time)") * 1000, TimeLineController.getJodaTimeZone()), // NON-NLS
|
||||
type,
|
||||
Arrays.asList(rs.getString("event_ids").split(",")),
|
||||
Arrays.asList(rs.getString("event_ids").split(",")), // NON-NLS
|
||||
rs.getString(descriptionColumn), lod);
|
||||
|
||||
//put events in map from type/descrition -> event
|
||||
@@ -967,16 +967,16 @@ public class EventDB {
|
||||
try (ResultSet rs = getDBInfoStmt.executeQuery()) {
|
||||
long result = defaultValue;
|
||||
while (rs.next()) {
|
||||
result = rs.getLong("value");
|
||||
result = rs.getLong("value"); // NON-NLS
|
||||
}
|
||||
return result;
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "failed to read key: " + key + " from db_info", ex);
|
||||
LOGGER.log(Level.SEVERE, "failed to read key: " + key + " from db_info", ex); // NON-NLS
|
||||
} finally {
|
||||
dbReadUnlock();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "failed to set key: " + key + " on getDBInfoStmt ", ex);
|
||||
LOGGER.log(Level.SEVERE, "failed to set key: " + key + " on getDBInfoStmt ", ex); // NON-NLS
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
@@ -997,19 +997,19 @@ public class EventDB {
|
||||
private String getStrfTimeFormat(TimeUnits info) {
|
||||
switch (info) {
|
||||
case DAYS:
|
||||
return "%Y-%m-%dT00:00:00";
|
||||
return "%Y-%m-%dT00:00:00"; // NON-NLS
|
||||
case HOURS:
|
||||
return "%Y-%m-%dT%H:00:00";
|
||||
return "%Y-%m-%dT%H:00:00"; // NON-NLS
|
||||
case MINUTES:
|
||||
return "%Y-%m-%dT%H:%M:00";
|
||||
return "%Y-%m-%dT%H:%M:00"; // NON-NLS
|
||||
case MONTHS:
|
||||
return "%Y-%m-01T00:00:00";
|
||||
return "%Y-%m-01T00:00:00"; // NON-NLS
|
||||
case SECONDS:
|
||||
return "%Y-%m-%dT%H:%M:%S";
|
||||
return "%Y-%m-%dT%H:%M:%S"; // NON-NLS
|
||||
case YEARS:
|
||||
return "%Y-01-01T00:00:00";
|
||||
return "%Y-01-01T00:00:00"; // NON-NLS
|
||||
default:
|
||||
return "%Y-%m-%dT%H:%M:%S";
|
||||
return "%Y-%m-%dT%H:%M:%S"; // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1026,7 +1026,7 @@ public class EventDB {
|
||||
recordDBInfoStmt.setLong(2, value);
|
||||
recordDBInfoStmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "failed to set dbinfo key: " + key + " value: " + value, ex);
|
||||
LOGGER.log(Level.SEVERE, "failed to set dbinfo key: " + key + " value: " + value, ex); // NON-NLS
|
||||
} finally {
|
||||
dbWriteUnlock();
|
||||
}
|
||||
@@ -1056,7 +1056,7 @@ public class EventDB {
|
||||
con.setAutoCommit(false);
|
||||
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "failed to set auto-commit to to false", ex);
|
||||
LOGGER.log(Level.SEVERE, "failed to set auto-commit to to false", ex); // NON-NLS
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1067,7 +1067,7 @@ public class EventDB {
|
||||
con.rollback();
|
||||
|
||||
} catch (SQLException ex1) {
|
||||
LOGGER.log(Level.SEVERE, "Exception while attempting to rollback!!", ex1);
|
||||
LOGGER.log(Level.SEVERE, "Exception while attempting to rollback!!", ex1); // NON-NLS
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
@@ -1085,7 +1085,7 @@ public class EventDB {
|
||||
// fireNewEvents(newEvents);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error commiting events.db.", ex);
|
||||
LOGGER.log(Level.SEVERE, "Error commiting events.db.", ex); // NON-NLS
|
||||
rollback();
|
||||
}
|
||||
}
|
||||
@@ -1096,7 +1096,7 @@ public class EventDB {
|
||||
try {
|
||||
con.setAutoCommit(true);
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error setting auto-commit to true.", ex);
|
||||
LOGGER.log(Level.SEVERE, "Error setting auto-commit to true.", ex); // NON-NLS
|
||||
} finally {
|
||||
closed = true;
|
||||
|
||||
@@ -1112,10 +1112,10 @@ public class EventDB {
|
||||
|
||||
public class MultipleTransactionException extends IllegalStateException {
|
||||
|
||||
private static final String CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO = "cannot have more than one open transaction";
|
||||
private static final String CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTION = "cannot have more than one open transaction"; // NON-NLS
|
||||
|
||||
public MultipleTransactionException() {
|
||||
super(CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTIO);
|
||||
super(CANNOT_HAVE_MORE_THAN_ONE_OPEN_TRANSACTION);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.Interval;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.timeline.ProgressWindow;
|
||||
@@ -126,13 +127,13 @@ public class EventsRepository {
|
||||
|
||||
/** @return min time (in seconds from unix epoch) */
|
||||
public Long getMaxTime() {
|
||||
return maxCache.getUnchecked("max");
|
||||
return maxCache.getUnchecked("max"); // NON-NLS
|
||||
// return eventDB.getMaxTime();
|
||||
}
|
||||
|
||||
/** @return max tie (in seconds from unix epoch) */
|
||||
public Long getMinTime() {
|
||||
return minCache.getUnchecked("min");
|
||||
return minCache.getUnchecked("min"); // NON-NLS
|
||||
// return eventDB.getMinTime();
|
||||
}
|
||||
|
||||
@@ -218,7 +219,8 @@ public class EventsRepository {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground() throws Exception {
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(0, -1, "(re)initializing events database", "")));
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(0, -1, NbBundle.getMessage(this.getClass(),
|
||||
"EventsRepository.progressWindow.msg.reinit_db"), "")));
|
||||
//reset database
|
||||
//TODO: can we do more incremental updates? -jm
|
||||
eventDB.dropTable();
|
||||
@@ -229,7 +231,8 @@ public class EventsRepository {
|
||||
List<Long> files = skCase.findAllFileIdsWhere(FILES_AND_DIRS_WHERE_CLAUSE);
|
||||
|
||||
final int numFiles = files.size();
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(0, numFiles, "populating mac events for files: ", "")));
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(0, numFiles, NbBundle.getMessage(this.getClass(),
|
||||
"EventsRepository.progressWindow.msg.populateMacEventsFiles"), "")));
|
||||
|
||||
//insert file events into db
|
||||
int i = 1;
|
||||
@@ -263,9 +266,11 @@ public class EventsRepository {
|
||||
eventDB.insertEvent(f.getCrtime(), FileSystemTypes.FILE_CREATED, fID, null, uniquePath, medD, shortDesc, f.getKnown(), trans);
|
||||
}
|
||||
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(i, numFiles, "populating mac events for files: ", f.getName())));
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(i, numFiles,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"EventsRepository.progressWindow.msg.populateMacEventsFiles2"), f.getName())));
|
||||
} catch (TskCoreException tskCoreException) {
|
||||
LOGGER.log(Level.WARNING, "failed to insert mac event for file : " + fID, tskCoreException);
|
||||
LOGGER.log(Level.WARNING, "failed to insert mac event for file : " + fID, tskCoreException); // NON-NLS
|
||||
}
|
||||
}
|
||||
i++;
|
||||
@@ -283,7 +288,8 @@ public class EventsRepository {
|
||||
}
|
||||
}
|
||||
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(0, -1, "commiting events db", "")));
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(0, -1, NbBundle.getMessage(this.getClass(),
|
||||
"EventsRepository.progressWindow.msg.commitingDb"), "")));
|
||||
if (isCancelled()) {
|
||||
eventDB.rollBackTransaction(trans);
|
||||
} else {
|
||||
@@ -315,13 +321,15 @@ public class EventsRepository {
|
||||
get();
|
||||
|
||||
} catch (CancellationException ex) {
|
||||
LOGGER.log(Level.INFO, "Database population was cancelled by the user. Not all events may be present or accurate. See the log for details.", ex);
|
||||
LOGGER.log(Level.INFO, "Database population was cancelled by the user. Not all events may be present or accurate. See the log for details.", ex); // NON-NLS
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
LOGGER.log(Level.WARNING, "Exception while populating database.", ex);
|
||||
JOptionPane.showMessageDialog(null, "There was a problem populating the timeline. Not all events may be present or accurate. See the log for details.");
|
||||
LOGGER.log(Level.WARNING, "Exception while populating database.", ex); // NON-NLS
|
||||
JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(),
|
||||
"EventsRepository.msgdlg.problem.text"));
|
||||
} catch (Exception ex) {
|
||||
LOGGER.log(Level.WARNING, "Unexpected exception while populating database.", ex);
|
||||
JOptionPane.showMessageDialog(null, "There was a problem populating the timeline. Not all events may be present or accurate. See the log for details.");
|
||||
LOGGER.log(Level.WARNING, "Unexpected exception while populating database.", ex); // NON-NLS
|
||||
JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(),
|
||||
"EventsRepository.msgdlg.problem.text"));
|
||||
}
|
||||
r.run(); //execute post db population operation
|
||||
}
|
||||
@@ -339,7 +347,10 @@ public class EventsRepository {
|
||||
final ArrayList<BlackboardArtifact> blackboardArtifacts = skCase.getBlackboardArtifacts(type.getArtifactType());
|
||||
final int numArtifacts = blackboardArtifacts.size();
|
||||
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(0, numArtifacts, "populating " + type.toString() + " events", "")));
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(0, numArtifacts,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"EventsRepository.progressWindow.populatingXevents",
|
||||
type.toString()), "")));
|
||||
|
||||
int i = 0;
|
||||
for (final BlackboardArtifact bbart : blackboardArtifacts) {
|
||||
@@ -351,10 +362,13 @@ public class EventsRepository {
|
||||
}
|
||||
|
||||
i++;
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(i, numArtifacts, "populating " + type.toString() + " events", "")));
|
||||
process(Arrays.asList(new ProgressWindow.ProgressUpdate(i, numArtifacts,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"EventsRepository.progressWindow.populatingXevents",
|
||||
type.toString()), "")));
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "There was a problem getting events with sub type = " + type.toString() + ".", ex);
|
||||
LOGGER.log(Level.SEVERE, "There was a problem getting events with sub type = " + type.toString() + ".", ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ public interface ArtifactEventType extends EventType {
|
||||
}
|
||||
|
||||
if (attrMap.get(type.getDateTimeAttrubuteType()) == null) {
|
||||
Logger.getLogger(AttributeEventDescription.class.getName()).log(Level.WARNING, "Artifact {0} has no date/time attribute, skipping it.", artf.getArtifactID());
|
||||
Logger.getLogger(AttributeEventDescription.class.getName()).log(Level.WARNING, "Artifact {0} has no date/time attribute, skipping it.", artf.getArtifactID()); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
//use the hook provided by this subtype implementation
|
||||
|
||||
@@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.timeline.events.type;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javafx.scene.image.Image;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,7 @@ import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||
*/
|
||||
public enum BaseTypes implements EventType {
|
||||
|
||||
FILE_SYSTEM("File System", "blue-document.png") {
|
||||
FILE_SYSTEM(NbBundle.getMessage(BaseTypes.class, "BaseTypes.fileSystem.name"), "blue-document.png") { // NON-NLS
|
||||
|
||||
@Override
|
||||
public List<? extends EventType> getSubTypes() {
|
||||
@@ -40,7 +41,7 @@ public enum BaseTypes implements EventType {
|
||||
return FileSystemTypes.valueOf(string);
|
||||
}
|
||||
},
|
||||
WEB_ACTIVITY("Web Activity", "web-file.png") {
|
||||
WEB_ACTIVITY(NbBundle.getMessage(BaseTypes.class, "BaseTypes.webActivity.name"), "web-file.png") { // NON-NLS
|
||||
|
||||
@Override
|
||||
public List<? extends EventType> getSubTypes() {
|
||||
@@ -52,7 +53,7 @@ public enum BaseTypes implements EventType {
|
||||
return WebTypes.valueOf(string);
|
||||
}
|
||||
},
|
||||
MISC_TYPES("Misc Types", "block.png") {
|
||||
MISC_TYPES(NbBundle.getMessage(BaseTypes.class, "BaseTypes.miscTypes.name"), "block.png") { // NON-NLS
|
||||
|
||||
@Override
|
||||
public List<? extends EventType> getSubTypes() {
|
||||
@@ -93,7 +94,7 @@ public enum BaseTypes implements EventType {
|
||||
private BaseTypes(String displayName, String iconBase) {
|
||||
this.displayName = displayName;
|
||||
this.iconBase = iconBase;
|
||||
this.image = new Image("org/sleuthkit/autopsy/timeline/images/" + iconBase, true);
|
||||
this.image = new Image("org/sleuthkit/autopsy/timeline/images/" + iconBase, true); // NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
BaseTypes.fileSystem.name=File System
|
||||
BaseTypes.webActivity.name=Web Activity
|
||||
BaseTypes.miscTypes.name=Misc Types
|
||||
FileSystemTypes.fileModified.name=File Modified
|
||||
FileSystemTypes.fileAccessed.name=File Accessed
|
||||
FileSystemTypes.fileCreated.name=File Created
|
||||
FileSystemTypes.fileChanged.name=File Changed
|
||||
MiscTypes.message.name=Messages
|
||||
MiscTypes.GPSRoutes.name=GPS Routes
|
||||
MiscTypes.GPSTrackpoint.name=Location History
|
||||
MiscTypes.Calls.name=Calls
|
||||
MiscTypes.Email.name=Email
|
||||
MiscTypes.recentDocuments.name=Recent Documents
|
||||
MiscTypes.installedPrograms.name=Installed Programs
|
||||
MiscTypes.exif.name=Exif
|
||||
MiscTypes.devicesAttached.name=Devices Attached
|
||||
RootEventType.eventTypes.name=Event Types
|
||||
WebTypes.webDownloads.name=Web Downloads
|
||||
WebTypes.webCookies.name=Web Cookies
|
||||
WebTypes.webBookmarks.name=Web Bookmarks
|
||||
WebTypes.webHistory.name=Web History
|
||||
WebTypes.webSearch.name=Web Searches
|
||||
@@ -0,0 +1,22 @@
|
||||
BaseTypes.fileSystem.name=\u30D5\u30A1\u30A4\u30EB\u30B7\u30B9\u30C6\u30E0
|
||||
BaseTypes.miscTypes.name=\u305D\u306E\u4ED6\u30BF\u30A4\u30D7
|
||||
BaseTypes.webActivity.name=\u30A6\u30A7\u30D6\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3
|
||||
FileSystemTypes.fileAccessed.name=\u30A2\u30AF\u30BB\u30B9\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB
|
||||
FileSystemTypes.fileChanged.name=\u5909\u66F4\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB
|
||||
FileSystemTypes.fileCreated.name=\u4F5C\u6210\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB
|
||||
FileSystemTypes.fileModified.name=\u66F4\u65B0\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB
|
||||
MiscTypes.Calls.name=\u30B3\u30FC\u30EB
|
||||
MiscTypes.devicesAttached.name=\u30A2\u30BF\u30C3\u30C1\u3055\u308C\u3066\u3044\u308B\u6A5F\u5668
|
||||
MiscTypes.Email.name=E\u30E1\u30FC\u30EB
|
||||
MiscTypes.exif.name=Exif
|
||||
MiscTypes.GPSRoutes.name=GPS\u30EB\u30FC\u30C8
|
||||
MiscTypes.GPSTrackpoint.name=\u4F4D\u7F6E\u60C5\u5831\u5C65\u6B74
|
||||
MiscTypes.installedPrograms.name=\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u3066\u3044\u308B\u30D7\u30ED\u30B0\u30E9\u30E0
|
||||
MiscTypes.message.name=\u30E1\u30C3\u30BB\u30FC\u30B8
|
||||
MiscTypes.recentDocuments.name=\u6700\u8FD1\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8
|
||||
RootEventType.eventTypes.name=\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7
|
||||
WebTypes.webBookmarks.name=\u30A6\u30A7\u30D6\u30D6\u30C3\u30AF\u30DE\u30FC\u30AF
|
||||
WebTypes.webCookies.name=\u30A6\u30A7\u30D6\u30AF\u30C3\u30AD\u30FC
|
||||
WebTypes.webDownloads.name=\u30A6\u30A7\u30D6\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9
|
||||
WebTypes.webHistory.name=\u30A6\u30A7\u30D6\u5C65\u6B74
|
||||
WebTypes.webSearch.name=\u30A6\u30A7\u30D6\u691C\u7D22
|
||||
@@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.timeline.events.type;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javafx.scene.image.Image;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||
|
||||
/**
|
||||
@@ -28,10 +29,10 @@ import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||
*/
|
||||
public enum FileSystemTypes implements EventType {
|
||||
|
||||
FILE_MODIFIED("File Modified", "blue-document-attribute-m.png"),
|
||||
FILE_ACCESSED("File Accessed", "blue-document-attribute-a.png"),
|
||||
FILE_CREATED("File Created", "blue-document-attribute-b.png"),
|
||||
FILE_CHANGED("File Changed", "blue-document-attribute-c.png");
|
||||
FILE_MODIFIED(NbBundle.getMessage(FileSystemTypes.class, "FileSystemTypes.fileModified.name"), "blue-document-attribute-m.png"), // NON-NLS
|
||||
FILE_ACCESSED(NbBundle.getMessage(FileSystemTypes.class, "FileSystemTypes.fileAccessed.name"), "blue-document-attribute-a.png"), // NON-NLS
|
||||
FILE_CREATED(NbBundle.getMessage(FileSystemTypes.class, "FileSystemTypes.fileCreated.name"), "blue-document-attribute-b.png"), // NON-NLS
|
||||
FILE_CHANGED(NbBundle.getMessage(FileSystemTypes.class, "FileSystemTypes.fileChanged.name"), "blue-document-attribute-c.png"); // NON-NLS
|
||||
|
||||
private final String iconBase;
|
||||
|
||||
@@ -72,7 +73,7 @@ public enum FileSystemTypes implements EventType {
|
||||
private FileSystemTypes(String displayName, String iconBase) {
|
||||
this.displayName = displayName;
|
||||
this.iconBase = iconBase;
|
||||
this.image = new Image("org/sleuthkit/autopsy/timeline/images/" + iconBase, true);
|
||||
this.image = new Image("org/sleuthkit/autopsy/timeline/images/" + iconBase, true); // NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.function.BiFunction;
|
||||
import javafx.scene.image.Image;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
@@ -36,7 +37,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
*/
|
||||
public enum MiscTypes implements EventType, ArtifactEventType {
|
||||
|
||||
MESSAGE("Messages", "message.png",
|
||||
MESSAGE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.message.name"), "message.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE),
|
||||
@@ -50,7 +51,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
||||
return StringUtils.join(asList, " ");
|
||||
},
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)),
|
||||
GPS_ROUTE("GPS Routes", "gps-search.png",
|
||||
GPS_ROUTE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSRoutes.name"), "gps-search.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME),
|
||||
@@ -60,35 +61,35 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
||||
final BlackboardAttribute longStart = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START);
|
||||
final BlackboardAttribute latEnd = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END);
|
||||
final BlackboardAttribute longEnd = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END);
|
||||
return String.format("from %1$g %2$g to %3$g %4$g", latStart.getValueDouble(), longStart.getValueDouble(), latEnd.getValueDouble(), longEnd.getValueDouble());
|
||||
return String.format("from %1$g %2$g to %3$g %4$g", latStart.getValueDouble(), longStart.getValueDouble(), latEnd.getValueDouble(), longEnd.getValueDouble()); // NON-NLS
|
||||
}),
|
||||
GPS_TRACKPOINT("Location History", "gps-trackpoint.png",
|
||||
GPS_TRACKPOINT(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSTrackpoint.name"), "gps-trackpoint.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME),
|
||||
(artf, attrMap) -> {
|
||||
final BlackboardAttribute longitude = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE);
|
||||
final BlackboardAttribute latitude = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE);
|
||||
return (latitude != null ? latitude.getValueDouble() : "") + " " + (longitude != null ? longitude.getValueDouble() : "");
|
||||
return (latitude != null ? latitude.getValueDouble() : "") + " " + (longitude != null ? longitude.getValueDouble() : ""); // NON-NLS
|
||||
},
|
||||
(artf, attrMap) -> ""),
|
||||
CALL_LOG("Calls", "calllog.png",
|
||||
CALL_LOG(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Calls.name"), "calllog.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME),
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER),
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)),
|
||||
EMAIL("Email", "mail-icon-16.png",
|
||||
EMAIL(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Email.name"), "mail-icon-16.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT,
|
||||
(artifact, attrMap) -> {
|
||||
final BlackboardAttribute emailFrom = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM);
|
||||
final BlackboardAttribute emailTo = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO);
|
||||
return (emailFrom != null ? emailFrom.getValueString() : "") + " to " + (emailTo != null ? emailTo.getValueString() : "");
|
||||
return (emailFrom != null ? emailFrom.getValueString() : "") + " to " + (emailTo != null ? emailTo.getValueString() : ""); // NON-NLS
|
||||
},
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT),
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN)),
|
||||
RECENT_DOCUMENTS("Recent Documents", "recent_docs.png",
|
||||
RECENT_DOCUMENTS(NbBundle.getMessage(MiscTypes.class, "MiscTypes.recentDocuments.name"), "recent_docs.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH).andThen(
|
||||
@@ -114,13 +115,13 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
||||
return new AttributeEventDescription(time, shortDescription, medDescription, fullDescription);
|
||||
}
|
||||
},
|
||||
INSTALLED_PROGRAM("Installed Programs", "programs.png",
|
||||
INSTALLED_PROGRAM(NbBundle.getMessage(MiscTypes.class, "MiscTypes.installedPrograms.name"), "programs.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME),
|
||||
new EmptyExtractor(),
|
||||
new EmptyExtractor()),
|
||||
EXIF("Exif", "camera-icon-16.png",
|
||||
EXIF(NbBundle.getMessage(MiscTypes.class, "MiscTypes.exif.name"), "camera-icon-16.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE),
|
||||
@@ -131,10 +132,10 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
||||
return t.getSleuthkitCase().getAbstractFileById(t.getObjectID()).getName();
|
||||
} catch (TskCoreException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
return " error loading file name";
|
||||
return " error loading file name"; // NON-NLS
|
||||
}
|
||||
}),
|
||||
DEVICES_ATTACHED("Devices Attached", "usb_devices.png",
|
||||
DEVICES_ATTACHED(NbBundle.getMessage(MiscTypes.class, "MiscTypes.devicesAttached.name"), "usb_devices.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE),
|
||||
@@ -150,12 +151,12 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
||||
return "";
|
||||
} else {
|
||||
switch (dir.getDisplayString()) {
|
||||
case "Incoming":
|
||||
return "from";
|
||||
case "Outgoing":
|
||||
return "to";
|
||||
case "Incoming": // NON-NLS
|
||||
return "from"; // NON-NLS
|
||||
case "Outgoing": // NON-NLS
|
||||
return "to"; // NON-NLS
|
||||
default:
|
||||
return "";
|
||||
return ""; // NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,7 +234,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
||||
this.shortExtractor = shortExtractor;
|
||||
this.medExtractor = medExtractor;
|
||||
this.longExtractor = longExtractor;
|
||||
this.image = new Image("org/sleuthkit/autopsy/timeline/images/" + iconBase, true);
|
||||
this.image = new Image("org/sleuthkit/autopsy/timeline/images/" + iconBase, true); // NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||
|
||||
/** A singleton {@link } EventType to represent the root type of all event
|
||||
@@ -81,12 +82,12 @@ public class RootEventType implements EventType {
|
||||
|
||||
@Override
|
||||
public String getIconBase() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
throw new UnsupportedOperationException("Not supported yet."); // NON-NLS //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Event Types";
|
||||
return NbBundle.getMessage(this.getClass(), "RootEventType.eventTypes.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import javafx.scene.image.Image;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
@@ -33,8 +34,8 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
*/
|
||||
public enum WebTypes implements EventType, ArtifactEventType {
|
||||
|
||||
WEB_DOWNLOADS("Web Downloads",
|
||||
"downloads.png",
|
||||
WEB_DOWNLOADS(NbBundle.getMessage(WebTypes.class, "WebTypes.webDownloads.name"),
|
||||
"downloads.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN),
|
||||
@@ -52,40 +53,40 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
||||
String fileName = StringUtils.substringAfterLast(path, "/");
|
||||
String url = getFullExtractor().apply(artf, attrMap);
|
||||
|
||||
//TODO: review non default descritpion construction
|
||||
String shortDescription = fileName + " from " + domain;
|
||||
String medDescription = fileName + " from " + url;
|
||||
String fullDescription = path + " from " + url;
|
||||
//TODO: review non default description construction
|
||||
String shortDescription = fileName + " from " + domain; // NON-NLS
|
||||
String medDescription = fileName + " from " + url; // NON-NLS
|
||||
String fullDescription = path + " from " + url; // NON-NLS
|
||||
return new AttributeEventDescription(time, shortDescription, medDescription, fullDescription);
|
||||
}
|
||||
},
|
||||
//TODO: review description seperators
|
||||
WEB_COOKIE("Web Cookies",
|
||||
"cookies.png",
|
||||
//TODO: review description separators
|
||||
WEB_COOKIE(NbBundle.getMessage(WebTypes.class, "WebTypes.webCookies.name"),
|
||||
"cookies.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN),
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME),
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE)),
|
||||
//TODO: review description seperators
|
||||
WEB_BOOKMARK("Web Bookmarks",
|
||||
"bookmarks.png",
|
||||
//TODO: review description separators
|
||||
WEB_BOOKMARK(NbBundle.getMessage(WebTypes.class, "WebTypes.webBookmarks.name"),
|
||||
"bookmarks.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN),
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
|
||||
//TODO: review description seperators
|
||||
WEB_HISTORY("Web History",
|
||||
"history.png",
|
||||
//TODO: review description separators
|
||||
WEB_HISTORY(NbBundle.getMessage(WebTypes.class, "WebTypes.webHistory.name"),
|
||||
"history.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN),
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
|
||||
//TODO: review description seperators
|
||||
WEB_SEARCH("Web Searches",
|
||||
"searchquery.png",
|
||||
//TODO: review description separators
|
||||
WEB_SEARCH(NbBundle.getMessage(WebTypes.class, "WebTypes.webSearch.name"),
|
||||
"searchquery.png", // NON-NLS
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT),
|
||||
@@ -160,7 +161,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
||||
this.shortExtractor = shortExtractor;
|
||||
this.medExtractor = medExtractor;
|
||||
this.longExtractor = longExtractor;
|
||||
this.image = new Image("org/sleuthkit/autopsy/timeline/images/" + iconBase, true);
|
||||
this.image = new Image("org/sleuthkit/autopsy/timeline/images/" + iconBase, true); // NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
EventRoodNode.tooManyNode.displayName=Too many events to display. Maximum \= {0}. But there are {1} to display.
|
||||
@@ -0,0 +1 @@
|
||||
EventRoodNode.tooManyNode.displayName=\u8868\u793A\u3059\u308B\u30A4\u30D9\u30F3\u30C8\u6570\u304C\u591A\u3059\u304E\u307E\u3059\u3002\u6700\u5927 \= {0}\u3002\u8868\u793A\u3059\u308B\u30A4\u30D9\u30F3\u30C8\u306F{1}\u3042\u308A\u307E\u3059\u3002
|
||||
@@ -49,13 +49,13 @@ class EventNode extends DisplayableItemNode {
|
||||
EventNode(TimeLineEvent eventById, AbstractFile file, BlackboardArtifact artifact) {
|
||||
super(Children.LEAF, Lookups.fixed(eventById, file, artifact));
|
||||
this.e = eventById;
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/timeline/images/" + e.getType().getIconBase());
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/timeline/images/" + e.getType().getIconBase()); // NON-NLS
|
||||
}
|
||||
|
||||
EventNode(TimeLineEvent eventById, AbstractFile file) {
|
||||
super(Children.LEAF, Lookups.fixed(eventById, file));
|
||||
this.e = eventById;
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/timeline/images/" + e.getType().getIconBase());
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/timeline/images/" + e.getType().getIconBase()); // NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,7 +67,7 @@ class EventNode extends DisplayableItemNode {
|
||||
s.put(properties);
|
||||
}
|
||||
|
||||
final TimeProperty timePropery = new TimeProperty("time", "Date/Time", "time ", getDateTimeString());
|
||||
final TimeProperty timePropery = new TimeProperty("time", "Date/Time", "time ", getDateTimeString()); // NON-NLS
|
||||
|
||||
TimeLineController.getTimeZone().addListener((Observable observable) -> {
|
||||
try {
|
||||
@@ -77,12 +77,12 @@ class EventNode extends DisplayableItemNode {
|
||||
}
|
||||
});
|
||||
|
||||
properties.put(new NodeProperty<>("icon", "Icon", "icon", true)); //gets overriden with icon
|
||||
properties.put(new NodeProperty<>("icon", "Icon", "icon", true)); // NON-NLS //gets overridden with icon
|
||||
properties.put(timePropery);
|
||||
properties.put(new NodeProperty<>("description", "Description", "description", e.getFullDescription()));
|
||||
properties.put(new NodeProperty<>("eventBaseType", "Base Type", "base type", e.getType().getSuperType().getDisplayName()));
|
||||
properties.put(new NodeProperty<>("eventSubType", "Sub Type", "sub type", e.getType().getDisplayName()));
|
||||
properties.put(new NodeProperty<>("Known", "Known", "known", e.getKnown().toString()));
|
||||
properties.put(new NodeProperty<>("description", "Description", "description", e.getFullDescription())); // NON-NLS
|
||||
properties.put(new NodeProperty<>("eventBaseType", "Base Type", "base type", e.getType().getSuperType().getDisplayName())); // NON-NLS
|
||||
properties.put(new NodeProperty<>("eventSubType", "Sub Type", "sub type", e.getType().getDisplayName())); // NON-NLS
|
||||
properties.put(new NodeProperty<>("Known", "Known", "known", e.getKnown().toString())); // NON-NLS
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ class EventNode extends DisplayableItemNode {
|
||||
|
||||
@Override
|
||||
public <T> T accept(DisplayableItemNodeVisitor<T> dinv) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
throw new UnsupportedOperationException("Not supported yet."); // NON-NLS //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
class TimeProperty extends PropertySupport.ReadWrite<String> {
|
||||
@@ -140,7 +140,7 @@ class EventNode extends DisplayableItemNode {
|
||||
public void setValue(String t) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
String oldValue = getValue();
|
||||
value = t;
|
||||
firePropertyChange("time", oldValue, t);
|
||||
firePropertyChange("time", oldValue, t); // NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.timeline.events.FilteredEventsModel;
|
||||
import org.sleuthkit.autopsy.timeline.events.TimeLineEvent;
|
||||
@@ -110,7 +111,7 @@ public class EventRootNode extends DisplayableItemNode {
|
||||
}
|
||||
|
||||
} catch (TskCoreException tskCoreException) {
|
||||
LOGGER.log(Level.WARNING, "Failed to lookup sleuthkit object backing TimeLineEvent.", tskCoreException);
|
||||
LOGGER.log(Level.WARNING, "Failed to lookup sleuthkit object backing TimeLineEvent.", tskCoreException); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
@@ -123,8 +124,12 @@ public class EventRootNode extends DisplayableItemNode {
|
||||
|
||||
public TooManyNode(int size) {
|
||||
super(Children.LEAF);
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/info-icon-16.png");
|
||||
setDisplayName("Too many events to display. Maximum = " + MAX_EVENTS_TO_DISPLAY + ". But there are " + size + " to display.");
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/info-icon-16.png"); // NON-NLS
|
||||
setDisplayName(
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"EventRoodNode.tooManyNode.displayName",
|
||||
MAX_EVENTS_TO_DISPLAY,
|
||||
size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public abstract class AbstractFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public String getStringCheckBox() {
|
||||
return "[" + (isActive() ? "x" : " ") + "]";
|
||||
return "[" + (isActive() ? "x" : " ") + "]"; // NON-NLS
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
hideKnownFilter.displayName.text=Hide Known Files
|
||||
IntersectionFilter.displayName.text=Intersection{0}
|
||||
TextFilter.displayName.text=Text Filter
|
||||
TypeFilter.displayName.text=Event Type Filter
|
||||
@@ -0,0 +1,4 @@
|
||||
hideKnownFilter.displayName.text=\u65E2\u77E5\u30D5\u30A1\u30A4\u30EB\u3092\u96A0\u3059
|
||||
TextFilter.displayName.text=\u30C6\u30AD\u30B9\u30C8\u30D5\u30A3\u30EB\u30BF
|
||||
TypeFilter.displayName.text=\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u30D5\u30A3\u30EB\u30BF
|
||||
IntersectionFilter.displayName.text=\u30A4\u30F3\u30BF\u30FC\u30BB\u30AF\u30B7\u30E7\u30F3{0}
|
||||
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.timeline.filters;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/**
|
||||
* Filter to hide known files
|
||||
*/
|
||||
@@ -25,7 +27,7 @@ public class HideKnownFilter extends AbstractFilter {
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Hide Known Files";
|
||||
return NbBundle.getMessage(this.getClass(), "hideKnownFilter.displayName.text");
|
||||
}
|
||||
|
||||
public HideKnownFilter() {
|
||||
@@ -43,7 +45,7 @@ public class HideKnownFilter extends AbstractFilter {
|
||||
|
||||
@Override
|
||||
public String getHTMLReportString() {
|
||||
return "hide known" + getStringCheckBox();
|
||||
return "hide known" + getStringCheckBox();// NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.sleuthkit.autopsy.timeline.filters;
|
||||
import java.util.stream.Collectors;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/** Intersection(And) filter */
|
||||
public class IntersectionFilter extends CompoundFilter {
|
||||
@@ -32,14 +33,16 @@ public class IntersectionFilter extends CompoundFilter {
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Intersection" + getSubFilters().stream()
|
||||
.map(Filter::getDisplayName)
|
||||
.collect(Collectors.joining(",", "[", "]"));
|
||||
return NbBundle.getMessage(this.getClass(),
|
||||
"IntersectionFilter.displayName.text",
|
||||
getSubFilters().stream()
|
||||
.map(Filter::getDisplayName)
|
||||
.collect(Collectors.joining(",", "[", "]")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHTMLReportString() {
|
||||
return getSubFilters().stream().filter(Filter::isActive).map(Filter::getHTMLReportString).collect(Collectors.joining("</li><li>", "<ul><li>", "</li></ul>"));
|
||||
return getSubFilters().stream().filter(Filter::isActive).map(Filter::getHTMLReportString).collect(Collectors.joining("</li><li>", "<ul><li>", "</li></ul>")); // NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Objects;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/** Filter for text matching */
|
||||
public class TextFilter extends AbstractFilter {
|
||||
@@ -41,7 +42,7 @@ public class TextFilter extends AbstractFilter {
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Text Filter";
|
||||
return NbBundle.getMessage(this.getClass(), "TextFilter.displayName.text");
|
||||
}
|
||||
|
||||
synchronized public String getText() {
|
||||
@@ -62,7 +63,7 @@ public class TextFilter extends AbstractFilter {
|
||||
|
||||
@Override
|
||||
public String getHTMLReportString() {
|
||||
return "text like \"" + StringUtils.defaultIfBlank(text.getValue(), "") + "\"" + getStringCheckBox();
|
||||
return "text like \"" + StringUtils.defaultIfBlank(text.getValue(), "") + "\"" + getStringCheckBox(); // NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.stream.Collectors;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.events.type.EventType;
|
||||
import org.sleuthkit.autopsy.timeline.events.type.RootEventType;
|
||||
|
||||
@@ -64,7 +65,11 @@ public class TypeFilter extends UnionFilter {
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return eventType == RootEventType.getInstance() ? "Event Type Filter" : eventType.getDisplayName();
|
||||
if (eventType == RootEventType.getInstance()) {
|
||||
return NbBundle.getMessage(this.getClass(), "TypeFilter.displayName.text");
|
||||
} else {
|
||||
return eventType.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
/** @return a color to use in GUI components representing this filter */
|
||||
@@ -95,7 +100,7 @@ public class TypeFilter extends UnionFilter {
|
||||
public String getHTMLReportString() {
|
||||
String string = getEventType().getDisplayName() + getStringCheckBox();
|
||||
if (getSubFilters().isEmpty() == false) {
|
||||
string = string + " : " + getSubFilters().stream().filter(Filter::isActive).map(Filter::getHTMLReportString).collect(Collectors.joining("</li><li>", "<ul><li>", "</li></ul>"));
|
||||
string = string + " : " + getSubFilters().stream().filter(Filter::isActive).map(Filter::getHTMLReportString).collect(Collectors.joining("</li><li>", "<ul><li>", "</li></ul>")); // NON-NLS
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
@@ -374,9 +374,9 @@ public abstract class AbstractVisualization<X, Y, N extends Node, C extends XYCh
|
||||
label.relocate(labelX, 0);
|
||||
|
||||
if (labelX == 0) { // first label has no border
|
||||
label.setStyle("-fx-border-width: 0 0 0 0 ; -fx-border-color:black;");
|
||||
label.setStyle("-fx-border-width: 0 0 0 0 ; -fx-border-color:black;"); // NON-NLS
|
||||
} else { // subsequent labels have border on left to create dividers
|
||||
label.setStyle("-fx-border-width: 0 0 0 1; -fx-border-color:black;");
|
||||
label.setStyle("-fx-border-width: 0 0 0 1; -fx-border-color:black;"); // NON-NLS
|
||||
}
|
||||
|
||||
branchPane.getChildren().add(label);
|
||||
|
||||
@@ -16,6 +16,44 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
AggregateEvent.diferentDescriptions=aggregate events are not compatible they have different descriptions
|
||||
|
||||
Timeline.node.root=Root
|
||||
Timeline.node.root=Root
|
||||
Timeline.ui.ZoomRanges.onemin.text=One Minute
|
||||
Timeline.ui.ZoomRanges.fifteenmin.text=Fifteen Minutes
|
||||
Timeline.ui.ZoomRanges.onehour.text=One Hour
|
||||
Timeline.ui.ZoomRanges.sixhours.text=Six Hours
|
||||
Timeline.ui.ZoomRanges.twelvehours.text=Twelve Hours
|
||||
Timeline.ui.ZoomRanges.oneday.text=One Day
|
||||
Timeline.ui.ZoomRanges.threedays.text=Three Days
|
||||
Timeline.ui.ZoomRanges.oneweek.text=One Week
|
||||
Timeline.ui.ZoomRanges.twoweeks.text=Two Weeks
|
||||
Timeline.ui.ZoomRanges.onemonth.text=One Month
|
||||
Timeline.ui.ZoomRanges.threemonths.text=Three Months
|
||||
Timeline.ui.ZoomRanges.sixmonths.text=Six Months
|
||||
Timeline.ui.ZoomRanges.oneyear.text=One Year
|
||||
Timeline.ui.ZoomRanges.threeyears.text=Three Years
|
||||
Timeline.ui.ZoomRanges.fiveyears.text=Five Years
|
||||
Timeline.ui.ZoomRanges.tenyears.text=Ten Years
|
||||
Timeline.ui.ZoomRanges.all.text=All
|
||||
Timeline.ui.TimeLineChart.tooltip.text=Double-click to zoom into range\:\n{0} to {1}\nRight-click to clear.
|
||||
TimeLineResultView.startDateToEndDate.text={0} to {1}
|
||||
VisualizationPanel.histogramTask.title=Rebuild Histogram
|
||||
VisualizationPanel.histogramTask.preparing=preparing
|
||||
VisualizationPanel.histogramTask.resetUI=resetting ui
|
||||
VisualizationPanel.histogramTask.queryDb=querying db
|
||||
VisualizationPanel.histogramTask.updateUI2=updating ui
|
||||
VisualizationPanel.visualizationModeLabel.text=Visualization Mode\:
|
||||
StatusBar.refreshLabel.text=New events may be available, re-open the timeline to refresh.
|
||||
StatusBar.messageLabel.text=Label
|
||||
StatusBar.taskLabel.text=Label
|
||||
VisualizationPanel.noEventsDialogLabel.text=There are no events visible with the current zoom / filter settings.
|
||||
VisualizationPanel.zoomButton.text=Zoom to events
|
||||
VisualizationPanel.startLabel.text=Start\:
|
||||
VisualizationPanel.endLabel.text=End\:
|
||||
TimeZonePanel.localRadio.text=Local Time Zone
|
||||
TimeZonePanel.otherRadio.text=GMT / UTC
|
||||
VisualizationPanel.zoomMenuButton.text=Zoom in/out to
|
||||
VisualizationPanel.snapShotButton.text=Screenshot
|
||||
VisualizationPanel.detailsToggle.text=Details
|
||||
VisualizationPanel.countsToggle.text=Counts
|
||||
VisualizationPanel.resetFiltersButton.text=Reset all filters
|
||||
@@ -0,0 +1,23 @@
|
||||
Timeline.node.root=\u30EB\u30FC\u30C8
|
||||
Timeline.ui.TimeLineChart.tooltip.text=\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF\u3067\u4E0B\u8A18\u306E\u7BC4\u56F2\u3078\u30BA\u30FC\u30E0\uFF1A\n{0}\u301C{1}\n\u53F3\u30AF\u30EA\u30C3\u30AF\u3067\u5143\u306B\u623B\u308A\u307E\u3059\u3002
|
||||
Timeline.ui.ZoomRanges.all.text=\u5168\u3066
|
||||
TimeLineResultView.startDateToEndDate.text={0}\u304B\u3089{1}
|
||||
VisualizationPanel.histogramTask.preparing=\u6E96\u5099\u4E2D
|
||||
VisualizationPanel.histogramTask.queryDb=DB\u3092\u30AF\u30A8\u30EA\u4E2D
|
||||
VisualizationPanel.histogramTask.resetUI=ui\u3092\u518D\u8A2D\u5B9A\u4E2D
|
||||
VisualizationPanel.histogramTask.title=\u30D2\u30B9\u30C8\u30B0\u30E9\u30E0\u3092\u518D\u4F5C\u6210
|
||||
VisualizationPanel.histogramTask.updateUI2=ui\u3092\u66F4\u65B0\u4E2D
|
||||
StatusBar.messageLabel.text=\u30E9\u30D9\u30EB
|
||||
StatusBar.refreshLabel.text=\u65B0\u898F\u30A4\u30D9\u30F3\u30C8\u304C\u3042\u308B\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5\u3059\u308B\u306B\u306F\u30BF\u30A4\u30E0\u30E9\u30A4\u30F3\u3092\u518D\u5EA6\u958B\u3044\u3066\u304F\u3060\u3055\u3044\u3002
|
||||
StatusBar.taskLabel.text=\u30E9\u30D9\u30EB
|
||||
TimeZonePanel.localRadio.text=\u30ED\u30FC\u30AB\u30EB\u30BF\u30A4\u30E0\u30BE\u30FC\u30F3
|
||||
VisualizationPanel.countsToggle.text=\u30AB\u30A6\u30F3\u30C8
|
||||
VisualizationPanel.detailsToggle.text=\u8A73\u7D30
|
||||
VisualizationPanel.endLabel.text=\u30A8\u30F3\u30C9\uFF1A
|
||||
VisualizationPanel.noEventsDialogLabel.text=\u73FE\u5728\u306E\u30BA\u30FC\u30E0\uFF0F\u30D5\u30A3\u30EB\u30BF\u8A2D\u5B9A\u3067\u306F\u898B\u3048\u308B\u30A4\u30D9\u30F3\u30C8\u304C\u3042\u308A\u307E\u305B\u3093\u3002
|
||||
VisualizationPanel.resetFiltersButton.text=\u5168\u3066\u306E\u30D5\u30A3\u30EB\u30BF\u3092\u30EA\u30BB\u30C3\u30C8
|
||||
VisualizationPanel.snapShotButton.text=\u30B9\u30AF\u30EA\u30FC\u30F3\u30B7\u30E7\u30C3\u30C8
|
||||
VisualizationPanel.startLabel.text=\u30B9\u30BF\u30FC\u30C8\uFF1A
|
||||
VisualizationPanel.visualizationModeLabel.text=\u53EF\u8996\u5316\u30E2\u30FC\u30C9\uFF1A
|
||||
VisualizationPanel.zoomButton.text=\u30A4\u30D9\u30F3\u30C8\u3078\u30BA\u30FC\u30E0
|
||||
VisualizationPanel.zoomMenuButton.text=\u4E0B\u8A18\u3078\u30BA\u30FC\u30E0\u30A4\u30F3\uFF0F\u30BA\u30FC\u30E0\u30A2\u30A6\u30C8
|
||||
@@ -19,7 +19,7 @@
|
||||
</graphic>
|
||||
<content>
|
||||
<VBox alignment="CENTER_RIGHT" fillWidth="false" prefHeight="130.0" prefWidth="259.0" spacing="5.0">
|
||||
<children><Label graphicTextGap="10.0" text="There are no events visible with the current zoom / filter settings. " wrapText="true" GridPane.columnIndex="1" VBox.vgrow="ALWAYS">
|
||||
<children><Label graphicTextGap="10.0" fx:id="noEventsDialogLabel" wrapText="true" GridPane.columnIndex="1" VBox.vgrow="ALWAYS">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
@@ -39,7 +39,7 @@
|
||||
<HBox.margin>
|
||||
<Insets />
|
||||
</HBox.margin></ImageView>
|
||||
</graphic></Label><Button fx:id="zoomButton" alignment="BASELINE_LEFT" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Zoom to events" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
</graphic></Label><Button fx:id="zoomButton" alignment="BASELINE_LEFT" maxWidth="1.7976931348623157E308" mnemonicParsing="false" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<graphic><ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../images/magnifier-zoom-out-red.png" />
|
||||
@@ -50,7 +50,7 @@
|
||||
</GridPane.margin>
|
||||
<VBox.margin>
|
||||
<Insets />
|
||||
</VBox.margin></Button><Button fx:id="resetFiltersButton" alignment="BASELINE_LEFT" maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="25.0" prefWidth="120.0" text="Reset all filters" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER">
|
||||
</VBox.margin></Button><Button fx:id="resetFiltersButton" alignment="BASELINE_LEFT" maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="25.0" prefWidth="120.0" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER">
|
||||
<graphic>
|
||||
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" type="ToolBar" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<items><Label fx:id="refreshLabel" text="New events may be available, re-open the timeline to refresh.">
|
||||
<items><Label fx:id="refreshLabel">
|
||||
<graphic><ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../images/info-icon-16.png" />
|
||||
</image></ImageView>
|
||||
</graphic></Label><Separator orientation="VERTICAL" /><Region fx:id="spacer" /><Separator orientation="VERTICAL" /><Label fx:id="taskLabel" contentDisplay="RIGHT" text="Label">
|
||||
</graphic></Label><Separator orientation="VERTICAL" /><Region fx:id="spacer" /><Separator orientation="VERTICAL" /><Label fx:id="taskLabel" contentDisplay="RIGHT">
|
||||
<graphic><StackPane>
|
||||
<children><ProgressBar fx:id="progressBar" progress="0.0" /><Label fx:id="messageLabel" text="Label" />
|
||||
<children><ProgressBar fx:id="progressBar" progress="0.0" /><Label fx:id="messageLabel" />
|
||||
</children></StackPane>
|
||||
</graphic></Label>
|
||||
</items>
|
||||
|
||||
@@ -25,6 +25,7 @@ import javafx.scene.control.ToolBar;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineUI;
|
||||
@@ -53,17 +54,20 @@ public class StatusBar extends ToolBar implements TimeLineUI {
|
||||
private Label messageLabel;
|
||||
|
||||
public StatusBar() {
|
||||
FXMLConstructor.construct(this, "StatusBar.fxml");
|
||||
FXMLConstructor.construct(this, "StatusBar.fxml"); // NON-NLS
|
||||
}
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
assert refreshLabel != null : "fx:id=\"refreshLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||
assert progressBar != null : "fx:id=\"progressBar\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||
assert spacer != null : "fx:id=\"spacer\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||
assert taskLabel != null : "fx:id=\"taskLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||
assert messageLabel != null : "fx:id=\"messageLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||
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 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 messageLabel != null : "fx:id=\"messageLabel\" was not injected: check your FXML file 'StatusBar.fxml'."; // NON-NLS
|
||||
refreshLabel.setVisible(false);
|
||||
refreshLabel.setText(NbBundle.getMessage(this.getClass(), "StatusBar.refreshLabel.text"));
|
||||
messageLabel.setText(NbBundle.getMessage(this.getClass(), "StatusBar.messageLabel.text"));
|
||||
taskLabel.setText(NbBundle.getMessage(this.getClass(), "StatusBar.taskLabel.text"));
|
||||
taskLabel.setVisible(false);
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Interval;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
||||
|
||||
@@ -249,7 +250,9 @@ public interface TimeLineChart<X> extends TimeLineView {
|
||||
final X start = getSpanStart();
|
||||
final X end = getSpanEnd();
|
||||
Tooltip.uninstall(this, tooltip);
|
||||
tooltip = new Tooltip("Double-click to zoom into range:\n" + formatSpan(start) + " to " + formatSpan(end) + "\nRight-click to clear.");
|
||||
tooltip = new Tooltip(
|
||||
NbBundle.getMessage(this.getClass(), "Timeline.ui.TimeLineChart.tooltip.text", formatSpan(start),
|
||||
formatSpan(end)));
|
||||
Tooltip.install(this, tooltip);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,9 +93,13 @@ public class TimeLineResultView implements TimeLineView {
|
||||
private String getSummaryString() {
|
||||
if (controller.getSelectedTimeRange().get() != null) {
|
||||
final DateTimeFormatter zonedFormatter = TimeLineController.getZonedFormatter();
|
||||
return controller.getSelectedTimeRange().get().getStart().withZone(TimeLineController.getJodaTimeZone()).toString(zonedFormatter)
|
||||
+ " to "
|
||||
+ controller.getSelectedTimeRange().get().getEnd().withZone(TimeLineController.getJodaTimeZone()).toString(zonedFormatter);
|
||||
return NbBundle.getMessage(this.getClass(), "TimeLineResultView.startDateToEndDate.text",
|
||||
controller.getSelectedTimeRange().get().getStart()
|
||||
.withZone(TimeLineController.getJodaTimeZone())
|
||||
.toString(zonedFormatter),
|
||||
controller.getSelectedTimeRange().get().getEnd()
|
||||
.withZone(TimeLineController.getJodaTimeZone())
|
||||
.toString(zonedFormatter));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<fx:root alignment="TOP_LEFT" animated="false" collapsible="false" contentDisplay="RIGHT" minHeight="-Infinity" minWidth="-Infinity" text="Display Times In:" type="TitledPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<fx:root alignment="TOP_LEFT" animated="false" collapsible="false" contentDisplay="RIGHT" minHeight="-Infinity" minWidth="-Infinity" type="TitledPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<graphic>
|
||||
<HBox spacing="5.0">
|
||||
<children><RadioButton fx:id="localRadio" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" selected="true" text="Local Time Zone">
|
||||
<children><RadioButton fx:id="localRadio" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" selected="true">
|
||||
<HBox.margin>
|
||||
<Insets />
|
||||
</HBox.margin>
|
||||
<toggleGroup>
|
||||
<ToggleGroup fx:id="localOtherGroup" />
|
||||
</toggleGroup></RadioButton><RadioButton fx:id="otherRadio" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" text="GMT / UTC" toggleGroup="$localOtherGroup">
|
||||
</toggleGroup></RadioButton><RadioButton fx:id="otherRadio" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" toggleGroup="$localOtherGroup">
|
||||
<HBox.margin>
|
||||
<Insets />
|
||||
</HBox.margin></RadioButton>
|
||||
|
||||
@@ -23,10 +23,8 @@ import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.RadioButton;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.control.Toggle;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.control.*;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
|
||||
@@ -47,7 +45,7 @@ public class TimeZonePanel extends TitledPane {
|
||||
|
||||
static private String getTimeZoneString(final TimeZone timeZone) {
|
||||
final String id = ZoneOffset.ofTotalSeconds(timeZone.getOffset(System.currentTimeMillis()) / 1000).getId();
|
||||
final String timeZoneString = "(GMT" + ("Z".equals(id) ? "+00:00" : id) + ") " + timeZone.getID() + " [" + timeZone.getDisplayName(timeZone.observesDaylightTime() && timeZone.inDaylightTime(new Date()), TimeZone.SHORT) + "]";
|
||||
final String timeZoneString = "(GMT" + ("Z".equals(id) ? "+00:00" : id) + ") " + timeZone.getID() + " [" + timeZone.getDisplayName(timeZone.observesDaylightTime() && timeZone.inDaylightTime(new Date()), TimeZone.SHORT) + "]"; // NON-NLS
|
||||
return timeZoneString;
|
||||
}
|
||||
|
||||
@@ -55,16 +53,21 @@ public class TimeZonePanel extends TitledPane {
|
||||
public void initialize() {
|
||||
|
||||
// localRadio.setText("Local Time Zone: " + getTimeZoneString(TimeZone.getDefault()));
|
||||
localOtherGroup.selectedToggleProperty().addListener((ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) -> {
|
||||
if (newValue == localRadio) {
|
||||
TimeLineController.setTimeZone(TimeZone.getDefault());
|
||||
} else {
|
||||
TimeLineController.setTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC));
|
||||
}
|
||||
});
|
||||
localRadio.setText(NbBundle.getMessage(this.getClass(), "TimeZonePanel.localRadio.text"));
|
||||
otherRadio.setText(NbBundle.getMessage(this.getClass(), "TimeZonePanel.otherRadio.text"));
|
||||
// The text field for this TimeZonePanel (TitlePane) object is set by the instantiating class (TimeLineTopComponent).
|
||||
|
||||
localOtherGroup.selectedToggleProperty().addListener(
|
||||
(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) -> {
|
||||
if (newValue == localRadio) {
|
||||
TimeLineController.setTimeZone(TimeZone.getDefault());
|
||||
} else {
|
||||
TimeLineController.setTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public TimeZonePanel() {
|
||||
FXMLConstructor.construct(this, "TimeZonePanel.fxml");
|
||||
FXMLConstructor.construct(this, "TimeZonePanel.fxml"); // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<items>
|
||||
<HBox alignment="CENTER" BorderPane.alignment="CENTER">
|
||||
<children>
|
||||
<Label text="Visualization Mode:">
|
||||
<Label fx:id="visualizationModeLabel">
|
||||
<HBox.margin>
|
||||
<Insets right="5.0" />
|
||||
</HBox.margin>
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
<org.controlsfx.control.SegmentedButton maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity">
|
||||
<buttons>
|
||||
<ToggleButton fx:id="countsToggle" alignment="TOP_LEFT" mnemonicParsing="false" selected="true" text="Counts">
|
||||
<ToggleButton fx:id="countsToggle" alignment="TOP_LEFT" mnemonicParsing="false" selected="true">
|
||||
<graphic>
|
||||
<ImageView fitHeight="16.0" fitWidth="16.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
@@ -38,7 +38,7 @@
|
||||
<Font name="System Bold" size="16.0" />
|
||||
</font>
|
||||
</ToggleButton>
|
||||
<ToggleButton fx:id="detailsToggle" alignment="CENTER_RIGHT" layoutX="74.0" mnemonicParsing="false" selected="false" text="Details">
|
||||
<ToggleButton fx:id="detailsToggle" alignment="CENTER_RIGHT" layoutX="74.0" mnemonicParsing="false" selected="false">
|
||||
<graphic>
|
||||
<ImageView fitHeight="16.0" fitWidth="16.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true" rotate="0.0" smooth="true" style="-fx-background-color:white;" x="2.0" y="1.0">
|
||||
<image>
|
||||
@@ -62,7 +62,7 @@
|
||||
</BorderPane.margin>
|
||||
</HBox>
|
||||
<Separator orientation="VERTICAL" />
|
||||
<Button fx:id="snapShotButton" mnemonicParsing="false" text="Screenshot">
|
||||
<Button fx:id="snapShotButton" mnemonicParsing="false">
|
||||
<graphic>
|
||||
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
@@ -99,7 +99,7 @@
|
||||
<Separator />
|
||||
<ToolBar>
|
||||
<items>
|
||||
<Label contentDisplay="RIGHT" minWidth="-Infinity" text="Start:">
|
||||
<Label fx:id="startLabel" contentDisplay="RIGHT" minWidth="-Infinity">
|
||||
<graphic>
|
||||
<LocalDateTimeTextField fx:id="startPicker" minWidth="200.0" prefWidth="200.0">
|
||||
<padding>
|
||||
@@ -141,7 +141,7 @@
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
<MenuButton fx:id="zoomMenuButton" mnemonicParsing="false" text="Zoom in/out to">
|
||||
<MenuButton fx:id="zoomMenuButton" mnemonicParsing="false">
|
||||
<graphic>
|
||||
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
@@ -158,7 +158,7 @@
|
||||
<Insets left="10.0" right="10.0" />
|
||||
</HBox.margin>
|
||||
</Separator>
|
||||
<Label contentDisplay="RIGHT" minWidth="-Infinity" text="End:">
|
||||
<Label fx:id="endLabel" contentDisplay="RIGHT" minWidth="-Infinity">
|
||||
<graphic>
|
||||
<LocalDateTimeTextField fx:id="endPicker" minWidth="200.0" nodeOrientation="LEFT_TO_RIGHT" prefWidth="200.0">
|
||||
<padding>
|
||||
|
||||
@@ -34,15 +34,7 @@ import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Rectangle2D;
|
||||
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.TitledPane;
|
||||
import javafx.scene.control.Toggle;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
import javafx.scene.control.ToolBar;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.effect.Lighting;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
@@ -64,6 +56,7 @@ import org.controlsfx.control.action.Action;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.Interval;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.LoggedTask;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
@@ -112,7 +105,7 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
|
||||
private final RangeSlider rangeSlider = new RangeSlider(0, 1.0, .25, .75);
|
||||
|
||||
//// time range selection componenets
|
||||
//// time range selection components
|
||||
@FXML
|
||||
protected MenuButton zoomMenuButton;
|
||||
|
||||
@@ -194,17 +187,17 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
|
||||
public VisualizationPanel(NavPanel navPanel) {
|
||||
this.navPanel = navPanel;
|
||||
FXMLConstructor.construct(this, "VisualizationPanel.fxml");
|
||||
FXMLConstructor.construct(this, "VisualizationPanel.fxml"); // NON-NLS
|
||||
}
|
||||
|
||||
@FXML // This method is called by the FXMLLoader when initialization is complete
|
||||
protected void initialize() {
|
||||
assert endPicker != null : "fx:id=\"endPicker\" was not injected: check your FXML file 'ViewWrapper.fxml'.";
|
||||
assert histogramBox != null : "fx:id=\"histogramBox\" was not injected: check your FXML file 'ViewWrapper.fxml'.";
|
||||
assert startPicker != null : "fx:id=\"startPicker\" was not injected: check your FXML file 'ViewWrapper.fxml'.";
|
||||
assert rangeHistogramStack != null : "fx:id=\"rangeHistogramStack\" was not injected: check your FXML file 'ViewWrapper.fxml'.";
|
||||
assert countsToggle != null : "fx:id=\"countsToggle\" was not injected: check your FXML file 'VisToggle.fxml'.";
|
||||
assert detailsToggle != null : "fx:id=\"eventsToggle\" was not injected: check your FXML file 'VisToggle.fxml'.";
|
||||
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 startPicker != null : "fx:id=\"startPicker\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS
|
||||
assert rangeHistogramStack != null : "fx:id=\"rangeHistogramStack\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS
|
||||
assert countsToggle != null : "fx:id=\"countsToggle\" was not injected: check your FXML file 'VisToggle.fxml'."; // NON-NLS
|
||||
assert detailsToggle != null : "fx:id=\"eventsToggle\" was not injected: check your FXML file 'VisToggle.fxml'."; // NON-NLS
|
||||
|
||||
HBox.setHgrow(leftSeperator, Priority.ALWAYS);
|
||||
HBox.setHgrow(rightSeperator, Priority.ALWAYS);
|
||||
@@ -227,6 +220,8 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
countsToggle.getToggleGroup().selectedToggleProperty().addListener(toggleListener);
|
||||
});
|
||||
}
|
||||
countsToggle.setText(NbBundle.getMessage(this.getClass(), "VisualizationPanel.countsToggle.text"));
|
||||
detailsToggle.setText(NbBundle.getMessage(this.getClass(), "VisualizationPanel.detailsToggle.text"));
|
||||
|
||||
//setup rangeslider
|
||||
rangeSlider.setOpacity(.7);
|
||||
@@ -253,7 +248,7 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
/* this padding attempts to compensates for the fact that the
|
||||
* rangeslider track doesn't extend to edge of node,and so the
|
||||
* histrogram doesn't quite line up with the rangeslider */
|
||||
histogramBox.setStyle(" -fx-padding: 0,0.5em,0,.5em; ");
|
||||
histogramBox.setStyle(" -fx-padding: 0,0.5em,0,.5em; "); // NON-NLS
|
||||
|
||||
zoomMenuButton.getItems().clear();
|
||||
for (ZoomRanges b : ZoomRanges.values()) {
|
||||
@@ -268,6 +263,7 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
});
|
||||
zoomMenuButton.getItems().add(menuItem);
|
||||
}
|
||||
zoomMenuButton.setText(NbBundle.getMessage(this.getClass(), "VisualizationPanel.zoomMenuButton.text"));
|
||||
|
||||
zoomOutButton.setOnAction(e -> {
|
||||
controller.pushZoomOutTime();
|
||||
@@ -287,6 +283,8 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
//pass snapshot to save action
|
||||
new SaveSnapshot(controller, snapshot).handle(event);
|
||||
});
|
||||
|
||||
snapShotButton.setText(NbBundle.getMessage(this.getClass(), "VisualizationPanel.snapShotButton.text"));
|
||||
}
|
||||
|
||||
// /**
|
||||
@@ -416,12 +414,13 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
histogramTask.cancel(true);
|
||||
}
|
||||
|
||||
histogramTask = new LoggedTask<Void>("Rebuild Histogram", true) {
|
||||
histogramTask = new LoggedTask<Void>(
|
||||
NbBundle.getMessage(this.getClass(), "VisualizationPanel.histogramTask.title"), true) {
|
||||
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
|
||||
updateMessage("preparing");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "VisualizationPanel.histogramTask.preparing"));
|
||||
|
||||
long max = 0;
|
||||
final RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval());
|
||||
@@ -434,7 +433,7 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
|
||||
//clear old data, and reset ranges and series
|
||||
Platform.runLater(() -> {
|
||||
updateMessage("resetting ui");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "VisualizationPanel.histogramTask.resetUI"));
|
||||
|
||||
});
|
||||
|
||||
@@ -451,7 +450,7 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
|
||||
start = end;
|
||||
|
||||
updateMessage("querying db");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "VisualizationPanel.histogramTask.queryDb"));
|
||||
//query for current range
|
||||
long count = filteredEvents.getEventCounts(interval).values().stream().mapToLong(Long::valueOf).sum();
|
||||
bins.add(count);
|
||||
@@ -461,7 +460,7 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
final double fMax = Math.log(max);
|
||||
final ArrayList<Long> fbins = new ArrayList<>(bins);
|
||||
Platform.runLater(() -> {
|
||||
updateMessage("updating ui");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "VisualizationPanel.histogramTask.updateUI2"));
|
||||
|
||||
histogramBox.getChildren().clear();
|
||||
|
||||
@@ -479,7 +478,7 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
Tooltip.install(bar, new Tooltip(bin.toString()));
|
||||
});
|
||||
bar.setEffect(lighting);
|
||||
//they each get equal width to fill the histogram horizontaly
|
||||
//they each get equal width to fill the histogram horizontally
|
||||
HBox.setHgrow(bar, Priority.ALWAYS);
|
||||
histogramBox.getChildren().add(bar);
|
||||
}
|
||||
@@ -553,17 +552,37 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
@FXML
|
||||
private Button zoomButton;
|
||||
|
||||
@FXML
|
||||
private Label visualizationModeLabel;
|
||||
|
||||
@FXML
|
||||
private Label noEventsDialogLabel;
|
||||
|
||||
@FXML
|
||||
private Label startLabel;
|
||||
|
||||
@FXML
|
||||
private Label endLabel;
|
||||
|
||||
public NoEventsDialog(Runnable closeCallback) {
|
||||
this.closeCallback = closeCallback;
|
||||
FXMLConstructor.construct(this, "NoEventsDialog.fxml");
|
||||
FXMLConstructor.construct(this, "NoEventsDialog.fxml"); // NON-NLS
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
assert resetFiltersButton != null : "fx:id=\"resetFiltersButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'.";
|
||||
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'.";
|
||||
assert resetFiltersButton != null : "fx:id=\"resetFiltersButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS
|
||||
assert dismissButton != null : "fx:id=\"dismissButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS
|
||||
assert zoomButton != null : "fx:id=\"zoomButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS
|
||||
|
||||
visualizationModeLabel.setText(
|
||||
NbBundle.getMessage(this.getClass(), "VisualizationPanel.visualizationModeLabel.text"));
|
||||
noEventsDialogLabel.setText(
|
||||
NbBundle.getMessage(this.getClass(), "VisualizationPanel.noEventsDialogLabel.text"));
|
||||
zoomButton.setText(NbBundle.getMessage(this.getClass(), "VisualizationPanel.zoomButton.text"));
|
||||
startLabel.setText(NbBundle.getMessage(this.getClass(), "VisualizationPanel.startLabel.text"));
|
||||
endLabel.setText(NbBundle.getMessage(this.getClass(), "VisualizationPanel.endLabel.text"));
|
||||
|
||||
Action zoomOutAction = new ZoomOut(controller);
|
||||
zoomButton.setOnAction(zoomOutAction);
|
||||
@@ -575,6 +594,8 @@ public class VisualizationPanel extends BorderPane implements TimeLineView {
|
||||
Action defaultFiltersAction = new DefaultFilters(controller);
|
||||
resetFiltersButton.setOnAction(defaultFiltersAction);
|
||||
resetFiltersButton.disableProperty().bind(defaultFiltersAction.disabledProperty());
|
||||
resetFiltersButton.setText(
|
||||
NbBundle.getMessage(this.getClass(), "VisualizationPanel.resetFiltersButton.text"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,29 +7,30 @@ import org.joda.time.Months;
|
||||
import org.joda.time.ReadablePeriod;
|
||||
import org.joda.time.Weeks;
|
||||
import org.joda.time.Years;
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public enum ZoomRanges {
|
||||
|
||||
ONE_MINUTE("One Minute", Minutes.ONE),
|
||||
FIFTEEN_MINUTES("Fifteen Minutes", Minutes.minutes(15)),
|
||||
ONE_HOUR("One Hour", Hours.ONE),
|
||||
SIX_HOURS("Six Hours", Hours.SIX),
|
||||
TWELVE_HOURS("Twelve Hours", Hours.hours(12)),
|
||||
ONE_DAY("One Day", Days.ONE),
|
||||
THREE_DAYS("Three Days", Days.THREE),
|
||||
ONE_WEEK("One Week", Weeks.ONE),
|
||||
TWO_WEEK("Two Weeks", Weeks.TWO),
|
||||
ONE_MONTH("One Month", Months.ONE),
|
||||
THREE_MONTHS("Three Months", Months.THREE),
|
||||
SIX_MONTHS("Six Months", Months.SIX),
|
||||
ONE_YEAR("One Year", Years.ONE),
|
||||
THREE_YEARS("Three Years", Years.THREE),
|
||||
FIVE_YEARS("Five Years", Years.years(5)),
|
||||
TEN_YEARS("Ten Years", Years.years(10)),
|
||||
ALL("All", Minutes.ONE);
|
||||
ONE_MINUTE(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.onemin.text"), Minutes.ONE),
|
||||
FIFTEEN_MINUTES(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.fifteenmin.text"), Minutes.minutes(15)),
|
||||
ONE_HOUR(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.onehour.text"), Hours.ONE),
|
||||
SIX_HOURS(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.sixhours.text"), Hours.SIX),
|
||||
TWELVE_HOURS(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.twelvehours.text"), Hours.hours(12)),
|
||||
ONE_DAY(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.oneday.text"), Days.ONE),
|
||||
THREE_DAYS(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.threedays.text"), Days.THREE),
|
||||
ONE_WEEK(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.oneweek.text"), Weeks.ONE),
|
||||
TWO_WEEK(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.twoweeks.text"), Weeks.TWO),
|
||||
ONE_MONTH(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.onemonth.text"), Months.ONE),
|
||||
THREE_MONTHS(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.threemonths.text"), Months.THREE),
|
||||
SIX_MONTHS(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.sixmonths.text"), Months.SIX),
|
||||
ONE_YEAR(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.oneyear.text"), Years.ONE),
|
||||
THREE_YEARS(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.threeyears.text"), Years.THREE),
|
||||
FIVE_YEARS(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.fiveyears.text"), Years.years(5)),
|
||||
TEN_YEARS(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.tenyears.text"), Years.years(10)),
|
||||
ALL(NbBundle.getMessage(ZoomRanges.class, "Timeline.ui.ZoomRanges.all.text"), Minutes.ONE);
|
||||
|
||||
private ZoomRanges(String displayName, ReadablePeriod period) {
|
||||
this.displayName = displayName;
|
||||
|
||||
@@ -22,3 +22,18 @@ CountsChartPane.numberOfEvents=Number of Events
|
||||
CountsViewPane.detailSwitchMessage=There is no temporal resolution smaller than Seconds.\nWould you like to switch to the Details view instead?
|
||||
#this is the title shown in the dialog when the user double clicks a bar at seconds resolution
|
||||
CountsViewPane.detailSwitchTitle="Switch to Details View?
|
||||
Timeline.ui.countsview.menuItem.selectTimeRange=Select Time Range
|
||||
Timeline.ui.countsview.menuItem.selectEventType=Select Event Type
|
||||
Timeline.ui.countsview.menuItem.selectTimeandType=Select Time and Type
|
||||
Timeline.ui.countsview.menuItem.zoomIntoTimeRange=Zoom into Time Range
|
||||
Timeline.ui.countsview.contextMenu.ActionGroup.zoomHistory.title=Zoom History
|
||||
CountsViewPane.loggedTask.name=Updating Counts Graph
|
||||
CountsViewPane.loggedTask.prepUpdate=preparing update
|
||||
CountsViewPane.loggedTask.resetUI=resetting ui
|
||||
CountsViewPane.tooltip.text={0} {1} events\nbetween {2}\nand {3}
|
||||
CountsViewPane.loggedTask.updatingCounts=updating counts
|
||||
CountsViewPane.loggedTask.wrappingUp=wrapping up
|
||||
EventCountsChart.contextMenu.zoomHistory.name=Zoom History
|
||||
CountsViewPane.scaleLabel.text=Scale\:
|
||||
CountsViewPane.logRadio.text=Logarithmic
|
||||
CountsViewPane.linearRadio.text=Linear
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
CountsChartPane.numberOfEvents=\u30A4\u30D9\u30F3\u30C8\u6570
|
||||
CountsViewPane.detailSwitchMessage=\u79D2\u3088\u308A\u5C0F\u3055\u3044\u5358\u4F4D\u306F\u3042\u308A\u307E\u305B\u3093\u3002\n\u8A73\u7D30\u30D3\u30E5\u30FC\u306B\u5909\u66F4\u3057\u307E\u3059\u304B\uFF1F
|
||||
CountsViewPane.detailSwitchTitle=\u8A73\u7D30\u30D3\u30E5\u30FC\u306B\u5909\u66F4\u3057\u307E\u3059\u304B\uFF1F
|
||||
Timeline.ui.countsview.contextMenu.ActionGroup.zoomHistory.title=\u30BA\u30FC\u30E0\u5C65\u6B74
|
||||
Timeline.ui.countsview.menuItem.selectEventType=\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u3092\u9078\u629E
|
||||
Timeline.ui.countsview.menuItem.selectTimeandType=\u6642\u9593\u3068\u30BF\u30A4\u30D7\u3092\u9078\u629E
|
||||
Timeline.ui.countsview.menuItem.selectTimeRange=\u6642\u9593\u7BC4\u56F2\u3092\u9078\u629E
|
||||
Timeline.ui.countsview.menuItem.zoomIntoTimeRange=\u6642\u9593\u7BC4\u56F2\u3078\u30BA\u30FC\u30E0\u30A4\u30F3
|
||||
CountsViewPane.loggedTask.name=\u30AB\u30A6\u30F3\u30C8\u30B0\u30E9\u30D5\u66F4\u65B0\u4E2D
|
||||
CountsViewPane.loggedTask.prepUpdate=\u66F4\u65B0\u3092\u6E96\u5099\u4E2D
|
||||
CountsViewPane.loggedTask.resetUI=ui\u3092\u30EA\u30BB\u30C3\u30C8\u4E2D
|
||||
CountsViewPane.loggedTask.updatingCounts=\u30AB\u30A6\u30F3\u30C8\u3092\u66F4\u65B0\u4E2D
|
||||
CountsViewPane.loggedTask.wrappingUp=\u6700\u7D42\u51E6\u7406\u5B9F\u884C\u4E2D
|
||||
CountsViewPane.tooltip.text={0} {1} \u30A4\u30D9\u30F3\u30C8\n{2}\u3068\n{3}\u306E\u9593
|
||||
EventCountsChart.contextMenu.zoomHistory.name=\u30BA\u30FC\u30E0\u5C65\u6B74
|
||||
CountsViewPane.linearRadio.text=\u30EA\u30CB\u30A2
|
||||
CountsViewPane.logRadio.text=\u5BFE\u6570\u7684
|
||||
CountsViewPane.scaleLabel.text=\u30B9\u30B1\u30FC\u30EB\uFF1A
|
||||
@@ -38,12 +38,7 @@ import javafx.scene.chart.CategoryAxis;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.StackedBarChart;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.RadioButton;
|
||||
import javafx.scene.control.SeparatorMenuItem;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.effect.DropShadow;
|
||||
import javafx.scene.effect.Effect;
|
||||
import javafx.scene.effect.Lighting;
|
||||
@@ -124,14 +119,16 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
|
||||
private ContextMenu getContextMenu() {
|
||||
|
||||
ContextMenu chartContextMenu = ActionUtils.createContextMenu(Arrays.asList(new ActionGroup("Zoom History", new Back(controller), new Forward(controller))));
|
||||
ContextMenu chartContextMenu = ActionUtils.createContextMenu(Arrays.asList(new ActionGroup(
|
||||
NbBundle.getMessage(this.getClass(), "Timeline.ui.countsview.contextMenu.ActionGroup.zoomHistory.title"),
|
||||
new Back(controller), new Forward(controller))));
|
||||
chartContextMenu.setAutoHide(true);
|
||||
return chartContextMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Task<Boolean> getUpdateTask() {
|
||||
return new LoggedTask<Boolean>("Updating Counts Graph", true) {
|
||||
return new LoggedTask<Boolean>(NbBundle.getMessage(this.getClass(), "CountsViewPane.loggedTask.name"), true) {
|
||||
|
||||
@Override
|
||||
protected Boolean call() throws Exception {
|
||||
@@ -139,7 +136,7 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
return null;
|
||||
}
|
||||
updateProgress(-1, 1);
|
||||
updateMessage("preparing update");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "CountsViewPane.loggedTask.prepUpdate"));
|
||||
Platform.runLater(() -> {
|
||||
setCursor(Cursor.WAIT);
|
||||
});
|
||||
@@ -156,7 +153,7 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
|
||||
//clear old data, and reset ranges and series
|
||||
Platform.runLater(() -> {
|
||||
updateMessage("resetting ui");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "CountsViewPane.loggedTask.resetUI"));
|
||||
eventTypeMap.clear();
|
||||
dataSets.clear();
|
||||
dateAxis.getCategories().clear();
|
||||
@@ -207,15 +204,18 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
xyData.nodeProperty().addListener((Observable o) -> {
|
||||
final Node node = xyData.getNode();
|
||||
if (node != null) {
|
||||
node.setStyle("-fx-border-width: 2; -fx-border-color: " + ColorUtilities.getRGBCode(et.getSuperType().getColor()) + "; -fx-bar-fill: " + ColorUtilities.getRGBCode(et.getColor()));
|
||||
node.setStyle("-fx-border-width: 2; -fx-border-color: " + ColorUtilities.getRGBCode(et.getSuperType().getColor()) + "; -fx-bar-fill: " + ColorUtilities.getRGBCode(et.getColor())); // NON-NLS
|
||||
node.setCursor(Cursor.HAND);
|
||||
|
||||
node.setOnMouseEntered((MouseEvent event) -> {
|
||||
//defer tooltip creation till needed, this had a surprisingly large impact on speed of loading the chart
|
||||
final Tooltip tooltip = new Tooltip(count + " " + et.getDisplayName() + " events\n"
|
||||
+ "between " + dateString + "\n"
|
||||
+ "and "
|
||||
+ interval.getEnd().toString(rangeInfo.getTickFormatter()));
|
||||
final Tooltip tooltip = new Tooltip(
|
||||
NbBundle.getMessage(this.getClass(), "CountsViewPane.tooltip.text",
|
||||
count,
|
||||
et.getDisplayName(),
|
||||
dateString,
|
||||
interval.getEnd().toString(
|
||||
rangeInfo.getTickFormatter())));
|
||||
tooltip.setGraphic(new ImageView(et.getFXImage()));
|
||||
Tooltip.install(node, tooltip);
|
||||
node.setEffect(new DropShadow(10, et.getColor()));
|
||||
@@ -237,7 +237,8 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
final double fmax = max;
|
||||
|
||||
Platform.runLater(() -> {
|
||||
updateMessage("updating counts");
|
||||
updateMessage(
|
||||
NbBundle.getMessage(this.getClass(), "CountsViewPane.loggedTask.updatingCounts"));
|
||||
getSeries(et).getData().add(xyData);
|
||||
if (scale.get().equals(ScaleType.LINEAR)) {
|
||||
countAxis.setTickUnit(Math.pow(10, Math.max(0, Math.floor(Math.log10(fmax)) - 1)));
|
||||
@@ -252,7 +253,8 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
final double fmax = max;
|
||||
|
||||
Platform.runLater(() -> {
|
||||
updateMessage("updating counts");
|
||||
updateMessage(
|
||||
NbBundle.getMessage(this.getClass(), "CountsViewPane.loggedTask.updatingCounts"));
|
||||
updateProgress(fp, rangeInfo.getPeriodsInRange());
|
||||
});
|
||||
}
|
||||
@@ -260,7 +262,7 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
updateMessage("wrapping up");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "CountsViewPane.loggedTask.wrappingUp"));
|
||||
updateProgress(1, 1);
|
||||
layoutDateLabels();
|
||||
setCursor(Cursor.NONE);
|
||||
@@ -397,7 +399,8 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
barContextMenu = new ContextMenu();
|
||||
barContextMenu.setAutoHide(true);
|
||||
barContextMenu.getItems().addAll(
|
||||
new MenuItem("Select Time Range") {
|
||||
new MenuItem(NbBundle.getMessage(this.getClass(),
|
||||
"Timeline.ui.countsview.menuItem.selectTimeRange")) {
|
||||
{
|
||||
setOnAction((ActionEvent t) -> {
|
||||
controller.selectTimeAndType(interval, RootEventType.getInstance());
|
||||
@@ -413,7 +416,8 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
});
|
||||
}
|
||||
},
|
||||
new MenuItem("Select Event Type") {
|
||||
new MenuItem(NbBundle.getMessage(this.getClass(),
|
||||
"Timeline.ui.countsview.menuItem.selectEventType")) {
|
||||
{
|
||||
setOnAction((ActionEvent t) -> {
|
||||
controller.selectTimeAndType(filteredEvents.getSpanningInterval(), type);
|
||||
@@ -426,7 +430,8 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
});
|
||||
}
|
||||
},
|
||||
new MenuItem("Select Time and Type") {
|
||||
new MenuItem(NbBundle.getMessage(this.getClass(),
|
||||
"Timeline.ui.countsview.menuItem.selectTimeandType")) {
|
||||
{
|
||||
setOnAction((ActionEvent t) -> {
|
||||
controller.selectTimeAndType(interval, type);
|
||||
@@ -435,7 +440,8 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
}
|
||||
},
|
||||
new SeparatorMenuItem(),
|
||||
new MenuItem("Zoom into Time Range") {
|
||||
new MenuItem(NbBundle.getMessage(this.getClass(),
|
||||
"Timeline.ui.countsview.menuItem.zoomIntoTimeRange")) {
|
||||
{
|
||||
setOnAction((ActionEvent t) -> {
|
||||
if (interval.toDuration().isShorterThan(Seconds.ONE.toStandardDuration()) == false) {
|
||||
@@ -499,10 +505,13 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
@FXML
|
||||
private ToggleGroup scaleGroup;
|
||||
|
||||
@FXML
|
||||
private Label scaleLabel;
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
assert logRadio != null : "fx:id=\"logRadio\" was not injected: check your FXML file 'CountsViewSettingsPane.fxml'.";
|
||||
assert linearRadio != null : "fx:id=\"linearRadio\" was not injected: check your FXML file 'CountsViewSettingsPane.fxml'.";
|
||||
assert logRadio != null : "fx:id=\"logRadio\" was not injected: check your FXML file 'CountsViewSettingsPane.fxml'."; // NON-NLS
|
||||
assert linearRadio != null : "fx:id=\"linearRadio\" was not injected: check your FXML file 'CountsViewSettingsPane.fxml'."; // NON-NLS
|
||||
logRadio.setSelected(true);
|
||||
scaleGroup.selectedToggleProperty().addListener(observable -> {
|
||||
if (scaleGroup.getSelectedToggle() == linearRadio) {
|
||||
@@ -512,10 +521,14 @@ public class CountsViewPane extends AbstractVisualization<String, Number, Node,
|
||||
scale.set(ScaleType.LOGARITHMIC);
|
||||
}
|
||||
});
|
||||
|
||||
logRadio.setText(NbBundle.getMessage(this.getClass(), "CountsViewPane.logRadio.text"));
|
||||
linearRadio.setText(NbBundle.getMessage(this.getClass(), "CountsViewPane.linearRadio.text"));
|
||||
scaleLabel.setText(NbBundle.getMessage(this.getClass(), "CountsViewPane.scaleLabel.text"));
|
||||
}
|
||||
|
||||
public CountsViewSettingsPane() {
|
||||
FXMLConstructor.construct(this, "CountsViewSettingsPane.fxml");
|
||||
FXMLConstructor.construct(this, "CountsViewSettingsPane.fxml"); // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label minHeight="-Infinity" minWidth="-Infinity" text="Scale: ">
|
||||
<Label fx:id="scaleLabel" minHeight="-Infinity" minWidth="-Infinity">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<RadioButton fx:id="logRadio" mnemonicParsing="false" selected="true" text="Logarithmic">
|
||||
<RadioButton fx:id="logRadio" mnemonicParsing="false" selected="true">
|
||||
<toggleGroup>
|
||||
<ToggleGroup fx:id="scaleGroup" />
|
||||
</toggleGroup>
|
||||
</RadioButton>
|
||||
<RadioButton fx:id="linearRadio" mnemonicParsing="false" text="Linear" toggleGroup="$scaleGroup" />
|
||||
<RadioButton fx:id="linearRadio" mnemonicParsing="false" toggleGroup="$scaleGroup" />
|
||||
</children>
|
||||
<HBox.margin>
|
||||
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
|
||||
|
||||
@@ -104,7 +104,10 @@ class EventCountsChart extends StackedBarChart<String, Number> implements TimeLi
|
||||
setModel(this.controller.getEventsModel());
|
||||
//we have defered creating context menu until control is available
|
||||
contextMenu = ActionUtils.createContextMenu(
|
||||
Arrays.asList(new ActionGroup("Zoom History", new Back(controller), new Forward(controller))));
|
||||
Arrays.asList(new ActionGroup(
|
||||
NbBundle.getMessage(this.getClass(), "EventCountsChart.contextMenu.zoomHistory.name"),
|
||||
new Back(controller),
|
||||
new Forward(controller))));
|
||||
contextMenu.setAutoHide(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Interval;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.ColorUtilities;
|
||||
import org.sleuthkit.autopsy.coreutils.LoggedTask;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
@@ -68,8 +69,8 @@ import org.sleuthkit.autopsy.timeline.zooming.ZoomParams;
|
||||
/** Represents an {@link AggregateEvent} in a {@link EventDetailChart}. */
|
||||
public class AggregateEventNode extends StackPane {
|
||||
|
||||
private final static Image PLUS = new Image("/org/sleuthkit/autopsy/timeline/images/plus-button.png");
|
||||
private final static Image MINUS = new Image("/org/sleuthkit/autopsy/timeline/images/minus-button.png");
|
||||
private final static Image PLUS = new Image("/org/sleuthkit/autopsy/timeline/images/plus-button.png"); // NON-NLS
|
||||
private final static Image MINUS = new Image("/org/sleuthkit/autopsy/timeline/images/minus-button.png"); // NON-NLS
|
||||
|
||||
private static final CornerRadii CORNER_RADII = new CornerRadii(3);
|
||||
|
||||
@@ -181,7 +182,7 @@ public class AggregateEventNode extends StackPane {
|
||||
spanFill = new Background(new BackgroundFill(evtColor.deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY));
|
||||
setBackground(new Background(new BackgroundFill(evtColor.deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY)));
|
||||
setCursor(Cursor.HAND);
|
||||
spanRegion.setStyle("-fx-border-width:2 0 2 2; -fx-border-radius: 2; -fx-border-color: " + ColorUtilities.getRGBCode(evtColor) + ";");
|
||||
spanRegion.setStyle("-fx-border-width:2 0 2 2; -fx-border-radius: 2; -fx-border-color: " + ColorUtilities.getRGBCode(evtColor) + ";"); // NON-NLS
|
||||
spanRegion.setBackground(spanFill);
|
||||
|
||||
//set up mouse hover effect and tooltip
|
||||
@@ -228,10 +229,11 @@ public class AggregateEventNode extends StackPane {
|
||||
}
|
||||
|
||||
private void installTooltip() {
|
||||
Tooltip.install(AggregateEventNode.this, new Tooltip(getEvent().getEventIDs().size() + " " + getEvent().getType() + " events\n"
|
||||
+ getEvent().getDescription()
|
||||
+ "\nbetween " + getEvent().getSpan().getStart().toString(TimeLineController.getZonedFormatter())
|
||||
+ "\nand " + getEvent().getSpan().getEnd().toString(TimeLineController.getZonedFormatter())));
|
||||
Tooltip.install(AggregateEventNode.this, new Tooltip(
|
||||
NbBundle.getMessage(this.getClass(), "AggregateEventNode.installTooltip.text",
|
||||
getEvent().getEventIDs().size(), getEvent().getType(), getEvent().getDescription(),
|
||||
getEvent().getSpan().getStart().toString(TimeLineController.getZonedFormatter()),
|
||||
getEvent().getSpan().getEnd().toString(TimeLineController.getZonedFormatter()))));
|
||||
}
|
||||
|
||||
public Pane getSubNodePane() {
|
||||
@@ -284,7 +286,7 @@ public class AggregateEventNode extends StackPane {
|
||||
? " ..." + StringUtils.substringAfter(description, parentEventNode.getEvent().getDescription())
|
||||
: description;
|
||||
descrLabel.setText(description);
|
||||
countLabel.setText(((size == 1) ? "" : " (" + size + ")"));
|
||||
countLabel.setText(((size == 1) ? "" : " (" + size + ")")); // NON-NLS
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -310,12 +312,12 @@ public class AggregateEventNode extends StackPane {
|
||||
void applyHighlightEffect(boolean applied) {
|
||||
|
||||
if (applied) {
|
||||
descrLabel.setStyle("-fx-font-weight: bold;");
|
||||
descrLabel.setStyle("-fx-font-weight: bold;"); // NON-NLS
|
||||
spanFill = new Background(new BackgroundFill(getEvent().getType().getColor().deriveColor(0, 1, 1, .3), CORNER_RADII, Insets.EMPTY));
|
||||
spanRegion.setBackground(spanFill);
|
||||
setBackground(new Background(new BackgroundFill(getEvent().getType().getColor().deriveColor(0, 1, 1, .2), CORNER_RADII, Insets.EMPTY)));
|
||||
} else {
|
||||
descrLabel.setStyle("-fx-font-weight: normal;");
|
||||
descrLabel.setStyle("-fx-font-weight: normal;"); // NON-NLS
|
||||
spanFill = new Background(new BackgroundFill(getEvent().getType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY));
|
||||
spanRegion.setBackground(spanFill);
|
||||
setBackground(new Background(new BackgroundFill(getEvent().getType().getColor().deriveColor(0, 1, 1, .1), CORNER_RADII, Insets.EMPTY)));
|
||||
@@ -366,7 +368,8 @@ public class AggregateEventNode extends StackPane {
|
||||
final Interval span = event.getSpan().withEndMillis(event.getSpan().getEndMillis() + 1000);
|
||||
|
||||
//make a task to load the subnodes
|
||||
LoggedTask<List<AggregateEventNode>> loggedTask = new LoggedTask<List<AggregateEventNode>>("Load sub events", true) {
|
||||
LoggedTask<List<AggregateEventNode>> loggedTask = new LoggedTask<List<AggregateEventNode>>(
|
||||
NbBundle.getMessage(this.getClass(), "AggregateEventNode.loggedTask.name"), true) {
|
||||
|
||||
@Override
|
||||
protected List<AggregateEventNode> call() throws Exception {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
Timeline.ui.detailview.tooltip.text={0}\nRight-click to remove.\nRight-drag to reposition.
|
||||
AggregateEventNode.installTooltip.text={0} {1} events\n{2}\nbetween {3}\nand {4}
|
||||
AggregateEventNode.loggedTask.name=Load sub events
|
||||
DetailViewPane.loggedTask.name=Update Details
|
||||
DetailViewPane.loggedTask.preparing=preparing
|
||||
DetailViewPane.loggedTask.queryDb=querying db
|
||||
DetailViewPane.loggedTask.updateUI=updating ui
|
||||
EventDetailChart.contextMenu.zoomHistory.name=Zoom History
|
||||
EventDetailChart.chartContextMenu.placeMarker.name=Place Marker
|
||||
DetailViewPane.truncateSliderLabel.text=max description width (px)\:
|
||||
DetailViewPane.advancedLayoutOptionsButtonLabel.text=Advanced Layout Options
|
||||
DetailViewPane.bandByTypeBox.text=Band by Type
|
||||
DetailViewPane.bandByTypeBoxMenuItem.text=Band by Type
|
||||
DetailViewPane.oneEventPerRowBox.text=One Event Per Row
|
||||
DetailViewPane.oneEventPerRowBoxMenuItem.text=One Event Per Row
|
||||
DetailViewPan.truncateAllBox.text=Truncate Descriptions
|
||||
DetailViewPan.truncateAllBoxMenuItem.text=Truncate Descriptions
|
||||
DetailViewPane.truncateSlideLabelMenuItem.text=max description width (px)
|
||||
DetailViewPane.descVisSeparatorMenuItem.text=Description Visibility
|
||||
DetailViewPane.showRadioMenuItem.text=Show Full Description
|
||||
DetailViewPane.showRadio.text=Show Full Description
|
||||
DetailViewPane.countsRadioMenuItem.text=Show Counts Only
|
||||
DetailViewPane.countsRadio.text=Show Counts Only
|
||||
DetailViewPane.hiddenRadioMenuItem.text=Hide Description
|
||||
DetailViewPane.hiddenRadio.text=Hide Description
|
||||
@@ -0,0 +1,25 @@
|
||||
Timeline.ui.detailview.tooltip.text={0}\n\u53F3\u30AF\u30EA\u30C3\u30AF\u3067\u524A\u9664\u3002\n\u53F3\u30AF\u30EA\u30C3\u30AF\uFF06\u30C9\u30E9\u30C3\u30B0\u3067\u4F4D\u7F6E\u5909\u66F4\u3002
|
||||
AggregateEventNode.installTooltip.text={0} {1} \u30A4\u30D9\u30F3\u30C8\n{2}\n{3}\u3068{4}\u306E\u9593
|
||||
AggregateEventNode.loggedTask.name=\u30B5\u30D6\u30A4\u30D9\u30F3\u30C8\u3092\u30ED\u30FC\u30C9
|
||||
DetailViewPane.loggedTask.name=\u8A73\u7D30\u3092\u66F4\u65B0
|
||||
DetailViewPane.loggedTask.preparing=\u6E96\u5099\u4E2D
|
||||
DetailViewPane.loggedTask.queryDb=DB\u3092\u30AF\u30A8\u30EA\u4E2D
|
||||
DetailViewPane.loggedTask.updateUI=ui\u3092\u66F4\u65B0\u4E2D
|
||||
EventDetailChart.chartContextMenu.placeMarker.name=\u30DE\u30FC\u30AB\u30FC\u3092\u8A2D\u7F6E
|
||||
EventDetailChart.contextMenu.zoomHistory.name=\u30BA\u30FC\u30E0\u5C65\u6B74
|
||||
DetailViewPan.truncateAllBox.text=\u8AAC\u660E\u3092\u524A\u9664
|
||||
DetailViewPan.truncateAllBoxMenuItem.text=\u8AAC\u660E\u3092\u524A\u9664
|
||||
DetailViewPane.advancedLayoutOptionsButtonLabel.text=\u30A2\u30C9\u30D0\u30F3\u30B9\u30EC\u30A4\u30A2\u30A6\u30C8\u30AA\u30D7\u30B7\u30E7\u30F3
|
||||
DetailViewPane.countsRadio.text=\u30AB\u30A6\u30F3\u30C8\u306E\u307F\u8868\u793A
|
||||
DetailViewPane.countsRadioMenuItem.text=\u30AB\u30A6\u30F3\u30C8\u306E\u307F\u8868\u793A
|
||||
DetailViewPane.descVisSeparatorMenuItem.text=\u8AAC\u660E\u53EF\u8996\u6027
|
||||
DetailViewPane.hiddenRadio.text=\u8AAC\u660E\u3092\u96A0\u3059
|
||||
DetailViewPane.hiddenRadioMenuItem.text=\u8AAC\u660E\u3092\u96A0\u3059
|
||||
DetailViewPane.oneEventPerRowBox.text=1\u5217\u306B\u3064\u304D1\u30A4\u30D9\u30F3\u30C8
|
||||
DetailViewPane.oneEventPerRowBoxMenuItem.text=1\u5217\u306B\u3064\u304D1\u30A4\u30D9\u30F3\u30C8
|
||||
DetailViewPane.showRadio.text=\u8A73\u7D30\u8AAC\u660E\u3092\u8868\u793A
|
||||
DetailViewPane.showRadioMenuItem.text=\u8A73\u7D30\u8AAC\u660E\u3092\u8868\u793A
|
||||
DetailViewPane.truncateSlideLabelMenuItem.text=\u8AAC\u660E\u306E\u6700\u5927\u5E45\uFF08px\uFF09
|
||||
DetailViewPane.truncateSliderLabel.text=\u8AAC\u660E\u306E\u6700\u5927\u5E45\uFF08px\uFF09\uFF1A
|
||||
DetailViewPane.bandByTypeBox.text=\u30BF\u30A4\u30D7\u306B\u5F93\u3044\u4E26\u3073\u66FF\u3048
|
||||
DetailViewPane.bandByTypeBoxMenuItem.text=\u30BF\u30A4\u30D7\u306B\u5F93\u3044\u4E26\u3073\u66FF\u3048
|
||||
@@ -67,7 +67,7 @@ final class DateAxis extends Axis<DateTime> {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "lowerBound";
|
||||
return "lowerBound"; // NON-NLS
|
||||
}
|
||||
};
|
||||
|
||||
@@ -105,7 +105,7 @@ final class DateAxis extends Axis<DateTime> {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "upperBound";
|
||||
return "upperBound"; // NON-NLS
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -37,14 +37,7 @@ import javafx.scene.Cursor;
|
||||
import javafx.scene.chart.Axis;
|
||||
import javafx.scene.chart.BarChart;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MultipleSelectionModel;
|
||||
import javafx.scene.control.RadioButton;
|
||||
import javafx.scene.control.ScrollBar;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.effect.Effect;
|
||||
import static javafx.scene.input.KeyCode.DOWN;
|
||||
import static javafx.scene.input.KeyCode.KP_DOWN;
|
||||
@@ -61,6 +54,7 @@ import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
import org.joda.time.DateTime;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.LoggedTask;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
@@ -287,7 +281,7 @@ public class DetailViewPane extends AbstractVisualization<DateTime, AggregateEve
|
||||
@Override
|
||||
protected Task<Boolean> getUpdateTask() {
|
||||
|
||||
return new LoggedTask<Boolean>("Update Details", true) {
|
||||
return new LoggedTask<Boolean>(NbBundle.getMessage(this.getClass(), "DetailViewPane.loggedTask.name"), true) {
|
||||
|
||||
@Override
|
||||
protected Boolean call() throws Exception {
|
||||
@@ -301,13 +295,13 @@ public class DetailViewPane extends AbstractVisualization<DateTime, AggregateEve
|
||||
});
|
||||
|
||||
updateProgress(-1, 1);
|
||||
updateMessage("preparing");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "DetailViewPane.loggedTask.preparing"));
|
||||
|
||||
final RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.timeRange().get());
|
||||
final long lowerBound = rangeInfo.getLowerBound();
|
||||
final long upperBound = rangeInfo.getUpperBound();
|
||||
|
||||
updateMessage("querying db");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "DetailViewPane.loggedTask.queryDb"));
|
||||
aggregatedEvents.setAll(filteredEvents.getAggregatedEvents());
|
||||
|
||||
Platform.runLater(() -> {
|
||||
@@ -330,7 +324,7 @@ public class DetailViewPane extends AbstractVisualization<DateTime, AggregateEve
|
||||
break;
|
||||
}
|
||||
updateProgress(i++, size);
|
||||
updateMessage("updating ui");
|
||||
updateMessage(NbBundle.getMessage(this.getClass(), "DetailViewPane.loggedTask.updateUI"));
|
||||
final XYChart.Data<DateTime, AggregateEvent> xyData = new BarChart.Data<>(new DateTime(e.getSpan().getStartMillis()), e);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
@@ -395,20 +389,48 @@ public class DetailViewPane extends AbstractVisualization<DateTime, AggregateEve
|
||||
@FXML
|
||||
private Label truncateSliderLabel;
|
||||
|
||||
@FXML
|
||||
private MenuButton advancedLayoutOptionsButtonLabel;
|
||||
|
||||
@FXML
|
||||
private CustomMenuItem bandByTypeBoxMenuItem;
|
||||
|
||||
@FXML
|
||||
private CustomMenuItem oneEventPerRowBoxMenuItem;
|
||||
|
||||
@FXML
|
||||
private CustomMenuItem truncateAllBoxMenuItem;
|
||||
|
||||
@FXML
|
||||
private CustomMenuItem truncateSliderLabelMenuItem;
|
||||
|
||||
@FXML
|
||||
private CustomMenuItem showRadioMenuItem;
|
||||
|
||||
@FXML
|
||||
private CustomMenuItem countsRadioMenuItem;
|
||||
|
||||
@FXML
|
||||
private CustomMenuItem hiddenRadioMenuItem;
|
||||
|
||||
@FXML
|
||||
private SeparatorMenuItem descVisibilitySeparatorMenuItem;
|
||||
|
||||
public DetailViewSettingsPane() {
|
||||
FXMLConstructor.construct(this, "DetailViewSettingsPane.fxml");
|
||||
FXMLConstructor.construct(this, "DetailViewSettingsPane.fxml"); // NON-NLS
|
||||
}
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
assert bandByTypeBox != null : "fx:id=\"bandByTypeBox\" was not injected: check your FXML file 'DetailViewSettings.fxml'.";
|
||||
assert oneEventPerRowBox != null : "fx:id=\"oneEventPerRowBox\" was not injected: check your FXML file 'DetailViewSettings.fxml'.";
|
||||
assert truncateAllBox != null : "fx:id=\"truncateAllBox\" was not injected: check your FXML file 'DetailViewSettings.fxml'.";
|
||||
assert truncateWidthSlider != null : "fx:id=\"truncateAllSlider\" was not injected: check your FXML file 'DetailViewSettings.fxml'.";
|
||||
assert bandByTypeBox != null : "fx:id=\"bandByTypeBox\" was not injected: check your FXML file 'DetailViewSettings.fxml'."; // NON-NLS
|
||||
assert oneEventPerRowBox != null : "fx:id=\"oneEventPerRowBox\" was not injected: check your FXML file 'DetailViewSettings.fxml'."; // NON-NLS
|
||||
assert truncateAllBox != null : "fx:id=\"truncateAllBox\" was not injected: check your FXML file 'DetailViewSettings.fxml'."; // NON-NLS
|
||||
assert truncateWidthSlider != null : "fx:id=\"truncateAllSlider\" was not injected: check your FXML file 'DetailViewSettings.fxml'."; // NON-NLS
|
||||
bandByTypeBox.selectedProperty().bindBidirectional(chart.getBandByType());
|
||||
truncateAllBox.selectedProperty().bindBidirectional(chart.getTruncateAll());
|
||||
oneEventPerRowBox.selectedProperty().bindBidirectional(chart.getOneEventPerRow());
|
||||
truncateSliderLabel.disableProperty().bind(truncateAllBox.selectedProperty().not());
|
||||
truncateSliderLabel.setText(NbBundle.getMessage(this.getClass(), "DetailViewPane.truncateSliderLabel.text"));
|
||||
final InvalidationListener sliderListener = o -> {
|
||||
if (truncateWidthSlider.isValueChanging() == false) {
|
||||
chart.getTruncateWidth().set(truncateWidthSlider.getValue());
|
||||
@@ -426,6 +448,28 @@ public class DetailViewPane extends AbstractVisualization<DateTime, AggregateEve
|
||||
chart.getDescrVisibility().set(DescriptionVisibility.HIDDEN);
|
||||
}
|
||||
});
|
||||
|
||||
advancedLayoutOptionsButtonLabel.setText(
|
||||
NbBundle.getMessage(this.getClass(), "DetailViewPane.advancedLayoutOptionsButtonLabel.text"));
|
||||
bandByTypeBox.setText(NbBundle.getMessage(this.getClass(), "DetailViewPane.bandByTypeBox.text"));
|
||||
bandByTypeBoxMenuItem.setText(
|
||||
NbBundle.getMessage(this.getClass(), "DetailViewPane.bandByTypeBoxMenuItem.text"));
|
||||
oneEventPerRowBox.setText(NbBundle.getMessage(this.getClass(), "DetailViewPane.oneEventPerRowBox.text"));
|
||||
oneEventPerRowBoxMenuItem.setText(
|
||||
NbBundle.getMessage(this.getClass(), "DetailViewPane.oneEventPerRowBoxMenuItem.text"));
|
||||
truncateAllBox.setText(NbBundle.getMessage(this.getClass(), "DetailViewPan.truncateAllBox.text"));
|
||||
truncateAllBoxMenuItem.setText(
|
||||
NbBundle.getMessage(this.getClass(), "DetailViewPan.truncateAllBoxMenuItem.text"));
|
||||
truncateSliderLabelMenuItem.setText(
|
||||
NbBundle.getMessage(this.getClass(), "DetailViewPane.truncateSlideLabelMenuItem.text"));
|
||||
descVisibilitySeparatorMenuItem.setText(
|
||||
NbBundle.getMessage(this.getClass(), "DetailViewPane.descVisSeparatorMenuItem.text"));
|
||||
showRadioMenuItem.setText(NbBundle.getMessage(this.getClass(), "DetailViewPane.showRadioMenuItem.text"));
|
||||
showRadio.setText(NbBundle.getMessage(this.getClass(), "DetailViewPane.showRadio.text"));
|
||||
countsRadioMenuItem.setText(NbBundle.getMessage(this.getClass(), "DetailViewPane.countsRadioMenuItem.text"));
|
||||
countsRadio.setText(NbBundle.getMessage(this.getClass(), "DetailViewPane.countsRadio.text"));
|
||||
hiddenRadioMenuItem.setText(NbBundle.getMessage(this.getClass(), "DetailViewPane.hiddenRadioMenuItem.text"));
|
||||
hiddenRadio.setText(NbBundle.getMessage(this.getClass(), "DetailViewPane.hiddenRadio.text"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,46 +7,46 @@
|
||||
|
||||
<fx:root alignment="CENTER_LEFT" spacing="5.0" type="javafx.scene.layout.HBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<MenuButton mnemonicParsing="false" text="Advanced Layout Options">
|
||||
<MenuButton fx:id="advancedLayoutOptionsButtonLabel" mnemonicParsing="false">
|
||||
<items>
|
||||
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="Band by Type">
|
||||
<CustomMenuItem fx:id="bandByTypeBoxMenuItem" hideOnClick="false" mnemonicParsing="false">
|
||||
<content>
|
||||
<CheckBox fx:id="bandByTypeBox" mnemonicParsing="false" text="Band by Type">
|
||||
<CheckBox fx:id="bandByTypeBox" mnemonicParsing="false">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></CheckBox>
|
||||
</content>
|
||||
</CustomMenuItem>
|
||||
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="One Event Per Row">
|
||||
<CustomMenuItem fx:id="oneEventPerRowBoxMenuItem" hideOnClick="false" mnemonicParsing="false">
|
||||
<content>
|
||||
<CheckBox fx:id="oneEventPerRowBox" mnemonicParsing="false" text="One Event Per Row">
|
||||
<CheckBox fx:id="oneEventPerRowBox" mnemonicParsing="false">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></CheckBox>
|
||||
</content>
|
||||
</CustomMenuItem>
|
||||
<SeparatorMenuItem mnemonicParsing="false" />
|
||||
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="Truncate Descriptions ">
|
||||
<CustomMenuItem fx:id="truncateAllBoxMenuItem" hideOnClick="false" mnemonicParsing="false">
|
||||
<content>
|
||||
<CheckBox fx:id="truncateAllBox" mnemonicParsing="false" text="Truncate Descriptions ">
|
||||
<CheckBox fx:id="truncateAllBox" mnemonicParsing="false">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></CheckBox>
|
||||
</content>
|
||||
</CustomMenuItem>
|
||||
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="max description width (px)">
|
||||
<CustomMenuItem fx:id="truncateSliderLabelMenuItem" hideOnClick="false" mnemonicParsing="false">
|
||||
<content>
|
||||
<Label fx:id="truncateSliderLabel" contentDisplay="BOTTOM" text="max description width (px):">
|
||||
<Label fx:id="truncateSliderLabel" contentDisplay="BOTTOM">
|
||||
<graphic>
|
||||
<Slider id="truncateAllSlider" fx:id="truncateWidthSlider" blockIncrement="50.0" disable="false" majorTickUnit="150.0" max="500.0" min="50.0" minorTickCount="0" prefHeight="33.0" prefWidth="150.0" showTickLabels="true" showTickMarks="false" value="200.0" />
|
||||
</graphic>
|
||||
</Label>
|
||||
</content>
|
||||
</CustomMenuItem>
|
||||
<SeparatorMenuItem mnemonicParsing="false" text="Description Visibility" />
|
||||
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="Show Full Description">
|
||||
<SeparatorMenuItem fx:id="descVisibilitySeparatorMenuItem" mnemonicParsing="false" />
|
||||
<CustomMenuItem fx:id="showRadioMenuItem" hideOnClick="false" mnemonicParsing="false">
|
||||
<content>
|
||||
<RadioButton fx:id="showRadio" mnemonicParsing="false" selected="true" text="Show Full Description">
|
||||
<RadioButton fx:id="showRadio" mnemonicParsing="false" selected="true">
|
||||
<toggleGroup>
|
||||
<ToggleGroup fx:id="descrVisibility" />
|
||||
</toggleGroup>
|
||||
@@ -56,17 +56,17 @@
|
||||
</RadioButton>
|
||||
</content>
|
||||
</CustomMenuItem>
|
||||
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="Show Counts Only">
|
||||
<CustomMenuItem fx:id="countsRadioMenuItem" hideOnClick="false" mnemonicParsing="false">
|
||||
<content>
|
||||
<RadioButton fx:id="countsRadio" mnemonicParsing="false" text="Show Counts Only" toggleGroup="$descrVisibility">
|
||||
<RadioButton fx:id="countsRadio" mnemonicParsing="false" toggleGroup="$descrVisibility">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></RadioButton>
|
||||
</content>
|
||||
</CustomMenuItem>
|
||||
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="Hide Description">
|
||||
<CustomMenuItem fx:id="hiddenRadioMenuItem" hideOnClick="false" mnemonicParsing="false">
|
||||
<content>
|
||||
<RadioButton fx:id="hiddenRadio" mnemonicParsing="false" text="Hide Description" toggleGroup="$descrVisibility">
|
||||
<RadioButton fx:id="hiddenRadio" mnemonicParsing="false" toggleGroup="$descrVisibility">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></RadioButton>
|
||||
|
||||
@@ -67,6 +67,7 @@ import org.controlsfx.control.action.ActionGroup;
|
||||
import org.controlsfx.control.action.ActionUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Interval;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.actions.Back;
|
||||
import org.sleuthkit.autopsy.timeline.actions.Forward;
|
||||
@@ -219,9 +220,10 @@ public final class EventDetailChart extends XYChart<DateTime, AggregateEvent> im
|
||||
}
|
||||
if (clickEvent.getButton() == MouseButton.SECONDARY && clickEvent.isStillSincePress()) {
|
||||
|
||||
chartContextMenu = ActionUtils.createContextMenu(Arrays.asList(new Action("Place Marker") {
|
||||
chartContextMenu = ActionUtils.createContextMenu(Arrays.asList(new Action(
|
||||
NbBundle.getMessage(this.getClass(), "EventDetailChart.chartContextMenu.placeMarker.name")) {
|
||||
{
|
||||
setGraphic(new ImageView(new Image("/org/sleuthkit/autopsy/timeline/images/marker.png", 16, 16, true, true, true)));
|
||||
setGraphic(new ImageView(new Image("/org/sleuthkit/autopsy/timeline/images/marker.png", 16, 16, true, true, true))); // NON-NLS
|
||||
setEventHandler((ActionEvent t) -> {
|
||||
if (guideLine == null) {
|
||||
guideLine = new GuideLine(0, 0, 0, getHeight(), dateAxis);
|
||||
@@ -242,7 +244,9 @@ public final class EventDetailChart extends XYChart<DateTime, AggregateEvent> im
|
||||
});
|
||||
}
|
||||
|
||||
}, new ActionGroup("Zoom History", new Back(controller),
|
||||
}, new ActionGroup(
|
||||
NbBundle.getMessage(this.getClass(), "EventDetailChart.contextMenu.zoomHistory.name"),
|
||||
new Back(controller),
|
||||
new Forward(controller))));
|
||||
chartContextMenu.setAutoHide(true);
|
||||
chartContextMenu.show(EventDetailChart.this, clickEvent.getScreenX(), clickEvent.getScreenY());
|
||||
@@ -392,7 +396,7 @@ public final class EventDetailChart extends XYChart<DateTime, AggregateEvent> im
|
||||
@Override
|
||||
protected synchronized void dataItemChanged(Data<DateTime, AggregateEvent> data) {
|
||||
//TODO: can we use this to help with local detail level adjustment -jm
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
throw new UnsupportedOperationException("Not supported yet."); // NON-NLS //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,6 +24,7 @@ import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Line;
|
||||
import org.joda.time.DateTime;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
|
||||
/**
|
||||
@@ -65,9 +66,8 @@ class GuideLine extends Line {
|
||||
|
||||
private void setTooltip() {
|
||||
Tooltip.uninstall(this, tooltip);
|
||||
tooltip = new Tooltip(formatSpan(getDateTime())
|
||||
+ "\nRight-click to remove."
|
||||
+ "\nRight-drag to reposition.");
|
||||
tooltip = new Tooltip(
|
||||
NbBundle.getMessage(this.getClass(), "Timeline.ui.detailview.tooltip.text", formatSpan(getDateTime())));
|
||||
Tooltip.install(this, tooltip);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
NavPanel.eventsTreeLabel.text=Sort By\:
|
||||
@@ -0,0 +1 @@
|
||||
NavPanel.eventsTreeLabel.text=\u4E0B\u8A18\u306B\u5F93\u3044\u4E26\u3079\u66FF\u3048\uFF1A
|
||||
@@ -13,7 +13,7 @@
|
||||
<top>
|
||||
<ToolBar>
|
||||
<items>
|
||||
<Label text="Sort By:" />
|
||||
<Label fx:id="eventsTreeLabel" />
|
||||
<ComboBox fx:id="sortByBox">
|
||||
<items>
|
||||
<FXCollections fx:factory="observableArrayList">
|
||||
|
||||
@@ -26,16 +26,12 @@ import javafx.application.Platform;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.SelectionMode;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.control.TreeCell;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.scene.control.TreeView;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
||||
@@ -69,12 +65,15 @@ public class NavPanel extends BorderPane implements TimeLineView {
|
||||
@FXML
|
||||
private TreeView< NavTreeNode> eventsTree;
|
||||
|
||||
@FXML
|
||||
private Label eventsTreeLabel;
|
||||
|
||||
@FXML
|
||||
private ComboBox<Comparator<TreeItem<NavTreeNode>>> sortByBox;
|
||||
|
||||
public NavPanel() {
|
||||
|
||||
FXMLConstructor.construct(this, "NavPanel.fxml");
|
||||
FXMLConstructor.construct(this, "NavPanel.fxml"); // NON-NLS
|
||||
}
|
||||
|
||||
public void setChart(DetailViewPane detailViewPane) {
|
||||
@@ -121,7 +120,7 @@ public class NavPanel extends BorderPane implements TimeLineView {
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
assert sortByBox != null : "fx:id=\"sortByBox\" was not injected: check your FXML file 'NavPanel.fxml'.";
|
||||
assert sortByBox != null : "fx:id=\"sortByBox\" was not injected: check your FXML file 'NavPanel.fxml'."; // NON-NLS
|
||||
|
||||
sortByBox.getItems().setAll(Arrays.asList(TreeComparator.Description, TreeComparator.Count));
|
||||
sortByBox.getSelectionModel().select(TreeComparator.Description);
|
||||
@@ -131,6 +130,8 @@ public class NavPanel extends BorderPane implements TimeLineView {
|
||||
eventsTree.setShowRoot(false);
|
||||
eventsTree.setCellFactory((TreeView<NavTreeNode> p) -> new EventTreeCell());
|
||||
eventsTree.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||
|
||||
eventsTreeLabel.setText(NbBundle.getMessage(this.getClass(), "NavPanel.eventsTreeLabel.text"));
|
||||
}
|
||||
|
||||
/** A tree cell to display {@link NavTreeNode}s. Shows the description, and
|
||||
@@ -141,7 +142,7 @@ public class NavPanel extends BorderPane implements TimeLineView {
|
||||
protected void updateItem(NavTreeNode item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null) {
|
||||
final String text = item.getDescription() + " (" + item.getCount() + ")";
|
||||
final String text = item.getDescription() + " (" + item.getCount() + ")"; // NON-NLS
|
||||
setText(text);
|
||||
setTooltip(new Tooltip(text));
|
||||
Rectangle rect = new Rectangle(24, 24);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Timeline.ui.filtering.menuItem.all=all
|
||||
Timeline.ui.filtering.menuItem.none=none
|
||||
Timeline.ui.filtering.menuItem.only=only
|
||||
Timeline.ui.filtering.menuItem.others=others
|
||||
Timeline.ui.filtering.menuItem.select=select
|
||||
Timeline.ui.filtering.promptText=enter filter string
|
||||
FilterSetPanel.eventTypeFilter.title=Event Type Filter
|
||||
FilterSetPanel.applyButton.text=Apply
|
||||
FilterSetPanel.defaultButton.text=Default
|
||||
FilterSetPanel.treeColumn.text=C1
|
||||
FilterSetPanel.legendColumn.text=C2
|
||||
@@ -0,0 +1,9 @@
|
||||
Timeline.ui.filtering.menuItem.all=\u5168\u3066
|
||||
Timeline.ui.filtering.menuItem.none=\u7121\u3057
|
||||
Timeline.ui.filtering.menuItem.only=\u4E0B\u8A18\u306B\u9650\u5B9A
|
||||
Timeline.ui.filtering.menuItem.others=\u305D\u306E\u4ED6
|
||||
Timeline.ui.filtering.menuItem.select=\u9078\u629E
|
||||
Timeline.ui.filtering.promptText=\u30D5\u30A3\u30EB\u30BF\u30B9\u30C8\u30EA\u30F3\u30B0\u3092\u5165\u529B
|
||||
FilterSetPanel.eventTypeFilter.title=\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u30D5\u30A3\u30EB\u30BF
|
||||
FilterSetPanel.applyButton.text=\u9069\u7528
|
||||
FilterSetPanel.defaultButton.text=\u30C7\u30D5\u30A9\u30EB\u30C8
|
||||
@@ -9,7 +9,7 @@
|
||||
<fx:root type="BorderPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<top><ToolBar prefWidth="200.0" BorderPane.alignment="CENTER">
|
||||
<items>
|
||||
<Button fx:id="applyButton" mnemonicParsing="false" text="Apply">
|
||||
<Button fx:id="applyButton" mnemonicParsing="false">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
@@ -17,7 +17,7 @@
|
||||
<image>
|
||||
<Image url="@../../images/tick.png" />
|
||||
</image></ImageView>
|
||||
</graphic></Button><Button fx:id="defaultButton" mnemonicParsing="false" text="Default">
|
||||
</graphic></Button><Button fx:id="defaultButton" mnemonicParsing="false">
|
||||
<graphic><ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../../images/arrow-circle-double-135.png" />
|
||||
@@ -28,8 +28,8 @@
|
||||
</top>
|
||||
<center><TreeTableView fx:id="filterTreeTable" editable="true" minWidth="-Infinity" showRoot="false" BorderPane.alignment="CENTER">
|
||||
<columns>
|
||||
<TreeTableColumn fx:id="treeColumn" minWidth="100.0" prefWidth="200.0" sortable="false" text="C1" />
|
||||
<TreeTableColumn fx:id="legendColumn" editable="false" minWidth="50.0" prefWidth="50.0" sortable="false" text="C2" />
|
||||
<TreeTableColumn fx:id="treeColumn" minWidth="100.0" prefWidth="200.0" sortable="false" />
|
||||
<TreeTableColumn fx:id="legendColumn" editable="false" minWidth="50.0" prefWidth="50.0" sortable="false" />
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TreeTableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
|
||||
|
||||
@@ -36,6 +36,7 @@ import javafx.scene.control.TreeTableRow;
|
||||
import javafx.scene.control.TreeTableView;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
||||
@@ -74,33 +75,35 @@ public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
assert applyButton != null : "fx:id=\"applyButton\" was not injected: check your FXML file 'FilterSetPanel.fxml'.";
|
||||
assert applyButton != null : "fx:id=\"applyButton\" was not injected: check your FXML file 'FilterSetPanel.fxml'."; // NON-NLS
|
||||
|
||||
applyButton.setOnAction(e -> {
|
||||
controller.pushFilters(filterTreeTable.getRoot().getValue().copyOf());
|
||||
});
|
||||
applyButton.setText(NbBundle.getMessage(this.getClass(), "FilterSetPanel.applyButton.text"));
|
||||
defaultButton.setText(NbBundle.getMessage(this.getClass(), "FilterSetPanel.defaultButton.text"));
|
||||
|
||||
//remove column headers via css.
|
||||
filterTreeTable.getStylesheets().addAll(getClass().getResource("FilterTable.css").toExternalForm());
|
||||
filterTreeTable.getStylesheets().addAll(getClass().getResource("FilterTable.css").toExternalForm()); // NON-NLS
|
||||
|
||||
//use row factory as hook to attach context menus to.
|
||||
filterTreeTable.setRowFactory((TreeTableView<Filter> param) -> {
|
||||
final TreeTableRow<Filter> row = new TreeTableRow<>();
|
||||
|
||||
MenuItem all = new MenuItem("all");
|
||||
MenuItem all = new MenuItem(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.all"));
|
||||
all.setOnAction(e -> {
|
||||
row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
|
||||
t.getValue().setActive(Boolean.TRUE);
|
||||
});
|
||||
});
|
||||
MenuItem none = new MenuItem("none");
|
||||
MenuItem none = new MenuItem(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.none"));
|
||||
none.setOnAction(e -> {
|
||||
row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
|
||||
t.getValue().setActive(Boolean.FALSE);
|
||||
});
|
||||
});
|
||||
|
||||
MenuItem only = new MenuItem("only");
|
||||
MenuItem only = new MenuItem(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.only"));
|
||||
only.setOnAction(e -> {
|
||||
row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
|
||||
if (t == row.getTreeItem()) {
|
||||
@@ -110,7 +113,7 @@ public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
}
|
||||
});
|
||||
});
|
||||
MenuItem others = new MenuItem("others");
|
||||
MenuItem others = new MenuItem(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.others"));
|
||||
others.setOnAction(e -> {
|
||||
row.getTreeItem().getParent().getChildren().forEach((TreeItem<Filter> t) -> {
|
||||
if (t == row.getTreeItem()) {
|
||||
@@ -121,7 +124,7 @@ public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
});
|
||||
});
|
||||
final ContextMenu rowMenu = new ContextMenu();
|
||||
Menu select = new Menu("select");
|
||||
Menu select = new Menu(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.menuItem.select"));
|
||||
select.setOnAction(e -> {
|
||||
row.getItem().setActive(!row.getItem().isActive());
|
||||
});
|
||||
@@ -135,15 +138,17 @@ public class FilterSetPanel extends BorderPane implements TimeLineView {
|
||||
//configure tree column to show name of filter and checkbox
|
||||
treeColumn.setCellValueFactory(param -> param.getValue().valueProperty());
|
||||
treeColumn.setCellFactory(col -> new FilterCheckBoxCell());
|
||||
treeColumn.setText(NbBundle.getMessage(this.getClass(), "FilterSetPanel.treeColumn.text"));
|
||||
|
||||
//configure legend column to show legend (or othe supplamantal ui, eg, text field for text filter)
|
||||
legendColumn.setCellValueFactory(param -> param.getValue().valueProperty());
|
||||
legendColumn.setCellFactory(col -> new LegendCell(this.controller));
|
||||
legendColumn.setText(NbBundle.getMessage(this.getClass(), "FilterSetPanel.legendColumn.text"));
|
||||
}
|
||||
|
||||
public FilterSetPanel() {
|
||||
FXMLConstructor.construct(this, "FilterSetPanel.fxml");
|
||||
expansionMap.put("Event Type Filter", Boolean.TRUE);
|
||||
FXMLConstructor.construct(this, "FilterSetPanel.fxml"); // NON-NLS
|
||||
expansionMap.put(NbBundle.getMessage(this.getClass(), "FilterSetPanel.eventTypeFilter.title"), Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,6 +28,7 @@ import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||
import org.sleuthkit.autopsy.timeline.TimeLineView;
|
||||
import org.sleuthkit.autopsy.timeline.events.FilteredEventsModel;
|
||||
@@ -92,7 +93,7 @@ class LegendCell extends TreeTableCell<AbstractFilter, AbstractFilter> implement
|
||||
} else if (item instanceof TextFilter) {
|
||||
TextFilter f = (TextFilter) item;
|
||||
TextField textField = new TextField();
|
||||
textField.setPromptText("enter filter string");
|
||||
textField.setPromptText(NbBundle.getMessage(this.getClass(), "Timeline.ui.filtering.promptText"));
|
||||
textField.textProperty().bindBidirectional(f.textProperty());
|
||||
Platform.runLater(() -> {
|
||||
setGraphic(textField);
|
||||
|
||||
@@ -105,27 +105,27 @@ public class RangeDivisionInfo {
|
||||
timeUnit = DateTimeFieldType.monthOfYear();
|
||||
long lower = startWithZone.property(timeUnit).roundFloorCopy().getMillis();
|
||||
long upper = endWithZone.property(timeUnit).roundCeilingCopy().getMillis();
|
||||
return new RangeDivisionInfo(timeRange, Months.monthsIn(timeRange).getMonths() + 1, TimeUnits.MONTHS, DateTimeFormat.forPattern("YYYY'-'MMMM"), lower, upper);
|
||||
return new RangeDivisionInfo(timeRange, Months.monthsIn(timeRange).getMonths() + 1, TimeUnits.MONTHS, DateTimeFormat.forPattern("YYYY'-'MMMM"), lower, upper); // NON-NLS
|
||||
} else if (Days.daysIn(timeRange).isGreaterThan(Days.THREE)) {
|
||||
timeUnit = DateTimeFieldType.dayOfMonth();
|
||||
long lower = startWithZone.property(timeUnit).roundFloorCopy().getMillis();
|
||||
long upper = endWithZone.property(timeUnit).roundCeilingCopy().getMillis();
|
||||
return new RangeDivisionInfo(timeRange, Days.daysIn(timeRange).getDays() + 1, TimeUnits.DAYS, DateTimeFormat.forPattern("YYYY'-'MMMM'-'dd"), lower, upper);
|
||||
return new RangeDivisionInfo(timeRange, Days.daysIn(timeRange).getDays() + 1, TimeUnits.DAYS, DateTimeFormat.forPattern("YYYY'-'MMMM'-'dd"), lower, upper); // NON-NLS
|
||||
} else if (Hours.hoursIn(timeRange).isGreaterThan(Hours.THREE)) {
|
||||
timeUnit = DateTimeFieldType.hourOfDay();
|
||||
long lower = startWithZone.property(timeUnit).roundFloorCopy().getMillis();
|
||||
long upper = endWithZone.property(timeUnit).roundCeilingCopy().getMillis();
|
||||
return new RangeDivisionInfo(timeRange, Hours.hoursIn(timeRange).getHours() + 1, TimeUnits.HOURS, DateTimeFormat.forPattern("YYYY'-'MMMM'-'dd HH"), lower, upper);
|
||||
return new RangeDivisionInfo(timeRange, Hours.hoursIn(timeRange).getHours() + 1, TimeUnits.HOURS, DateTimeFormat.forPattern("YYYY'-'MMMM'-'dd HH"), lower, upper); // NON-NLS
|
||||
} else if (Minutes.minutesIn(timeRange).isGreaterThan(Minutes.THREE)) {
|
||||
timeUnit = DateTimeFieldType.minuteOfHour();
|
||||
long lower = startWithZone.property(timeUnit).roundFloorCopy().getMillis();
|
||||
long upper = endWithZone.property(timeUnit).roundCeilingCopy().getMillis();
|
||||
return new RangeDivisionInfo(timeRange, Minutes.minutesIn(timeRange).getMinutes() + 1, TimeUnits.MINUTES, DateTimeFormat.forPattern("YYYY'-'MMMM'-'dd HH':'mm"), lower, upper);
|
||||
return new RangeDivisionInfo(timeRange, Minutes.minutesIn(timeRange).getMinutes() + 1, TimeUnits.MINUTES, DateTimeFormat.forPattern("YYYY'-'MMMM'-'dd HH':'mm"), lower, upper); // NON-NLS
|
||||
} else {
|
||||
timeUnit = DateTimeFieldType.secondOfMinute();
|
||||
long lower = startWithZone.property(timeUnit).roundFloorCopy().getMillis();
|
||||
long upper = endWithZone.property(timeUnit).roundCeilingCopy().getMillis();
|
||||
return new RangeDivisionInfo(timeRange, Seconds.secondsIn(timeRange).getSeconds() + 1, TimeUnits.SECONDS, DateTimeFormat.forPattern("YYYY'-'MMMM'-'dd HH':'mm':'ss"), lower, upper);
|
||||
return new RangeDivisionInfo(timeRange, Seconds.secondsIn(timeRange).getSeconds() + 1, TimeUnits.SECONDS, DateTimeFormat.forPattern("YYYY'-'MMMM'-'dd HH':'mm':'ss"), lower, upper); // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
DescriptionLOD.short=Short
|
||||
DescriptionLOD.medium=Medium
|
||||
DescriptionLOD.full=Full
|
||||
EventTypeZoomLevel.rootType=Root Type
|
||||
EventTypeZoomLevel.baseType=Base Type
|
||||
EventTypeZoomLevel.subType=Sub Type
|
||||
ZoomParams.toString=zoom state\: {0}
|
||||
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\:
|
||||
@@ -0,0 +1,14 @@
|
||||
EventTypeZoomLevel.baseType=\u30D9\u30FC\u30B9\u30BF\u30A4\u30D7
|
||||
EventTypeZoomLevel.rootType=\u30EB\u30FC\u30C8\u30BF\u30A4\u30D7
|
||||
EventTypeZoomLevel.subType=\u30B5\u30D6\u30BF\u30A4\u30D7
|
||||
ZoomParams.toString=\u30BA\u30FC\u30E0\u72B6\u614B\uFF1A{0}
|
||||
ZoomSettingsPane.backButton.toolTip.text=\u623B\u308B\uFF1A{0}
|
||||
ZoomSettingsPane.forwardButton.toolTip.text=\u9032\u3080\uFF1A{0}
|
||||
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
|
||||
@@ -18,12 +18,16 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.timeline.zooming;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public enum DescriptionLOD {
|
||||
|
||||
SHORT("Short"), MEDIUM("Medium"), FULL("Full");
|
||||
SHORT(NbBundle.getMessage(DescriptionLOD.class, "DescriptionLOD.short")), MEDIUM(
|
||||
NbBundle.getMessage(DescriptionLOD.class, "DescriptionLOD.medium")), FULL(
|
||||
NbBundle.getMessage(DescriptionLOD.class, "DescriptionLOD.full"));
|
||||
|
||||
private final String displayName;
|
||||
|
||||
|
||||
@@ -18,13 +18,17 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.timeline.zooming;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public enum EventTypeZoomLevel {
|
||||
|
||||
ROOT_TYPE("Root Type"), BASE_TYPE("Base Type"), SUB_TYPE("Sub Type");
|
||||
ROOT_TYPE(NbBundle.getMessage(EventTypeZoomLevel.class, "EventTypeZoomLevel.rootType")), BASE_TYPE(
|
||||
NbBundle.getMessage(EventTypeZoomLevel.class, "EventTypeZoomLevel.baseType")), SUB_TYPE(
|
||||
NbBundle.getMessage(EventTypeZoomLevel.class, "EventTypeZoomLevel.subType"));
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import org.joda.time.Interval;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.timeline.filters.Filter;
|
||||
|
||||
/**
|
||||
@@ -157,7 +158,7 @@ public class ZoomParams {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "zoom state: " + getTimeRange().toString();
|
||||
return NbBundle.getMessage(this.getClass(), "ZoomParams.toString", getTimeRange().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<children>
|
||||
<GridPane alignment="CENTER" hgap="5.0" minHeight="-Infinity" minWidth="-Infinity" vgap="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<Label text="Description Detail:" GridPane.rowIndex="2">
|
||||
<Label fx:id="descrLODLabel" GridPane.rowIndex="2">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
@@ -23,7 +23,7 @@
|
||||
<Insets />
|
||||
</GridPane.margin>
|
||||
</Slider>
|
||||
<Label text="Event Type: " GridPane.rowIndex="1">
|
||||
<Label fx:id="typeZoomLabel" GridPane.rowIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
@@ -33,7 +33,7 @@
|
||||
<Insets />
|
||||
</GridPane.margin>
|
||||
</Slider>
|
||||
<Label text="Time Units:" GridPane.valignment="CENTER">
|
||||
<Label fx:id="timeUnitLabel" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
@@ -66,7 +66,7 @@
|
||||
<left>
|
||||
<HBox alignment="CENTER" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" spacing="5.0" BorderPane.alignment="CENTER_LEFT">
|
||||
<children>
|
||||
<Label text="Zoom ">
|
||||
<Label fx:id="zoomLabel">
|
||||
<font>
|
||||
<Font name="System Bold" size="12.0" />
|
||||
</font>
|
||||
@@ -79,7 +79,7 @@
|
||||
</graphic>
|
||||
</Label>
|
||||
<Region maxWidth="1.7976931348623157E308" minWidth="60.0" HBox.hgrow="ALWAYS" />
|
||||
<Label text="History: " />
|
||||
<Label fx:id="historyLabel" />
|
||||
<Button fx:id="backButton" mnemonicParsing="false" HBox.hgrow="SOMETIMES">
|
||||
<graphic>
|
||||
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||
|
||||
@@ -25,11 +25,9 @@ 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.Slider;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.control.*;
|
||||
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.TimeLineView;
|
||||
@@ -67,6 +65,21 @@ public class ZoomSettingsPane extends TitledPane implements TimeLineView {
|
||||
@FXML
|
||||
private Slider timeUnitSlider;
|
||||
|
||||
@FXML
|
||||
private Label descrLODLabel;
|
||||
|
||||
@FXML
|
||||
private Label typeZoomLabel;
|
||||
|
||||
@FXML
|
||||
private Label timeUnitLabel;
|
||||
|
||||
@FXML
|
||||
private Label zoomLabel;
|
||||
|
||||
@FXML
|
||||
private Label historyLabel;
|
||||
|
||||
private TimeLineController controller;
|
||||
|
||||
private FilteredEventsModel filteredEvents;
|
||||
@@ -84,10 +97,16 @@ public class ZoomSettingsPane extends TitledPane implements TimeLineView {
|
||||
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"));
|
||||
}
|
||||
|
||||
public ZoomSettingsPane() {
|
||||
FXMLConstructor.construct(this, "ZoomSettingsPane.fxml");
|
||||
FXMLConstructor.construct(this, "ZoomSettingsPane.fxml"); // NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,11 +117,15 @@ public class ZoomSettingsPane extends TitledPane implements TimeLineView {
|
||||
Back back = new Back(controller);
|
||||
backButton.disableProperty().bind(back.disabledProperty());
|
||||
backButton.setOnAction(back);
|
||||
backButton.setTooltip(new Tooltip("Back: " + back.getAccelerator().getName()));
|
||||
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("Forward: " + forward.getAccelerator().getName()));
|
||||
forwardButton.setTooltip(new Tooltip(
|
||||
NbBundle.getMessage(this.getClass(), "ZoomSettingsPane.forwardButton.toolTip.text",
|
||||
forward.getAccelerator().getName())));
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user