Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 3321-AutoIngestRadioButtons

This commit is contained in:
William Schaefer 2017-12-12 14:19:43 -05:00
commit afdedfe914
20 changed files with 775 additions and 637 deletions

View File

@ -4,7 +4,6 @@ CTL_CaseCloseAct=Close Case
CTL_CaseNewAction=New Case
CTL_CasePropertiesAction=Case Properties
CTL_CaseDeleteAction=Delete Case
CTL_CaseOpenAction=Open Case
Menu/Case/OpenRecentCase=Open Recent Case
CTL_CaseDeleteAction=Delete Case
OpenIDE-Module-Name=Case
@ -210,14 +209,8 @@ CasePropertiesPanel.lbDbName.text=Database Name:
CasePropertiesPanel.lbDbType.text=Case Type:
CasePropertiesPanel.caseNumberLabel.text=Case Number:
LocalDiskPanel.changeDatabasePathCheckbox.text=Update case to use VHD file upon completion
CueBannerPanel.openMultiUserCaseButton.text=
CueBannerPanel.openExistingCaseButton.text=
CueBannerPanel.openRecentCaseButton.text=
CueBannerPanel.createNewCaseButton.text=
CueBannerPanel.createNewCaseLabel.text=Create New Case
CueBannerPanel.openRecentCaseLabel.text=Open Recent Case
CueBannerPanel.openExistingCaseLabel.text=Open Existing Case
CueBannerPanel.openMultiUserCaseLabel.text=Open Multi-User Case
ReviewModeCasePanel.cannotOpenCase=Cannot Open Case
ReviewModeCasePanel.casePathNotFound=Case path not found
ReviewModeCasePanel.caseIsLocked=Single-user case is locked.
@ -239,3 +232,8 @@ MultiUserCasesPanel.bnRefresh.text=&Refresh
MultiUserCasesPanel.bnOpen.text=&Open
MultiUserCasesPanel.rbGroupLabel.text=Show cases accessed in the last 10:
MultiUserCasesPanel.rbMonths.text=Months
CueBannerPanel.newCaseLabel.text=New Case
CueBannerPanel.openCaseButton.text=
CueBannerPanel.openCaseLabel.text=Open Case
MultiUserCasesPanel.bnOpenSingleUserCase.text=Open Single-User Case...
CueBannerPanel.newCaseButton.text=

View File

@ -190,10 +190,10 @@ CasePropertiesPanel.caseNumberLabel.text=\u30b1\u30fc\u30b9\u756a\u53f7\uff1a
CasePropertiesPanel.examinerLabel.text=\u8abf\u67fb\u62c5\u5f53\u8005\uff1a
OptionalCasePropertiesPanel.examinerLabel.text=\u8abf\u67fb\u62c5\u5f53\u8005\uff1a
OptionalCasePropertiesPanel.caseDisplayNameLabel.text=\u30b1\u30fc\u30b9\u756a\u53f7\uff1a
CueBannerPanel.createNewCaseLabel.text=\u65b0\u898f\u30b1\u30fc\u30b9\u3092\u4f5c\u6210
CueBannerPanel.openRecentCaseLabel.text=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
CueBannerPanel.openExistingCaseLabel.text=\u65e2\u5b58\u30b1\u30fc\u30b9\u3092\u958b\u304f
CueBannerPanel.openAutoIngestCaseLabel.text=\u65e2\u5b58\u30b1\u30fc\u30b9\u3092\u958b\u304f
OpenMultiUserCasePanel.openButton.text=\u958b\u304f
OpenMultiUserCasePanel.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
OpenMultiUserCasePanel.jLabel1.text=\u6700\u8fd1\u958b\u3044\u305f\u30d5\u30a1\u30a4\u30eb
CueBannerPanel.newCaseLabel.text=\u65b0\u898f\u30b1\u30fc\u30b9\u3092\u4f5c\u6210
CueBannerPanel.openCaseLabel.text=\u65e2\u5b58\u30b1\u30fc\u30b9\u3092\u958b\u304f

View File

