Bug fixes for Case actions

This commit is contained in:
Richard Cordovano 2017-01-24 00:36:36 -05:00
parent 938edeb0ab
commit e7ecd2e756
13 changed files with 260 additions and 292 deletions

View File

@ -30,7 +30,8 @@ import org.sleuthkit.autopsy.casemodule.CaseActionException;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* An action wired in to the Case/Exit menu item. * The action associated with the Case/Exit menu item. It closes the current
* case, if any, and shuts down the application.
*/ */
@ActionRegistration(displayName = "Exit", iconInMenu = true) @ActionRegistration(displayName = "Exit", iconInMenu = true)
@ActionReference(path = "Menu/Case", position = 1000, separatorBefore = 999) @ActionReference(path = "Menu/Case", position = 1000, separatorBefore = 999)

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2014-2017 Basis Technology Corp. * Copyright 2011-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");
@ -35,32 +35,37 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* Action to open the log subdirectory for the currently open case, or the log * The action associated with the Help/Open Log Folder menu item. It opens a
* subdirectory of the user directory if there is no current case. * file explorer window for the log subdirectory for the currently open case, or
* the log subdirectory of the user directory if there is no current case.
*/ */
@ActionRegistration(displayName = "#CTL_OpenLogFolder", iconInMenu = true) @ActionRegistration(displayName = "#CTL_OpenLogFolder", iconInMenu = true)
@ActionReference(path = "Menu/Help", position = 1750) @ActionReference(path = "Menu/Help", position = 1750)
@ActionID(id = "org.sleuthkit.autopsy.actions.OpenLogFolderAction", category = "Help") @ActionID(id = "org.sleuthkit.autopsy.actions.OpenLogFolderAction", category = "Help")
public final class OpenLogFolderAction implements ActionListener { public final class OpenLogFolderAction implements ActionListener {
private static final Logger LOGGER = Logger.getLogger(OpenLogFolderAction.class.getName()); private static final Logger logger = Logger.getLogger(OpenLogFolderAction.class.getName());
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
File logDir; File logDir;
try { if (Case.isCaseOpen()) {
Case currentCase = Case.getCurrentCase(); try {
logDir = new File(currentCase.getLogDirectoryPath()); Case currentCase = Case.getCurrentCase();
} catch (IllegalStateException ex) { logDir = new File(currentCase.getLogDirectoryPath());
/* } catch (IllegalStateException ex) {
* No open case. /*
*/ * The case
*/
logDir = new File(Places.getUserDirectory().getAbsolutePath() + File.separator + "var" + File.separator + "log");
}
} else {
logDir = new File(Places.getUserDirectory().getAbsolutePath() + File.separator + "var" + File.separator + "log"); logDir = new File(Places.getUserDirectory().getAbsolutePath() + File.separator + "var" + File.separator + "log");
} }
try { try {
if (logDir.exists() == false) { if (logDir.exists() == false) {
LOGGER.log(Level.SEVERE, String.format("The log subdirectory %s does not exist", logDir)); logger.log(Level.SEVERE, String.format("The log subdirectory %s does not exist", logDir));
NotifyDescriptor notifyDescriptor = new NotifyDescriptor.Message( NotifyDescriptor notifyDescriptor = new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenLogFolder.error1", logDir.getAbsolutePath()), NbBundle.getMessage(this.getClass(), "OpenLogFolder.error1", logDir.getAbsolutePath()),
NotifyDescriptor.ERROR_MESSAGE); NotifyDescriptor.ERROR_MESSAGE);
@ -69,12 +74,12 @@ public final class OpenLogFolderAction implements ActionListener {
Desktop.getDesktop().open(logDir); Desktop.getDesktop().open(logDir);
} }
} catch (IOException ex) { } catch (IOException ex) {
LOGGER.log(Level.SEVERE, String.format("Could not open log directory %s", logDir), ex); logger.log(Level.SEVERE, String.format("Could not open log directory %s", logDir), ex);
NotifyDescriptor notifyDescriptor = new NotifyDescriptor.Message( NotifyDescriptor notifyDescriptor = new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenLogFolder.CouldNotOpenLogFolder", logDir.getAbsolutePath()), NbBundle.getMessage(this.getClass(), "OpenLogFolder.CouldNotOpenLogFolder", logDir.getAbsolutePath()),
NotifyDescriptor.ERROR_MESSAGE); NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDescriptor); DialogDisplayer.getDefault().notify(notifyDescriptor);
} }
} }
} }

View File

@ -35,16 +35,19 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* Action to open the subdirectory of the current case that contains the output * The action associated with the Tools/Open Output Folder menu item. It opens a
* files. * file explorer window for the root output directory for the currently open
* case. If the case is a single-user case, this is the case directory. If the
* case is a multi-user case, this is a subdirectory of the case directory
* specific to the host machine.
*/ */
@ActionRegistration(displayName = "#CTL_OpenOutputFolder", iconInMenu = true, lazy = true) @ActionRegistration(displayName = "#CTL_OpenOutputFolder", iconInMenu = true, lazy = true)
@ActionReference(path = "Menu/Tools", position = 1850, separatorBefore = 1849) @ActionReference(path = "Menu/Tools", position = 1850, separatorBefore = 1849)
@ActionID(id = "org.sleuthkit.autopsy.actions.OpenOutputFolderAction", category = "Help") @ActionID(id = "org.sleuthkit.autopsy.actions.OpenOutputFolderAction", category = "Help")
public final class OpenOutputFolderAction extends CallableSystemAction { public final class OpenOutputFolderAction extends CallableSystemAction {
private static final Logger LOGGER = Logger.getLogger(OpenOutputFolderAction.class.getName());
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(OpenOutputFolderAction.class.getName());
@Override @Override
public void performAction() { public void performAction() {
@ -56,7 +59,7 @@ public final class OpenOutputFolderAction extends CallableSystemAction {
try { try {
Desktop.getDesktop().open(outputDir); Desktop.getDesktop().open(outputDir);
} catch (IOException ex) { } catch (IOException ex) {
LOGGER.log(Level.SEVERE, String.format("Failed to open output folder %s", outputDir), ex); //NON-NLS logger.log(Level.SEVERE, String.format("Failed to open output folder %s", outputDir), ex); //NON-NLS
NotifyDescriptor descriptor = new NotifyDescriptor.Message( NotifyDescriptor descriptor = new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenOutputFolder.CouldNotOpenOutputFolder", outputDir.getAbsolutePath()), NotifyDescriptor.ERROR_MESSAGE); NbBundle.getMessage(this.getClass(), "OpenOutputFolder.CouldNotOpenOutputFolder", outputDir.getAbsolutePath()), NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(descriptor); DialogDisplayer.getDefault().notify(descriptor);
@ -67,19 +70,14 @@ public final class OpenOutputFolderAction extends CallableSystemAction {
DialogDisplayer.getDefault().notify(descriptor); DialogDisplayer.getDefault().notify(descriptor);
} }
} catch (IllegalStateException ex) { } catch (IllegalStateException ex) {
LOGGER.log(Level.SEVERE, "OpenOutputFolderAction enabled with no current case", ex); //NON-NLS logger.log(Level.SEVERE, "OpenOutputFolderAction enabled with no current case", ex); //NON-NLS
JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(), "OpenOutputFolder.noCaseOpen")); JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(), "OpenOutputFolder.noCaseOpen"));
} }
} }
@Override @Override
public boolean isEnabled() { public boolean isEnabled() {
try { return Case.isCaseOpen();
Case.getCurrentCase();
return true;
} catch (IllegalStateException ex) {
return false;
}
} }
@Override @Override

