diff --git a/Timeline/src/org/sleuthkit/autopsy/timeline/HistoryManager.java b/Timeline/src/org/sleuthkit/autopsy/timeline/HistoryManager.java new file mode 100644 index 0000000000..ed0e2e2a31 --- /dev/null +++ b/Timeline/src/org/sleuthkit/autopsy/timeline/HistoryManager.java @@ -0,0 +1,94 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2014 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.timeline; + +import javafx.beans.property.ReadOnlyObjectWrapper; +import javax.annotation.concurrent.GuardedBy; +import org.sleuthkit.autopsy.coreutils.ObservableStack; + +/** + * + */ +public class HistoryManager { + + /** list based stack to hold history, 'top' is at index 0; */ + @GuardedBy("this") + private final ObservableStack historyStack = new ObservableStack<>(); + + @GuardedBy("this") + private final ObservableStack forwardStack = new ObservableStack<>(); + + private final ReadOnlyObjectWrapper currentState = new ReadOnlyObjectWrapper<>(); + + public ReadOnlyObjectWrapper getCurrentState() { + return currentState; + } + + public T currentState() { + return currentState.get(); + } + + synchronized public ObservableStack getHistoryStack() { + return historyStack; + } + + synchronized public ObservableStack getForwardStack() { + return forwardStack; + } + + synchronized public T advance() { + + final T peek = forwardStack.peek(); + + if (peek != null && peek.equals(currentState.get()) == false) { + historyStack.push(currentState.get()); + currentState.set(peek); + forwardStack.pop(); + } + return peek; + } + + synchronized public T retreat() { + + final T peek = historyStack.peek(); + + if (peek != null && peek.equals(currentState.get()) == false) { + forwardStack.push(currentState.get()); + currentState.set(peek); + } else if (peek != null && peek.equals(currentState)) { + historyStack.pop(); + return retreat(); + } + return peek; + } + + synchronized private void advance(T newState) { + + if (currentState.equals(newState) == false) { + historyStack.push(currentState.get()); + currentState.set(newState); + if (newState.equals(forwardStack.peek())) { + forwardStack.pop(); + } else { + forwardStack.clear(); + } + } + } + +} diff --git a/Timeline/src/org/sleuthkit/autopsy/timeline/TimeLineController.java b/Timeline/src/org/sleuthkit/autopsy/timeline/TimeLineController.java index 4ac22a91fc..7d5d9e4898 100644 --- a/Timeline/src/org/sleuthkit/autopsy/timeline/TimeLineController.java +++ b/Timeline/src/org/sleuthkit/autopsy/timeline/TimeLineController.java @@ -529,22 +529,14 @@ public class TimeLineController { return peek; } - @Deprecated - synchronized public void popZoomUpTo(ZoomParams zCrumb) { - ZoomParams popped = historyStack.peek(); + - while (popped.equals(zCrumb) == false) { - popped = historyStack.pop(); - } - pushZoom(zCrumb); - } - - synchronized private void pushZoom(ZoomParams zCrumb, boolean force) { + synchronized private void pushZoom(ZoomParams zCrumb) { final ZoomParams currentZoom = filteredEvents.getRequestedZoomParamters().get(); - if (force || currentZoom.equals(zCrumb) == false) { + if ( currentZoom.equals(zCrumb) == false) { historyStack.push(currentZoom); - filteredEvents.requestZoomState(zCrumb, force); + filteredEvents.requestZoomState(zCrumb, false); if (zCrumb.equals(forwardStack.peek())) { forwardStack.pop(); } else { @@ -553,9 +545,7 @@ public class TimeLineController { } } - synchronized private void pushZoom(ZoomParams zCrumb) { - pushZoom(zCrumb, false); - } + public void selectTimeAndType(Interval interval, EventType type) { final Interval timeRange = filteredEvents.getSpanningInterval().overlap(interval);