@ -1610,11 +1610,8 @@ public class Case {
* will be created if it doesn't already exist; if it
* exists, it is ASSUMED it was created by calling
* createCaseDirectory.
* @param caseDisplayName The display name of case, which may be changed
* later by the user.
* @param caseNumber The case number, can be the empty string.
* @param examiner The examiner to associate with the case, can be
* the empty string.
* @param caseDetails Contains details of the case, such as examiner, display name, etc
*
*/
private Case(CaseType caseType, String caseDir, CaseDetails caseDetails) {
metadata = new CaseMetadata(caseType, caseDir, displayNameToUniqueName(caseDetails.getCaseDisplayName()), caseDetails);

View File

@ -24,17 +24,22 @@ import java.awt.event.ActionListener;
import java.io.File;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.JDialog;
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.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.Version;
@ -46,21 +51,26 @@ import org.sleuthkit.autopsy.coreutils.Version;
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ActionID(category = "Case", id = "org.sleuthkit.autopsy.casemodule.CaseOpenAction")
@ActionReference(path = "Menu/Case", position = 102)
@ActionRegistration(displayName = "#CTL_CaseOpenAction", lazy = false)
@NbBundle.Messages({"CTL_CaseOpenAction=Open Case"})
@ServiceProvider(service = CaseOpenAction.class)
public final class CaseOpenAction extends CallableSystemAction implements ActionListener {
private static final long serialVersionUID = 1L;
private static final String DISPLAY_NAME = Bundle.CTL_CaseOpenAction();
private static final String PROP_BASECASE = "LBL_BaseCase_PATH"; //NON-NLS
private static final Logger logger = Logger.getLogger(CaseOpenAction.class.getName());
private static final Logger LOGGER = Logger.getLogger(CaseOpenAction.class.getName());
private static JDialog multiUserCaseWindow;
private final JFileChooser fileChooser = new JFileChooser();
private final FileFilter caseMetadataFileFilter;
/**
* 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.
*
* the layer.xml file, a toolbar button, and the Open Case button of the
* start up window that allows a user to open a case. It opens an existing
* case.
*/
public CaseOpenAction() {
caseMetadataFileFilter = new FileNameExtensionFilter(NbBundle.getMessage(CaseOpenAction.class, "CaseOpenAction.autFilter.title", Version.getName(), CaseMetadata.getFileExtension()), CaseMetadata.getFileExtension().substring(1));
@ -74,13 +84,11 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
}
/**
* Pops up a file chooser to allow the user to select a case metadata file
* (.aut file) and attempts to open the case described by the file.
*
* @param e The action event.
* Open the case selection window to allow the user to select a case
* metadata file (.aut file). Upon confirming the selection, it will attempt
* to open the case described by the file.
*/
@Override
public void actionPerformed(ActionEvent e) {
void openCaseSelectionWindow() {
String optionsDlgTitle = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title");
String optionsDlgMessage = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning");
if (IngestRunningCheck.checkAndConfirmProceed(optionsDlgTitle, optionsDlgMessage)) {
@ -95,6 +103,13 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
*/
StartupWindowProvider.getInstance().close();
/*
* Close the Open Multi-User Case window, if it is open.
*/
if (multiUserCaseWindow != null) {
multiUserCaseWindow.setVisible(false);
}
/*
* Try to open the case associated with the case metadata file
* the user selected.
@ -117,7 +132,7 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
get();
} catch (InterruptedException | ExecutionException ex) {
if (ex instanceof InterruptedException || (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException))) {
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
JOptionPane.showMessageDialog(
WindowManager.getDefault().getMainWindow(),
ex.getCause().getMessage(), //get the message of the wrapped exception
@ -134,6 +149,29 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
}
}
/**
* Pops up either the case selection window or the Open Multi-User Case
* window, depending on the multi-user case settings.
*
* @param e The action event.
*/
@Override
public void actionPerformed(ActionEvent e) {
if (UserPreferences.getIsMultiUserModeEnabled()) {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
if (multiUserCaseWindow == null) {
multiUserCaseWindow = MultiUserCasesDialog.getInstance();
}
multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
multiUserCaseWindow.setVisible(true);
WindowManager.getDefault().getMainWindow().setCursor(null);
} else {
openCaseSelectionWindow();
}
}
@Override
public void performAction() {
actionPerformed(null);
@ -141,7 +179,7 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
@Override
public String getName() {
return NbBundle.getMessage(CaseOpenAction.class, "CTL_CaseOpenAction");
return DISPLAY_NAME;
}
@Override

View File

@ -1,97 +0,0 @@
/*
* 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.casemodule;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JDialog;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.core.UserPreferences;
/**
* The action associated with the Open Multi-User Case menu item via the
* layer.xml file.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ActionID(category = "Case", id = "org.sleuthkit.autopsy.casemodule.CaseOpenMultiUserAction")
@ActionReference(path = "Menu/Case", position = 102)
@ActionRegistration(displayName = "#CTL_CaseOpenMultiUserAction", lazy = false)
@NbBundle.Messages({"CTL_CaseOpenMultiUserAction=Open Multi-User Case"})
public final class CaseOpenMultiUserAction extends CallableSystemAction implements ActionListener {
private static final long serialVersionUID = 1L;
private static JDialog multiUserCaseWindow;
private static final String DISPLAY_NAME = Bundle.CTL_CaseOpenMultiUserAction();
public CaseOpenMultiUserAction() {
}
@Override
public boolean isEnabled() {
return UserPreferences.getIsMultiUserModeEnabled();
}
/**
* Pops up a case selection panel to allow the user to select a multi-user
* case to open.
*
* @param event The action event.
*/
@Override
public void actionPerformed(ActionEvent event) {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
if (multiUserCaseWindow == null) {
multiUserCaseWindow = MultiUserCasesDialog.getInstance();
}
multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
multiUserCaseWindow.setVisible(true);
WindowManager.getDefault().getMainWindow().setCursor(null);
}
@Override
public void performAction() {
actionPerformed(null);
}
@Override
public String getName() {
return DISPLAY_NAME;
}
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
@Override
public boolean asynchronous() {
return false; // run on edt
}
}

View File

@ -18,41 +18,45 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="autopsyLogo" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSeparator1" min="-2" pref="5" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="2" attributes="0">
<Component id="createNewCaseButton" alignment="2" min="-2" max="-2" attributes="1"/>
<Component id="newCaseButton" alignment="2" min="-2" max="-2" attributes="1"/>
<Component id="openRecentCaseButton" alignment="2" min="-2" pref="70" max="-2" attributes="1"/>
<Component id="openExistingCaseButton" alignment="2" min="-2" max="-2" attributes="1"/>
<Component id="openMultiUserCaseButton" alignment="2" min="-2" max="-2" attributes="1"/>
<Component id="openCaseButton" alignment="2" min="-2" max="-2" attributes="1"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="createNewCaseLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="newCaseLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="openRecentCaseLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="openExistingCaseLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="openMultiUserCaseLabel" min="-2" max="-2" attributes="0"/>
<Component id="openCaseLabel" alignment="0" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
</Group>
<Component id="closeButton" alignment="1" min="-2" pref="73" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace pref="139" max="32767" attributes="0"/>
<Component id="closeButton" min="-2" pref="73" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="autopsyLogo" alignment="0" min="-2" pref="257" max="-2" attributes="0"/>
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="2" attributes="0">
<Component id="createNewCaseButton" alignment="2" min="-2" pref="56" max="-2" attributes="0"/>
<Component id="createNewCaseLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="newCaseButton" alignment="2" min="-2" pref="56" max="-2" attributes="0"/>
<Component id="newCaseLabel" alignment="2" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="2" attributes="0">
@ -61,24 +65,16 @@
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="2" attributes="0">
<Component id="openExistingCaseButton" alignment="2" min="-2" pref="58" max="-2" attributes="0"/>
<Component id="openExistingCaseLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="openCaseButton" alignment="2" min="-2" pref="58" max="-2" attributes="0"/>
<Component id="openCaseLabel" alignment="2" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="openMultiUserCaseButton" alignment="1" min="-2" pref="58" max="-2" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="openMultiUserCaseLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<Component id="jSeparator1" alignment="0" max="32767" attributes="0"/>
<Component id="autopsyLogo" alignment="0" min="-2" pref="257" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="10" max="32767" attributes="0"/>
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Component id="jSeparator1" alignment="0" min="-2" pref="260" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -97,13 +93,13 @@
<AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="this.autopsyLogo.setText(&quot;&quot;);"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="createNewCaseButton">
<Component class="javax.swing.JButton" name="newCaseButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/casemodule/btn_icon_create_new_case.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.createNewCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.newCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="null" type="code"/>
@ -115,7 +111,7 @@
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="createNewCaseButtonActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newCaseButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="openRecentCaseButton">
@ -139,15 +135,15 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openRecentCaseButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="createNewCaseLabel">
<Component class="javax.swing.JLabel" name="newCaseLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="createNewCaseLabel" property="font" relativeSize="false" size="13"/>
<Font bold="false" component="newCaseLabel" property="font" relativeSize="false" size="13"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.createNewCaseLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.newCaseLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -163,13 +159,13 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="openExistingCaseButton">
<Component class="javax.swing.JButton" name="openCaseButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/casemodule/btn_icon_open_existing.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openExistingCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="null" type="code"/>
@ -184,18 +180,18 @@
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openExistingCaseButtonActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openCaseButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="openExistingCaseLabel">
<Component class="javax.swing.JLabel" name="openCaseLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="openExistingCaseLabel" property="font" relativeSize="false" size="13"/>
<Font bold="false" component="openCaseLabel" property="font" relativeSize="false" size="13"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openExistingCaseLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openCaseLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -216,41 +212,5 @@
<Property name="orientation" type="int" value="1"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="openMultiUserCaseButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/casemodule/btn_icon_open_existing.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openMultiUserCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="null" type="code"/>
</Property>
<Property name="borderPainted" type="boolean" value="false"/>
<Property name="contentAreaFilled" type="boolean" value="false"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[1, 1, 1, 1]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[64, 64]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openMultiUserCaseButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="openMultiUserCaseLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="openMultiUserCaseLabel" property="font" relativeSize="false" size="13"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openMultiUserCaseLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -31,7 +31,6 @@ import javax.swing.KeyStroke;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.core.UserPreferences;
/*
* The panel in the default Autopsy startup window.
@ -107,10 +106,6 @@ public class CueBannerPanel extends javax.swing.JPanel {
boolean enableOpenRecentCaseButton = (RecentCases.getInstance().getTotalRecentCases() > 0);
openRecentCaseButton.setEnabled(enableOpenRecentCaseButton);
openRecentCaseLabel.setEnabled(enableOpenRecentCaseButton);
boolean enableOpenMultiUserCaseButton = UserPreferences.getIsMultiUserModeEnabled();
openMultiUserCaseButton.setEnabled(enableOpenMultiUserCaseButton);
openMultiUserCaseLabel.setEnabled(enableOpenMultiUserCaseButton);
}
/**
@ -124,29 +119,27 @@ public class CueBannerPanel extends javax.swing.JPanel {
autopsyLogo = new javax.swing.JLabel();
this.autopsyLogo.setText("");
createNewCaseButton = new javax.swing.JButton();
newCaseButton = new javax.swing.JButton();
openRecentCaseButton = new javax.swing.JButton();
createNewCaseLabel = new javax.swing.JLabel();
newCaseLabel = new javax.swing.JLabel();
openRecentCaseLabel = new javax.swing.JLabel();
openExistingCaseButton = new javax.swing.JButton();
openExistingCaseLabel = new javax.swing.JLabel();
openCaseButton = new javax.swing.JButton();
openCaseLabel = new javax.swing.JLabel();
closeButton = new javax.swing.JButton();
jSeparator1 = new javax.swing.JSeparator();
openMultiUserCaseButton = new javax.swing.JButton();
openMultiUserCaseLabel = new javax.swing.JLabel();
autopsyLogo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/welcome_logo.png"))); // NOI18N
autopsyLogo.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.autopsyLogo.text")); // NOI18N
createNewCaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/btn_icon_create_new_case.png"))); // NOI18N
createNewCaseButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.createNewCaseButton.text")); // NOI18N
createNewCaseButton.setBorder(null);
createNewCaseButton.setBorderPainted(false);
createNewCaseButton.setContentAreaFilled(false);
createNewCaseButton.setPreferredSize(new java.awt.Dimension(64, 64));
createNewCaseButton.addActionListener(new java.awt.event.ActionListener() {
newCaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/btn_icon_create_new_case.png"))); // NOI18N
newCaseButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.newCaseButton.text")); // NOI18N
newCaseButton.setBorder(null);
newCaseButton.setBorderPainted(false);
newCaseButton.setContentAreaFilled(false);
newCaseButton.setPreferredSize(new java.awt.Dimension(64, 64));
newCaseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
createNewCaseButtonActionPerformed(evt);
newCaseButtonActionPerformed(evt);
}
});
@ -162,113 +155,95 @@ public class CueBannerPanel extends javax.swing.JPanel {
}
});
createNewCaseLabel.setFont(createNewCaseLabel.getFont().deriveFont(createNewCaseLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 13));
createNewCaseLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.createNewCaseLabel.text")); // NOI18N
newCaseLabel.setFont(newCaseLabel.getFont().deriveFont(newCaseLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 13));
newCaseLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.newCaseLabel.text")); // NOI18N
openRecentCaseLabel.setFont(openRecentCaseLabel.getFont().deriveFont(openRecentCaseLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 13));
openRecentCaseLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openRecentCaseLabel.text")); // NOI18N
openExistingCaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/btn_icon_open_existing.png"))); // NOI18N
openExistingCaseButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openExistingCaseButton.text")); // NOI18N
openExistingCaseButton.setBorder(null);
openExistingCaseButton.setBorderPainted(false);
openExistingCaseButton.setContentAreaFilled(false);
openExistingCaseButton.setMargin(new java.awt.Insets(1, 1, 1, 1));
openExistingCaseButton.setPreferredSize(new java.awt.Dimension(64, 64));
openExistingCaseButton.addActionListener(new java.awt.event.ActionListener() {
openCaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/btn_icon_open_existing.png"))); // NOI18N
openCaseButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openCaseButton.text")); // NOI18N
openCaseButton.setBorder(null);
openCaseButton.setBorderPainted(false);
openCaseButton.setContentAreaFilled(false);
openCaseButton.setMargin(new java.awt.Insets(1, 1, 1, 1));
openCaseButton.setPreferredSize(new java.awt.Dimension(64, 64));
openCaseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
openExistingCaseButtonActionPerformed(evt);
openCaseButtonActionPerformed(evt);
}
});
openExistingCaseLabel.setFont(openExistingCaseLabel.getFont().deriveFont(openExistingCaseLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 13));
openExistingCaseLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openExistingCaseLabel.text")); // NOI18N
openCaseLabel.setFont(openCaseLabel.getFont().deriveFont(openCaseLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 13));
openCaseLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openCaseLabel.text")); // NOI18N
closeButton.setFont(closeButton.getFont().deriveFont(closeButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
closeButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.closeButton.text")); // NOI18N
jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
openMultiUserCaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/btn_icon_open_existing.png"))); // NOI18N
openMultiUserCaseButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openMultiUserCaseButton.text")); // NOI18N
openMultiUserCaseButton.setBorder(null);
openMultiUserCaseButton.setBorderPainted(false);
openMultiUserCaseButton.setContentAreaFilled(false);
openMultiUserCaseButton.setMargin(new java.awt.Insets(1, 1, 1, 1));
openMultiUserCaseButton.setPreferredSize(new java.awt.Dimension(64, 64));
openMultiUserCaseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
openMultiUserCaseButtonActionPerformed(evt);
}
});
openMultiUserCaseLabel.setFont(openMultiUserCaseLabel.getFont().deriveFont(openMultiUserCaseLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 13));
openMultiUserCaseLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openMultiUserCaseLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(autopsyLogo)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 5, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
.addComponent(createNewCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(newCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(openRecentCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(openExistingCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(openMultiUserCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(openCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(createNewCaseLabel)
.addComponent(newCaseLabel)
.addComponent(openRecentCaseLabel)
.addComponent(openExistingCaseLabel)
.addComponent(openMultiUserCaseLabel)))
.addComponent(closeButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
.addComponent(openCaseLabel))
.addGap(18, 18, 18))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 139, Short.MAX_VALUE)
.addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(autopsyLogo, javax.swing.GroupLayout.PREFERRED_SIZE, 257, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
.addComponent(createNewCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(createNewCaseLabel))
.addComponent(newCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(newCaseLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
.addComponent(openRecentCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(openRecentCaseLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
.addComponent(openExistingCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(openExistingCaseLabel))
.addComponent(openCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(openCaseLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(openMultiUserCaseButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(openMultiUserCaseLabel)
.addGap(20, 20, 20))))
.addComponent(jSeparator1)
.addComponent(autopsyLogo, javax.swing.GroupLayout.PREFERRED_SIZE, 257, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 10, Short.MAX_VALUE)
.addComponent(closeButton)
.addContainerGap())
.addComponent(closeButton))
.addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void createNewCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createNewCaseButtonActionPerformed
private void newCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newCaseButtonActionPerformed
Lookup.getDefault().lookup(CaseNewActionInterface.class).actionPerformed(evt);
}//GEN-LAST:event_createNewCaseButtonActionPerformed
}//GEN-LAST:event_newCaseButtonActionPerformed
private void openExistingCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openExistingCaseButtonActionPerformed
private void openCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openCaseButtonActionPerformed
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
Lookup.getDefault().lookup(CaseOpenAction.class).actionPerformed(evt);
}//GEN-LAST:event_openExistingCaseButtonActionPerformed
setCursor(null);
}//GEN-LAST:event_openCaseButtonActionPerformed
private void openRecentCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openRecentCaseButtonActionPerformed
recentCasesWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
@ -276,27 +251,14 @@ public class CueBannerPanel extends javax.swing.JPanel {
recentCasesWindow.setVisible(true);
}//GEN-LAST:event_openRecentCaseButtonActionPerformed
private void openMultiUserCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openMultiUserCaseButtonActionPerformed
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
MultiUserCasesDialog multiUserCaseWindow = MultiUserCasesDialog.getInstance();
multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
multiUserCaseWindow.setVisible(true);
setCursor(null);
}//GEN-LAST:event_openMultiUserCaseButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel autopsyLogo;
private javax.swing.JButton closeButton;
private javax.swing.JButton createNewCaseButton;
private javax.swing.JLabel createNewCaseLabel;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JButton openMultiUserCaseButton;
private javax.swing.JLabel openMultiUserCaseLabel;
private javax.swing.JButton openExistingCaseButton;
private javax.swing.JLabel openExistingCaseLabel;
private javax.swing.JButton newCaseButton;
private javax.swing.JLabel newCaseLabel;
private javax.swing.JButton openCaseButton;
private javax.swing.JLabel openCaseLabel;
private javax.swing.JButton openRecentCaseButton;
private javax.swing.JLabel openRecentCaseLabel;
// End of variables declaration//GEN-END:variables

View File

@ -7,6 +7,9 @@
</NonVisualComponents>
<Properties>
<Property name="name" type="java.lang.String" value="Completed Cases" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[960, 485]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
@ -30,8 +33,10 @@
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
<Component id="bnOpen" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnOpenSingleUserCase" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnShowLog" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace pref="13" max="32767" attributes="0"/>
<Component id="rbGroupLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="rbDays" min="-2" max="-2" attributes="0"/>
@ -41,9 +46,8 @@
<Component id="rbMonths" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="panelFilter" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
<Component id="bnRefresh" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
</Group>
<Component id="scrollPaneTable" max="32767" attributes="0"/>
</Group>
@ -60,9 +64,9 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnOpen" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnOpenSingleUserCase" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnShowLog" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="bnRefresh" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="103" alignment="1" groupAlignment="3" attributes="0">
<Component id="rbDays" alignment="3" min="-2" max="-2" attributes="0"/>
@ -72,6 +76,7 @@
</Group>
<Component id="panelFilter" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="bnRefresh" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
@ -224,5 +229,15 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnOpenSingleUserCase">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.bnOpenSingleUserCase.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOpenSingleUserCaseActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

View File

@ -29,12 +29,12 @@ import java.util.List;
import java.util.logging.Level;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.casemodule.MultiUserCaseManager.MultiUserCase;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -369,8 +369,10 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
rbWeeks = new javax.swing.JRadioButton();
rbMonths = new javax.swing.JRadioButton();
rbGroupLabel = new javax.swing.JLabel();
bnOpenSingleUserCase = new javax.swing.JButton();
setName("Completed Cases"); // NOI18N
setPreferredSize(new java.awt.Dimension(960, 485));
org.openide.awt.Mnemonics.setLocalizedText(bnOpen, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnOpen.text")); // NOI18N
bnOpen.setEnabled(false);
@ -458,6 +460,13 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
rbGroupLabel.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(rbGroupLabel, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbGroupLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnOpenSingleUserCase, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnOpenSingleUserCase.text")); // NOI18N
bnOpenSingleUserCase.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnOpenSingleUserCaseActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@ -469,8 +478,10 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
.addGap(4, 4, 4)
.addComponent(bnOpen, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnOpenSingleUserCase)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnShowLog)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 13, Short.MAX_VALUE)
.addComponent(rbGroupLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rbDays)
@ -480,9 +491,8 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
.addComponent(rbMonths)
.addGap(0, 0, 0)
.addComponent(panelFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bnRefresh)
.addGap(4, 4, 4))
.addGap(14, 14, 14)
.addComponent(bnRefresh))
.addComponent(scrollPaneTable))
.addContainerGap())
);
@ -495,15 +505,16 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnOpen)
.addComponent(bnOpenSingleUserCase)
.addComponent(bnShowLog))
.addComponent(bnRefresh)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(rbDays)
.addComponent(rbWeeks)
.addComponent(rbMonths)
.addComponent(rbGroupLabel))
.addComponent(panelFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addComponent(panelFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(bnRefresh, javax.swing.GroupLayout.Alignment.TRAILING))
.addGap(0, 0, 0))
);
}// </editor-fold>//GEN-END:initComponents
@ -586,8 +597,13 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
}
}//GEN-LAST:event_casesTableMouseClicked
private void bnOpenSingleUserCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOpenSingleUserCaseActionPerformed
Lookup.getDefault().lookup(CaseOpenAction.class).openCaseSelectionWindow();
}//GEN-LAST:event_bnOpenSingleUserCaseActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bnOpen;
private javax.swing.JButton bnOpenSingleUserCase;
private javax.swing.JButton bnRefresh;
private javax.swing.JButton bnShowLog;
private javax.swing.JTable casesTable;

View File

@ -75,6 +75,7 @@ public class EamGlobalSet {
* @param version
* @param knownStatus
* @param isReadOnly
* @param type
*/
public EamGlobalSet(
int orgID,
@ -164,7 +165,7 @@ public class EamGlobalSet {
}
/**
* @param knownStatus the known status to set
* @param fileKnownStatus the known status to set
*/
public void setFileKnownStatus(TskData.FileKnown fileKnownStatus) {
this.fileKnownStatus = fileKnownStatus;

View File

@ -645,8 +645,9 @@ public class SqliteEamDb extends AbstractSqlEamDb {
/**
* Check if the given hash is in a specific reference set
* @param hash
* @param value
* @param referenceSetID
* @param correlationTypeID
* @return true if the hash is found in the reference set
*/
@Override

View File

@ -49,12 +49,6 @@
</file>
<file name="org-sleuthkit-autopsy-casemodule-CasePropertiesAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-CaseDeleteAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance">
<attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseOpenAction"/>
<attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_CaseOpenAction"/>
<attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
<attr name="noIconInMenu" boolvalue="false"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-CaseSaveAction.instance">
<attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseSaveAction"/>
<attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_SaveCaseAction"/>
@ -152,12 +146,8 @@
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseNewAction.instance"/>
<attr name="position" intvalue="100"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-CaseOpenAction.shadow">
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance"/>
<attr name="position" intvalue="101"/>
</file>
<folder name="Open Recent Case">
<attr name="position" intvalue="103"/>
<attr name="position" intvalue="101"/>
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.sleuthkit.autopsy.casemodule.Bundle"/>
<file name="org-sleuthkit-autopsy-casemodule-RecentCasesAction.shadow">
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-RecentCases.instance"/>
@ -165,11 +155,11 @@
</folder>
<file name="org-sleuthkit-autopsy-casemodule-CaseCloseAct.shadow">
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance"/>
<attr name="position" intvalue="104"/>
<attr name="position" intvalue="103"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-CaseDeleteAction.shadow">
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseDeleteAction.instance"/>
<attr name="position" intvalue="105"/>
<attr name="position" intvalue="104"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-AddImage-separatorBefore.instance">
<attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>

View File

@ -2,9 +2,11 @@
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="buttonGroup1">
<Component class="javax.swing.ButtonGroup" name="fileSelectionButtonGroup">
</Component>
<Component class="javax.swing.ButtonGroup" name="buttonGroup3">
<Component class="javax.swing.ButtonGroup" name="displayTimesButtonGroup">
</Component>
<Component class="javax.swing.ButtonGroup" name="logoSourceButtonGroup">
</Component>
</NonVisualComponents>
<AuxValues>
@ -22,10 +24,7 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane1" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
</Group>
<Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
@ -69,7 +68,7 @@
<Component id="runtimePanel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="logoPanel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -92,13 +91,17 @@
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="agencyLogoImageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="specifyLogoRB" alignment="0" min="-2" pref="93" max="-2" attributes="0"/>
<Component id="defaultLogoRB" alignment="0" min="-2" pref="81" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="agencyLogoPathField" min="-2" pref="259" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="browseLogosButton" min="-2" max="-2" attributes="0"/>
<Component id="browseLogosButton" min="-2" pref="67" max="-2" attributes="0"/>
</Group>
<Component id="agencyLogoPathFieldValidationLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="agencyLogoPreview" min="-2" max="-2" attributes="0"/>
@ -109,42 +112,31 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="agencyLogoPreview" alignment="1" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="agencyLogoImageLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="defaultLogoRB" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="agencyLogoPathFieldValidationLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="specifyLogoRB" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="agencyLogoPathField" alignment="3" max="32767" attributes="0"/>
<Component id="browseLogosButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="agencyLogoPreview" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="agencyLogoImageLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.agencyLogoImageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="agencyLogoPathField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="ff" green="ff" red="ff" type="rgb"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.agencyLogoPathField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="browseLogosButton">
@ -179,6 +171,42 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="defaultLogoRB">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="logoSourceButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.defaultLogoRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="defaultLogoRBActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="specifyLogoRB">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="logoSourceButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.specifyLogoRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="specifyLogoRBActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="agencyLogoPathFieldValidationLabel">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="viewPanel">
@ -276,7 +304,7 @@
<Component class="javax.swing.JRadioButton" name="useBestViewerRB">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup1"/>
<ComponentRef name="fileSelectionButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.useBestViewerRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
@ -292,7 +320,7 @@
<Component class="javax.swing.JRadioButton" name="keepCurrentViewerRB">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup1"/>
<ComponentRef name="fileSelectionButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.keepCurrentViewerRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
@ -369,7 +397,7 @@
<Component class="javax.swing.JRadioButton" name="useLocalTimeRB">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup3"/>
<ComponentRef name="displayTimesButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.useLocalTimeRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
@ -382,7 +410,7 @@
<Component class="javax.swing.JRadioButton" name="useGMTTimeRB">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup3"/>
<ComponentRef name="displayTimesButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.useGMTTimeRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
@ -427,7 +455,7 @@
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="restartNecessaryWarning" pref="417" max="32767" attributes="0"/>
<Component id="invalidReasonLabel" max="32767" attributes="0"/>
<Component id="memFieldValidationLabel" max="32767" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
@ -442,7 +470,7 @@
<Component id="maxMemoryUnitsLabel" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="memField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="invalidReasonLabel" alignment="0" max="32767" attributes="0"/>
<Component id="memFieldValidationLabel" alignment="0" max="32767" attributes="0"/>
<Component id="maxMemoryLabel" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
@ -503,7 +531,7 @@
<EventHandler event="keyReleased" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="memFieldKeyReleased"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="invalidReasonLabel">
<Component class="javax.swing.JLabel" name="memFieldValidationLabel">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>

View File

@ -34,6 +34,8 @@ import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -58,34 +60,44 @@ import org.sleuthkit.autopsy.report.ReportBranding;
"AutopsyOptionsPanel.maxMemoryLabel.text=Maximum JVM Memory:",
"AutopsyOptionsPanel.maxMemoryUnitsLabel.text=GB",
"AutopsyOptionsPanel.runtimePanel.border.title=Runtime",
"AutopsyOptionsPanel.invalidReasonLabel.not64BitInstall.text=JVM memory settings only enabled for 64 bit version",
"AutopsyOptionsPanel.invalidReasonLabel.noValueEntered.text=No value entered",
"AutopsyOptionsPanel.invalidReasonLabel.invalidCharacters.text=Invalid characters, value must be a positive integer",
"AutopsyOptionsPanel.memFieldValidationLabel.not64BitInstall.text=JVM memory settings only enabled for 64 bit version",
"AutopsyOptionsPanel.memFieldValidationLabel.noValueEntered.text=No value entered",
"AutopsyOptionsPanel.memFieldValidationLabel.invalidCharacters.text=Invalid characters, value must be a positive integer",
"# {0} - minimumMemory",
"AutopsyOptionsPanel.invalidReasonLabel.underMinMemory.text=Value must be at least {0}GB",
"AutopsyOptionsPanel.memFieldValidationLabel.underMinMemory.text=Value must be at least {0}GB",
"# {0} - systemMemory",
"AutopsyOptionsPanel.invalidReasonLabel.overMaxMemory.text=Value must be less than the total system memory of {0}GB",
"AutopsyOptionsPanel.invalidReasonLabel.developerMode.text=Memory settings are not available while running in developer mode"})
"AutopsyOptionsPanel.memFieldValidationLabel.overMaxMemory.text=Value must be less than the total system memory of {0}GB",
"AutopsyOptionsPanel.memFieldValidationLabel.developerMode.text=Memory settings are not available while running in developer mode",
"AutopsyOptionsPanel.defaultLogoRB.text=Use default",
"AutopsyOptionsPanel.specifyLogoRB.text=Specify a logo",
"AutopsyOptionsPanel.browseLogosButton.text=Browse",
"AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.invalidPath.text=Path is not valid.",
"AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.pathNotSet.text=Agency logo path must be set."
})
final class AutopsyOptionsPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
private final JFileChooser fc;
private final JFileChooser fileChooser;
private final TextFieldListener textFieldListener;
private static final String ETC_FOLDER_NAME = "etc";
private static final String CONFIG_FILE_EXTENSION = ".conf";
private static final long ONE_BILLION = 1000000000L; //used to roughly convert system memory from bytes to gigabytes
private static final long MEGA_IN_GIGA = 1024; //used to convert memory settings saved as megabytes to gigabytes
private static final int MIN_MEMORY_IN_GB = 2; //the enforced minimum memory in gigabytes
private static final Logger logger = Logger.getLogger(AutopsyOptionsPanel.class.getName());
private static final Logger LOGGER = Logger.getLogger(AutopsyOptionsPanel.class.getName());
private String initialMemValue = Long.toString(Runtime.getRuntime().maxMemory() / ONE_BILLION);
/**
* Instantiate the Autopsy options panel.
*/
AutopsyOptionsPanel() {
initComponents();
fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
fc.setMultiSelectionEnabled(false);
fc.setAcceptAllFileFilterUsed(false);
fc.setFileFilter(new GeneralFilter(GeneralFilter.GRAPHIC_IMAGE_EXTS, GeneralFilter.GRAPHIC_IMG_DECR));
fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setMultiSelectionEnabled(false);
fileChooser.setAcceptAllFileFilterUsed(false);
fileChooser.setFileFilter(new GeneralFilter(GeneralFilter.GRAPHIC_IMAGE_EXTS, GeneralFilter.GRAPHIC_IMG_DECR));
if (!PlatformUtil.is64BitJVM() || Version.getBuildType() == Version.Type.DEVELOPMENT) {
//32 bit JVM has a max heap size of 1.4 gb to 4 gb depending on OS
//So disabling the setting of heap size when the JVM is not 64 bit
@ -94,6 +106,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
memField.setEnabled(false);
}
systemMemoryTotal.setText(Long.toString(getSystemMemoryInGB()));
textFieldListener = new TextFieldListener();
agencyLogoPathField.getDocument().addDocumentListener(textFieldListener);
}
/**
@ -247,7 +262,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
try {
lines = Files.readAllLines(filePath, charset);
} catch (IOException e) {
logger.log(Level.SEVERE, "Error reading config file contents. {}", configFile.getAbsolutePath());
LOGGER.log(Level.SEVERE, "Error reading config file contents. {}", configFile.getAbsolutePath());
}
}
return lines;
@ -273,6 +288,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
return new String[]{};
}
/**
* Load the saved user preferences.
*/
void load() {
boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer();
keepCurrentViewerRB.setSelected(keepPreferredViewer);
@ -285,23 +303,36 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
useLocalTimeRB.setSelected(useLocalTime);
useGMTTimeRB.setSelected(!useLocalTime);
String path = ModuleSettings.getConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP);
boolean useDefault = (path == null || path.isEmpty());
defaultLogoRB.setSelected(useDefault);
specifyLogoRB.setSelected(!useDefault);
agencyLogoPathField.setEnabled(!useDefault);
browseLogosButton.setEnabled(!useDefault);
try {
updateAgencyLogo(path);
} catch (IOException ex) {
logger.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex);
LOGGER.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex);
}
if (memField.isEnabled()) {
try {
initialMemValue = Long.toString(getCurrentJvmMaxMemoryInGB());
} catch (IOException ex) {
logger.log(Level.SEVERE, "Can't read current Jvm max memory setting from file", ex);
LOGGER.log(Level.SEVERE, "Can't read current Jvm max memory setting from file", ex);
memField.setEnabled(false);
}
memField.setText(initialMemValue);
}
isMemFieldValid(); //ensure the error message is up to date
valid(); //ensure the error messages are up to date
}
/**
* Update the agency logo with the image specified by the path.
*
* @param path The path to the image.
*
* @throws IOException Thrown when there is a problem reading the file.
*/
private void updateAgencyLogo(String path) throws IOException {
agencyLogoPathField.setText(path);
ImageIcon agencyLogoIcon = new ImageIcon();
@ -321,6 +352,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
agencyLogoPreview.repaint();
}
/**
* Store the current user preferences.
*/
void store() {
UserPreferences.setKeepPreferredContentViewer(keepCurrentViewerRB.isSelected());
UserPreferences.setHideKnownFilesInDataSourcesTree(dataSourcesHideKnownCB.isSelected());
@ -333,18 +367,124 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
if (file.exists()) {
ModuleSettings.setConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP, agencyLogoPathField.getText());
}
} else {
ModuleSettings.setConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP, "");
}
if (memField.isEnabled()) { //if the field could of been changed we need to try and save it
try {
writeEtcConfFile();
} catch (IOException ex) {
logger.log(Level.WARNING, "Unable to save config file to " + PlatformUtil.getUserDirectory() + "\\" + ETC_FOLDER_NAME, ex);
LOGGER.log(Level.WARNING, "Unable to save config file to " + PlatformUtil.getUserDirectory() + "\\" + ETC_FOLDER_NAME, ex);
}
}
}
/**
* Checks to see if the memory and agency logo field inputs are valid.
*
* @return True if valid; false otherwise.
*/
boolean valid() {
return isMemFieldValid();
boolean valid = true;
if (!isAgencyLogoPathValid()) {
valid = false;
}
if (!isMemFieldValid()) {
valid = false;
}
return valid;
}
/**
* Validates the agency logo path to ensure it is valid.
*
* @return True if the default logo is being used or if the path is valid;
* otherwise false.
*/
boolean isAgencyLogoPathValid() {
boolean valid = true;
if (defaultLogoRB.isSelected()) {
agencyLogoPathFieldValidationLabel.setText("");
} else {
String agencyLogoPath = agencyLogoPathField.getText();
if (agencyLogoPath.isEmpty()) {
agencyLogoPathFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_agencyLogoPathFieldValidationLabel_pathNotSet_text());
valid = false;
} else {
File file = new File(agencyLogoPathField.getText());
if (file.exists() && file.isFile()) {
agencyLogoPathFieldValidationLabel.setText("");
} else {
agencyLogoPathFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_agencyLogoPathFieldValidationLabel_invalidPath_text());
valid = false;
}
}
}
return valid;
}
/**
* Checks that if the mem field is enabled it has a valid value.
*
* @return true if the memfield is valid false if it is not
*/
private boolean isMemFieldValid() {
String memText = memField.getText();
memFieldValidationLabel.setText("");
if (!PlatformUtil.is64BitJVM()) {
memFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_memFieldValidationLabel_not64BitInstall_text());
//the panel should be valid when it is a 32 bit jvm because the memfield will be disabled.
return true;
}
if (Version.getBuildType() == Version.Type.DEVELOPMENT) {
memFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_memFieldValidationLabel_developerMode_text());
//the panel should be valid when you are running in developer mode because the memfield will be disabled
return true;
}
if (memText.length() == 0) {
memFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_memFieldValidationLabel_noValueEntered_text());
return false;
}
if (memText.replaceAll("[^\\d]", "").length() != memText.length()) {
memFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_memFieldValidationLabel_invalidCharacters_text());
return false;
}
int parsedInt = Integer.parseInt(memText);
if (parsedInt < MIN_MEMORY_IN_GB) {
memFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_memFieldValidationLabel_underMinMemory_text(MIN_MEMORY_IN_GB));
return false;
}
if (parsedInt >= getSystemMemoryInGB()) {
memFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_memFieldValidationLabel_overMaxMemory_text(getSystemMemoryInGB()));
return false;
}
return true;
}
/**
* Listens for registered text fields that have changed and fires a
* PropertyChangeEvent accordingly.
*/
private class TextFieldListener implements DocumentListener {
@Override
public void insertUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
@Override
public void removeUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
@Override
public void changedUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
}
/**
@ -355,15 +495,18 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
buttonGroup1 = new javax.swing.ButtonGroup();
buttonGroup3 = new javax.swing.ButtonGroup();
fileSelectionButtonGroup = new javax.swing.ButtonGroup();
displayTimesButtonGroup = new javax.swing.ButtonGroup();
logoSourceButtonGroup = new javax.swing.ButtonGroup();
jScrollPane1 = new javax.swing.JScrollPane();
jPanel1 = new javax.swing.JPanel();
logoPanel = new javax.swing.JPanel();
agencyLogoImageLabel = new javax.swing.JLabel();
agencyLogoPathField = new javax.swing.JTextField();
browseLogosButton = new javax.swing.JButton();
agencyLogoPreview = new javax.swing.JLabel();
defaultLogoRB = new javax.swing.JRadioButton();
specifyLogoRB = new javax.swing.JRadioButton();
agencyLogoPathFieldValidationLabel = new javax.swing.JLabel();
viewPanel = new javax.swing.JPanel();
jLabelSelectFile = new javax.swing.JLabel();
useBestViewerRB = new javax.swing.JRadioButton();
@ -384,20 +527,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
systemMemoryTotal = new javax.swing.JLabel();
restartNecessaryWarning = new javax.swing.JLabel();
memField = new javax.swing.JTextField();
invalidReasonLabel = new javax.swing.JLabel();
memFieldValidationLabel = new javax.swing.JLabel();
maxMemoryUnitsLabel1 = new javax.swing.JLabel();
jScrollPane1.setBorder(null);
logoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.logoPanel.border.title"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(agencyLogoImageLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.agencyLogoImageLabel.text")); // NOI18N
agencyLogoPathField.setEditable(false);
agencyLogoPathField.setBackground(new java.awt.Color(255, 255, 255));
agencyLogoPathField.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.agencyLogoPathField.text")); // NOI18N
agencyLogoPathField.setFocusable(false);
agencyLogoPathField.setRequestFocusEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(browseLogosButton, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.browseLogosButton.text")); // NOI18N
browseLogosButton.addActionListener(new java.awt.event.ActionListener() {
@ -413,6 +550,25 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
agencyLogoPreview.setMinimumSize(new java.awt.Dimension(64, 64));
agencyLogoPreview.setPreferredSize(new java.awt.Dimension(64, 64));
logoSourceButtonGroup.add(defaultLogoRB);
org.openide.awt.Mnemonics.setLocalizedText(defaultLogoRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.defaultLogoRB.text")); // NOI18N
defaultLogoRB.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
defaultLogoRBActionPerformed(evt);
}
});
logoSourceButtonGroup.add(specifyLogoRB);
org.openide.awt.Mnemonics.setLocalizedText(specifyLogoRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.specifyLogoRB.text")); // NOI18N
specifyLogoRB.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
specifyLogoRBActionPerformed(evt);
}
});
agencyLogoPathFieldValidationLabel.setForeground(new java.awt.Color(255, 0, 0));
org.openide.awt.Mnemonics.setLocalizedText(agencyLogoPathFieldValidationLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.text")); // NOI18N
javax.swing.GroupLayout logoPanelLayout = new javax.swing.GroupLayout(logoPanel);
logoPanel.setLayout(logoPanelLayout);
logoPanelLayout.setHorizontalGroup(
@ -420,12 +576,15 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, logoPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(agencyLogoImageLabel)
.addComponent(specifyLogoRB, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(defaultLogoRB, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(logoPanelLayout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(agencyLogoPathField, javax.swing.GroupLayout.PREFERRED_SIZE, 259, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(browseLogosButton)))
.addComponent(browseLogosButton, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(agencyLogoPathFieldValidationLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(agencyLogoPreview, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
@ -433,23 +592,25 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
logoPanelLayout.setVerticalGroup(
logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(logoPanelLayout.createSequentialGroup()
.addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(agencyLogoPreview, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(logoPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(agencyLogoImageLabel)
.addGap(6, 6, 6)
.addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(defaultLogoRB)
.addComponent(agencyLogoPathFieldValidationLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(specifyLogoRB)
.addComponent(agencyLogoPathField)
.addComponent(browseLogosButton))))
.addGap(0, 0, 0))
.addComponent(browseLogosButton)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, logoPanelLayout.createSequentialGroup()
.addComponent(agencyLogoPreview, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))
);
viewPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.viewPanel.border.title"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabelSelectFile, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelSelectFile.text")); // NOI18N
buttonGroup1.add(useBestViewerRB);
fileSelectionButtonGroup.add(useBestViewerRB);
org.openide.awt.Mnemonics.setLocalizedText(useBestViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useBestViewerRB.text")); // NOI18N
useBestViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useBestViewerRB.toolTipText")); // NOI18N
useBestViewerRB.addActionListener(new java.awt.event.ActionListener() {
@ -458,7 +619,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
}
});
buttonGroup1.add(keepCurrentViewerRB);
fileSelectionButtonGroup.add(keepCurrentViewerRB);
org.openide.awt.Mnemonics.setLocalizedText(keepCurrentViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.keepCurrentViewerRB.text")); // NOI18N
keepCurrentViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText")); // NOI18N
keepCurrentViewerRB.addActionListener(new java.awt.event.ActionListener() {
@ -501,7 +662,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
org.openide.awt.Mnemonics.setLocalizedText(jLabelTimeDisplay, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelTimeDisplay.text")); // NOI18N
buttonGroup3.add(useLocalTimeRB);
displayTimesButtonGroup.add(useLocalTimeRB);
org.openide.awt.Mnemonics.setLocalizedText(useLocalTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useLocalTimeRB.text")); // NOI18N
useLocalTimeRB.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -509,7 +670,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
}
});
buttonGroup3.add(useGMTTimeRB);
displayTimesButtonGroup.add(useGMTTimeRB);
org.openide.awt.Mnemonics.setLocalizedText(useGMTTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useGMTTimeRB.text")); // NOI18N
useGMTTimeRB.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -598,7 +759,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
}
});
invalidReasonLabel.setForeground(new java.awt.Color(255, 0, 0));
memFieldValidationLabel.setForeground(new java.awt.Color(255, 0, 0));
org.openide.awt.Mnemonics.setLocalizedText(maxMemoryUnitsLabel1, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.maxMemoryUnitsLabel.text")); // NOI18N
@ -622,7 +783,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
.addGap(18, 18, 18)
.addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, 417, Short.MAX_VALUE)
.addComponent(invalidReasonLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(memFieldValidationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
runtimePanelLayout.setVerticalGroup(
@ -633,7 +794,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
.addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(memField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(invalidReasonLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(memFieldValidationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(maxMemoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
@ -665,7 +826,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
.addComponent(runtimePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0))
.addContainerGap())
);
jScrollPane1.setViewportView(jPanel1);
@ -674,9 +835,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1)
.addGap(0, 0, 0))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -718,9 +877,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
private void browseLogosButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseLogosButtonActionPerformed
String oldLogoPath = agencyLogoPathField.getText();
int returnState = fc.showOpenDialog(this);
int returnState = fileChooser.showOpenDialog(this);
if (returnState == JFileChooser.APPROVE_OPTION) {
String path = fc.getSelectedFile().getPath();
String path = fileChooser.getSelectedFile().getPath();
try {
updateAgencyLogo(path);
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
@ -733,7 +892,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
try {
updateAgencyLogo(oldLogoPath); //restore previous setting if new one is invalid
} catch (IOException ex1) {
logger.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex1);
LOGGER.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex1);
}
}
}
@ -748,53 +907,44 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_memFieldKeyReleased
/**
* Checks that if the mem field is enabled it has a valid value.
*
* @return true if the memfield is valid false if it is not
*/
private boolean isMemFieldValid() {
String memText = memField.getText();
invalidReasonLabel.setText("");
if (!PlatformUtil.is64BitJVM()) {
invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_not64BitInstall_text());
//the panel should be valid when it is a 32 bit jvm because the memfield will be disabled.
return true;
private void defaultLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_defaultLogoRBActionPerformed
agencyLogoPathField.setEnabled(false);
browseLogosButton.setEnabled(false);
try {
updateAgencyLogo("");
} catch (IOException ex) {
// This should never happen since we're not reading from a file.
LOGGER.log(Level.SEVERE, "Unexpected error occurred while updating the agency logo.", ex);
}
if (Version.getBuildType() == Version.Type.DEVELOPMENT) {
invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_developerMode_text());
//the panel should be valid when you are running in developer mode because the memfield will be disabled
return true;
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_defaultLogoRBActionPerformed
private void specifyLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyLogoRBActionPerformed
agencyLogoPathField.setEnabled(true);
browseLogosButton.setEnabled(true);
try {
if (agencyLogoPathField.getText().isEmpty()) {
String path = ModuleSettings.getConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP);
if (path != null && !path.isEmpty()) {
updateAgencyLogo(path);
}
if (memText.length() == 0) {
invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_noValueEntered_text());
return false;
}
if (memText.replaceAll("[^\\d]", "").length() != memText.length()) {
invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_invalidCharacters_text());
return false;
}
int parsedInt = Integer.parseInt(memText);
if (parsedInt < MIN_MEMORY_IN_GB) {
invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_underMinMemory_text(MIN_MEMORY_IN_GB));
return false;
}
if (parsedInt >= getSystemMemoryInGB()) {
invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_overMaxMemory_text(getSystemMemoryInGB()));
return false;
}
return true;
} catch (IOException ex) {
LOGGER.log(Level.WARNING, "Error loading image from previously saved agency logo path.", ex);
}
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_specifyLogoRBActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel agencyLogoImageLabel;
private javax.swing.JTextField agencyLogoPathField;
private javax.swing.JLabel agencyLogoPathFieldValidationLabel;
private javax.swing.JLabel agencyLogoPreview;
private javax.swing.JButton browseLogosButton;
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.ButtonGroup buttonGroup3;
private javax.swing.JCheckBox dataSourcesHideKnownCB;
private javax.swing.JCheckBox dataSourcesHideSlackCB;
private javax.swing.JLabel invalidReasonLabel;
private javax.swing.JRadioButton defaultLogoRB;
private javax.swing.ButtonGroup displayTimesButtonGroup;
private javax.swing.ButtonGroup fileSelectionButtonGroup;
private javax.swing.JLabel jLabelHideKnownFiles;
private javax.swing.JLabel jLabelHideSlackFiles;
private javax.swing.JLabel jLabelSelectFile;
@ -803,12 +953,15 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JRadioButton keepCurrentViewerRB;
private javax.swing.JPanel logoPanel;
private javax.swing.ButtonGroup logoSourceButtonGroup;
private javax.swing.JLabel maxMemoryLabel;
private javax.swing.JLabel maxMemoryUnitsLabel;
private javax.swing.JLabel maxMemoryUnitsLabel1;
private javax.swing.JTextField memField;
private javax.swing.JLabel memFieldValidationLabel;
private javax.swing.JLabel restartNecessaryWarning;
private javax.swing.JPanel runtimePanel;
private javax.swing.JRadioButton specifyLogoRB;
private javax.swing.JLabel systemMemoryTotal;
private javax.swing.JLabel totalMemoryLabel;
private javax.swing.JRadioButton useBestViewerRB;