View File

@ -1,15 +1,15 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2014 Basis Technology Corp. * Copyright 2011-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");
* 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.
@ -29,19 +29,18 @@ import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog; import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog;
@ActionID( /**
category = "Help", * The action associated with the Help/Get Ingest Progress Snapshot menu item.
id = "org.sleuthkit.autopsy.actions.ShowIngestProgressSnapshotAction" * It opens a the Ingest Progress Snapshot dialog.
) */
@ActionRegistration( @ActionID(category = "Help", id = "org.sleuthkit.autopsy.actions.ShowIngestProgressSnapshotAction")
displayName = "#CTL_ShowIngestProgressSnapshotAction", @ActionRegistration(displayName = "#CTL_ShowIngestProgressSnapshotAction", lazy = false)
lazy = false
)
@ActionReference(path = "Menu/Help", position = 1125) @ActionReference(path = "Menu/Help", position = 1125)
@Messages("CTL_ShowIngestProgressSnapshotAction=Ingest Status Details") @Messages("CTL_ShowIngestProgressSnapshotAction=Ingest Status Details")
public final class ShowIngestProgressSnapshotAction extends CallableSystemAction implements ActionListener { public final class ShowIngestProgressSnapshotAction extends CallableSystemAction implements ActionListener {
private static final String ACTION_NAME = NbBundle.getMessage(ShowIngestProgressSnapshotAction.class, "ShowIngestProgressSnapshotAction.actionName.text"); private static final String ACTION_NAME = NbBundle.getMessage(ShowIngestProgressSnapshotAction.class, "ShowIngestProgressSnapshotAction.actionName.text");
private static final long serialVersionUID = 1L;
@Override @Override
public void performAction() { public void performAction() {
@ -60,16 +59,11 @@ public final class ShowIngestProgressSnapshotAction extends CallableSystemAction
@Override @Override
public boolean isEnabled() { public boolean isEnabled() {
try { return Case.isCaseOpen();
Case.getCurrentCase();
return true;
} catch (IllegalStateException ex) {
return false;
}
} }
@Override @Override
public boolean asynchronous() { public boolean asynchronous() {
return false; // run on edt return false;
} }
} }

View File

@ -128,9 +128,10 @@ public class Case {
/* /*
* The application name, used to make the title of the main application * The application name, used to make the title of the main application
* window [application] name when there is no open case and [application * window [application name] when there is no open case and [curent case
* name]-[curent case display name] when there is an open case. Initialized * display name] - [application name] when there is an open case.
* by getting the main window title before a case has been opened. * Initialized by getting the main window title before a case has been
* opened.
* *
* TODO (JIRA-2231): Make the application name a RuntimeProperties item set * TODO (JIRA-2231): Make the application name a RuntimeProperties item set
* by Installers. * by Installers.
@ -749,9 +750,9 @@ public class Case {
if (RuntimeProperties.runningWithGUI()) { if (RuntimeProperties.runningWithGUI()) {
progressIndicator = new ModalDialogProgressIndicator( progressIndicator = new ModalDialogProgressIndicator(
Bundle.Case_progressIndicatorTitle_closingCase(), Bundle.Case_progressIndicatorTitle_closingCase(),
new String[]{Bundle.Case_progressIndicatorCancelButton_label()}, new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
Bundle.Case_progressIndicatorCancelButton_label(), Bundle.Case_progressIndicatorCancelButton_label(),
null, null,
listener); listener);
} else { } else {
progressIndicator = new LoggingProgressIndicator(); progressIndicator = new LoggingProgressIndicator();
@ -873,10 +874,10 @@ public class Case {
ProgressIndicator progressIndicator; ProgressIndicator progressIndicator;
if (RuntimeProperties.runningWithGUI()) { if (RuntimeProperties.runningWithGUI()) {
progressIndicator = new ModalDialogProgressIndicator( progressIndicator = new ModalDialogProgressIndicator(
Bundle.Case_progressIndicatorTitle_deletingCase(), Bundle.Case_progressIndicatorTitle_deletingCase(),
new String[]{Bundle.Case_progressIndicatorCancelButton_label()}, new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
Bundle.Case_progressIndicatorCancelButton_label(), Bundle.Case_progressIndicatorCancelButton_label(),
null, null,
listener); listener);
} else { } else {
progressIndicator = new LoggingProgressIndicator(); progressIndicator = new LoggingProgressIndicator();
@ -891,7 +892,7 @@ public class Case {
* cannot be deleted if another node has it open. * cannot be deleted if another node has it open.
*/ */
progressIndicator.start(Bundle.Case_progressMessage_acquiringLocks()); progressIndicator.start(Bundle.Case_progressMessage_acquiringLocks());
try (CoordinationService.Lock dirLock = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, metadata.getCaseDatabasePath())) { try (CoordinationService.Lock dirLock = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, metadata.getCaseDirectory())) {
assert (null != dirLock); assert (null != dirLock);
/* /*
@ -1277,7 +1278,7 @@ public class Case {
CallableSystemAction.get(AddImageAction.class).setEnabled(true); CallableSystemAction.get(AddImageAction.class).setEnabled(true);
CallableSystemAction.get(CaseCloseAction.class).setEnabled(true); CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true); CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
CallableSystemAction.get(DeleteCurrentCaseAction.class).setEnabled(true); CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true);
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true); CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true);
/* /*
@ -1296,8 +1297,8 @@ public class Case {
} }
/* /*
* Reset the main window title to be [application name] - [case * Reset the main window title to be [curent case display name]
* name], instead of just the application name. * - [application name], instead of just the application name.
*/ */
addCaseNameToMainWindowTitle(currentCase.getDisplayName()); addCaseNameToMainWindowTitle(currentCase.getDisplayName());
}); });
@ -1323,7 +1324,7 @@ public class Case {
CallableSystemAction.get(AddImageAction.class).setEnabled(false); CallableSystemAction.get(AddImageAction.class).setEnabled(false);
CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); CallableSystemAction.get(CaseCloseAction.class).setEnabled(false);
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false); CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false);
CallableSystemAction.get(DeleteCurrentCaseAction.class).setEnabled(false); CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false);
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(false); CallableSystemAction.get(OpenTimelineAction.class).setEnabled(false);
/* /*
@ -1334,7 +1335,7 @@ public class Case {
/* /*
* Reset the main window title to be just the application name, * Reset the main window title to be just the application name,
* instead of [application name] - [case name]. * instead of [curent case display name] - [application name].
*/ */
Frame mainWindow = WindowManager.getDefault().getMainWindow(); Frame mainWindow = WindowManager.getDefault().getMainWindow();
mainWindow.setTitle(appName); mainWindow.setTitle(appName);
@ -1786,7 +1787,7 @@ public class Case {
/** /**
* Updates the case display name name. * Updates the case display name name.
* *
* @param oldCaseName The old case name. * @param oldCaseName The old case name.
* @param oldPath The old path name. * @param oldPath The old path name.
* @param newCaseName The new case name. * @param newCaseName The new case name.
@ -1873,10 +1874,21 @@ public class Case {
progressIndicator.progress(Bundle.Case_progressMessage_creatingCaseDatabase()); progressIndicator.progress(Bundle.Case_progressMessage_creatingCaseDatabase());
String dbName = null; String dbName = null;
try { try {
if (caseType == CaseType.SINGLE_USER_CASE) { if (CaseType.SINGLE_USER_CASE == caseType) {
dbName = Paths.get(caseDir, SINGLE_USER_CASE_DB_NAME).toString(); /*
this.caseDb = SleuthkitCase.newCase(dbName); * For single-user cases, the case database is a SQLite database
} else if (caseType == CaseType.MULTI_USER_CASE) { * with a fixed name and is physically located in the root of
* the case directory.
*/
dbName = SINGLE_USER_CASE_DB_NAME;
this.caseDb = SleuthkitCase.newCase(Paths.get(caseDir, SINGLE_USER_CASE_DB_NAME).toString());
} else if (CaseType.MULTI_USER_CASE == caseType) {
/*
* For multi-user cases, the case database is a PostgreSQL
* database with a name consiting of the case name with a time
* stamp suffix and is physically located on the database
* server.
*/
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss"); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
Date date = new Date(); Date date = new Date();
dbName = caseName + "_" + dateFormat.format(date); dbName = caseName + "_" + dateFormat.format(date);
@ -1924,7 +1936,7 @@ public class Case {
try { try {
progressIndicator.progress(Bundle.Case_progressMessage_openingCaseDatabase()); progressIndicator.progress(Bundle.Case_progressMessage_openingCaseDatabase());
if (CaseType.SINGLE_USER_CASE == metadata.getCaseType()) { if (CaseType.SINGLE_USER_CASE == metadata.getCaseType()) {
this.caseDb = SleuthkitCase.openCase(metadata.getCaseDatabasePath()); this.caseDb = SleuthkitCase.openCase(Paths.get(metadata.getCaseDirectory(), metadata.getCaseDatabaseName()).toString());
} else if (UserPreferences.getIsMultiUserModeEnabled()) { } else if (UserPreferences.getIsMultiUserModeEnabled()) {
try { try {
this.caseDb = SleuthkitCase.openCase(metadata.getCaseDatabaseName(), UserPreferences.getDatabaseConnectionInfo(), metadata.getCaseDirectory()); this.caseDb = SleuthkitCase.openCase(metadata.getCaseDatabaseName(), UserPreferences.getDatabaseConnectionInfo(), metadata.getCaseDirectory());

View File

@ -43,14 +43,13 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
/** /**
* An action to close the current case and pop up the start up window that * The action associated with the Case/Close Case menu item and the Close Case
* allows a user to open another case. * toolbar button. It closes the current case and pops up the start up window
* that allows a user to open another case.
*/ */
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.casemodule.CaseCloseAction") @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.casemodule.CaseCloseAction")
@ActionRegistration(displayName = "#CTL_CaseCloseAct", lazy = false) @ActionRegistration(displayName = "#CTL_CaseCloseAct", lazy = false)
@ActionReferences(value = { @ActionReferences(value = {@ActionReference(path = "Toolbars/Case", position = 104)})
@ActionReference(path = "Toolbars/Case", position = 104)
})
public final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar { public final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -58,19 +57,20 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
private final JButton toolbarButton = new JButton(); private final JButton toolbarButton = new JButton();
/** /**
* The constructor for this class * Constructs the action associated with the Case/Close Case menu item and
* the Close Case toolbar button.
*/ */
public CaseCloseAction() { public CaseCloseAction() {
putValue("iconBase", "org/sleuthkit/autopsy/images/close-icon.png"); // put the icon NON-NLS putValue("iconBase", "org/sleuthkit/autopsy/images/close-icon.png"); //NON-NLS
putValue(Action.NAME, NbBundle.getMessage(CaseCloseAction.class, "CTL_CaseCloseAct")); // put the action Name putValue(Action.NAME, NbBundle.getMessage(CaseCloseAction.class, "CTL_CaseCloseAct")); //NON-NLS
toolbarButton.addActionListener(CaseCloseAction.this::actionPerformed); toolbarButton.addActionListener(CaseCloseAction.this::actionPerformed);
this.setEnabled(false); this.setEnabled(false);
} }
/** /**
* Closes the current opened case. * Closes the current case.
* *
* @param e the action event for this method * @param e The action event.
*/ */
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
@ -117,17 +117,17 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
} }
/** /**
* This method does nothing. Use the "actionPerformed(ActionEvent e)" * Closes the current case.
* instead of this method.
*/ */
@Override @Override
public void performAction() { public void performAction() {
actionPerformed(null);
} }
/** /**
* Gets the name of this action. This may be presented as an item in a menu. * Gets the action name.
* *
* @return actionName * @return The action name.
*/ */
@Override @Override
public String getName() { public String getName() {
@ -135,9 +135,9 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
} }
/** /**
* Gets the HelpCtx associated with implementing object * Gets the help context.
* *
* @return HelpCtx or HelpCtx.DEFAULT_HELP * @return The help context.
*/ */
@Override @Override
public HelpCtx getHelpCtx() { public HelpCtx getHelpCtx() {
@ -145,9 +145,9 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
} }
/** /**
* Returns the toolbar component of this action * Returns the toolbar component of this action.
* *
* @return component the toolbar button * @return The toolbar button
*/ */
@Override @Override
public Component getToolbarPresenter() { public Component getToolbarPresenter() {

View File

@ -19,9 +19,11 @@
package org.sleuthkit.autopsy.casemodule; package org.sleuthkit.autopsy.casemodule;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.Action; import javax.swing.Action;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import org.openide.DialogDescriptor; import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer; import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor; import org.openide.NotifyDescriptor;
@ -32,15 +34,16 @@ import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* An action to delete the current case. * The action associated with the Delete button of the Case Properties panel. It
* deletes the current case.
*/ */
final class DeleteCurrentCaseAction extends CallableSystemAction { final class CaseDeleteAction extends CallableSystemAction {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(DeleteCurrentCaseAction.class.getName()); private static final Logger logger = Logger.getLogger(CaseDeleteAction.class.getName());
DeleteCurrentCaseAction() { // Should pass in caller CaseDeleteAction() {
putValue(Action.NAME, NbBundle.getMessage(DeleteCurrentCaseAction.class, "CTL_CaseDeleteAction")); putValue(Action.NAME, NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction"));
this.setEnabled(false); this.setEnabled(false);
} }
@ -68,18 +71,34 @@ final class DeleteCurrentCaseAction extends CallableSystemAction {
null, null,
NotifyDescriptor.NO_OPTION)); NotifyDescriptor.NO_OPTION));
if (null != response && DialogDescriptor.YES_OPTION == response) { if (null != response && DialogDescriptor.YES_OPTION == response) {
try {
Case.deleteCurrentCase(); new SwingWorker<Void, Void>() {
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Failed to delete case %s at %s", caseName, caseDirectory), ex); @Override
JOptionPane.showMessageDialog( protected Void doInBackground() throws Exception {
null, Case.deleteCurrentCase();
Bundle.Case_deleteCaseFailureMessageBox_message(ex.getMessage()), return null;
Bundle.Case_deleteCaseFailureMessageBox_title(), }
JOptionPane.ERROR_MESSAGE);
} @Override
// because the "Delete Case" button is in the "CaseProperties" window, we have to close that window when we delete the case. protected void done() {
CasePropertiesAction.closeCasePropertiesWindow(); try {
get();
} catch (InterruptedException | ExecutionException ex) {
logger.log(Level.SEVERE, String.format("Failed to delete case %s at %s", caseName, caseDirectory), ex);
JOptionPane.showMessageDialog(
null,
Bundle.Case_deleteCaseFailureMessageBox_message(ex.getMessage()),
Bundle.Case_deleteCaseFailureMessageBox_title(),
JOptionPane.ERROR_MESSAGE);
}
/*
* Close the Case Properties dialog that is the parent
* of the Delete button that invokes this action.
*/
CasePropertiesAction.closeCasePropertiesWindow();
}
}.execute();
} }
} catch (IllegalStateException ex) { } catch (IllegalStateException ex) {
logger.log(Level.SEVERE, "Case delete action called with no current case", ex); logger.log(Level.SEVERE, "Case delete action called with no current case", ex);
@ -92,7 +111,7 @@ final class DeleteCurrentCaseAction extends CallableSystemAction {
@Override @Override
public String getName() { public String getName() {
return NbBundle.getMessage(DeleteCurrentCaseAction.class, "CTL_CaseDeleteAction"); return NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction");
} }
@Override @Override

View File

@ -54,11 +54,11 @@ public final class CaseMetadata {
private static final String FILE_EXTENSION = ".aut"; private static final String FILE_EXTENSION = ".aut";
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)"); private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
private static final String SCHEMA_VERSION_ONE = "1.0"; private static final String SCHEMA_VERSION_ONE = "1.0";
private static final String SCHEMA_VERSION_TWO = "2"; private static final String SCHEMA_VERSION_TWO = "2.0";
private final static String AUTOPSY_VERSION_ELEMENT_NAME = "AutopsyCreatedVersion"; //NON-NLS private final static String AUTOPSY_VERSION_ELEMENT_NAME = "AutopsyCreatedVersion"; //NON-NLS
private final static String CASE_DATABASE_NAME_ELEMENT_NAME = "DatabaseName"; //NON-NLS private final static String CASE_DATABASE_NAME_ELEMENT_NAME = "DatabaseName"; //NON-NLS
private final static String TEXT_INDEX_NAME_ELEMENT = "TextIndexName"; //NON-NLS private final static String TEXT_INDEX_NAME_ELEMENT = "TextIndexName"; //NON-NLS
private static final String CURRENT_SCHEMA_VERSION = "2.0"; private static final String CURRENT_SCHEMA_VERSION = "3.0";
private final static String ROOT_ELEMENT_NAME = "AutopsyCase"; //NON-NLS private final static String ROOT_ELEMENT_NAME = "AutopsyCase"; //NON-NLS
private final static String SCHEMA_VERSION_ELEMENT_NAME = "SchemaVersion"; //NON-NLS private final static String SCHEMA_VERSION_ELEMENT_NAME = "SchemaVersion"; //NON-NLS
private final static String CREATED_DATE_ELEMENT_NAME = "CreatedDate"; //NON-NLS private final static String CREATED_DATE_ELEMENT_NAME = "CreatedDate"; //NON-NLS
@ -67,6 +67,7 @@ public final class CaseMetadata {
private final static String AUTOPSY_SAVED_BY_ELEMENT_NAME = "SavedByAutopsyVersion"; //NON-NLS private final static String AUTOPSY_SAVED_BY_ELEMENT_NAME = "SavedByAutopsyVersion"; //NON-NLS
private final static String CASE_ELEMENT_NAME = "Case"; //NON-NLS private final static String CASE_ELEMENT_NAME = "Case"; //NON-NLS
private final static String CASE_NAME_ELEMENT_NAME = "Name"; //NON-NLS private final static String CASE_NAME_ELEMENT_NAME = "Name"; //NON-NLS
private final static String CASE_DISPLAY_NAME_ELEMENT_NAME = "DisplayName"; //NON-NLS
private final static String CASE_NUMBER_ELEMENT_NAME = "Number"; //NON-NLS private final static String CASE_NUMBER_ELEMENT_NAME = "Number"; //NON-NLS
private final static String EXAMINER_ELEMENT_NAME = "Examiner"; //NON-NLS private final static String EXAMINER_ELEMENT_NAME = "Examiner"; //NON-NLS
private final static String CASE_TYPE_ELEMENT_NAME = "CaseType"; //NON-NLS private final static String CASE_TYPE_ELEMENT_NAME = "CaseType"; //NON-NLS
@ -78,7 +79,7 @@ public final class CaseMetadata {
private String caseDisplayName; private String caseDisplayName;
private String caseNumber; private String caseNumber;
private String examiner; private String examiner;
private String caseDatabase; private String caseDatabaseName;
private String textIndexName; private String textIndexName;
private String createdDate; private String createdDate;
private String createdByVersion; private String createdByVersion;
@ -96,16 +97,16 @@ public final class CaseMetadata {
* Constructs an object that provides access to the case metadata stored in * Constructs an object that provides access to the case metadata stored in
* a new case metadata file that is created using the supplied metadata. * a new case metadata file that is created using the supplied metadata.
* *
* @param caseDirectory The case directory. * @param caseDirectory The case directory.
* @param caseType The type of case. * @param caseType The type of case.
* @param caseName The immutable name of the case. * @param caseName The immutable name of the case.
* @param caseDisplayName The display name of the case, can be changed by * @param caseDisplayName The display name of the case, can be changed by a
* a user. * user.
* @param caseNumber The case number. * @param caseNumber The case number.
* @param examiner The name of the case examiner. * @param examiner The name of the case examiner.
* @param caseDatabase For a single-user case, the full path to the * @param caseDatabase For a single-user case, the full path to the case
* case database file. For a multi-user case, the * database file. For a multi-user case, the case
* case database name. * database name.
* *
* @throws CaseMetadataException If the new case metadata file cannot be * @throws CaseMetadataException If the new case metadata file cannot be
* created. * created.
@ -117,7 +118,7 @@ public final class CaseMetadata {
this.caseDisplayName = caseDisplayName; this.caseDisplayName = caseDisplayName;
this.caseNumber = caseNumber; this.caseNumber = caseNumber;
this.examiner = examiner; this.examiner = examiner;
this.caseDatabase = caseDatabase; this.caseDatabaseName = caseDatabase;
createdByVersion = Version.getVersion(); createdByVersion = Version.getVersion();
createdDate = CaseMetadata.DATE_FORMAT.format(new Date()); createdDate = CaseMetadata.DATE_FORMAT.format(new Date());
writeToFile(); writeToFile();
@ -172,7 +173,7 @@ public final class CaseMetadata {
public String getCaseName() { public String getCaseName() {
return caseName; return caseName;
} }
/** /**
* Gets the case display name. * Gets the case display name.
* *
@ -181,7 +182,7 @@ public final class CaseMetadata {
public String getCaseDisplayName() { public String getCaseDisplayName() {
return this.caseDisplayName; return this.caseDisplayName;
} }
/** /**
* Sets the case display name. This does not change the name of the case * Sets the case display name. This does not change the name of the case
* directory, the case database, or the text index name. * directory, the case database, or the text index name.
@ -198,7 +199,7 @@ public final class CaseMetadata {
throw ex; throw ex;
} }
} }
/** /**
* Gets the case number. * Gets the case number.
* *
@ -218,32 +219,12 @@ public final class CaseMetadata {
} }
/** /**
* Gets the name of the case case database. * Gets the name of the case database.
* *
* @return The case database name. * @return The case database name.
*/ */
public String getCaseDatabaseName() { public String getCaseDatabaseName() {
if (caseType == Case.CaseType.MULTI_USER_CASE) { return caseDatabaseName;
return caseDatabase;
} else {
return Paths.get(caseDatabase).getFileName().toString();
}
}
/**
* Gets the full path to the case database file if the case is a single-user
* case.
*
* @return The full path to the case database file for a single-user case.
*
* @throws UnsupportedOperationException If called for a multi-user case.
*/
public String getCaseDatabasePath() throws UnsupportedOperationException {
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
return caseDatabase;
} else {
throw new UnsupportedOperationException();
}
} }
/** /**
@ -260,8 +241,8 @@ public final class CaseMetadata {
this.textIndexName = oldIndexName; this.textIndexName = oldIndexName;
throw ex; throw ex;
} }
} }
/** /**
* Gets the text index name. * Gets the text index name.
* *
@ -383,10 +364,11 @@ public final class CaseMetadata {
* Create the children of the case element. * Create the children of the case element.
*/ */
createChildElement(doc, caseElement, CASE_NAME_ELEMENT_NAME, caseName); createChildElement(doc, caseElement, CASE_NAME_ELEMENT_NAME, caseName);
createChildElement(doc, caseElement, CASE_DISPLAY_NAME_ELEMENT_NAME, caseDisplayName);
createChildElement(doc, caseElement, CASE_NUMBER_ELEMENT_NAME, caseNumber); createChildElement(doc, caseElement, CASE_NUMBER_ELEMENT_NAME, caseNumber);
createChildElement(doc, caseElement, EXAMINER_ELEMENT_NAME, examiner); createChildElement(doc, caseElement, EXAMINER_ELEMENT_NAME, examiner);
createChildElement(doc, caseElement, CASE_TYPE_ELEMENT_NAME, caseType.toString()); createChildElement(doc, caseElement, CASE_TYPE_ELEMENT_NAME, caseType.toString());
createChildElement(doc, caseElement, CASE_DATABASE_ELEMENT_NAME, caseDatabase); createChildElement(doc, caseElement, CASE_DATABASE_ELEMENT_NAME, caseDatabaseName);
createChildElement(doc, caseElement, TEXT_INDEX_ELEMENT, textIndexName); createChildElement(doc, caseElement, TEXT_INDEX_ELEMENT, textIndexName);
} }
@ -444,6 +426,11 @@ public final class CaseMetadata {
} }
Element caseElement = (Element) caseElements.item(0); Element caseElement = (Element) caseElements.item(0);
this.caseName = getElementTextContent(caseElement, CASE_NAME_ELEMENT_NAME, true); this.caseName = getElementTextContent(caseElement, CASE_NAME_ELEMENT_NAME, true);
if (schemaVersion.equals(SCHEMA_VERSION_ONE) || schemaVersion.equals(SCHEMA_VERSION_TWO)) {
this.caseDisplayName = caseName;
} else {
this.caseDisplayName = getElementTextContent(caseElement, CASE_DISPLAY_NAME_ELEMENT_NAME, true);
}
this.caseNumber = getElementTextContent(caseElement, CASE_NUMBER_ELEMENT_NAME, false); this.caseNumber = getElementTextContent(caseElement, CASE_NUMBER_ELEMENT_NAME, false);
this.examiner = getElementTextContent(caseElement, EXAMINER_ELEMENT_NAME, false); this.examiner = getElementTextContent(caseElement, EXAMINER_ELEMENT_NAME, false);
this.caseType = Case.CaseType.fromString(getElementTextContent(caseElement, CASE_TYPE_ELEMENT_NAME, true)); this.caseType = Case.CaseType.fromString(getElementTextContent(caseElement, CASE_TYPE_ELEMENT_NAME, true));
@ -451,10 +438,10 @@ public final class CaseMetadata {
throw new CaseMetadataException("Case metadata file corrupted"); throw new CaseMetadataException("Case metadata file corrupted");
} }
if (schemaVersion.equals(SCHEMA_VERSION_ONE)) { if (schemaVersion.equals(SCHEMA_VERSION_ONE)) {
this.caseDatabase = getElementTextContent(caseElement, CASE_DATABASE_NAME_ELEMENT_NAME, true); this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_NAME_ELEMENT_NAME, true);
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_NAME_ELEMENT, true); this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_NAME_ELEMENT, true);
} else { } else {
this.caseDatabase = getElementTextContent(caseElement, CASE_DATABASE_ELEMENT_NAME, true); this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_ELEMENT_NAME, true);
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, true); this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, true);
} }
@ -511,4 +498,22 @@ public final class CaseMetadata {
} }
} }
/**
* Gets the full path to the case database file if the case is a single-user
* case.
*
* @return The full path to the case database file for a single-user case.
*
* @throws UnsupportedOperationException If called for a multi-user case.
* @deprecated
*/
@Deprecated
public String getCaseDatabasePath() throws UnsupportedOperationException {
if (Case.CaseType.SINGLE_USER_CASE == caseType) {
return Paths.get(getCaseDirectory(), caseDatabaseName).toString();
} else {
throw new UnsupportedOperationException();
}
}
} }

