mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 07:56:16 +00:00
use event bus for category change events
This commit is contained in:
parent
06e0a33499
commit
a20f040066
@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.imagegallery;
|
|||||||
|
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
@ -83,25 +82,25 @@ import org.sleuthkit.datamodel.TskData;
|
|||||||
* control.
|
* control.
|
||||||
*/
|
*/
|
||||||
public final class ImageGalleryController {
|
public final class ImageGalleryController {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(ImageGalleryController.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ImageGalleryController.class.getName());
|
||||||
|
|
||||||
private final Region infoOverLayBackground = new Region() {
|
private final Region infoOverLayBackground = new Region() {
|
||||||
{
|
{
|
||||||
setBackground(new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)));
|
setBackground(new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||||
setOpacity(.4);
|
setOpacity(.4);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static ImageGalleryController instance;
|
private static ImageGalleryController instance;
|
||||||
|
|
||||||
public static synchronized ImageGalleryController getDefault() {
|
public static synchronized ImageGalleryController getDefault() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new ImageGalleryController();
|
instance = new ImageGalleryController();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final History<GroupViewState> historyManager = new History<>();
|
private final History<GroupViewState> historyManager = new History<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,73 +108,73 @@ public final class ImageGalleryController {
|
|||||||
* not listen to speed up ingest
|
* not listen to speed up ingest
|
||||||
*/
|
*/
|
||||||
private final SimpleBooleanProperty listeningEnabled = new SimpleBooleanProperty(false);
|
private final SimpleBooleanProperty listeningEnabled = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
private final ReadOnlyIntegerWrapper queueSizeProperty = new ReadOnlyIntegerWrapper(0);
|
private final ReadOnlyIntegerWrapper queueSizeProperty = new ReadOnlyIntegerWrapper(0);
|
||||||
|
|
||||||
private final ReadOnlyBooleanWrapper regroupDisabled = new ReadOnlyBooleanWrapper(false);
|
private final ReadOnlyBooleanWrapper regroupDisabled = new ReadOnlyBooleanWrapper(false);
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private final ReadOnlyBooleanWrapper stale = new ReadOnlyBooleanWrapper(false);
|
private final ReadOnlyBooleanWrapper stale = new ReadOnlyBooleanWrapper(false);
|
||||||
|
|
||||||
private final ReadOnlyBooleanWrapper metaDataCollapsed = new ReadOnlyBooleanWrapper(false);
|
private final ReadOnlyBooleanWrapper metaDataCollapsed = new ReadOnlyBooleanWrapper(false);
|
||||||
|
|
||||||
private final FileIDSelectionModel selectionModel = FileIDSelectionModel.getInstance();
|
private final FileIDSelectionModel selectionModel = FileIDSelectionModel.getInstance();
|
||||||
|
|
||||||
private DBWorkerThread dbWorkerThread;
|
private DBWorkerThread dbWorkerThread;
|
||||||
|
|
||||||
private DrawableDB db;
|
private DrawableDB db;
|
||||||
|
|
||||||
private final GroupManager groupManager = new GroupManager(this);
|
private final GroupManager groupManager = new GroupManager(this);
|
||||||
|
|
||||||
private StackPane fullUIStackPane;
|
private StackPane fullUIStackPane;
|
||||||
|
|
||||||
private StackPane centralStackPane;
|
private StackPane centralStackPane;
|
||||||
|
|
||||||
private Node infoOverlay;
|
private Node infoOverlay;
|
||||||
private final HashSetManager hashSetManager = new HashSetManager();
|
private final HashSetManager hashSetManager = new HashSetManager();
|
||||||
private final CategoryManager categoryManager = new CategoryManager();
|
private final CategoryManager categoryManager = new CategoryManager();
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty getMetaDataCollapsed() {
|
public ReadOnlyBooleanProperty getMetaDataCollapsed() {
|
||||||
return metaDataCollapsed.getReadOnlyProperty();
|
return metaDataCollapsed.getReadOnlyProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMetaDataCollapsed(Boolean metaDataCollapsed) {
|
public void setMetaDataCollapsed(Boolean metaDataCollapsed) {
|
||||||
this.metaDataCollapsed.set(metaDataCollapsed);
|
this.metaDataCollapsed.set(metaDataCollapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GroupViewState getViewState() {
|
private GroupViewState getViewState() {
|
||||||
return historyManager.getCurrentState();
|
return historyManager.getCurrentState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty regroupDisabled() {
|
public ReadOnlyBooleanProperty regroupDisabled() {
|
||||||
return regroupDisabled.getReadOnlyProperty();
|
return regroupDisabled.getReadOnlyProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<GroupViewState> viewState() {
|
public ReadOnlyObjectProperty<GroupViewState> viewState() {
|
||||||
return historyManager.currentState();
|
return historyManager.currentState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized FileIDSelectionModel getSelectionModel() {
|
public synchronized FileIDSelectionModel getSelectionModel() {
|
||||||
|
|
||||||
return selectionModel;
|
return selectionModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupManager getGroupManager() {
|
public GroupManager getGroupManager() {
|
||||||
return groupManager;
|
return groupManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DrawableDB getDatabase() {
|
public DrawableDB getDatabase() {
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void setListeningEnabled(boolean enabled) {
|
synchronized public void setListeningEnabled(boolean enabled) {
|
||||||
listeningEnabled.set(enabled);
|
listeningEnabled.set(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized boolean isListeningEnabled() {
|
synchronized boolean isListeningEnabled() {
|
||||||
return listeningEnabled.get();
|
return listeningEnabled.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.ANY)
|
@ThreadConfined(type = ThreadConfined.ThreadType.ANY)
|
||||||
void setStale(Boolean b) {
|
void setStale(Boolean b) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
@ -185,18 +184,18 @@ public final class ImageGalleryController {
|
|||||||
new PerCaseProperties(Case.getCurrentCase()).setConfigSetting(ImageGalleryModule.getModuleName(), PerCaseProperties.STALE, b.toString());
|
new PerCaseProperties(Case.getCurrentCase()).setConfigSetting(ImageGalleryModule.getModuleName(), PerCaseProperties.STALE, b.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty stale() {
|
public ReadOnlyBooleanProperty stale() {
|
||||||
return stale.getReadOnlyProperty();
|
return stale.getReadOnlyProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
boolean isStale() {
|
boolean isStale() {
|
||||||
return stale.get();
|
return stale.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImageGalleryController() {
|
private ImageGalleryController() {
|
||||||
|
|
||||||
listeningEnabled.addListener((observable, oldValue, newValue) -> {
|
listeningEnabled.addListener((observable, oldValue, newValue) -> {
|
||||||
//if we just turned on listening and a case is open and that case is not up to date
|
//if we just turned on listening and a case is open and that case is not up to date
|
||||||
if (newValue && !oldValue && Case.existsCurrentCase() && ImageGalleryModule.isDrawableDBStale(Case.getCurrentCase())) {
|
if (newValue && !oldValue && Case.existsCurrentCase() && ImageGalleryModule.isDrawableDBStale(Case.getCurrentCase())) {
|
||||||
@ -204,28 +203,28 @@ public final class ImageGalleryController {
|
|||||||
queueDBWorkerTask(new CopyAnalyzedFiles());
|
queueDBWorkerTask(new CopyAnalyzedFiles());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
groupManager.getAnalyzedGroups().addListener((Observable o) -> {
|
groupManager.getAnalyzedGroups().addListener((Observable o) -> {
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
checkForGroups();
|
checkForGroups();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
groupManager.getUnSeenGroups().addListener((Observable observable) -> {
|
groupManager.getUnSeenGroups().addListener((Observable observable) -> {
|
||||||
//if there are unseen groups and none being viewed
|
//if there are unseen groups and none being viewed
|
||||||
if (groupManager.getUnSeenGroups().isEmpty() == false && (getViewState() == null || getViewState().getGroup() == null)) {
|
if (groupManager.getUnSeenGroups().isEmpty() == false && (getViewState() == null || getViewState().getGroup() == null)) {
|
||||||
advance(GroupViewState.tile(groupManager.getUnSeenGroups().get(0)));
|
advance(GroupViewState.tile(groupManager.getUnSeenGroups().get(0)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
viewState().addListener((Observable observable) -> {
|
viewState().addListener((Observable observable) -> {
|
||||||
selectionModel.clearSelection();
|
selectionModel.clearSelection();
|
||||||
});
|
});
|
||||||
|
|
||||||
regroupDisabled.addListener((Observable observable) -> {
|
regroupDisabled.addListener((Observable observable) -> {
|
||||||
checkForGroups();
|
checkForGroups();
|
||||||
});
|
});
|
||||||
|
|
||||||
IngestManager.getInstance().addIngestModuleEventListener((PropertyChangeEvent evt) -> {
|
IngestManager.getInstance().addIngestModuleEventListener((PropertyChangeEvent evt) -> {
|
||||||
Platform.runLater(this::updateRegroupDisabled);
|
Platform.runLater(this::updateRegroupDisabled);
|
||||||
});
|
});
|
||||||
@ -234,27 +233,27 @@ public final class ImageGalleryController {
|
|||||||
});
|
});
|
||||||
// metaDataCollapsed.bind(Toolbar.getDefault().showMetaDataProperty());
|
// metaDataCollapsed.bind(Toolbar.getDefault().showMetaDataProperty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty getCanAdvance() {
|
public ReadOnlyBooleanProperty getCanAdvance() {
|
||||||
return historyManager.getCanAdvance();
|
return historyManager.getCanAdvance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty getCanRetreat() {
|
public ReadOnlyBooleanProperty getCanRetreat() {
|
||||||
return historyManager.getCanRetreat();
|
return historyManager.getCanRetreat();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void advance(GroupViewState newState) {
|
public void advance(GroupViewState newState) {
|
||||||
historyManager.advance(newState);
|
historyManager.advance(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupViewState advance() {
|
public GroupViewState advance() {
|
||||||
return historyManager.advance();
|
return historyManager.advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupViewState retreat() {
|
public GroupViewState retreat() {
|
||||||
return historyManager.retreat();
|
return historyManager.retreat();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRegroupDisabled() {
|
private void updateRegroupDisabled() {
|
||||||
regroupDisabled.set(getFileUpdateQueueSizeProperty().get() > 0 || IngestManager.getInstance().isIngestRunning());
|
regroupDisabled.set(getFileUpdateQueueSizeProperty().get() > 0 || IngestManager.getInstance().isIngestRunning());
|
||||||
}
|
}
|
||||||
@ -276,7 +275,7 @@ public final class ImageGalleryController {
|
|||||||
new NoGroupsDialog("No groups are fully analyzed yet, but ingest is still ongoing. Please Wait.",
|
new NoGroupsDialog("No groups are fully analyzed yet, but ingest is still ongoing. Please Wait.",
|
||||||
new ProgressIndicator()));
|
new ProgressIndicator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (getFileUpdateQueueSizeProperty().get() > 0) {
|
} else if (getFileUpdateQueueSizeProperty().get() > 0) {
|
||||||
replaceNotification(fullUIStackPane,
|
replaceNotification(fullUIStackPane,
|
||||||
new NoGroupsDialog("No groups are fully analyzed yet, but image / video data is still being populated. Please Wait.",
|
new NoGroupsDialog("No groups are fully analyzed yet, but image / video data is still being populated. Please Wait.",
|
||||||
@ -290,19 +289,19 @@ public final class ImageGalleryController {
|
|||||||
replaceNotification(fullUIStackPane,
|
replaceNotification(fullUIStackPane,
|
||||||
new NoGroupsDialog("There are no images/videos in the added datasources."));
|
new NoGroupsDialog("There are no images/videos in the added datasources."));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!groupManager.isRegrouping()) {
|
} else if (!groupManager.isRegrouping()) {
|
||||||
replaceNotification(centralStackPane,
|
replaceNotification(centralStackPane,
|
||||||
new NoGroupsDialog("There are no fully analyzed groups to display:"
|
new NoGroupsDialog("There are no fully analyzed groups to display:"
|
||||||
+ " the current Group By setting resulted in no groups, "
|
+ " the current Group By setting resulted in no groups, "
|
||||||
+ "or no groups are fully analyzed but ingest is not running."));
|
+ "or no groups are fully analyzed but ingest is not running."));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
clearNotification();
|
clearNotification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearNotification() {
|
private void clearNotification() {
|
||||||
//remove the ingest spinner
|
//remove the ingest spinner
|
||||||
if (fullUIStackPane != null) {
|
if (fullUIStackPane != null) {
|
||||||
@ -313,27 +312,27 @@ public final class ImageGalleryController {
|
|||||||
centralStackPane.getChildren().remove(infoOverlay);
|
centralStackPane.getChildren().remove(infoOverlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceNotification(StackPane stackPane, Node newNode) {
|
private void replaceNotification(StackPane stackPane, Node newNode) {
|
||||||
clearNotification();
|
clearNotification();
|
||||||
|
|
||||||
infoOverlay = new StackPane(infoOverLayBackground, newNode);
|
infoOverlay = new StackPane(infoOverLayBackground, newNode);
|
||||||
if (stackPane != null) {
|
if (stackPane != null) {
|
||||||
stackPane.getChildren().add(infoOverlay);
|
stackPane.getChildren().add(infoOverlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restartWorker() {
|
private void restartWorker() {
|
||||||
if (dbWorkerThread != null) {
|
if (dbWorkerThread != null) {
|
||||||
// Keep using the same worker thread if one exists
|
// Keep using the same worker thread if one exists
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dbWorkerThread = new DBWorkerThread();
|
dbWorkerThread = new DBWorkerThread();
|
||||||
|
|
||||||
getFileUpdateQueueSizeProperty().addListener((Observable o) -> {
|
getFileUpdateQueueSizeProperty().addListener((Observable o) -> {
|
||||||
Platform.runLater(this::updateRegroupDisabled);
|
Platform.runLater(this::updateRegroupDisabled);
|
||||||
});
|
});
|
||||||
|
|
||||||
Thread th = new Thread(dbWorkerThread);
|
Thread th = new Thread(dbWorkerThread);
|
||||||
th.setDaemon(false); // we want it to go away when it is done
|
th.setDaemon(false); // we want it to go away when it is done
|
||||||
th.start();
|
th.start();
|
||||||
@ -346,7 +345,7 @@ public final class ImageGalleryController {
|
|||||||
*/
|
*/
|
||||||
public synchronized void setCase(Case theNewCase) {
|
public synchronized void setCase(Case theNewCase) {
|
||||||
this.db = DrawableDB.getDrawableDB(ImageGalleryModule.getModuleOutputDir(theNewCase), this);
|
this.db = DrawableDB.getDrawableDB(ImageGalleryModule.getModuleOutputDir(theNewCase), this);
|
||||||
|
|
||||||
setListeningEnabled(ImageGalleryModule.isEnabledforCase(theNewCase));
|
setListeningEnabled(ImageGalleryModule.isEnabledforCase(theNewCase));
|
||||||
setStale(ImageGalleryModule.isDrawableDBStale(theNewCase));
|
setStale(ImageGalleryModule.isDrawableDBStale(theNewCase));
|
||||||
|
|
||||||
@ -358,7 +357,7 @@ public final class ImageGalleryController {
|
|||||||
hashSetManager.setDb(db);
|
hashSetManager.setDb(db);
|
||||||
categoryManager.setDb(db);
|
categoryManager.setDb(db);
|
||||||
db.initializeImageList();
|
db.initializeImageList();
|
||||||
SummaryTablePane.getDefault().handleCategoryChanged(Collections.emptyList());
|
SummaryTablePane.getDefault().refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -373,7 +372,7 @@ public final class ImageGalleryController {
|
|||||||
historyManager.clear();
|
historyManager.clear();
|
||||||
});
|
});
|
||||||
Category.clearTagNames();
|
Category.clearTagNames();
|
||||||
|
|
||||||
Toolbar.getDefault().reset();
|
Toolbar.getDefault().reset();
|
||||||
groupManager.clear();
|
groupManager.clear();
|
||||||
if (db != null) {
|
if (db != null) {
|
||||||
@ -395,21 +394,21 @@ public final class ImageGalleryController {
|
|||||||
}
|
}
|
||||||
dbWorkerThread.addTask(innerTask);
|
dbWorkerThread.addTask(innerTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DrawableFile<?> getFileFromId(Long fileID) throws TskCoreException {
|
public DrawableFile<?> getFileFromId(Long fileID) throws TskCoreException {
|
||||||
return db.getFileFromID(fileID);
|
return db.getFileFromID(fileID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStacks(StackPane fullUIStack, StackPane centralStack) {
|
public void setStacks(StackPane fullUIStack, StackPane centralStack) {
|
||||||
fullUIStackPane = fullUIStack;
|
fullUIStackPane = fullUIStack;
|
||||||
this.centralStackPane = centralStack;
|
this.centralStackPane = centralStack;
|
||||||
Platform.runLater(this::checkForGroups);
|
Platform.runLater(this::checkForGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ReadOnlyIntegerProperty getFileUpdateQueueSizeProperty() {
|
public final ReadOnlyIntegerProperty getFileUpdateQueueSizeProperty() {
|
||||||
return queueSizeProperty.getReadOnlyProperty();
|
return queueSizeProperty.getReadOnlyProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyDoubleProperty regroupProgress() {
|
public ReadOnlyDoubleProperty regroupProgress() {
|
||||||
return groupManager.regroupProgress();
|
return groupManager.regroupProgress();
|
||||||
}
|
}
|
||||||
@ -481,11 +480,11 @@ public final class ImageGalleryController {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashSetManager getHashSetManager() {
|
public HashSetManager getHashSetManager() {
|
||||||
return hashSetManager;
|
return hashSetManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CategoryManager getCategoryManager() {
|
public CategoryManager getCategoryManager() {
|
||||||
return categoryManager;
|
return categoryManager;
|
||||||
}
|
}
|
||||||
@ -526,7 +525,7 @@ public final class ImageGalleryController {
|
|||||||
queueSizeProperty.set(workQueue.size());
|
queueSizeProperty.set(workQueue.size());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
@ -537,22 +536,22 @@ public final class ImageGalleryController {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
InnerTask it = workQueue.take();
|
InnerTask it = workQueue.take();
|
||||||
|
|
||||||
if (it.cancelled == false) {
|
if (it.cancelled == false) {
|
||||||
it.run();
|
it.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
queueSizeProperty.set(workQueue.size());
|
queueSizeProperty.set(workQueue.size());
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
Exceptions.printStackTrace(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SleuthkitCase getSleuthKitCase() throws IllegalStateException {
|
public SleuthkitCase getSleuthKitCase() throws IllegalStateException {
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
return Case.getCurrentCase().getSleuthkitCase();
|
return Case.getCurrentCase().getSleuthkitCase();
|
||||||
@ -565,55 +564,55 @@ public final class ImageGalleryController {
|
|||||||
* Abstract base class for task to be done on {@link DBWorkerThread}
|
* Abstract base class for task to be done on {@link DBWorkerThread}
|
||||||
*/
|
*/
|
||||||
static public abstract class InnerTask implements Runnable {
|
static public abstract class InnerTask implements Runnable {
|
||||||
|
|
||||||
public double getProgress() {
|
public double getProgress() {
|
||||||
return progress.get();
|
return progress.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void updateProgress(Double workDone) {
|
public final void updateProgress(Double workDone) {
|
||||||
this.progress.set(workDone);
|
this.progress.set(workDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message.get();
|
return message.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void updateMessage(String Status) {
|
public final void updateMessage(String Status) {
|
||||||
this.message.set(Status);
|
this.message.set(Status);
|
||||||
}
|
}
|
||||||
SimpleObjectProperty<Worker.State> state = new SimpleObjectProperty<>(Worker.State.READY);
|
SimpleObjectProperty<Worker.State> state = new SimpleObjectProperty<>(Worker.State.READY);
|
||||||
SimpleDoubleProperty progress = new SimpleDoubleProperty(this, "pregress");
|
SimpleDoubleProperty progress = new SimpleDoubleProperty(this, "pregress");
|
||||||
SimpleStringProperty message = new SimpleStringProperty(this, "status");
|
SimpleStringProperty message = new SimpleStringProperty(this, "status");
|
||||||
|
|
||||||
public SimpleDoubleProperty progressProperty() {
|
public SimpleDoubleProperty progressProperty() {
|
||||||
return progress;
|
return progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleStringProperty messageProperty() {
|
public SimpleStringProperty messageProperty() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Worker.State getState() {
|
public Worker.State getState() {
|
||||||
return state.get();
|
return state.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateState(Worker.State newState) {
|
protected void updateState(Worker.State newState) {
|
||||||
state.set(newState);
|
state.set(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Worker.State> stateProperty() {
|
public ReadOnlyObjectProperty<Worker.State> stateProperty() {
|
||||||
return new ReadOnlyObjectWrapper<>(state.get());
|
return new ReadOnlyObjectWrapper<>(state.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InnerTask() {
|
protected InnerTask() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected volatile boolean cancelled = false;
|
protected volatile boolean cancelled = false;
|
||||||
|
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
updateState(Worker.State.CANCELLED);
|
updateState(Worker.State.CANCELLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isCancelled() {
|
protected boolean isCancelled() {
|
||||||
return getState() == Worker.State.CANCELLED;
|
return getState() == Worker.State.CANCELLED;
|
||||||
}
|
}
|
||||||
@ -623,25 +622,25 @@ public final class ImageGalleryController {
|
|||||||
* Abstract base class for tasks associated with a file in the database
|
* Abstract base class for tasks associated with a file in the database
|
||||||
*/
|
*/
|
||||||
static public abstract class FileTask extends InnerTask {
|
static public abstract class FileTask extends InnerTask {
|
||||||
|
|
||||||
private final AbstractFile file;
|
private final AbstractFile file;
|
||||||
|
|
||||||
public AbstractFile getFile() {
|
public AbstractFile getFile() {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileTask(AbstractFile f) {
|
public FileTask(AbstractFile f) {
|
||||||
super();
|
super();
|
||||||
this.file = f;
|
this.file = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* task that updates one file in database with results from ingest
|
* task that updates one file in database with results from ingest
|
||||||
*/
|
*/
|
||||||
private class UpdateFileTask extends FileTask {
|
private class UpdateFileTask extends FileTask {
|
||||||
|
|
||||||
public UpdateFileTask(AbstractFile f) {
|
public UpdateFileTask(AbstractFile f) {
|
||||||
super(f);
|
super(f);
|
||||||
}
|
}
|
||||||
@ -668,7 +667,7 @@ public final class ImageGalleryController {
|
|||||||
* task that updates one file in database with results from ingest
|
* task that updates one file in database with results from ingest
|
||||||
*/
|
*/
|
||||||
private class RemoveFileTask extends FileTask {
|
private class RemoveFileTask extends FileTask {
|
||||||
|
|
||||||
public RemoveFileTask(AbstractFile f) {
|
public RemoveFileTask(AbstractFile f) {
|
||||||
super(f);
|
super(f);
|
||||||
}
|
}
|
||||||
@ -687,7 +686,7 @@ public final class ImageGalleryController {
|
|||||||
Logger.getLogger(RemoveFileTask.class.getName()).log(Level.SEVERE, "Case was closed out from underneath RemoveFile task");
|
Logger.getLogger(RemoveFileTask.class.getName()).log(Level.SEVERE, "Case was closed out from underneath RemoveFile task");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,16 +698,16 @@ public final class ImageGalleryController {
|
|||||||
* adds them to the Drawable DB
|
* adds them to the Drawable DB
|
||||||
*/
|
*/
|
||||||
private class CopyAnalyzedFiles extends InnerTask {
|
private class CopyAnalyzedFiles extends InnerTask {
|
||||||
|
|
||||||
final private String DRAWABLE_QUERY = "name LIKE '%." + StringUtils.join(ImageGalleryModule.getAllSupportedExtensions(), "' or name LIKE '%.") + "'";
|
final private String DRAWABLE_QUERY = "name LIKE '%." + StringUtils.join(ImageGalleryModule.getAllSupportedExtensions(), "' or name LIKE '%.") + "'";
|
||||||
|
|
||||||
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("populating analyzed image/video database");
|
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("populating analyzed image/video database");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
progressHandle.start();
|
progressHandle.start();
|
||||||
updateMessage("populating analyzed image/video database");
|
updateMessage("populating analyzed image/video database");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//grab all files with supported extension or detected mime types
|
//grab all files with supported extension or detected mime types
|
||||||
final List<AbstractFile> files = getSleuthKitCase().findAllFilesWhere(DRAWABLE_QUERY + " or tsk_files.obj_id in (select tsk_files.obj_id from tsk_files , blackboard_artifacts, blackboard_attributes"
|
final List<AbstractFile> files = getSleuthKitCase().findAllFilesWhere(DRAWABLE_QUERY + " or tsk_files.obj_id in (select tsk_files.obj_id from tsk_files , blackboard_artifacts, blackboard_attributes"
|
||||||
@ -718,7 +717,7 @@ public final class ImageGalleryController {
|
|||||||
+ " and blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG.getTypeID()
|
+ " and blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG.getTypeID()
|
||||||
+ " and blackboard_attributes.value_text in ('" + StringUtils.join(ImageGalleryModule.getSupportedMimes(), "','") + "'))");
|
+ " and blackboard_attributes.value_text in ('" + StringUtils.join(ImageGalleryModule.getSupportedMimes(), "','") + "'))");
|
||||||
progressHandle.switchToDeterminate(files.size());
|
progressHandle.switchToDeterminate(files.size());
|
||||||
|
|
||||||
updateProgress(0.0);
|
updateProgress(0.0);
|
||||||
|
|
||||||
//do in transaction
|
//do in transaction
|
||||||
@ -732,7 +731,7 @@ public final class ImageGalleryController {
|
|||||||
}
|
}
|
||||||
final Boolean hasMimeType = ImageGalleryModule.hasSupportedMimeType(f);
|
final Boolean hasMimeType = ImageGalleryModule.hasSupportedMimeType(f);
|
||||||
final boolean known = f.getKnown() == TskData.FileKnown.KNOWN;
|
final boolean known = f.getKnown() == TskData.FileKnown.KNOWN;
|
||||||
|
|
||||||
if (known) {
|
if (known) {
|
||||||
db.removeFile(f.getId(), tr); //remove known files
|
db.removeFile(f.getId(), tr); //remove known files
|
||||||
} else {
|
} else {
|
||||||
@ -752,38 +751,38 @@ public final class ImageGalleryController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
units++;
|
units++;
|
||||||
final int prog = units;
|
final int prog = units;
|
||||||
progressHandle.progress(f.getName(), units);
|
progressHandle.progress(f.getName(), units);
|
||||||
updateProgress(prog - 1 / (double) files.size());
|
updateProgress(prog - 1 / (double) files.size());
|
||||||
updateMessage(f.getName());
|
updateMessage(f.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
|
|
||||||
progressHandle = ProgressHandleFactory.createHandle("commiting image/video database");
|
progressHandle = ProgressHandleFactory.createHandle("commiting image/video database");
|
||||||
updateMessage("commiting image/video database");
|
updateMessage("commiting image/video database");
|
||||||
updateProgress(1.0);
|
updateProgress(1.0);
|
||||||
|
|
||||||
progressHandle.start();
|
progressHandle.start();
|
||||||
db.commitTransaction(tr, true);
|
db.commitTransaction(tr, true);
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getLogger(CopyAnalyzedFiles.class.getName()).log(Level.WARNING, "failed to transfer all database contents", ex);
|
Logger.getLogger(CopyAnalyzedFiles.class.getName()).log(Level.WARNING, "failed to transfer all database contents", ex);
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
Logger.getLogger(CopyAnalyzedFiles.class.getName()).log(Level.SEVERE, "Case was closed out from underneath CopyDataSource task", ex);
|
Logger.getLogger(CopyAnalyzedFiles.class.getName()).log(Level.SEVERE, "Case was closed out from underneath CopyDataSource task", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
|
|
||||||
updateMessage(
|
updateMessage(
|
||||||
"");
|
"");
|
||||||
updateProgress(
|
updateProgress(
|
||||||
-1.0);
|
-1.0);
|
||||||
setStale(false);
|
setStale(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -794,7 +793,7 @@ public final class ImageGalleryController {
|
|||||||
* netbeans and ImageGallery progress/status
|
* netbeans and ImageGallery progress/status
|
||||||
*/
|
*/
|
||||||
class PrePopulateDataSourceFiles extends InnerTask {
|
class PrePopulateDataSourceFiles extends InnerTask {
|
||||||
|
|
||||||
private final Content dataSource;
|
private final Content dataSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -804,7 +803,7 @@ public final class ImageGalleryController {
|
|||||||
*/
|
*/
|
||||||
// (name like '.jpg' or name like '.png' ...)
|
// (name like '.jpg' or name like '.png' ...)
|
||||||
private final String DRAWABLE_QUERY = "(name LIKE '%." + StringUtils.join(ImageGalleryModule.getAllSupportedExtensions(), "' or name LIKE '%.") + "') ";
|
private final String DRAWABLE_QUERY = "(name LIKE '%." + StringUtils.join(ImageGalleryModule.getAllSupportedExtensions(), "' or name LIKE '%.") + "') ";
|
||||||
|
|
||||||
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("prepopulating image/video database");
|
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("prepopulating image/video database");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -830,7 +829,7 @@ public final class ImageGalleryController {
|
|||||||
final List<AbstractFile> files;
|
final List<AbstractFile> files;
|
||||||
try {
|
try {
|
||||||
List<Long> fsObjIds = new ArrayList<>();
|
List<Long> fsObjIds = new ArrayList<>();
|
||||||
|
|
||||||
String fsQuery;
|
String fsQuery;
|
||||||
if (dataSource instanceof Image) {
|
if (dataSource instanceof Image) {
|
||||||
Image image = (Image) dataSource;
|
Image image = (Image) dataSource;
|
||||||
@ -844,7 +843,7 @@ public final class ImageGalleryController {
|
|||||||
else {
|
else {
|
||||||
fsQuery = "(fs_obj_id IS NULL) ";
|
fsQuery = "(fs_obj_id IS NULL) ";
|
||||||
}
|
}
|
||||||
|
|
||||||
files = getSleuthKitCase().findAllFilesWhere(fsQuery + " and " + DRAWABLE_QUERY);
|
files = getSleuthKitCase().findAllFilesWhere(fsQuery + " and " + DRAWABLE_QUERY);
|
||||||
progressHandle.switchToDeterminate(files.size());
|
progressHandle.switchToDeterminate(files.size());
|
||||||
|
|
||||||
@ -862,21 +861,21 @@ public final class ImageGalleryController {
|
|||||||
final int prog = units;
|
final int prog = units;
|
||||||
progressHandle.progress(f.getName(), units);
|
progressHandle.progress(f.getName(), units);
|
||||||
}
|
}
|
||||||
|
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
progressHandle = ProgressHandleFactory.createHandle("commiting image/video database");
|
progressHandle = ProgressHandleFactory.createHandle("commiting image/video database");
|
||||||
|
|
||||||
progressHandle.start();
|
progressHandle.start();
|
||||||
db.commitTransaction(tr, false);
|
db.commitTransaction(tr, false);
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getLogger(PrePopulateDataSourceFiles.class.getName()).log(Level.WARNING, "failed to transfer all database contents", ex);
|
Logger.getLogger(PrePopulateDataSourceFiles.class.getName()).log(Level.WARNING, "failed to transfer all database contents", ex);
|
||||||
} catch (IllegalStateException | NullPointerException ex) {
|
} catch (IllegalStateException | NullPointerException ex) {
|
||||||
Logger.getLogger(PrePopulateDataSourceFiles.class.getName()).log(Level.WARNING, "Case was closed out from underneath prepopulating database");
|
Logger.getLogger(PrePopulateDataSourceFiles.class.getName()).log(Level.WARNING, "Case was closed out from underneath prepopulating database");
|
||||||
}
|
}
|
||||||
|
|
||||||
progressHandle.finish();
|
progressHandle.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2015 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> 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.imagegallery.datamodel;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CategoryChangeEvent {
|
||||||
|
|
||||||
|
private final Collection<Long> ids;
|
||||||
|
|
||||||
|
public Collection<Long> getIds() {
|
||||||
|
return Collections.unmodifiableCollection(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategoryChangeEvent(Collection<Long> ids) {
|
||||||
|
this.ids = ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,12 +3,11 @@ package org.sleuthkit.autopsy.imagegallery.datamodel;
|
|||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
@ -19,6 +18,7 @@ public class CategoryManager {
|
|||||||
|
|
||||||
private static final java.util.logging.Logger LOGGER = Logger.getLogger(CategoryManager.class.getName());
|
private static final java.util.logging.Logger LOGGER = Logger.getLogger(CategoryManager.class.getName());
|
||||||
private DrawableDB db;
|
private DrawableDB db;
|
||||||
|
private final EventBus categoryEventBus = new EventBus("Category Event Bus");
|
||||||
|
|
||||||
public void setDb(DrawableDB db) {
|
public void setDb(DrawableDB db) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
@ -94,35 +94,19 @@ public class CategoryManager {
|
|||||||
}
|
}
|
||||||
return longAdder;
|
return longAdder;
|
||||||
}
|
}
|
||||||
@GuardedBy("listeners")
|
|
||||||
private final Set<CategoryListener> listeners = new HashSet<>();
|
|
||||||
|
|
||||||
public void fireChange(Collection<Long> ids) {
|
public void fireChange(Collection<Long> ids) {
|
||||||
Set<CategoryListener> listenersCopy = new HashSet<>();
|
|
||||||
synchronized (listeners) {
|
categoryEventBus.post(new CategoryChangeEvent(ids));
|
||||||
listenersCopy.addAll(listeners);
|
|
||||||
}
|
|
||||||
for (CategoryListener list : listenersCopy) {
|
|
||||||
list.handleCategoryChanged(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerListener(CategoryListener aThis) {
|
public void registerListener(Object aThis) {
|
||||||
synchronized (listeners) {
|
categoryEventBus.register(aThis);
|
||||||
listeners.add(aThis);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregisterListener(CategoryListener aThis) {
|
public void unregisterListener(Object aThis) {
|
||||||
synchronized (listeners) {
|
categoryEventBus.unregister(aThis);
|
||||||
listeners.remove(aThis);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface CategoryListener {
|
|
||||||
|
|
||||||
public void handleCategoryChanged(Collection<Long> ids);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -34,7 +34,6 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
|||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined.ThreadType;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined.ThreadType;
|
||||||
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.imagegallery.TagUtils;
|
import org.sleuthkit.autopsy.imagegallery.TagUtils;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GUI component that represents a single image as a tile with an icon, a label
|
* GUI component that represents a single image as a tile with an icon, a label
|
||||||
@ -44,7 +43,7 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
|||||||
*
|
*
|
||||||
* TODO: refactor this to extend from {@link Control}? -jm
|
* TODO: refactor this to extend from {@link Control}? -jm
|
||||||
*/
|
*/
|
||||||
public class DrawableTile extends SingleDrawableViewBase implements CategoryManager.CategoryListener, TagUtils.TagListener {
|
public class DrawableTile extends SingleDrawableViewBase implements TagUtils.TagListener {
|
||||||
|
|
||||||
private static final DropShadow LAST_SELECTED_EFFECT = new DropShadow(10, Color.BLUE);
|
private static final DropShadow LAST_SELECTED_EFFECT = new DropShadow(10, Color.BLUE);
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.sleuthkit.autopsy.imagegallery.gui;
|
package org.sleuthkit.autopsy.imagegallery.gui;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
@ -14,6 +15,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.imagegallery.TagUtils;
|
import org.sleuthkit.autopsy.imagegallery.TagUtils;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
||||||
|
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryChangeEvent;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
||||||
|
|
||||||
@ -21,7 +23,7 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
|||||||
* TODO: extract common interface out of {@link SingleImageView} and
|
* TODO: extract common interface out of {@link SingleImageView} and
|
||||||
* {@link MetaDataPane}
|
* {@link MetaDataPane}
|
||||||
*/
|
*/
|
||||||
public interface DrawableView extends CategoryManager.CategoryListener, TagUtils.TagListener {
|
public interface DrawableView extends TagUtils.TagListener {
|
||||||
|
|
||||||
//TODO: do this all in css? -jm
|
//TODO: do this all in css? -jm
|
||||||
static final int CAT_BORDER_WIDTH = 10;
|
static final int CAT_BORDER_WIDTH = 10;
|
||||||
@ -52,8 +54,8 @@ public interface DrawableView extends CategoryManager.CategoryListener, TagUtils
|
|||||||
|
|
||||||
Long getFileID();
|
Long getFileID();
|
||||||
|
|
||||||
@Override
|
@Subscribe
|
||||||
void handleCategoryChanged(Collection<Long> ids);
|
void handleCategoryChanged(CategoryChangeEvent evt);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void handleTagsChanged(Collection<Long> ids);
|
void handleTagsChanged(Collection<Long> ids);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.imagegallery.gui;
|
package org.sleuthkit.autopsy.imagegallery.gui;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -51,6 +52,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
import org.sleuthkit.autopsy.imagegallery.TagUtils;
|
import org.sleuthkit.autopsy.imagegallery.TagUtils;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
||||||
|
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryChangeEvent;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
||||||
@ -60,7 +62,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MetaDataPane extends AnchorPane implements CategoryManager.CategoryListener, TagUtils.TagListener, DrawableView {
|
public class MetaDataPane extends AnchorPane implements TagUtils.TagListener, DrawableView {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(MetaDataPane.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(MetaDataPane.class.getName());
|
||||||
|
|
||||||
@ -237,9 +239,10 @@ public class MetaDataPane extends AnchorPane implements CategoryManager.Category
|
|||||||
return imageBorder;
|
return imageBorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
@Override
|
@Override
|
||||||
public void handleCategoryChanged(Collection<Long> ids) {
|
public void handleCategoryChanged(CategoryChangeEvent evt) {
|
||||||
if (getFile() != null && ids.contains(getFileID())) {
|
if (getFile() != null && evt.getIds().contains(getFileID())) {
|
||||||
updateUI();
|
updateUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.imagegallery.gui;
|
package org.sleuthkit.autopsy.imagegallery.gui;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -71,6 +72,8 @@ import org.sleuthkit.autopsy.imagegallery.TagUtils;
|
|||||||
import org.sleuthkit.autopsy.imagegallery.actions.AddDrawableTagAction;
|
import org.sleuthkit.autopsy.imagegallery.actions.AddDrawableTagAction;
|
||||||
import org.sleuthkit.autopsy.imagegallery.actions.CategorizeAction;
|
import org.sleuthkit.autopsy.imagegallery.actions.CategorizeAction;
|
||||||
import org.sleuthkit.autopsy.imagegallery.actions.SwingMenuItemAdapter;
|
import org.sleuthkit.autopsy.imagegallery.actions.SwingMenuItemAdapter;
|
||||||
|
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryChangeEvent;
|
||||||
|
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
||||||
import org.sleuthkit.autopsy.imagegallery.grouping.GroupKey;
|
import org.sleuthkit.autopsy.imagegallery.grouping.GroupKey;
|
||||||
@ -396,9 +399,9 @@ public abstract class SingleDrawableViewBase extends AnchorPane implements Drawa
|
|||||||
return imageBorder;
|
return imageBorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Subscribe
|
||||||
public void handleCategoryChanged(Collection<Long> ids) {
|
public void handleCategoryChanged(CategoryChangeEvent evt) {
|
||||||
if (ids.contains(fileID)) {
|
if (evt.getIds().contains(fileID)) {
|
||||||
updateCategoryBorder();
|
updateCategoryBorder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ import org.sleuthkit.autopsy.imagegallery.FileIDSelectionModel;
|
|||||||
import org.sleuthkit.autopsy.imagegallery.TagUtils;
|
import org.sleuthkit.autopsy.imagegallery.TagUtils;
|
||||||
import org.sleuthkit.autopsy.imagegallery.actions.CategorizeAction;
|
import org.sleuthkit.autopsy.imagegallery.actions.CategorizeAction;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.ImageFile;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.ImageFile;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.VideoFile;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.VideoFile;
|
||||||
@ -65,7 +64,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* GroupPane. TODO: Extract a subclass for video files in slideshow mode-jm
|
* GroupPane. TODO: Extract a subclass for video files in slideshow mode-jm
|
||||||
* TODO: reduce coupling to GroupPane
|
* TODO: reduce coupling to GroupPane
|
||||||
*/
|
*/
|
||||||
public class SlideShowView extends SingleDrawableViewBase implements TagUtils.TagListener, CategoryManager.CategoryListener {
|
public class SlideShowView extends SingleDrawableViewBase implements TagUtils.TagListener {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(SlideShowView.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(SlideShowView.class.getName());
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.imagegallery.gui;
|
package org.sleuthkit.autopsy.imagegallery.gui;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
@ -38,13 +38,14 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
||||||
|
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryChangeEvent;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays summary statistics (counts) for each group
|
* Displays summary statistics (counts) for each group
|
||||||
*/
|
*/
|
||||||
public class SummaryTablePane extends AnchorPane implements CategoryManager.CategoryListener {
|
public class SummaryTablePane extends AnchorPane {
|
||||||
|
|
||||||
private static SummaryTablePane instance;
|
private static SummaryTablePane instance;
|
||||||
|
|
||||||
@ -95,8 +96,12 @@ public class SummaryTablePane extends AnchorPane implements CategoryManager.Cate
|
|||||||
/**
|
/**
|
||||||
* listen to Category updates and rebuild the table
|
* listen to Category updates and rebuild the table
|
||||||
*/
|
*/
|
||||||
@Override
|
@Subscribe
|
||||||
public void handleCategoryChanged(Collection<Long> ids) {
|
public void handleCategoryChanged(CategoryChangeEvent evt) {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh() {
|
||||||
final ObservableList<Pair<Category, Long>> data = FXCollections.observableArrayList();
|
final ObservableList<Pair<Category, Long>> data = FXCollections.observableArrayList();
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
for (Category cat : Category.values()) {
|
for (Category cat : Category.values()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user