mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
disable Timeline and image gallery if there are more than 6M files in the DB
This commit is contained in:
parent
91c48b7e72
commit
b68e794a0e
84
Core/src/org/sleuthkit/autopsy/guiutils/JavaFXUtils.java
Normal file
84
Core/src/org/sleuthkit/autopsy/guiutils/JavaFXUtils.java
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2017 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.guiutils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.ButtonType;
|
||||||
|
import javafx.scene.control.Dialog;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.stage.Modality;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities for dealing with JavaFX gui components.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class JavaFXUtils {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(JavaFXUtils.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image to use as title bar icon in dialogs
|
||||||
|
*/
|
||||||
|
private static final Image AUTOPSY_ICON;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Image tempImg = null;
|
||||||
|
try {
|
||||||
|
tempImg = new Image(new URL("nbresloc:/org/netbeans/core/startup/frame.gif").openStream()); //NON-NLS
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to load branded icon for progress dialog.", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
AUTOPSY_ICON = tempImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JavaFXUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the title bar icon for the given Dialog to be the Autopsy logo icon.
|
||||||
|
*
|
||||||
|
* @param dialog The dialog to set the title bar icon for.
|
||||||
|
*/
|
||||||
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
|
public static void setDialogIcons(Dialog<?> dialog) {
|
||||||
|
((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().setAll(AUTOPSY_ICON);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages(value = {"# {0} - Tool name",
|
||||||
|
"JavaFXUtils.showTooManyFiles.contentText="
|
||||||
|
+ "There are too many files in the DB to ensure reasonable performance."
|
||||||
|
+ " {0} will be disabled. ",
|
||||||
|
"JavaFXUtils.showTooManyFiles.headerText="})
|
||||||
|
public static void showTooManyFiles(String toolName) {
|
||||||
|
Alert dialog = new Alert(Alert.AlertType.INFORMATION, Bundle.JavaFXUtils_showTooManyFiles_contentText(toolName), ButtonType.OK);
|
||||||
|
dialog.initModality(Modality.APPLICATION_MODAL);
|
||||||
|
dialog.setTitle(toolName);
|
||||||
|
setDialogIcons(dialog);
|
||||||
|
dialog.setHeaderText(Bundle.JavaFXUtils_showTooManyFiles_headerText());
|
||||||
|
dialog.showAndWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2014-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.timeline;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import org.openide.awt.ActionID;
|
import org.openide.awt.ActionID;
|
||||||
@ -36,8 +37,10 @@ import org.sleuthkit.autopsy.core.Installer;
|
|||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
|
import org.sleuthkit.autopsy.guiutils.JavaFXUtils;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An Action that opens the Timeline window. Has methods to open the window in
|
* An Action that opens the Timeline window. Has methods to open the window in
|
||||||
@ -51,9 +54,8 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
|||||||
public final class OpenTimelineAction extends CallableSystemAction implements Presenter.Toolbar {
|
public final class OpenTimelineAction extends CallableSystemAction implements Presenter.Toolbar {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger LOGGER = Logger.getLogger(OpenTimelineAction.class.getName());
|
private static final Logger logger = Logger.getLogger(OpenTimelineAction.class.getName());
|
||||||
|
private static final int FILE_LIMIT = 6_000_000;
|
||||||
private static final boolean FX_INITED = Installer.isJavaFxInited();
|
|
||||||
|
|
||||||
private static TimeLineController timeLineController = null;
|
private static TimeLineController timeLineController = null;
|
||||||
|
|
||||||
@ -78,15 +80,26 @@ public final class OpenTimelineAction extends CallableSystemAction implements Pr
|
|||||||
/**
|
/**
|
||||||
* We used to also check if Case.getCurrentCase().hasData() was true. We
|
* We used to also check if Case.getCurrentCase().hasData() was true. We
|
||||||
* disabled that check because if it is executed while a data source is
|
* disabled that check because if it is executed while a data source is
|
||||||
* being added, it blocks the edt
|
* being added, it blocks the edt. We still do that in ImageGallery.
|
||||||
*/
|
*/
|
||||||
return Case.isCaseOpen() && FX_INITED;
|
return Case.isCaseOpen() && Installer.isJavaFxInited();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
public void performAction() {
|
public void performAction() {
|
||||||
showTimeline();
|
if (tooManyFiles()) {
|
||||||
|
Platform.runLater(() ->
|
||||||
|
JavaFXUtils.showTooManyFiles(Bundle.Timeline_dialogs_title()));
|
||||||
|
synchronized (OpenTimelineAction.this) {
|
||||||
|
if (timeLineController != null) {
|
||||||
|
timeLineController.shutDownTimeLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setEnabled(false);
|
||||||
|
} else {
|
||||||
|
showTimeline();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
@ -97,7 +110,7 @@ public final class OpenTimelineAction extends CallableSystemAction implements Pr
|
|||||||
Case currentCase = Case.getCurrentCase();
|
Case currentCase = Case.getCurrentCase();
|
||||||
if (currentCase.hasData() == false) {
|
if (currentCase.hasData() == false) {
|
||||||
MessageNotifyUtil.Message.info(Bundle.OpenTimeLineAction_msgdlg_text());
|
MessageNotifyUtil.Message.info(Bundle.OpenTimeLineAction_msgdlg_text());
|
||||||
LOGGER.log(Level.INFO, "Could not create timeline, there are no data sources.");// NON-NLS
|
logger.log(Level.INFO, "Could not create timeline, there are no data sources.");// NON-NLS
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -112,7 +125,7 @@ public final class OpenTimelineAction extends CallableSystemAction implements Pr
|
|||||||
|
|
||||||
} catch (IOException iOException) {
|
} catch (IOException iOException) {
|
||||||
MessageNotifyUtil.Message.error(Bundle.OpenTimelineAction_settingsErrorMessage());
|
MessageNotifyUtil.Message.error(Bundle.OpenTimelineAction_settingsErrorMessage());
|
||||||
LOGGER.log(Level.SEVERE, "Failed to initialize per case timeline settings.", iOException);
|
logger.log(Level.SEVERE, "Failed to initialize per case timeline settings.", iOException);
|
||||||
}
|
}
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
//there is no case... Do nothing.
|
//there is no case... Do nothing.
|
||||||
@ -169,12 +182,12 @@ public final class OpenTimelineAction extends CallableSystemAction implements Pr
|
|||||||
/**
|
/**
|
||||||
* Set this action to be enabled/disabled
|
* Set this action to be enabled/disabled
|
||||||
*
|
*
|
||||||
* @param value whether to enable this action or not
|
* @param enable whether to enable this action or not
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setEnabled(boolean value) {
|
public void setEnabled(boolean enable) {
|
||||||
super.setEnabled(value);
|
super.setEnabled(enable);
|
||||||
toolbarButton.setEnabled(value);
|
toolbarButton.setEnabled(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -189,4 +202,16 @@ public final class OpenTimelineAction extends CallableSystemAction implements Pr
|
|||||||
toolbarButton.setText(this.getName());
|
toolbarButton.setText(this.getName());
|
||||||
return toolbarButton;
|
return toolbarButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean tooManyFiles() {
|
||||||
|
try {
|
||||||
|
return FILE_LIMIT < Case.getCurrentCase().getSleuthkitCase().countFilesWhere("1 = 1");
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Can not open timeline with no case open.", ex);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error counting files in the DB.", ex);
|
||||||
|
}
|
||||||
|
//if there is any doubt (no case, tskcore error, etc) just disable .
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline;
|
package org.sleuthkit.autopsy.timeline;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
@ -30,14 +27,13 @@ import javafx.scene.control.ButtonType;
|
|||||||
import javafx.scene.control.Dialog;
|
import javafx.scene.control.Dialog;
|
||||||
import javafx.scene.control.DialogPane;
|
import javafx.scene.control.DialogPane;
|
||||||
import javafx.scene.control.ListView;
|
import javafx.scene.control.ListView;
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.stage.Modality;
|
import javafx.stage.Modality;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.controlsfx.dialog.ProgressDialog;
|
import org.controlsfx.dialog.ProgressDialog;
|
||||||
import org.controlsfx.tools.Borders;
|
import org.controlsfx.tools.Borders;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
|
import org.sleuthkit.autopsy.guiutils.JavaFXUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for the various prompts and dialogs Timeline shows the user related
|
* Manager for the various prompts and dialogs Timeline shows the user related
|
||||||
@ -45,8 +41,6 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
|||||||
*/
|
*/
|
||||||
public final class PromptDialogManager {
|
public final class PromptDialogManager {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(PromptDialogManager.class.getName());
|
|
||||||
|
|
||||||
@NbBundle.Messages("PrompDialogManager.buttonType.showTimeline=Continue")
|
@NbBundle.Messages("PrompDialogManager.buttonType.showTimeline=Continue")
|
||||||
private static final ButtonType CONTINUE = new ButtonType(Bundle.PrompDialogManager_buttonType_showTimeline(), ButtonBar.ButtonData.OK_DONE);
|
private static final ButtonType CONTINUE = new ButtonType(Bundle.PrompDialogManager_buttonType_showTimeline(), ButtonBar.ButtonData.OK_DONE);
|
||||||
|
|
||||||
@ -56,21 +50,6 @@ public final class PromptDialogManager {
|
|||||||
@NbBundle.Messages("PrompDialogManager.buttonType.update=Update DB")
|
@NbBundle.Messages("PrompDialogManager.buttonType.update=Update DB")
|
||||||
private static final ButtonType UPDATE = new ButtonType(Bundle.PrompDialogManager_buttonType_update(), ButtonBar.ButtonData.OK_DONE);
|
private static final ButtonType UPDATE = new ButtonType(Bundle.PrompDialogManager_buttonType_update(), ButtonBar.ButtonData.OK_DONE);
|
||||||
|
|
||||||
/**
|
|
||||||
* Image to use as title bar icon in dialogs
|
|
||||||
*/
|
|
||||||
private static final Image AUTOPSY_ICON;
|
|
||||||
|
|
||||||
static {
|
|
||||||
Image tempImg = null;
|
|
||||||
try {
|
|
||||||
tempImg = new Image(new URL("nbresloc:/org/netbeans/core/startup/frame.gif").openStream()); //NON-NLS
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.log(Level.WARNING, "Failed to load branded icon for progress dialog.", ex); //NON-NLS
|
|
||||||
}
|
|
||||||
AUTOPSY_ICON = tempImg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private Dialog<?> currentDialog;
|
private Dialog<?> currentDialog;
|
||||||
|
|
||||||
@ -143,8 +122,9 @@ public final class PromptDialogManager {
|
|||||||
* @param dialog The dialog to set the title bar icon for.
|
* @param dialog The dialog to set the title bar icon for.
|
||||||
*/
|
*/
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
|
@Deprecated
|
||||||
public static void setDialogIcons(Dialog<?> dialog) {
|
public static void setDialogIcons(Dialog<?> dialog) {
|
||||||
((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().setAll(AUTOPSY_ICON);
|
JavaFXUtils.setDialogIcons(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,6 +148,8 @@ public final class PromptDialogManager {
|
|||||||
return currentDialog.showAndWait().map(CONTINUE::equals).orElse(false);
|
return currentDialog.showAndWait().map(CONTINUE::equals).orElse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prompt the user to confirm rebuilding the database for the given list of
|
* Prompt the user to confirm rebuilding the database for the given list of
|
||||||
* reasons.
|
* reasons.
|
||||||
@ -177,7 +159,8 @@ public final class PromptDialogManager {
|
|||||||
* @return True if the user a confirms rebuilding the database.
|
* @return True if the user a confirms rebuilding the database.
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"PromptDialogManager.rebuildPrompt.headerText=The Timeline DB is incomplete and/or out of date. Some events may be missing or inaccurate and some features may be unavailable.",
|
"PromptDialogManager.rebuildPrompt.headerText=The Timeline DB is incomplete and/or out of date."
|
||||||
|
+ " Some events may be missing or inaccurate and some features may be unavailable.",
|
||||||
"PromptDialogManager.rebuildPrompt.details=Details"})
|
"PromptDialogManager.rebuildPrompt.details=Details"})
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
boolean confirmRebuild(List<String> rebuildReasons) {
|
boolean confirmRebuild(List<String> rebuildReasons) {
|
||||||
|
@ -58,6 +58,7 @@ import org.controlsfx.validation.Validator;
|
|||||||
import org.joda.time.Interval;
|
import org.joda.time.Interval;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.guiutils.JavaFXUtils;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.SingleEvent;
|
import org.sleuthkit.autopsy.timeline.datamodel.SingleEvent;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
||||||
import org.sleuthkit.autopsy.timeline.events.ViewInTimelineRequestedEvent;
|
import org.sleuthkit.autopsy.timeline.events.ViewInTimelineRequestedEvent;
|
||||||
@ -151,7 +152,7 @@ final class ShowInTimelineDialog extends Dialog<ViewInTimelineRequestedEvent> {
|
|||||||
Validator.createPredicateValidator(NumberUtils::isDigits, Bundle.ShowInTimelineDialog_amountValidator_message()));
|
Validator.createPredicateValidator(NumberUtils::isDigits, Bundle.ShowInTimelineDialog_amountValidator_message()));
|
||||||
|
|
||||||
//configure dialog properties
|
//configure dialog properties
|
||||||
PromptDialogManager.setDialogIcons(this);
|
JavaFXUtils.setDialogIcons(this);
|
||||||
initModality(Modality.APPLICATION_MODAL);
|
initModality(Modality.APPLICATION_MODAL);
|
||||||
|
|
||||||
//add scenegraph loaded from fxml to this dialog.
|
//add scenegraph loaded from fxml to this dialog.
|
||||||
|
@ -48,7 +48,7 @@ import org.openide.util.NbBundle;
|
|||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.timeline.PromptDialogManager;
|
import org.sleuthkit.autopsy.guiutils.JavaFXUtils;
|
||||||
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
import org.sleuthkit.autopsy.timeline.TimeLineController;
|
||||||
import org.sleuthkit.autopsy.timeline.snapshot.SnapShotReportWriter;
|
import org.sleuthkit.autopsy.timeline.snapshot.SnapShotReportWriter;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
@ -105,7 +105,7 @@ public class SaveSnapshotAsReport extends Action {
|
|||||||
|
|
||||||
//prompt user to pick report name
|
//prompt user to pick report name
|
||||||
TextInputDialog textInputDialog = new TextInputDialog();
|
TextInputDialog textInputDialog = new TextInputDialog();
|
||||||
PromptDialogManager.setDialogIcons(textInputDialog);
|
JavaFXUtils.setDialogIcons(textInputDialog);
|
||||||
textInputDialog.setTitle(Bundle.SaveSnapShotAsReport_action_dialogs_title());
|
textInputDialog.setTitle(Bundle.SaveSnapShotAsReport_action_dialogs_title());
|
||||||
textInputDialog.getEditor().setPromptText(Bundle.SaveSnapShotAsReport_reportName_prompt(defaultReportName));
|
textInputDialog.getEditor().setPromptText(Bundle.SaveSnapShotAsReport_reportName_prompt(defaultReportName));
|
||||||
textInputDialog.setHeaderText(Bundle.SaveSnapShotAsReport_reportName_header());
|
textInputDialog.setHeaderText(Bundle.SaveSnapShotAsReport_reportName_header());
|
||||||
|
@ -1,26 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-17 Basis Technology Corp.
|
* Copyright 2015-17 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.imagegallery.actions;
|
package org.sleuthkit.autopsy.imagegallery.actions;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
@ -29,6 +31,7 @@ import org.openide.awt.ActionReference;
|
|||||||
import org.openide.awt.ActionReferences;
|
import org.openide.awt.ActionReferences;
|
||||||
import org.openide.awt.ActionRegistration;
|
import org.openide.awt.ActionRegistration;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.openide.util.actions.Presenter;
|
import org.openide.util.actions.Presenter;
|
||||||
@ -37,49 +40,53 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
|||||||
import org.sleuthkit.autopsy.core.Installer;
|
import org.sleuthkit.autopsy.core.Installer;
|
||||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.guiutils.JavaFXUtils;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryModule;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryModule;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryTopComponent;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryTopComponent;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.imagegallery.OpenAction")
|
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.imagegallery.OpenAction")
|
||||||
@ActionReferences(value = {
|
@ActionReferences(value = {
|
||||||
@ActionReference(path = "Menu/Tools", position = 101),
|
@ActionReference(path = "Menu/Tools", position = 101),
|
||||||
@ActionReference(path = "Toolbars/Case", position = 101)
|
@ActionReference(path = "Toolbars/Case", position = 101)})
|
||||||
})
|
|
||||||
@ActionRegistration(displayName = "#CTL_OpenAction", lazy = false)
|
@ActionRegistration(displayName = "#CTL_OpenAction", lazy = false)
|
||||||
@Messages({"CTL_OpenAction=View Images/Videos",
|
@Messages({"CTL_OpenAction=View Images/Videos",
|
||||||
"OpenAction.stale.confDlg.msg=The image / video database may be out of date. " +
|
"OpenAction.stale.confDlg.msg=The image / video database may be out of date. "
|
||||||
"Do you want to update and listen for further ingest results?\n" +
|
+ "Do you want to update and listen for further ingest results?\n"
|
||||||
"Choosing 'yes' will update the database and enable listening to future ingests.",
|
+ "Choosing 'yes' will update the database and enable listening to future ingests.",
|
||||||
"OpenAction.stale.confDlg.title=Image Gallery"})
|
"OpenAction.stale.confDlg.title=Image Gallery"})
|
||||||
public final class OpenAction extends CallableSystemAction implements Presenter.Toolbar {
|
public final class OpenAction extends CallableSystemAction implements Presenter.Toolbar {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(OpenAction.class.getName());
|
private static final Logger logger = Logger.getLogger(OpenAction.class.getName());
|
||||||
private static final String VIEW_IMAGES_VIDEOS = Bundle.CTL_OpenAction();
|
private static final String VIEW_IMAGES_VIDEOS = Bundle.CTL_OpenAction();
|
||||||
|
|
||||||
private final JButton toolbarButton = new JButton();
|
private final JButton toolbarButton = new JButton();
|
||||||
private final PropertyChangeListener pcl;
|
private final PropertyChangeListener pcl;
|
||||||
|
private static final long FILE_LIMIT = 6_000_000;
|
||||||
|
|
||||||
public OpenAction() {
|
public OpenAction() {
|
||||||
super();
|
super();
|
||||||
toolbarButton.addActionListener(actionEvent -> performAction());
|
toolbarButton.addActionListener(actionEvent -> performAction());
|
||||||
pcl = (PropertyChangeEvent evt) -> {
|
pcl = (PropertyChangeEvent evt) -> {
|
||||||
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
||||||
setEnabled(RuntimeProperties.runningWithGUI() && evt.getNewValue() != null);
|
setEnabled(RuntimeProperties.runningWithGUI() && evt.getNewValue() != null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Case.addPropertyChangeListener(pcl);
|
Case.addPropertyChangeListener(pcl);
|
||||||
this.setEnabled(false);
|
this.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return Case.isCaseOpen() && Installer.isJavaFxInited() && Case.getCurrentCase().hasData();
|
return Case.isCaseOpen() && Installer.isJavaFxInited() && Case.getCurrentCase().hasData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the toolbar component of this action
|
/**
|
||||||
|
* Returns the toolbar component of this action
|
||||||
*
|
*
|
||||||
* @return component the toolbar button */
|
* @return component the toolbar button
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Component getToolbarPresenter() {
|
public Component getToolbarPresenter() {
|
||||||
ImageIcon icon = new ImageIcon(getClass().getResource("btn_icon_image_gallery_26.png")); //NON-NLS
|
ImageIcon icon = new ImageIcon(getClass().getResource("btn_icon_image_gallery_26.png")); //NON-NLS
|
||||||
@ -87,7 +94,7 @@ public final class OpenAction extends CallableSystemAction implements Presenter.
|
|||||||
toolbarButton.setText(this.getName());
|
toolbarButton.setText(this.getName());
|
||||||
return toolbarButton;
|
return toolbarButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set this action to be enabled/disabled
|
* Set this action to be enabled/disabled
|
||||||
*
|
*
|
||||||
@ -98,26 +105,35 @@ public final class OpenAction extends CallableSystemAction implements Presenter.
|
|||||||
super.setEnabled(value);
|
super.setEnabled(value);
|
||||||
toolbarButton.setEnabled(value);
|
toolbarButton.setEnabled(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("fallthrough")
|
@SuppressWarnings("fallthrough")
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"OpenAction.dialogTitle=Image Gallery"
|
||||||
|
})
|
||||||
public void performAction() {
|
public void performAction() {
|
||||||
|
|
||||||
//check case
|
//check case
|
||||||
if (!Case.isCaseOpen()) {
|
if (!Case.isCaseOpen()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Case currentCase = Case.getCurrentCase();
|
final Case currentCase = Case.getCurrentCase();
|
||||||
|
|
||||||
|
if (tooManyFiles()) {
|
||||||
|
Platform.runLater(() ->
|
||||||
|
JavaFXUtils.showTooManyFiles(Bundle.OpenAction_dialogTitle()));
|
||||||
|
setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (ImageGalleryModule.isDrawableDBStale(currentCase)) {
|
if (ImageGalleryModule.isDrawableDBStale(currentCase)) {
|
||||||
//drawable db is stale, ask what to do
|
//drawable db is stale, ask what to do
|
||||||
int answer = JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), Bundle.OpenAction_stale_confDlg_msg(),
|
int answer = JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), Bundle.OpenAction_stale_confDlg_msg(),
|
||||||
Bundle.OpenAction_stale_confDlg_title(), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
|
Bundle.OpenAction_stale_confDlg_title(), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||||
|
|
||||||
switch (answer) {
|
switch (answer) {
|
||||||
case JOptionPane.YES_OPTION:
|
case JOptionPane.YES_OPTION:
|
||||||
ImageGalleryController.getDefault().setListeningEnabled(true);
|
ImageGalleryController.getDefault().setListeningEnabled(true);
|
||||||
//fall through
|
//fall through
|
||||||
case JOptionPane.NO_OPTION:
|
case JOptionPane.NO_OPTION:
|
||||||
ImageGalleryTopComponent.openTopComponent();
|
ImageGalleryTopComponent.openTopComponent();
|
||||||
break;
|
break;
|
||||||
@ -129,17 +145,29 @@ public final class OpenAction extends CallableSystemAction implements Presenter.
|
|||||||
ImageGalleryTopComponent.openTopComponent();
|
ImageGalleryTopComponent.openTopComponent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean tooManyFiles() {
|
||||||
|
try {
|
||||||
|
return FILE_LIMIT < Case.getCurrentCase().getSleuthkitCase().countFilesWhere("1 = 1");
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Can not open image gallery with no case open.", ex);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error counting files in the DB.", ex);
|
||||||
|
}
|
||||||
|
//if there is any doubt (no case, tskcore error, etc) just disable .
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return VIEW_IMAGES_VIDEOS;
|
return VIEW_IMAGES_VIDEOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HelpCtx getHelpCtx() {
|
public HelpCtx getHelpCtx() {
|
||||||
return HelpCtx.DEFAULT_HELP;
|
return HelpCtx.DEFAULT_HELP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean asynchronous() {
|
public boolean asynchronous() {
|
||||||
return false; // run on edt
|
return false; // run on edt
|
||||||
|
Loading…
x
Reference in New Issue
Block a user