View File

@ -26,9 +26,9 @@ import org.openide.util.actions.SystemAction;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
/** /**
* The action to create a new case. This action class is always enabled. * The action associated with the Case/New Case menu item and the Create New
* * Case button of the start up window that allows a user to open a case. It
* IMPORTANT: Must be called in the Swing Event Dispatch Thread (EDT). * invokes the New Case wizard.
*/ */
@ServiceProvider(service = CaseNewActionInterface.class) @ServiceProvider(service = CaseNewActionInterface.class)
public final class CaseNewAction extends CallableSystemAction implements CaseNewActionInterface { public final class CaseNewAction extends CallableSystemAction implements CaseNewActionInterface {
@ -42,6 +42,7 @@ public final class CaseNewAction extends CallableSystemAction implements CaseNew
@Override @Override
public void performAction() { public void performAction() {
actionPerformed(null);
} }
@Override @Override

View File

@ -43,21 +43,25 @@ import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
/** /**
* An action that opens an existing case. It is associated with the Case/Open * The action associated with the Case/Open Case menu item via the layer.xml
* menu item via the layer.xml file, with a toolbar button, and with a button on * file, a toolbar button, and the Create New Case button of the start up window
* the startup window. * that allows a user to open a case. It opens an existing case.
*/ */
@ServiceProvider(service = CaseOpenAction.class) @ServiceProvider(service = CaseOpenAction.class)
public final class CaseOpenAction extends CallableSystemAction implements ActionListener { public final class CaseOpenAction extends CallableSystemAction implements ActionListener {
private static final Logger LOGGER = Logger.getLogger(CaseOpenAction.class.getName());
private static final String PROP_BASECASE = "LBL_BaseCase_PATH"; //NON-NLS
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final String PROP_BASECASE = "LBL_BaseCase_PATH"; //NON-NLS
private static final Logger logger = Logger.getLogger(CaseOpenAction.class.getName());
private final JFileChooser fileChooser = new JFileChooser(); private final JFileChooser fileChooser = new JFileChooser();
private final FileFilter caseMetadataFileFilter; private final FileFilter caseMetadataFileFilter;
/** /**
* Constructs an action that opens an existing case. * Constructs the action associated with the Case/Open Case menu item via
* the layer.xml file, a toolbar button, and the Create New Case button of
* the start up window that allows a user to open a case. It opens an
* existing case.
*
*/ */
public CaseOpenAction() { public CaseOpenAction() {
caseMetadataFileFilter = new FileNameExtensionFilter(NbBundle.getMessage(CaseOpenAction.class, "CaseOpenAction.autFilter.title", Version.getName(), CaseMetadata.getFileExtension()), CaseMetadata.getFileExtension().substring(1)); caseMetadataFileFilter = new FileNameExtensionFilter(NbBundle.getMessage(CaseOpenAction.class, "CaseOpenAction.autFilter.title", Version.getName(), CaseMetadata.getFileExtension()), CaseMetadata.getFileExtension().substring(1));
@ -127,7 +131,7 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
try { try {
get(); get();
} catch (InterruptedException | ExecutionException ex) { } catch (InterruptedException | ExecutionException ex) {
LOGGER.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", path), ex); //NON-NLS logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", path), ex); //NON-NLS
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
JOptionPane.showMessageDialog( JOptionPane.showMessageDialog(
WindowManager.getDefault().getMainWindow(), WindowManager.getDefault().getMainWindow(),
@ -144,6 +148,7 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
@Override @Override
public void performAction() { public void performAction() {
actionPerformed(null);
} }
@Override @Override

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2014 Basis Technology Corp. * Copyright 2011-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");
@ -23,98 +23,70 @@ import java.awt.Toolkit;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import javax.swing.Action; import javax.swing.Action;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JFrame; import javax.swing.SwingUtilities;
import org.openide.util.HelpCtx; import org.openide.util.HelpCtx;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.CallableSystemAction;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* The action to pop up the Case Properties Form window. By using this form, * The action associated with the Case/Case Properties menu item. It invokes the
* user can update the case properties (for example: updates the case name and * Case Properties dialog.
* removes the image from the current case)
*
* @author jantonius
*/ */
final class CasePropertiesAction extends CallableSystemAction { final class CasePropertiesAction extends CallableSystemAction {
private static JDialog popUpWindow; private static final long serialVersionUID = 1L;
private static JDialog casePropertiesDialog;
/**
* The CasePropertiesAction constructor
*/
CasePropertiesAction() { CasePropertiesAction() {
putValue(Action.NAME, NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction")); // put the action Name putValue(Action.NAME, NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction"));
this.setEnabled(false); this.setEnabled(false);
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), new PropertyChangeListener() { Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), new PropertyChangeListener() {
@Override @Override
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
popUpWindow = null; setEnabled(null != evt.getNewValue());
} }
}); });
} }
/**
* Pop-up the Case Properties Form window where user can change the case
* properties (example: update case name and remove the image from the case)
*/
@Override @Override
public void performAction() { public void performAction() {
if (popUpWindow == null) { SwingUtilities.invokeLater(() -> {
// create the popUp window for it if (null == casePropertiesDialog) {
String title = NbBundle.getMessage(this.getClass(), "CasePropertiesAction.window.title"); String title = NbBundle.getMessage(this.getClass(), "CasePropertiesAction.window.title");
popUpWindow = new JDialog((JFrame) WindowManager.getDefault().getMainWindow(), title, false); casePropertiesDialog = new JDialog(WindowManager.getDefault().getMainWindow(), title, false);
try {
CaseInformationPanel caseInformationPanel = new CaseInformationPanel(); CaseInformationPanel caseInformationPanel = new CaseInformationPanel();
caseInformationPanel.addCloseButtonAction((ActionEvent e) -> { caseInformationPanel.addCloseButtonAction((ActionEvent e) -> {
popUpWindow.dispose(); casePropertiesDialog.setVisible(false);
}); });
casePropertiesDialog.add(caseInformationPanel);
casePropertiesDialog.setResizable(true);
casePropertiesDialog.pack();
popUpWindow.add(caseInformationPanel);
popUpWindow.setResizable(true);
popUpWindow.pack();
// set the location of the popUp Window on the center of the screen
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
double w = popUpWindow.getSize().getWidth(); double w = casePropertiesDialog.getSize().getWidth();
double h = popUpWindow.getSize().getHeight(); double h = casePropertiesDialog.getSize().getHeight();
popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2)); casePropertiesDialog.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
casePropertiesDialog.setVisible(true);
popUpWindow.setVisible(true);
} catch (Exception ex) {
Logger.getLogger(CasePropertiesAction.class.getName()).log(Level.WARNING, "Error displaying Case Properties window.", ex); //NON-NLS
} }
} casePropertiesDialog.setVisible(true);
popUpWindow.setVisible(true); casePropertiesDialog.toFront();
popUpWindow.toFront(); });
} }
/**
* Gets the name of this action. This may be presented as an item in a menu.
*
* @return actionName
*/
@Override @Override
public String getName() { public String getName() {
return NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction"); return NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction");
} }
/**
* Gets the HelpCtx associated with implementing object
*
* @return HelpCtx or HelpCtx.DEFAULT_HELP
*/
@Override @Override
public HelpCtx getHelpCtx() { public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP; return HelpCtx.DEFAULT_HELP;
} }
static void closeCasePropertiesWindow() { static void closeCasePropertiesWindow() {
popUpWindow.dispose(); casePropertiesDialog.setVisible(false);
} }
} }

