(still buggy)show unseen status and improve next unseen action; reset changes that broke regrouping

This commit is contained in:
jmillman 2015-06-03 16:49:40 -04:00
parent 7e260f6818
commit b2d2b3e746
6 changed files with 82 additions and 22 deletions

View File

@ -19,8 +19,8 @@
package org.sleuthkit.autopsy.imagegallery.actions;
import java.util.Optional;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.Observable;
import javafx.beans.binding.ObjectExpression;
import javafx.event.ActionEvent;
import javafx.scene.image.ImageView;
import org.controlsfx.control.action.Action;
@ -31,24 +31,43 @@ import org.sleuthkit.autopsy.imagegallery.grouping.GroupViewState;
*
*/
public class NextUnseenGroup extends Action {
private final ImageGalleryController controller;
public NextUnseenGroup(ImageGalleryController controller) {
super("Next Unseen group");
this.controller = controller;
setGraphic(new ImageView("/org/sleuthkit/autopsy/imagegallery/images/control-double.png"));
disabledProperty().bind(Bindings.isEmpty(controller.getGroupManager().getUnSeenGroups()));
controller.getGroupManager().getUnSeenGroups().addListener((Observable observable) -> {
updateDisabledStatus();
});
setEventHandler((ActionEvent t) -> {
Optional.ofNullable(controller.viewState())
.map((ReadOnlyObjectProperty<GroupViewState> t1) -> t1.get())
.map(ObjectExpression<GroupViewState>::getValue)
.map(GroupViewState::getGroup)
.ifPresent(controller.getGroupManager()::markGroupSeen);
if (controller.getGroupManager().getUnSeenGroups().isEmpty() == false) {
if (controller.getGroupManager().getUnSeenGroups().size() <= 1) {
setText("Mark Group Seen");
setGraphic(new ImageView("/org/sleuthkit/autopsy/imagegallery/images/control-stop.png"));
if (!controller.getGroupManager().getUnSeenGroups().isEmpty()) {
controller.advance(GroupViewState.tile(controller.getGroupManager().getUnSeenGroups().get(0)));
}
} else {
setText("Next Unseen group");
setGraphic(new ImageView("/org/sleuthkit/autopsy/imagegallery/images/control-double.png"));
setDisabled(false);
controller.advance(GroupViewState.tile(controller.getGroupManager().getUnSeenGroups().get(0)));
}
updateDisabledStatus();
});
updateDisabledStatus();
}
private void updateDisabledStatus() {
disabledProperty().set(controller.getGroupManager().getUnSeenGroups().isEmpty());
}
}

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.imagegallery.grouping;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import javafx.beans.property.ReadOnlyBooleanWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -35,7 +36,6 @@ public class DrawableGroup implements Comparable<DrawableGroup> {
private static final Logger LOGGER = Logger.getLogger(DrawableGroup.class.getName());
public static String getBlankGroupName() {
return "unknown";
}
@ -44,6 +44,7 @@ public class DrawableGroup implements Comparable<DrawableGroup> {
//cache the number of files in this groups with hashset hits
private int hashSetHitsCount = -1;
private final ReadOnlyBooleanWrapper seen = new ReadOnlyBooleanWrapper(false);
synchronized public ObservableList<Long> fileIds() {
return fileIDs;
@ -148,4 +149,16 @@ public class DrawableGroup implements Comparable<DrawableGroup> {
public int compareTo(DrawableGroup other) {
return this.groupKey.getValueDisplayName().compareTo(other.groupKey.getValueDisplayName());
}
void setSeen() {
this.seen.set(true);
}
public ReadOnlyBooleanWrapper seenProperty() {
return seen;
}
public boolean isSeen() {
return seen.get();
}
}

View File

@ -81,18 +81,27 @@ public class GroupManager implements FileUpdateEvent.FileUpdateListener {
/**
* map from {@link GroupKey}s to {@link DrawableGroup}s. All groups (even
* not fully analyzed or not visible groups) could be in this map
* not
* fully analyzed or not visible groups could be in this map
*/
private final Map<GroupKey<?>, DrawableGroup> groupMap = new HashMap<>();
/** list of all analyzed groups */
/**
* list of all analyzed groups
*/
@ThreadConfined(type = ThreadType.JFX)
private final ObservableList<DrawableGroup> analyzedGroups = FXCollections.observableArrayList();
/** list of unseen groups */
private final ObservableList<DrawableGroup> publicAnalyzedGroupsWrapper = FXCollections.unmodifiableObservableList(analyzedGroups);
/**
* list of unseen groups
*/
@ThreadConfined(type = ThreadType.JFX)
private final ObservableList<DrawableGroup> unSeenGroups = FXCollections.observableArrayList();
// private final SortedList<Grouping> sortedUnSeenGroups = new SortedList<>(unSeenGroups);
private final ObservableList<DrawableGroup> publicSortedUnseenGroupsWrapper = FXCollections.unmodifiableObservableList(unSeenGroups);
private ReGroupTask<?> groupByTask;
/* --- current grouping/sorting attributes --- */
@ -101,7 +110,7 @@ public class GroupManager implements FileUpdateEvent.FileUpdateListener {
private volatile DrawableAttribute<?> groupBy = DrawableAttribute.PATH;
private volatile SortOrder sortOrder = SortOrder.ASCENDING;
private final ReadOnlyDoubleWrapper regroupProgress = new ReadOnlyDoubleWrapper();
private ReadOnlyDoubleWrapper regroupProgress = new ReadOnlyDoubleWrapper();
public void setDB(DrawableDB db) {
this.db = db;
@ -110,13 +119,12 @@ public class GroupManager implements FileUpdateEvent.FileUpdateListener {
}
public ObservableList<DrawableGroup> getAnalyzedGroups() {
return FXCollections.unmodifiableObservableList(analyzedGroups);
return publicAnalyzedGroupsWrapper;
}
@ThreadConfined(type = ThreadType.JFX)
public ObservableList<DrawableGroup> getUnSeenGroups() {
return FXCollections.unmodifiableObservableList(unSeenGroups);
return publicSortedUnseenGroupsWrapper;
}
/**
@ -253,7 +261,9 @@ public class GroupManager implements FileUpdateEvent.FileUpdateListener {
* @param group the {@link DrawableGroup} to mark as seen
*/
public void markGroupSeen(DrawableGroup group) {
db.markGroupSeen(group.getGroupKey());
group.setSeen();
synchronized (unSeenGroups) {
unSeenGroups.remove(group);
}

View File

@ -50,7 +50,8 @@ class GroupTreeCell extends TreeCell<TreeNode> {
* reference to listener that allows us to remove it from a group when a new
* group is assigned to this Cell
*/
private InvalidationListener listener;
private InvalidationListener fileListener;
private InvalidationListener seenListener;
public GroupTreeCell() {
//TODO: move this to .css file
@ -70,8 +71,9 @@ class GroupTreeCell extends TreeCell<TreeNode> {
if (Objects.nonNull(listener)) {
Optional.ofNullable(getItem())
.map(TreeNode::getGroup)
.ifPresent((DrawableGroup t) -> {
t.fileIds().removeListener(listener);
.ifPresent(group -> {
group.fileIds().removeListener(fileListener);
group.seenProperty().removeListener(seenListener);
});
}
@ -82,6 +84,7 @@ class GroupTreeCell extends TreeCell<TreeNode> {
setTooltip(null);
setText(null);
setGraphic(null);
setStyle("");
});
} else {
final String groupName = StringUtils.defaultIfBlank(tNode.getPath(), DrawableGroup.getBlankGroupName());
@ -92,30 +95,45 @@ class GroupTreeCell extends TreeCell<TreeNode> {
setTooltip(new Tooltip(groupName));
setText(groupName);
setGraphic(new ImageView(EMPTY_FOLDER_ICON));
setStyle("");
});
} else {
listener = (Observable o) -> {
fileListener = (Observable o) -> {
final String countsText = getCountsText();
Platform.runLater(() -> {
setText(groupName + countsText);
});
};
//if number of files in this group changes (eg file is recategorized), update counts via listener
tNode.getGroup().fileIds().addListener(listener);
tNode.getGroup().fileIds().addListener(fileListener);
seenListener = (Observable observable) -> {
final String style = getSeenStyle();
Platform.runLater(() -> {
setStyle(style);
});
};
tNode.getGroup().seenProperty().addListener(seenListener);
//... and use icon corresponding to group type
final Image icon = tNode.getGroup().groupKey.getAttribute().getIcon();
final String countsText = getCountsText();
final String style = getSeenStyle();
Platform.runLater(() -> {
setTooltip(new Tooltip(groupName));
setGraphic(new ImageView(icon));
setText(groupName + countsText);
setStyle(style);
});
}
}
}
private String getSeenStyle() {
return getItem().getGroup().isSeen() ? "" : "-fx-font-weight:bold;";
}
private synchronized String getCountsText() {
final String counts = Optional.ofNullable(getItem())
.map(TreeNode::getGroup)

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B