View File

@ -192,8 +192,6 @@ AutopsyOptionsPanel.jLabelHideSlackFiles.text=Hide slack files in the:
AutopsyOptionsPanel.dataSourcesHideSlackCB.text=Data Sources area (the directory hierarchy)
AutopsyOptionsPanel.viewsHideSlackCB.text=Views area
AutopsyOptionsPanel.agencyLogoImageLabel.toolTipText=
AutopsyOptionsPanel.agencyLogoImageLabel.text=Image to use as the agency logo for HTML reports:
AutopsyOptionsPanel.browseLogosButton.text=Browse
AutopsyOptionsPanel.agencyLogoPathField.text=
SortChooserDialog.label=remove
SortChooser.addCriteriaButton.text=Add Sort Criteria
@ -201,3 +199,4 @@ DataResultViewerThumbnail.sortButton.text=Sort
CriterionChooser.ascendingRadio.text=\u25b2 Ascending\n
CriterionChooser.removeButton.text=Remove
CriterionChooser.descendingRadio.text=\u25bc Descending
AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.text=

View File

@ -29,6 +29,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.AbstractAction;
@ -58,32 +60,33 @@ import org.sleuthkit.datamodel.VolumeSystem;
* Extracts all the unallocated space as a single file
*/
final class ExtractUnallocAction extends AbstractAction {
private final List<UnallocStruct> LstUnallocs = new ArrayList<UnallocStruct>();
private static final List<String> lockedVols = new ArrayList<String>();
private static final List<Long> lockedImages = new ArrayList<Long>();
private long currentImage = 0L;
private static final Logger logger = Logger.getLogger(ExtractUnallocAction.class.getName());
private boolean isImage = false;
public ExtractUnallocAction(String title, Volume volu) {
private final List<OutputFileData> filesToExtract = new ArrayList<>();
private static final Set<String> volumesInProgress = new HashSet<>();
private static final Set<Long> imagesInProgress = new HashSet<>();
private long currentImage = 0L;
private final boolean isImage;
public ExtractUnallocAction(String title, Volume volume) {
super(title);
UnallocStruct us = new UnallocStruct(volu);
LstUnallocs.add(us);
isImage = false;
OutputFileData outputFileData = new OutputFileData(volume);
filesToExtract.add(outputFileData);
}
public ExtractUnallocAction(String title, Image img) {
public ExtractUnallocAction(String title, Image image) {
super(title);
isImage = true;
currentImage = img.getId();
if (hasVolumeSystem(img)) {
for (Volume v : getVolumes(img)) {
UnallocStruct us = new UnallocStruct(v);
LstUnallocs.add(us);
currentImage = image.getId();
if (hasVolumeSystem(image)) {
for (Volume v : getVolumes(image)) {
OutputFileData outputFileData = new OutputFileData(v);
filesToExtract.add(outputFileData);
}
} else {
UnallocStruct us = new UnallocStruct(img);
LstUnallocs.add(us);
OutputFileData outputFileData = new OutputFileData(image);
filesToExtract.add(outputFileData);
}
}
@ -93,21 +96,28 @@ final class ExtractUnallocAction extends AbstractAction {
*
* @param e
*/
@NbBundle.Messages({"# {0} - fileName",
"ExtractUnallocAction.volumeInProgress=Already extracting unallocated space into {0} - will skip this volume",
"ExtractUnallocAction.volumeError=Error extracting unallocated space from volume",
"ExtractUnallocAction.noFiles=No unallocated files found on volume",
"ExtractUnallocAction.imageError=Error extracting unallocated space from image"})
@Override
public void actionPerformed(ActionEvent e) {
if (LstUnallocs != null && LstUnallocs.size() > 0) {
if (lockedImages.contains(currentImage)) {
if (filesToExtract != null && filesToExtract.size() > 0) {
// This check doesn't absolutely guarantee that the image won't be in progress when we make the worker,
// but in general it will suffice.
if (isImage && isImageInProgress(currentImage)) {
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.notifyMsg.unallocAlreadyBeingExtr.msg"));
//JOptionPane.showMessageDialog(new Frame(), "Unallocated Space is already being extracted on this Image. Please select a different Image.");
return;
}
List<UnallocStruct> copyList = new ArrayList<UnallocStruct>() {
List<OutputFileData> copyList = new ArrayList<OutputFileData>() {
{
addAll(LstUnallocs);
addAll(filesToExtract);
}
};
JFileChooser fc = new JFileChooser() {
JFileChooser fileChooser = new JFileChooser() {
@Override
public void approveSelection() {
File f = getSelectedFile();
@ -120,45 +130,72 @@ final class ExtractUnallocAction extends AbstractAction {
}
};
fc.setCurrentDirectory(new File(Case.getCurrentCase().getExportDirectory()));
fc.setDialogTitle(
fileChooser.setCurrentDirectory(new File(Case.getCurrentCase().getExportDirectory()));
fileChooser.setDialogTitle(
NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.dlgTitle.selectDirToSaveTo.msg"));
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fc.setAcceptAllFileFilterUsed(false);
int returnValue = fc.showSaveDialog((Component) e.getSource());
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setAcceptAllFileFilterUsed(false);
int returnValue = fileChooser.showSaveDialog((Component) e.getSource());
if (returnValue == JFileChooser.APPROVE_OPTION) {
String destination = fc.getSelectedFile().getPath();
for (UnallocStruct u : LstUnallocs) {
u.setPath(destination);
if (u.llf != null && u.llf.size() > 0 && !lockedVols.contains(u.getFileName())) {
String destination = fileChooser.getSelectedFile().getPath();
for (OutputFileData outputFileData : filesToExtract) {
outputFileData.setPath(destination);
if (outputFileData.layoutFiles != null && outputFileData.layoutFiles.size() > 0 && (! isVolumeInProgress(outputFileData.getFileName()))) {
//Format for single Unalloc File is ImgName-Unalloc-ImgObjectID-VolumeID.dat
if (u.FileInstance.exists()) {
// Check if there is already a file with this name
if (outputFileData.fileInstance.exists()) {
int res = JOptionPane.showConfirmDialog(new Frame(), NbBundle.getMessage(this.getClass(),
"ExtractUnallocAction.confDlg.unallocFileAlreadyExist.msg",
u.getFileName()));
outputFileData.getFileName()));
if (res == JOptionPane.YES_OPTION) {
u.FileInstance.delete();
// If the user wants to overwrite, delete the exising output file
outputFileData.fileInstance.delete();
} else {
copyList.remove(u);
// Otherwise remove it from the list of output files
copyList.remove(outputFileData);
}
}
if (!isImage & !copyList.isEmpty()) {
ExtractUnallocWorker uw = new ExtractUnallocWorker(u);
uw.execute();
try{
ExtractUnallocWorker worker = new ExtractUnallocWorker(outputFileData);
worker.execute();
} catch (Exception ex){
logger.log(Level.WARNING, "Already extracting unallocated space into " + outputFileData.getFileName());
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.volumeInProgress", outputFileData.getFileName()));
}
}
} else {
if(lockedVols.contains(u.getFileName())){
logger.log(Level.WARNING, "Tried to get unallocated content but the volume is locked"); // NON_NLS
} else if (u.llf == null){
// The output file for this volume could not be created for one of the following reasons
if (outputFileData.layoutFiles == null){
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.volumeError"));
logger.log(Level.SEVERE, "Tried to get unallocated content but the list of unallocated files was null"); //NON-NLS
} else if (outputFileData.layoutFiles.isEmpty()){
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.noFiles"));
logger.log(Level.WARNING, "No unallocated files found in volume"); //NON-NLS
copyList.remove(outputFileData);
} else {
logger.log(Level.INFO, "No unallocated files found in volume"); //NON-NLS
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.volumeInProgress", outputFileData.getFileName()));
logger.log(Level.WARNING, "Tried to get unallocated content but the volume is locked"); // NON_NLS
copyList.remove(outputFileData);
}
}
}
// This needs refactoring. The idea seems to be that we'll take advantage of the loop above to
// check whether each output file exists but wait until this point to make a worker
// to extract everything (the worker in the above loop doesn't get created because isImage is true)
// It's also unclear to me why we need the two separate worker types.
if (isImage && !copyList.isEmpty()) {
ExtractUnallocWorker uw = new ExtractUnallocWorker(copyList);
uw.execute();
try{
ExtractUnallocWorker worker = new ExtractUnallocWorker(copyList);
worker.execute();
} catch (Exception ex){
logger.log(Level.WARNING, "Error creating ExtractUnallocWorker", ex);
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.imageError"));
}
}
}
}
@ -186,6 +223,37 @@ final class ExtractUnallocAction extends AbstractAction {
return Collections.emptyList();
}
synchronized static private void addVolumeInProgress(String volumeOutputFileName) throws TskCoreException {
if(volumesInProgress.contains(volumeOutputFileName)){
throw new TskCoreException("Already writing unallocated space to " + volumeOutputFileName);
}
volumesInProgress.add(volumeOutputFileName);
}
synchronized static private void removeVolumeInProgress(String volumeOutputFileName){
volumesInProgress.remove(volumeOutputFileName);
}
synchronized static private boolean isVolumeInProgress(String volumeOutputFileName){
return volumesInProgress.contains(volumeOutputFileName);
}
synchronized static private void addImageInProgress(Long id) throws TskCoreException {
if(imagesInProgress.contains(id)){
throw new TskCoreException("Image " + id + " is in use");
}
imagesInProgress.add(id);
}
synchronized static private void removeImageInProgress(Long id){
imagesInProgress.remove(id);
}
synchronized static private boolean isImageInProgress(Long id){
return imagesInProgress.contains(id);
}
/**
* Private class for dispatching the file IO in a background thread.
*/
@ -193,32 +261,40 @@ final class ExtractUnallocAction extends AbstractAction {
private ProgressHandle progress;
private boolean canceled = false;
private List<UnallocStruct> lus = new ArrayList<UnallocStruct>();
private List<OutputFileData> outputFileDataList = new ArrayList<>();
private File currentlyProcessing;
private int totalSizeinMegs;
long totalBytes = 0;
ExtractUnallocWorker(UnallocStruct us) {
ExtractUnallocWorker(OutputFileData outputFileData) throws TskCoreException {
//Getting the total megs this worker is going to be doing
if (!lockedVols.contains(us.getFileName())) {
this.lus.add(us);
totalBytes = us.getSizeInBytes();
addVolumeInProgress(outputFileData.getFileName());
outputFileDataList.add(outputFileData);
totalBytes = outputFileData.getSizeInBytes();
totalSizeinMegs = toMb(totalBytes);
lockedVols.add(us.getFileName());
}
ExtractUnallocWorker(List<OutputFileData> outputFileDataList) throws TskCoreException {
addImageInProgress(currentImage);
//Getting the total megs this worker is going to be doing
for (OutputFileData outputFileData : outputFileDataList) {
try{
// If a volume is locked, skip it but continue trying to process any other requested volumes
addVolumeInProgress(outputFileData.getFileName());
totalBytes += outputFileData.getSizeInBytes();
this.outputFileDataList.add(outputFileData);
} catch (TskCoreException ex){
logger.log(Level.WARNING, "Already extracting data into " + outputFileData.getFileName());
}
}
ExtractUnallocWorker(List<UnallocStruct> lst) {
//Getting the total megs this worker is going to be doing
for (UnallocStruct lu : lst) {
if (!lockedVols.contains(lu.getFileName())) {
totalBytes += lu.getSizeInBytes();
lockedVols.add(lu.getFileName());
this.lus.add(lu);
}
// If we don't have anything to output (because of locking), throw an exception
if(this.outputFileDataList.isEmpty()){
throw new TskCoreException("No unallocated files can be extracted");
}
totalSizeinMegs = toMb(totalBytes);
lockedImages.add(currentImage);
}
private int toMb(long bytes) {
@ -254,47 +330,47 @@ final class ExtractUnallocAction extends AbstractAction {
progress.start(totalSizeinMegs);
int kbs = 0; //Each completion of the while loop adds one to kbs. 16kb * 64 = 1mb.
int mbs = 0; //Increments every 128th tick of kbs
for (UnallocStruct u : this.lus) {
currentlyProcessing = u.getFile();
for (OutputFileData outputFileData : this.outputFileDataList) {
currentlyProcessing = outputFileData.getFile();
logger.log(Level.INFO, "Writing Unalloc file to " + currentlyProcessing.getPath()); //NON-NLS
OutputStream dos = new FileOutputStream(currentlyProcessing);
OutputStream outputStream = new FileOutputStream(currentlyProcessing);
long bytes = 0;
int i = 0;
while (i < u.getLayouts().size() && bytes != u.getSizeInBytes()) {
LayoutFile f = u.getLayouts().get(i);
while (i < outputFileData.getLayouts().size() && bytes != outputFileData.getSizeInBytes()) {
LayoutFile layoutFile = outputFileData.getLayouts().get(i);
long offsetPerFile = 0L;
int bytesRead;
while (offsetPerFile != f.getSize() && !canceled) {
while (offsetPerFile != layoutFile.getSize() && !canceled) {
if (++kbs % 128 == 0) {
mbs++;
progress.progress(NbBundle.getMessage(this.getClass(),
"ExtractUnallocAction.processing.counter.msg",
mbs, totalSizeinMegs), mbs - 1);
}
bytesRead = f.read(buf, offsetPerFile, MAX_BYTES);
bytesRead = layoutFile.read(buf, offsetPerFile, MAX_BYTES);
offsetPerFile += bytesRead;
dos.write(buf, 0, bytesRead);
outputStream.write(buf, 0, bytesRead);
}
bytes += f.getSize();
bytes += layoutFile.getSize();
i++;
}
dos.flush();
dos.close();
outputStream.flush();
outputStream.close();
if (canceled) {
u.getFile().delete();
logger.log(Level.INFO, "Canceled extraction of " + u.getFileName() + " and deleted file"); //NON-NLS
outputFileData.getFile().delete();
logger.log(Level.INFO, "Canceled extraction of " + outputFileData.getFileName() + " and deleted file"); //NON-NLS
} else {
logger.log(Level.INFO, "Finished writing unalloc file " + u.getFile().getPath()); //NON-NLS
logger.log(Level.INFO, "Finished writing unalloc file " + outputFileData.getFile().getPath()); //NON-NLS
}
}
progress.finish();
} catch (IOException ioe) {
logger.log(Level.WARNING, "Could not create Unalloc File; error writing file", ioe); //NON-NLS
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not create Unalloc File; error writing file", ex); //NON-NLS
return -1;
} catch (TskCoreException tce) {
logger.log(Level.WARNING, "Could not create Unalloc File; error getting image info", tce); //NON-NLS
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Could not create Unalloc File; error getting image info", ex); //NON-NLS
return -1;
}
return 1;
@ -303,20 +379,20 @@ final class ExtractUnallocAction extends AbstractAction {
@Override
protected void done() {
if (isImage) {
lockedImages.remove(currentImage);
removeImageInProgress(currentImage);
}
for (UnallocStruct u : lus) {
lockedVols.remove(u.getFileName());
for (OutputFileData u : outputFileDataList) {
removeVolumeInProgress(u.getFileName());
}
try {
get();
if (!canceled && !lus.isEmpty()) {
if (!canceled && !outputFileDataList.isEmpty()) {
MessageNotifyUtil.Notify.info(NbBundle.getMessage(this.getClass(),
"ExtractUnallocAction.done.notifyMsg.completedExtract.title"),
NbBundle.getMessage(this.getClass(),
"ExtractUnallocAction.done.notifyMsg.completedExtract.msg",
lus.get(0).getFile().getParent()));
outputFileDataList.get(0).getFile().getParent()));
}
} catch (InterruptedException | ExecutionException ex) {
MessageNotifyUtil.Notify.error(
@ -342,8 +418,8 @@ final class ExtractUnallocAction extends AbstractAction {
return true;
}
}
} catch (TskCoreException tce) {
logger.log(Level.SEVERE, "Unable to determine if image has a volume system, extraction may be incomplete", tce); //NON-NLS
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Unable to determine if image has a volume system, extraction may be incomplete", ex); //NON-NLS
}
return false;
}
@ -357,17 +433,17 @@ final class ExtractUnallocAction extends AbstractAction {
* matches.
*/
private List<Volume> getVolumes(Image img) {
List<Volume> lstVol = new ArrayList<Volume>();
List<Volume> volumes = new ArrayList<>();
try {
for (Content v : img.getChildren().get(0).getChildren()) {
if (v instanceof Volume) {
lstVol.add((Volume) v);
volumes.add((Volume) v);
}
}
} catch (TskCoreException tce) {
logger.log(Level.WARNING, "Could not get volume information from image. Extraction may be incomplete", tce); //NON-NLS
}
return lstVol;
return volumes;
}
/**
@ -412,8 +488,8 @@ final class ExtractUnallocAction extends AbstractAction {
}
}
}
} catch (TskCoreException tce) {
logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at visiting FileSystem " + fs.getId(), tce); //NON-NLS
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at visiting FileSystem " + fs.getId(), ex); //NON-NLS
}
return Collections.emptyList();
}
@ -429,15 +505,15 @@ final class ExtractUnallocAction extends AbstractAction {
@Override
public List<LayoutFile> visit(VirtualDirectory vd) {
try {
List<LayoutFile> lflst = new ArrayList<>();
List<LayoutFile> layoutFiles = new ArrayList<>();
for (Content layout : vd.getChildren()) {
if (layout instanceof LayoutFile) {
lflst.add((LayoutFile) layout);
layoutFiles.add((LayoutFile) layout);
}
}
return lflst;
} catch (TskCoreException tce) {
logger.log(Level.WARNING, "Could not get list of Layout Files, failed at visiting Layout Directory", tce); //NON-NLS
return layoutFiles;
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Could not get list of Layout Files, failed at visiting Layout Directory", ex); //NON-NLS
}
return Collections.emptyList();
}
@ -455,12 +531,13 @@ final class ExtractUnallocAction extends AbstractAction {
public List<LayoutFile> visit(Directory dir) {
try {
for (Content c : dir.getChildren()) {
// Only the $Unalloc dir will contain unallocated files
if ((c instanceof VirtualDirectory) && (c.getName().equals(VirtualDirectory.NAME_UNALLOC))) {
return c.accept(this);
}
}
} catch (TskCoreException tce) {
logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at visiting Directory " + dir.getId(), tce); //NON-NLS
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at visiting Directory " + dir.getId(), ex); //NON-NLS
}
return Collections.emptyList();
}
@ -495,97 +572,97 @@ final class ExtractUnallocAction extends AbstractAction {
* Private class for assisting in the running the action over an image with
* multiple volumes.
*/
private class UnallocStruct {
private class OutputFileData {
private List<LayoutFile> llf;
private long SizeInBytes;
private long VolumeId;
private long ImageId;
private String ImageName;
private String FileName;
private File FileInstance;
private List<LayoutFile> layoutFiles;
private final long sizeInBytes;
private long volumeId;
private long imageId;
private String imageName;
private final String fileName;
private File fileInstance;
/**
* Contingency constructor in event no VolumeSystem exists on an Image.
*
* @param img Image file to be analyzed
*/
UnallocStruct(Image img) {
this.llf = getUnallocFiles(img);
Collections.sort(llf, new SortObjId());
this.VolumeId = 0;
this.ImageId = img.getId();
this.ImageName = img.getName();
this.FileName = this.ImageName + "-Unalloc-" + this.ImageId + "-" + 0 + ".dat"; //NON-NLS
this.FileInstance = new File(Case.getCurrentCase().getExportDirectory() + File.separator + this.FileName);
this.SizeInBytes = calcSizeInBytes();
OutputFileData(Image img) {
this.layoutFiles = getUnallocFiles(img);
Collections.sort(layoutFiles, new SortObjId());
this.volumeId = 0;
this.imageId = img.getId();
this.imageName = img.getName();
this.fileName = this.imageName + "-Unalloc-" + this.imageId + "-" + 0 + ".dat"; //NON-NLS
this.fileInstance = new File(Case.getCurrentCase().getExportDirectory() + File.separator + this.fileName);
this.sizeInBytes = calcSizeInBytes();
}
/**
* Default constructor for extracting info from Volumes.
*
* @param volu Volume file to be analyzed
* @param volume Volume file to be analyzed
*/
UnallocStruct(Volume volu) {
OutputFileData(Volume volume) {
try {
this.ImageName = volu.getDataSource().getName();
this.ImageId = volu.getDataSource().getId();
this.VolumeId = volu.getId();
this.imageName = volume.getDataSource().getName();
this.imageId = volume.getDataSource().getId();
this.volumeId = volume.getId();
} catch (TskCoreException tce) {
logger.log(Level.WARNING, "Unable to properly create ExtractUnallocAction, extraction may be incomplete", tce); //NON-NLS
this.ImageName = "";
this.ImageId = 0;
this.imageName = "";
this.imageId = 0;
}
this.FileName = this.ImageName + "-Unalloc-" + this.ImageId + "-" + VolumeId + ".dat"; //NON-NLS
this.FileInstance = new File(Case.getCurrentCase().getExportDirectory() + File.separator + this.FileName);
this.llf = getUnallocFiles(volu);
Collections.sort(llf, new SortObjId());
this.SizeInBytes = calcSizeInBytes();
this.fileName = this.imageName + "-Unalloc-" + this.imageId + "-" + volumeId + ".dat"; //NON-NLS
this.fileInstance = new File(Case.getCurrentCase().getExportDirectory() + File.separator + this.fileName);
this.layoutFiles = getUnallocFiles(volume);
Collections.sort(layoutFiles, new SortObjId());
this.sizeInBytes = calcSizeInBytes();
}
//Getters
int size() {
return llf.size();
return layoutFiles.size();
}
private long calcSizeInBytes() {
long size = 0L;
for (LayoutFile f : llf) {
for (LayoutFile f : layoutFiles) {
size += f.getSize();
}
return size;
}
long getSizeInBytes() {
return this.SizeInBytes;
return this.sizeInBytes;
}
long getVolumeId() {
return this.VolumeId;
return this.volumeId;
}
long getImageId() {
return this.ImageId;
return this.imageId;
}
String getImageName() {
return this.ImageName;
return this.imageName;
}
List<LayoutFile> getLayouts() {
return this.llf;
return this.layoutFiles;
}
String getFileName() {
return this.FileName;
return this.fileName;
}
File getFile() {
return this.FileInstance;
return this.fileInstance;
}
void setPath(String path) {
this.FileInstance = new File(path + File.separator + this.FileName);
this.fileInstance = new File(path + File.separator + this.fileName);
}
}
}

View File

@ -61,7 +61,7 @@ final class SearchRunner {
private static SearchRunner instance = null;
private IngestServices services = IngestServices.getInstance();
private Ingester ingester = null;
private long defaultUpdateIntervalMs;
private long currentUpdateIntervalMs;
private volatile boolean periodicSearchTaskRunning = false;
private Future<?> jobProcessingTaskFuture;
private final ScheduledThreadPoolExecutor jobProcessingExecutor;
@ -72,7 +72,7 @@ final class SearchRunner {
private Map<Long, SearchJobInfo> jobs = new ConcurrentHashMap<>();
SearchRunner() {
defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000;
currentUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000;
ingester = Ingester.getDefault();
jobProcessingExecutor = new ScheduledThreadPoolExecutor(NUM_SEARCH_SCHEDULING_THREADS, new ThreadFactoryBuilder().setNameFormat(SEARCH_SCHEDULER_THREAD_NAME).build());
}
@ -108,8 +108,8 @@ final class SearchRunner {
if ((jobs.size() > 0) && (periodicSearchTaskRunning == false)) {
// reset the default periodic search frequency to the user setting
logger.log(Level.INFO, "Resetting periodic search time out to default value"); //NON-NLS
defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000;
jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), defaultUpdateIntervalMs, MILLISECONDS);
currentUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000;
jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), currentUpdateIntervalMs, MILLISECONDS);
periodicSearchTaskRunning = true;
}
}
@ -304,25 +304,25 @@ final class SearchRunner {
logger.log(Level.INFO, "All periodic searches cumulatively took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS
// calculate "hold off" time
final long timeToTextSearchMs = getTimeToNextPeriodicSearch(stopWatch.getElapsedTimeSecs()); // ELDEBUG
recalculateUpdateIntervalTime(stopWatch.getElapsedTimeSecs()); // ELDEBUG
// schedule next PeriodicSearchTask
jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), timeToTextSearchMs, MILLISECONDS);
jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), currentUpdateIntervalMs, MILLISECONDS);
// exit this thread
return;
}
private long getTimeToNextPeriodicSearch(long lastSerchTimeSec) {
private void recalculateUpdateIntervalTime(long lastSerchTimeSec) {
// If periodic search takes more than 1/4 of the current periodic search interval, then double the search interval
if (lastSerchTimeSec * 1000 < defaultUpdateIntervalMs / 4) {
return defaultUpdateIntervalMs;
if (lastSerchTimeSec * 1000 < currentUpdateIntervalMs / 4) {
return;
}
// double the search interval
defaultUpdateIntervalMs = defaultUpdateIntervalMs * 2;
logger.log(Level.WARNING, "Last periodic search took {0} sec. Increasing search interval to {1} sec", new Object[]{lastSerchTimeSec, defaultUpdateIntervalMs/1000});
return defaultUpdateIntervalMs;
currentUpdateIntervalMs = currentUpdateIntervalMs * 2;
logger.log(Level.WARNING, "Last periodic search took {0} sec. Increasing search interval to {1} sec", new Object[]{lastSerchTimeSec, currentUpdateIntervalMs/1000});
return;
}
}

View File

@ -37,9 +37,9 @@ Substring match should be used where the search term is just part of a word, or
## Regex match
Regex match can be used to search for a specific pattern. Regular expressions are supported using Lucene Regex Syntax which is documented here: https://lucene.apache.org/core/6_4_0/core/org/apache/lucene/util/automaton/RegExp.html. .* is automatically added to the beginning and end of the regular expressions to ensure all matches are found. Additionally, the resulting hits are split on common token separator boundaries (e.g. space, newline, colon, exclamation point etc.) to make the resulting keyword hit more amenable to highlighting.
Regex match can be used to search for a specific pattern. Regular expressions are supported using Lucene Regex Syntax which is documented here: https://www.elastic.co/guide/en/elasticsearch/reference/1.6/query-dsl-regexp-query.html#regexp-syntax. Wildcards are automatically added to the beginning and end of the regular expressions to ensure all matches are found. Additionally, the resulting hits are split on common token separator boundaries (e.g. space, newline, colon, exclamation point etc.) to make the resulting keyword hit more amenable to highlighting.
There is some validation on the regex but it's best to test on a sample image to make sure your regexes are correct and working as expected.
There is some validation on the regex but it's best to test on a sample image to make sure your regexes are correct and working as expected. One simple way to test is by creating a sample text file that your expression should match, ingesting it as a \ref ds_log "Logical File Set" and then running the regex query.
> In the year 1885 in an article titled Current Notes, the quick brown fox first jumped over the lazy dog.

View File

@ -6,8 +6,8 @@ app.name=${branding.token}
### if left unset, version will default to today's date
app.version=4.5.0
### build.type must be one of: DEVELOPMENT, RELEASE
#build.type=RELEASE
build.type=DEVELOPMENT
build.type=RELEASE
#build.type=DEVELOPMENT
project.org.netbeans.progress=org-netbeans-api-progress
project.org.sleuthkit.autopsy.experimental=Experimental

View File

@ -368,7 +368,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
*
* @param input - input string, like the To/CC line from an email header
*
* @param Set<String>: set of email addresses found in the input string
* @return Set<String>: set of email addresses found in the input string
*/
private Set<String> findEmailAddresess(String input) {
Pattern p = Pattern.compile("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b",