View File

@ -200,9 +200,6 @@
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="caseNameTextFieldActionPerformed"/>
</Events>
</Component> </Component>
<Component class="javax.swing.JButton" name="updateCaseNameButton"> <Component class="javax.swing.JButton" name="updateCaseNameButton">
<Properties> <Properties>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2016 Basis Technology Corp. * Copyright 2011-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");
@ -17,14 +17,9 @@
* limitations under the License. * limitations under the License.
*/ */
/*
* CasePropertiesForm.java
*
* Created on Mar 14, 2011, 1:48:20 PM
*/
package org.sleuthkit.autopsy.casemodule; package org.sleuthkit.autopsy.casemodule;
import java.io.File; import java.nio.file.Paths;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
@ -37,44 +32,15 @@ import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* The form where user can change / update the properties of the current case * A panel that allows the user to view various properties of the current case
* metadata. * and change the display name of the case.
*/ */
class CasePropertiesForm extends javax.swing.JPanel { class CasePropertiesForm extends javax.swing.JPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Case current = null; private Case current = null;
private static JPanel caller; // panel for error private static JPanel caller; // panel for error
// Shrink a path to fit in targetLength (if necessary), by replaceing part
// of the path with "...". Ex: "C:\Users\bob\...\folder\other\Image.img"
private String shrinkPath(String path, int targetLength) {
if (path.length() > targetLength) {
String fill = "...";
int partsLength = targetLength - fill.length();
String front = path.substring(0, partsLength / 4);
int frontSep = front.lastIndexOf(File.separatorChar);
if (frontSep != -1) {
front = front.substring(0, frontSep + 1);
}
String back = path.substring(partsLength * 3 / 4);
int backSep = back.indexOf(File.separatorChar);
if (backSep != -1) {
back = back.substring(backSep);
}
return back + fill + front;
} else {
return path;
}
}
/**
* Creates new form CasePropertiesForm
*/
CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) throws CaseMetadata.CaseMetadataException { CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) throws CaseMetadata.CaseMetadataException {
initComponents(); initComponents();
caseNameTextField.setText(currentCase.getDisplayName()); caseNameTextField.setText(currentCase.getDisplayName());
@ -93,10 +59,10 @@ class CasePropertiesForm extends javax.swing.JPanel {
crDateField.setText(crDate); crDateField.setText(crDate);
caseDirField.setText(caseDir); caseDirField.setText(caseDir);
current = currentCase; current = currentCase;
CaseMetadata caseMetadata = currentCase.getCaseMetadata(); CaseMetadata caseMetadata = currentCase.getCaseMetadata();
if (caseMetadata.getCaseType() == Case.CaseType.SINGLE_USER_CASE) { if (caseMetadata.getCaseType() == Case.CaseType.SINGLE_USER_CASE) {
dbNameField.setText(caseMetadata.getCaseDatabasePath()); dbNameField.setText(Paths.get(caseMetadata.getCaseDirectory(), caseMetadata.getCaseDatabaseName()).toString());
} else { } else {
dbNameField.setText(caseMetadata.getCaseDatabaseName()); dbNameField.setText(caseMetadata.getCaseDatabaseName());
} }
@ -162,11 +128,6 @@ class CasePropertiesForm extends javax.swing.JPanel {
caseNameTextField.setFont(caseNameTextField.getFont().deriveFont(caseNameTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); caseNameTextField.setFont(caseNameTextField.getFont().deriveFont(caseNameTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseNameTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNameTextField.text")); // NOI18N caseNameTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNameTextField.text")); // NOI18N
caseNameTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
caseNameTextFieldActionPerformed(evt);
}
});
updateCaseNameButton.setFont(updateCaseNameButton.getFont().deriveFont(updateCaseNameButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); updateCaseNameButton.setFont(updateCaseNameButton.getFont().deriveFont(updateCaseNameButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
updateCaseNameButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.updateCaseNameButton.text")); // NOI18N updateCaseNameButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.updateCaseNameButton.text")); // NOI18N
@ -318,34 +279,36 @@ class CasePropertiesForm extends javax.swing.JPanel {
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
} else // check if case Name contain one of this following symbol: } else // check if case Name contain one of this following symbol:
// \ / : * ? " < > | // \ / : * ? " < > |
if (newCaseName.contains("\\") || newCaseName.contains("/") || newCaseName.contains(":") {
|| newCaseName.contains("*") || newCaseName.contains("?") || newCaseName.contains("\"") if (newCaseName.contains("\\") || newCaseName.contains("/") || newCaseName.contains(":")
|| newCaseName.contains("<") || newCaseName.contains(">") || newCaseName.contains("|")) { || newCaseName.contains("*") || newCaseName.contains("?") || newCaseName.contains("\"")
String errorMsg = NbBundle || newCaseName.contains("<") || newCaseName.contains(">") || newCaseName.contains("|")) {
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg"); String errorMsg = NbBundle
JOptionPane.showMessageDialog(caller, errorMsg, .getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg");
NbBundle.getMessage(this.getClass(), JOptionPane.showMessageDialog(caller, errorMsg,
"CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title"), NbBundle.getMessage(this.getClass(),
JOptionPane.ERROR_MESSAGE); "CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title"),
} else { JOptionPane.ERROR_MESSAGE);
// ask for the confirmation first } else {
String confMsg = NbBundle // ask for the confirmation first
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.confMsg.msg", oldCaseName, String confMsg = NbBundle
newCaseName); .getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.confMsg.msg", oldCaseName,
NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg, newCaseName);
NbBundle.getMessage(this.getClass(), NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg,
"CasePropertiesForm.updateCaseName.confMsg.title"), NbBundle.getMessage(this.getClass(),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE); "CasePropertiesForm.updateCaseName.confMsg.title"),
d.setValue(NotifyDescriptor.NO_OPTION); NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(d);
if (res != null && res == DialogDescriptor.YES_OPTION) { Object res = DialogDisplayer.getDefault().notify(d);
// if user select "Yes" if (res != null && res == DialogDescriptor.YES_OPTION) {
String oldPath = current.getCaseMetadata().getFilePath().toString(); // if user select "Yes"
try { String oldPath = current.getCaseMetadata().getFilePath().toString();
current.updateCaseName(oldCaseName, oldPath, newCaseName, oldPath); try {
} catch (Exception ex) { current.updateCaseName(oldCaseName, oldPath, newCaseName, oldPath);
Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: problem updating case name.", ex); //NON-NLS } catch (CaseActionException ex) {
Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: problem updating case name.", ex); //NON-NLS
}
} }
} }
} }
@ -353,13 +316,9 @@ class CasePropertiesForm extends javax.swing.JPanel {
}//GEN-LAST:event_updateCaseNameButtonActionPerformed }//GEN-LAST:event_updateCaseNameButtonActionPerformed
private void deleteCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteCaseButtonActionPerformed private void deleteCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteCaseButtonActionPerformed
CallableSystemAction.get(DeleteCurrentCaseAction.class).actionPerformed(evt); CallableSystemAction.get(CaseDeleteAction.class).actionPerformed(evt);
}//GEN-LAST:event_deleteCaseButtonActionPerformed }//GEN-LAST:event_deleteCaseButtonActionPerformed
private void caseNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseNameTextFieldActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_caseNameTextFieldActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel caseDirField; private javax.swing.JLabel caseDirField;