diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index a7615403ec..1b91d37a82 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -749,6 +749,7 @@ public class Case { } progressIndicator.start(Bundle.Case_progressMessage_preparingToCloseCase()); +// LOGGER.log(Level.INFO, "Opening case with metadata file path {0}", caseMetadataFilePath); //NON-NLS RJCTOD try { /* * Closing a case is always done in the same non-UI thread that @@ -772,7 +773,6 @@ public class Case { releaseSharedCaseDirLock(caseName); } } - currentCase = null; return null; }); if (RuntimeProperties.runningWithGUI()) { @@ -780,11 +780,16 @@ public class Case { -> ((ModalDialogProgressIndicator) progressIndicator).setVisible(true)); } future.get(); +// LOGGER.log(Level.INFO, "Closed case {0} in directory = {1}", new Object[]{metadata.getCaseName(), metadata.getCaseDirectory()}); //NON-NLS RJCTODO + if (RuntimeProperties.runningWithGUI()) { + updateGUIForCaseClosed(); + } + eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), null, currentCase)); } catch (InterruptedException | ExecutionException ex) { if (ex instanceof ExecutionException) { - throw new CaseActionException(Bundle.Case_openException_couldNotOpenCase(ex.getCause().getMessage()), ex); + throw new CaseActionException(Bundle.Case_openException_couldNotOpenCase(ex.getCause().getMessage()), ex); // RJCTODO } else { - throw new CaseActionException(Bundle.Case_openException_couldNotOpenCase("Interrupted during locks acquisition"), ex); + throw new CaseActionException(Bundle.Case_openException_couldNotOpenCase("Interrupted during locks acquisition"), ex); // RJCTODO } } finally { currentCase = null; diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseActionHelper.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseActionHelper.java index 46eb180ba4..a488a05fb1 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseActionHelper.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseActionHelper.java @@ -42,7 +42,7 @@ class CaseActionHelper { * @param * @return True if the current case, if any, is closed, false otherwise. */ - // RJCTODO: Be sure to test this! + // RJCTODO: Be sure to test this! Discard this class static boolean closeCaseAndContinueAction() { if (IngestManager.getInstance().isIngestRunning()) { NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation( @@ -60,7 +60,6 @@ class CaseActionHelper { } } WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - new T try { Case.closeCurrentCase(); } catch (CaseActionException ex) { diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java index 1da9ab0061..3090d3d18b 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java @@ -19,10 +19,16 @@ package org.sleuthkit.autopsy.casemodule; import java.awt.Component; +import java.awt.Cursor; import java.awt.event.ActionEvent; +import java.util.concurrent.ExecutionException; import javax.swing.Action; import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.SwingWorker; +import org.openide.DialogDescriptor; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionReferences; @@ -31,13 +37,12 @@ import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.Presenter; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.ingest.IngestManager; /** * An action to close the current case and pop up the start up window that - * allows a user to open anothjer case. This action should only be enabled when - * there is a current case. - * - * IMPORTANT: Must be called in the Swing Event Dispatch Thread (EDT). + * allows a user to open another case. */ @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.casemodule.CaseCloseAction") @ActionRegistration(displayName = "#CTL_CaseCloseAct", lazy = false) @@ -66,9 +71,46 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese */ @Override public void actionPerformed(ActionEvent e) { - if (CaseActionHelper.closeCaseAndContinueAction()) { - StartupWindowProvider.getInstance().open(); + /* + * If ingest is running, give the user the option to abort changing + * cases. + */ + if (IngestManager.getInstance().isIngestRunning()) { + NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation( + NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"), // RJCTODO + NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"), // RJCTODO + NotifyDescriptor.YES_NO_OPTION, + NotifyDescriptor.WARNING_MESSAGE); + descriptor.setValue(NotifyDescriptor.NO_OPTION); + Object response = DialogDisplayer.getDefault().notify(descriptor); + if (DialogDescriptor.NO_OPTION == response) { + return; + } } + + /* + * Close the case. + */ + WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + Case.closeCurrentCase(); + return null; + } + + @Override + protected void done() { + try { + get(); + } catch (InterruptedException | ExecutionException ex) { + // RJCTODO: Pop up error and log + } + WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + StartupWindowProvider.getInstance().open(); + } + }.execute(); } /** diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java index 62604a2d39..26404fbfd7 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java @@ -22,11 +22,16 @@ import java.awt.Cursor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; +import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JFileChooser; import javax.swing.JOptionPane; +import javax.swing.SwingWorker; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; +import org.openide.DialogDescriptor; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; @@ -35,11 +40,10 @@ import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.Version; +import org.sleuthkit.autopsy.ingest.IngestManager; /** * An action that opens an existing case. - * - * IMPORTANT: Must be called in the Swing Event Dispatch Thread (EDT). */ @ServiceProvider(service = CaseOpenAction.class) public final class CaseOpenAction extends CallableSystemAction implements ActionListener { @@ -72,41 +76,68 @@ public final class CaseOpenAction extends CallableSystemAction implements Action */ @Override public void actionPerformed(ActionEvent e) { - if (CaseActionHelper.closeCaseAndContinueAction()) { - - /** - * Pop up a file chooser to allow the user to select a case metadata - * file (.aut file). - */ - int retval = fileChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()); - if (retval == JFileChooser.APPROVE_OPTION) { - /* - * Close the startup window, if it is open. - */ - StartupWindowProvider.getInstance().close(); - - /* - * Try to open the case associated with the case metadata file - * the user selected. - */ - final String path = fileChooser.getSelectedFile().getPath(); - String dirPath = fileChooser.getSelectedFile().getParent(); - ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE, dirPath.substring(0, dirPath.lastIndexOf(File.separator))); - WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - try { - Case.openCurrentCase(path); - } catch (CaseActionException ex) { - 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)); - JOptionPane.showMessageDialog( - WindowManager.getDefault().getMainWindow(), - ex.getMessage(), // Should be user-friendly - NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS - JOptionPane.ERROR_MESSAGE); - StartupWindowProvider.getInstance().open(); - } + /* + * If ingest is running, give the user the option to abort changing + * cases. + */ + if (IngestManager.getInstance().isIngestRunning()) { + NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation( + NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"), // RJCTODO + NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"), // RJCTODO + NotifyDescriptor.YES_NO_OPTION, + NotifyDescriptor.WARNING_MESSAGE); + descriptor.setValue(NotifyDescriptor.NO_OPTION); + Object response = DialogDisplayer.getDefault().notify(descriptor); + if (DialogDescriptor.NO_OPTION == response) { + return; } } + + /** + * Pop up a file chooser to allow the user to select a case metadata + * file (.aut file). + */ + int retval = fileChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()); + if (retval == JFileChooser.APPROVE_OPTION) { + /* + * Close the startup window, if it is open. + */ + StartupWindowProvider.getInstance().close(); + + /* + * Try to open the case associated with the case metadata file the + * user selected. + */ + final String path = fileChooser.getSelectedFile().getPath(); + String dirPath = fileChooser.getSelectedFile().getParent(); + ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE, dirPath.substring(0, dirPath.lastIndexOf(File.separator))); + WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + Case.openCurrentCase(path); + return null; + } + + @Override + protected void done() { + try { + get(); + } catch (InterruptedException | ExecutionException ex) { + 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)); + JOptionPane.showMessageDialog( + WindowManager.getDefault().getMainWindow(), + ex.getMessage(), // Should be user-friendly + NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS + JOptionPane.ERROR_MESSAGE); + StartupWindowProvider.getInstance().open(); + } + WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + }.execute(); + } } @Override