Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 2173-OpenRecentCaseSingleSelection

This commit is contained in:
William Schaefer 2019-07-01 10:14:29 -04:00
commit db0f97eb6f
143 changed files with 4473 additions and 1960 deletions

View File

@ -351,7 +351,11 @@ class UnpackagePortableCaseDialog extends javax.swing.JDialog {
private void unpackageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unpackageButtonActionPerformed
UnpackagePortableCaseProgressDialog dialog = new UnpackagePortableCaseProgressDialog();
dialog.unpackageCase(caseTextField.getText(), outputTextField.getText());
validatePaths(); // The output folder now exists so we need to disable the unpackage button
if (dialog.isSuccess()) {
dispose();
} else {
validatePaths(); // The output folder now exists so we need to disable the unpackage button
}
}//GEN-LAST:event_unpackageButtonActionPerformed

View File

@ -67,8 +67,8 @@ class UnpackagePortableCaseProgressDialog extends javax.swing.JDialog implements
/**
* Unpackage the case
*
* @param packagedCase The compressed case
* @param outputFolder The output folder
* @param packagedCase The compressed case
* @param outputFolder The output folder
*/
void unpackageCase(String packagedCase, String outputFolder) {
@ -81,6 +81,19 @@ class UnpackagePortableCaseProgressDialog extends javax.swing.JDialog implements
}
/**
* Returns whether the unpackaging was completed successfully.
*
* @return True if unpackaging was completed successfully, false otherwise
*/
boolean isSuccess() {
if (worker == null) {
return false;
} else {
return worker.isSuccess();
}
}
@NbBundle.Messages({"UnpackagePortableCaseProgressDialog.propertyChange.success=Successfully unpacked case",})
@Override
public void propertyChange(PropertyChangeEvent evt) {
@ -125,10 +138,9 @@ class UnpackagePortableCaseProgressDialog extends javax.swing.JDialog implements
}
@NbBundle.Messages({
"UnpackageWorker.doInBackground.errorFinding7zip=Could not locate 7-Zip executable",
"UnpackageWorker.doInBackground.errorCompressingCase=Error unpackaging case",
"UnpackageWorker.doInBackground.canceled=Unpackaging canceled by user",
})
"UnpackageWorker.doInBackground.errorFinding7zip=Could not locate 7-Zip executable",
"UnpackageWorker.doInBackground.errorCompressingCase=Error unpackaging case",
"UnpackageWorker.doInBackground.canceled=Unpackaging canceled by user",})
@Override
protected Void doInBackground() throws Exception {
@ -143,7 +155,7 @@ class UnpackagePortableCaseProgressDialog extends javax.swing.JDialog implements
ProcessBuilder procBuilder = new ProcessBuilder();
procBuilder.command(
sevenZipExe.getAbsolutePath(),
"x", // Extract
"x", // Extract
packagedCase,
outputFolderSwitch
);
@ -206,38 +218,39 @@ class UnpackagePortableCaseProgressDialog extends javax.swing.JDialog implements
/**
* Gets the error to display to the user
*
* @return Error to be displayed in the UI
*/
private synchronized String getDisplayError() {
return lastError;
}
private boolean isSuccess() {
protected boolean isSuccess() {
return success.get();
}
/**
* Locate the 7-Zip executable from the release folder.
*
* @return 7-Zip executable
*/
private File locate7ZipExecutable() {
if (!PlatformUtil.isWindowsOS()) {
return null;
}
* Locate the 7-Zip executable from the release folder.
*
* @return 7-Zip executable
*/
private File locate7ZipExecutable() {
if (!PlatformUtil.isWindowsOS()) {
return null;
}
String executableToFindName = Paths.get("7-Zip", "7z.exe").toString(); // NON-NLS
File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, UnpackagePortableCaseProgressDialog.class.getPackage().getName(), false);
if (null == exeFile) {
return null;
}
String executableToFindName = Paths.get("7-Zip", "7z.exe").toString(); // NON-NLS
File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, UnpackagePortableCaseProgressDialog.class.getPackage().getName(), false);
if (null == exeFile) {
return null;
}
if (!exeFile.canExecute()) {
return null;
}
if (!exeFile.canExecute()) {
return null;
}
return exeFile;
}
return exeFile;
}
}
/**

View File

@ -1,7 +1,6 @@
DataContentViewerOtherCases.selectAllMenuItem.text=Select All
DataContentViewerOtherCases.showCaseDetailsMenuItem.text=Show Case Details
DataContentViewerOtherCases.table.toolTip.text=Click column name to sort. Right-click on the table for more options.
DataContentViewerOtherCases.exportToCSVMenuItem.text=Export Selected Rows to CSV
DataContentViewerOtherCases.exportToCSVMenuItem.text=Export all Other Occurrences to CSV
DataContentViewerOtherCases.showCommonalityMenuItem.text=Show Frequency
DataContentViewerOtherCases.earliestCaseDate.text=Earliest Case Date
DataContentViewerOtherCases.earliestCaseLabel.toolTipText=

View File

@ -13,12 +13,11 @@ DataContentViewerOtherCases.dataSources.header.text=Data Source Name
DataContentViewerOtherCases.earliestCaseNotAvailable=\ Not Enabled.
DataContentViewerOtherCases.foundIn.text=Found %d instances in %d cases and %d data sources.
DataContentViewerOtherCases.noOpenCase.errMsg=No open case available.
DataContentViewerOtherCases.selectAllMenuItem.text=Select All
DataContentViewerOtherCases.showCaseDetailsMenuItem.text=Show Case Details
DataContentViewerOtherCases.table.noArtifacts=Item has no attributes with which to search.
DataContentViewerOtherCases.table.noResultsFound=No results found.
DataContentViewerOtherCases.table.toolTip.text=Click column name to sort. Right-click on the table for more options.
DataContentViewerOtherCases.exportToCSVMenuItem.text=Export Selected Rows to CSV
DataContentViewerOtherCases.exportToCSVMenuItem.text=Export all Other Occurrences to CSV
DataContentViewerOtherCases.showCommonalityMenuItem.text=Show Frequency
DataContentViewerOtherCases.earliestCaseDate.text=Earliest Case Date
DataContentViewerOtherCases.earliestCaseLabel.toolTipText=

View File

@ -11,13 +11,6 @@
<Property name="useNullLayout" type="boolean" value="true"/>
</Layout>
<SubComponents>
<MenuItem class="javax.swing.JMenuItem" name="selectAllMenuItem">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle.properties" key="DataContentViewerOtherCases.selectAllMenuItem.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</MenuItem>
<MenuItem class="javax.swing.JMenuItem" name="exportToCSVMenuItem">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">

View File

@ -89,11 +89,10 @@ import org.sleuthkit.datamodel.TskData;
public class DataContentViewerOtherCases extends JPanel implements DataContentViewer {
private static final long serialVersionUID = -1L;
private static final String UUID_PLACEHOLDER_STRING = "NoCorrelationAttributeInstance";
private static final Logger LOGGER = Logger.getLogger(DataContentViewerOtherCases.class.getName());
private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE = new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noArtifacts());
private static final CorrelationCaseWrapper NO_RESULTS_CASE = new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noResultsFound());
private final OtherOccurrencesFilesTableModel filesTableModel;
private final OtherOccurrencesCasesTableModel casesTableModel;
private final OtherOccurrencesDataSourcesTableModel dataSourcesTableModel;
@ -129,12 +128,20 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
reset();
}
/**
* Get a placeholder string to use in place of case uuid when it isn't
* available
*
* @return UUID_PLACEHOLDER_STRING
*/
static String getPlaceholderUUID() {
return UUID_PLACEHOLDER_STRING;
}
private void customizeComponents() {
ActionListener actList = (ActionEvent e) -> {
JMenuItem jmi = (JMenuItem) e.getSource();
if (jmi.equals(selectAllMenuItem)) {
filesTable.selectAll();
} else if (jmi.equals(showCaseDetailsMenuItem)) {
if (jmi.equals(showCaseDetailsMenuItem)) {
showCaseDetails(filesTable.getSelectedRow());
} else if (jmi.equals(exportToCSVMenuItem)) {
try {
@ -148,7 +155,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
};
exportToCSVMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList);
showCaseDetailsMenuItem.addActionListener(actList);
showCommonalityMenuItem.addActionListener(actList);
@ -837,7 +843,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
* selection
*/
private void updateOnDataSourceSelection() {
int[] selectedCaseIndexes = casesTable.getSelectedRows();
int[] selectedDataSources = dataSourcesTable.getSelectedRows();
filesTableModel.clearTable();
for (CorrelationAttributeInstance corAttr : correlationAttributes) {
@ -846,23 +851,20 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
// get correlation and reference set instances from DB
correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
for (int selectedCaseRow : selectedCaseIndexes) {
for (int selectedDataSourceRow : selectedDataSources) {
try {
if (nodeData.isCentralRepoNode()) {
if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedCaseRow)) != null
&& casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedCaseRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
&& dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
filesTableModel.addNodeData(nodeData);
}
} else {
if (dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
filesTableModel.addNodeData(nodeData);
}
for (int selectedDataSourceRow : selectedDataSources) {
try {
if (nodeData.isCentralRepoNode()) {
if (dataSourcesTableModel.getCaseUUIDForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
&& dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
filesTableModel.addNodeData(nodeData);
}
} else {
if (dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
filesTableModel.addNodeData(nodeData);
}
} catch (EamDbException ex) {
LOGGER.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
}
} catch (EamDbException ex) {
LOGGER.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
}
}
}
@ -928,7 +930,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
if (EamDb.isEnabled()) {
CorrelationCase partialCase;
partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx));
if (partialCase == null){
if (partialCase == null) {
return "";
}
return EamDb.getInstance().getCaseByUUID(partialCase.getCaseUUID()).getCreationDate();
@ -951,7 +953,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
private void initComponents() {
rightClickPopupMenu = new javax.swing.JPopupMenu();
selectAllMenuItem = new javax.swing.JMenuItem();
exportToCSVMenuItem = new javax.swing.JMenuItem();
showCaseDetailsMenuItem = new javax.swing.JMenuItem();
showCommonalityMenuItem = new javax.swing.JMenuItem();
@ -981,9 +982,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
}
});
org.openide.awt.Mnemonics.setLocalizedText(selectAllMenuItem, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.selectAllMenuItem.text")); // NOI18N
rightClickPopupMenu.add(selectAllMenuItem);
org.openide.awt.Mnemonics.setLocalizedText(exportToCSVMenuItem, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.exportToCSVMenuItem.text")); // NOI18N
rightClickPopupMenu.add(exportToCSVMenuItem);
@ -1125,7 +1123,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
private javax.swing.JScrollPane filesTableScrollPane;
private javax.swing.JLabel foundInLabel;
private javax.swing.JPopupMenu rightClickPopupMenu;
private javax.swing.JMenuItem selectAllMenuItem;
private javax.swing.JMenuItem showCaseDetailsMenuItem;
private javax.swing.JMenuItem showCommonalityMenuItem;
private javax.swing.JPanel tableContainerPanel;
@ -1141,6 +1138,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
private final String dataSourceID;
private final String filePath;
private final String type;
private final String caseUUID;
UniquePathKey(OtherOccurrenceNodeInstanceData nodeData) {
super();
@ -1151,6 +1149,14 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
filePath = null;
}
type = nodeData.getType();
String tempCaseUUID;
try {
tempCaseUUID = nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID();
} catch (EamDbException ignored) {
tempCaseUUID = UUID_PLACEHOLDER_STRING;
//place holder value will be used since correlation attribute was unavailble
}
caseUUID = tempCaseUUID;
}
@Override
@ -1159,14 +1165,15 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
UniquePathKey otherKey = (UniquePathKey) (other);
return (Objects.equals(otherKey.getDataSourceID(), this.getDataSourceID())
&& Objects.equals(otherKey.getFilePath(), this.getFilePath())
&& Objects.equals(otherKey.getType(), this.getType()));
&& Objects.equals(otherKey.getType(), this.getType())
&& Objects.equals(otherKey.getCaseUUID(), this.getCaseUUID()));
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(getDataSourceID(), getFilePath(), getType());
return Objects.hash(getDataSourceID(), getFilePath(), getType(), getCaseUUID());
}
/**
@ -1195,5 +1202,14 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
String getDataSourceID() {
return dataSourceID;
}
/**
* Get the case uuid for the UniquePathKey
*
* @return the case UUID
*/
String getCaseUUID() {
return caseUUID;
}
}
}

View File

@ -23,6 +23,7 @@ import java.util.Objects;
import java.util.Set;
import javax.swing.table.AbstractTableModel;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
/**
* Model for cells in the data sources section of the other occurrences data
@ -86,6 +87,25 @@ final class OtherOccurrencesDataSourcesTableModel extends AbstractTableModel {
return ((DataSourceColumnItem) dataSourceSet.toArray()[rowIdx]).getDeviceId();
}
/**
* Get the case uuid of the case the data source shown at the specified row
* index exists in
*
* @param rowIdx the row index of the data source you want the case uuid for
*
* @return the case uuid of the case the specified data source exists in or
* an empty string if a device id could not be retrieved
*/
String getCaseUUIDForRow(int rowIdx) {
//if anything would prevent this from working we will return an empty string
if (dataSourceSet.isEmpty() || rowIdx < 0
|| rowIdx >= dataSourceSet.size()
|| !(dataSourceSet.toArray()[rowIdx] instanceof DataSourceColumnItem)) {
return "";
}
return ((DataSourceColumnItem) dataSourceSet.toArray()[rowIdx]).getCaseUUID();
}
/**
* Get the case name of the data source shown at the specified row index
*
@ -115,7 +135,15 @@ final class OtherOccurrencesDataSourcesTableModel extends AbstractTableModel {
* @param newNodeData data to add to the table
*/
void addNodeData(OtherOccurrenceNodeData newNodeData) {
dataSourceSet.add(new DataSourceColumnItem((OtherOccurrenceNodeInstanceData) newNodeData));
OtherOccurrenceNodeInstanceData nodeData = (OtherOccurrenceNodeInstanceData) newNodeData;
String caseUUID;
try {
caseUUID = nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID();
} catch (EamDbException ignored) {
caseUUID = DataContentViewerOtherCases.getPlaceholderUUID();
//place holder value will be used since correlation attribute was unavailble
}
dataSourceSet.add(new DataSourceColumnItem(nodeData.getCaseName(), nodeData.getDeviceID(), nodeData.getDataSourceName(), caseUUID));
fireTableDataChanged();
}
@ -136,30 +164,23 @@ final class OtherOccurrencesDataSourcesTableModel extends AbstractTableModel {
private final String caseName;
private final String deviceId;
private final String dataSourceName;
/**
* Create a DataSourceColumnItem given an
* OtherOccurrenceNodeInstanceData object
*
* @param nodeData the OtherOccurrenceNodeInstanceData which contains
* the data source information
*/
private DataSourceColumnItem(OtherOccurrenceNodeInstanceData nodeData) {
this(nodeData.getCaseName(), nodeData.getDeviceID(), nodeData.getDataSourceName());
}
private final String caseUUID;
/**
* Create a DataSourceColumnItem given a case name, device id, and data
* source name
*
* @param caseName the name of the case the data source exists in
* @param deviceId the name of the device id for the data source
* @param deviceId the device id for the data source
* @param dataSourceName the name of the data source
* @param caseUUID the case uuid for the case the data source
* exists in
*/
private DataSourceColumnItem(String caseName, String deviceId, String dataSourceName) {
private DataSourceColumnItem(String caseName, String deviceId, String dataSourceName, String caseUUID) {
this.caseName = caseName;
this.deviceId = deviceId;
this.dataSourceName = dataSourceName;
this.caseUUID = caseUUID;
}
/**
@ -189,17 +210,27 @@ final class OtherOccurrencesDataSourcesTableModel extends AbstractTableModel {
return caseName;
}
/**
* Get the case uuid of the case the data source exists in
*
* @return the case UUID
*/
private String getCaseUUID() {
return caseUUID;
}
@Override
public boolean equals(Object other) {
return other instanceof DataSourceColumnItem
&& caseName.equals(((DataSourceColumnItem) other).getCaseName())
&& dataSourceName.equals(((DataSourceColumnItem) other).getDataSourceName())
&& deviceId.equals(((DataSourceColumnItem) other).getDeviceId());
&& deviceId.equals(((DataSourceColumnItem) other).getDeviceId())
&& caseUUID.equals(((DataSourceColumnItem) other).getCaseUUID());
}
@Override
public int hashCode() {
return Objects.hash(caseName, deviceId, dataSourceName);
return Objects.hash(caseName, deviceId, dataSourceName, caseUUID);
}
}

View File

@ -25,6 +25,7 @@ import java.util.Map;
import javax.swing.table.AbstractTableModel;
import org.openide.util.NbBundle.Messages;
import org.apache.commons.io.FilenameUtils;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
/**
* Model for cells in the files section of the other occurrences data content
@ -114,7 +115,14 @@ public class OtherOccurrencesFilesTableModel extends AbstractTableModel {
}
private String createNodeKey(OtherOccurrenceNodeInstanceData nodeData) {
return nodeData.getCaseName() + nodeData.getDataSourceName() + nodeData.getDeviceID() + nodeData.getFilePath();
String caseUUID;
try {
caseUUID = nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID();
} catch (EamDbException ignored) {
caseUUID = DataContentViewerOtherCases.getPlaceholderUUID();
//place holder value will be used since correlation attribute was unavailble
}
return nodeData.getCaseName() + nodeData.getDataSourceName() + nodeData.getDeviceID() + nodeData.getFilePath() + caseUUID;
}
/**

View File

@ -123,9 +123,9 @@ public final class InstanceCountNode extends DisplayableItemNode {
final String NO_DESCR = Bundle.InstanceCountNode_createSheet_noDescription();
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.nameColLbl"), NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.nameColLbl"), NO_DESCR, ""));
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.score.name"), NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.score.name"), NO_DESCR, ""));
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.comment.name"), NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.comment.name"), NO_DESCR, ""));
if (UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
if (UserPreferences.getHideSCOColumns() == false) {
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.score.name"), NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.score.name"), NO_DESCR, ""));
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.comment.name"), NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.comment.name"), NO_DESCR, ""));
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.count.name"), NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.createSheet.count.name"), NO_DESCR, ""));
}
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_instancesColLbl(), Bundle.CommonFilesSearchResultsViewerTable_instancesColLbl(), NO_DESCR, this.getInstanceCount()));

View File

@ -72,7 +72,7 @@ final class AccountDeviceInstanceNode extends AbstractNode {
}
@Override
@NbBundle.Messages(value = {"AccountNode.device=Device", "AccountNode.accountName=Account", "AccountNode.accountType=Type", "AccountNode.messageCount=Messages"})
@NbBundle.Messages(value = {"AccountNode.device=Device", "AccountNode.accountName=Account", "AccountNode.accountType=Type", "AccountNode.messageCount=Items"})
protected Sheet createSheet() {
Sheet sheet = super.createSheet();
Sheet.Set properties = sheet.get(Sheet.PROPERTIES);

View File

@ -108,7 +108,7 @@ public final class AccountsBrowser extends JPanel implements ExplorerManager.Pro
accountDeviceInstances.add(((AccountDeviceInstanceNode) node).getAccountDeviceInstance());
filter = ((AccountDeviceInstanceNode)node).getFilter();
}
relationshipBrowser.setSelectionInfo(new SelectionInfo(accountDeviceInstances, filter));
relationshipBrowser.setSelectionInfo(new SelectionInfo(accountDeviceInstances, new HashSet<>(), filter));
}
});

View File

@ -1,7 +1,7 @@
AccountNode.accountName=Account
AccountNode.accountType=Type
AccountNode.device=Device
AccountNode.messageCount=Messages
AccountNode.messageCount=Items
applyText=Apply
CTL_OpenCVTAction=Communications
CVTTopComponent.name=\ Communications Visualization

View File

@ -914,23 +914,24 @@ final public class VisualizationPanel extends JPanel {
Object[] selectionCells = graph.getSelectionCells();
if (selectionCells.length > 0) {
mxICell[] selectedCells = Arrays.asList(selectionCells).toArray(new mxCell[selectionCells.length]);
HashSet<AccountDeviceInstance> deviceInstances = new HashSet<>();
HashSet<AccountDeviceInstance> selectedNodes = new HashSet<>();
HashSet<SelectionInfo.GraphEdge> selectedEdges = new HashSet<>();
for (mxICell cell : selectedCells) {
if (cell.isEdge()) {
mxICell source = (mxICell) graph.getModel().getTerminal(cell, true);
mxICell target = (mxICell) graph.getModel().getTerminal(cell, false);
deviceInstances.add(((AccountDeviceInstanceKey) source.getValue()).getAccountDeviceInstance());
deviceInstances.add(((AccountDeviceInstanceKey) target.getValue()).getAccountDeviceInstance());
selectedEdges.add(new SelectionInfo.GraphEdge(((AccountDeviceInstanceKey) source.getValue()).getAccountDeviceInstance(),
((AccountDeviceInstanceKey) target.getValue()).getAccountDeviceInstance()));
} else if (cell.isVertex()) {
deviceInstances.add(((AccountDeviceInstanceKey) cell.getValue()).getAccountDeviceInstance());
selectedNodes.add(((AccountDeviceInstanceKey) cell.getValue()).getAccountDeviceInstance());
}
}
relationshipBrowser.setSelectionInfo(new SelectionInfo(deviceInstances, currentFilter));
relationshipBrowser.setSelectionInfo(new SelectionInfo(selectedNodes, selectedEdges, currentFilter));
} else {
relationshipBrowser.setSelectionInfo(new SelectionInfo(Collections.EMPTY_SET, currentFilter));
relationshipBrowser.setSelectionInfo(new SelectionInfo(new HashSet<>(), new HashSet<>(), currentFilter));
}
}
}

View File

@ -1,13 +1,11 @@
ContactDetailsPane.nameLabel.text=Placeholder
SummaryViewer.countsPanel.border.title=Counts
SummaryViewer.emailLabel.text=Emails:
SummaryViewer.contactsLabel.text=Contacts:
SummaryViewer.attachmentsLabel.text=Attachments:
SummaryViewer.attachmentsLabel.text=Media Attachments:
OutlineViewPanel.messageLabel.text=<Control Disabled>
SummaryViewer.messagesDataLabel.text=messages
SummaryViewer.callLogsDataLabel.text=callLogs
SummaryViewer.contactsDataLabel.text=contacts
SummaryViewer.emailDataLabel.text=emails
SummaryViewer.attachmentsDataLabel.text=attachments
SummaryViewer.messagesLabel.text=Messages:
SummaryViewer.callLogsLabel.text=Call Logs:

View File

@ -11,7 +11,7 @@ ContactsViewer_columnHeader_Name=Name
ContactsViewer_columnHeader_Phone=Phone
ContactsViewer_noContacts_message=<No contacts found for selected account>
ContactsViewer_tabTitle=Contacts
MediaViewer_Name=Media
MediaViewer_Name=Media Attachments
MessageNode_Node_Property_Attms=Attachments
MessageNode_Node_Property_Date=Date
MessageNode_Node_Property_From=From
@ -27,17 +27,16 @@ MessageViewer_columnHeader_To=To
MessageViewer_no_messages=<No messages found for selected account>
MessageViewer_tabTitle=Messages
MessageViewer_viewMessage_all=All
MessageViewer_viewMessage_calllogs=Call Logs
MessageViewer_viewMessage_selected=Selected
MessageViewer_viewMessage_unthreaded=Unthreaded
SummaryViewer.countsPanel.border.title=Counts
SummaryViewer.emailLabel.text=Emails:
SummaryViewer.contactsLabel.text=Contacts:
SummaryViewer.attachmentsLabel.text=Attachments:
SummaryViewer.attachmentsLabel.text=Media Attachments:
OutlineViewPanel.messageLabel.text=<Control Disabled>
SummaryViewer.messagesDataLabel.text=messages
SummaryViewer.callLogsDataLabel.text=callLogs
SummaryViewer.contactsDataLabel.text=contacts
SummaryViewer.emailDataLabel.text=emails
SummaryViewer.attachmentsDataLabel.text=attachments
SummaryViewer.messagesLabel.text=Messages:
SummaryViewer.callLogsLabel.text=Call Logs:

View File

@ -68,37 +68,29 @@ final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{
*/
@Override
protected boolean createKeys(List<BlackboardArtifact> list) {
CommunicationsManager communicationManager;
try {
communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get communications manager from case.", ex); //NON-NLS
return false;
}
if(selectionInfo == null) {
return true;
}
final Set<Content> relationshipSources;
try {
relationshipSources = communicationManager.getRelationshipSources(selectionInfo.getAccountDevicesInstances(), selectionInfo.getCommunicationsFilter());
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
BlackboardArtifact bba = (BlackboardArtifact) content;
BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(bba.getArtifactTypeID());
if (fromID == TSK_CONTACT) {
list.add(bba);
}
});
relationshipSources = selectionInfo.getRelationshipSources();
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get relationship sources.", ex); //NON-NLS
logger.log(Level.SEVERE, "Failed to load relationship sources.", ex); //NON-NLS
return false;
}
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
BlackboardArtifact bba = (BlackboardArtifact) content;
BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(bba.getArtifactTypeID());
if (fromID == TSK_CONTACT) {
list.add(bba);
}
});
return true;
}

View File

@ -59,7 +59,7 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM
private final ModifiableProxyLookup proxyLookup;
@Messages({
"MediaViewer_Name=Media"
"MediaViewer_Name=Media Attachments"
})
/**
* Creates new form ThumbnailViewer
@ -113,20 +113,17 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM
@Override
public void setSelectionInfo(SelectionInfo info) {
final Set<Content> relationshipSources;
CommunicationsManager communicationManager;
Set<Content> relationshipSources;
Set<BlackboardArtifact> artifactList = new HashSet<>();
try {
communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
relationshipSources = communicationManager.getRelationshipSources(info.getAccountDevicesInstances(), info.getCommunicationsFilter());
relationshipSources = info.getRelationshipSources();
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
artifactList.add((BlackboardArtifact) content);
});
} catch (TskCoreException | NoCurrentCaseException ex) {
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Unable to update selection." , ex);
}

View File

@ -48,6 +48,7 @@ import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
class MessageNode extends BlackboardArtifactNode {
public static final String UNTHREADED_ID = "<UNTHREADED>";
public static final String CALL_LOG_ID = "<CALLLOG>";
private static final Logger logger = Logger.getLogger(MessageNode.class.getName());
@ -87,9 +88,14 @@ class MessageNode extends BlackboardArtifactNode {
sheetSet.put(new NodeProperty<>("Type", Bundle.MessageNode_Node_Property_Type(), "", getDisplayName())); //NON-NLS
sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",threadID == null ? UNTHREADED_ID : threadID)); //NON-NLS
final BlackboardArtifact artifact = getArtifact();
if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()) {
sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",CALL_LOG_ID)); //NON-NLS
} else {
sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",threadID == null ? UNTHREADED_ID : threadID)); //NON-NLS
}
BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact.getArtifactTypeID());
if (null != fromID) {

View File

@ -82,7 +82,8 @@ public class MessageViewer extends JPanel implements RelationshipsViewer {
"MessageViewer_no_messages=<No messages found for selected account>",
"MessageViewer_viewMessage_all=All",
"MessageViewer_viewMessage_selected=Selected",
"MessageViewer_viewMessage_unthreaded=Unthreaded",})
"MessageViewer_viewMessage_unthreaded=Unthreaded",
"MessageViewer_viewMessage_calllogs=Call Logs"})
/**
* Creates new form MessageViewer
@ -228,7 +229,11 @@ public class MessageViewer extends JPanel implements RelationshipsViewer {
if (!subject.isEmpty()) {
threadNameLabel.setText(subject);
} else {
threadNameLabel.setText(Bundle.MessageViewer_viewMessage_unthreaded());
if (threadIDList.contains(MessageNode.CALL_LOG_ID)) {
threadNameLabel.setText(Bundle.MessageViewer_viewMessage_calllogs());
} else {
threadNameLabel.setText(Bundle.MessageViewer_viewMessage_unthreaded());
}
}
showMessagesPane();

View File

@ -70,24 +70,20 @@ public class MessagesChildNodeFactory extends ChildFactory<BlackboardArtifact>{
@Override
protected boolean createKeys(List<BlackboardArtifact> list) {
CommunicationsManager communicationManager;
try {
communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get communications manager from case.", ex); //NON-NLS
return false;
}
if(selectionInfo == null) {
return true;
}
final Set<Content> relationshipSources;
try {
relationshipSources = selectionInfo.getRelationshipSources();
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to load relationship sources.", ex); //NON-NLS
return false;
}
try {
relationshipSources = communicationManager.getRelationshipSources(selectionInfo.getAccountDevicesInstances(), selectionInfo.getCommunicationsFilter());
for(Content content: relationshipSources) {
if( !(content instanceof BlackboardArtifact)){
continue;
@ -102,10 +98,16 @@ public class MessagesChildNodeFactory extends ChildFactory<BlackboardArtifact>{
continue;
}
// We want all artifacts that do not have "threadIDs" to appear as one thread in the UI
// We want email and message artifacts that do not have "threadIDs" to appear as one thread in the UI
// To achive this assign any artifact that does not have a threadID
// the "UNTHREADED_ID"
String artifactThreadID = MessageNode.UNTHREADED_ID;
// All call logs will default to a single call logs thread
String artifactThreadID;
if (fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG) {
artifactThreadID = MessageNode.CALL_LOG_ID;
} else {
artifactThreadID = MessageNode.UNTHREADED_ID;
}
BlackboardAttribute attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID));
if(attribute != null) {
@ -119,7 +121,7 @@ public class MessagesChildNodeFactory extends ChildFactory<BlackboardArtifact>{
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get relationship sources.", ex); //NON-NLS
logger.log(Level.SEVERE, "Failed to load artifacts for relationship sources.", ex); //NON-NLS
}
return true;

View File

@ -40,7 +40,8 @@ public final class SelectionInfo {
private static final Logger logger = Logger.getLogger(SelectionInfo.class.getName());
private final Set<AccountDeviceInstance> accountDeviceInstances;
private final Set<AccountDeviceInstance> selectedNodes;
private final Set<GraphEdge> selectedEdges;
private final CommunicationsFilter communicationFilter;
private final Set<Account> accounts;
@ -50,26 +51,38 @@ public final class SelectionInfo {
/**
* Wraps the details of the currently selected accounts.
*
* @param accountDeviceInstances Selected accountDecivedInstances
* @param selectedNodes Selected AccountDeviceInstances
* @param selectedEdges Selected pairs of AccountDeviceInstances
* @param communicationFilter Currently selected communications filters
*/
public SelectionInfo(Set<AccountDeviceInstance> accountDeviceInstances, CommunicationsFilter communicationFilter) {
this.accountDeviceInstances = accountDeviceInstances;
public SelectionInfo(Set<AccountDeviceInstance> selectedNodes, Set<GraphEdge> selectedEdges,
CommunicationsFilter communicationFilter) {
this.selectedNodes = selectedNodes;
this.selectedEdges = selectedEdges;
this.communicationFilter = communicationFilter;
accounts = new HashSet<>();
accountDeviceInstances.forEach((instance) -> {
selectedNodes.forEach((instance) -> {
accounts.add(instance.getAccount());
});
}
/**
* Returns the currently selected accountDeviceInstances
* Returns the currently selected nodes
*
* @return Set of AccountDeviceInstance
*/
public Set<AccountDeviceInstance> getAccountDevicesInstances() {
return accountDeviceInstances;
public Set<AccountDeviceInstance> getSelectedNodes() {
return selectedNodes;
}
/**
* Returns the currently selected edges
*
* @return Set of GraphEdge objects
*/
public Set<GraphEdge> getSelectedEdges() {
return selectedEdges;
}
/**
@ -85,28 +98,50 @@ public final class SelectionInfo {
return accounts;
}
/**
* Get the set of relationship sources from the case database
*
* @return the relationship sources (may be empty)
* @throws TskCoreException
*/
Set<Content> getRelationshipSources() throws TskCoreException {
CommunicationsManager communicationManager;
try {
communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
} catch (NoCurrentCaseException ex) {
throw new TskCoreException("Failed to get current case", ex);
}
Set<Content> relationshipSources = new HashSet<>();
try {
// Add all nodes
relationshipSources.addAll(communicationManager.getRelationshipSources(getSelectedNodes(), getCommunicationsFilter()));
// Add all edges. For edges, the relationship has to include both endpoints
for (SelectionInfo.GraphEdge edge : getSelectedEdges()) {
relationshipSources.addAll(communicationManager.getRelationshipSources(edge.getStartNode(),
edge.getEndNode(), getCommunicationsFilter()));
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get relationships from case database.", ex); //NON-NLS
}
return relationshipSources;
}
public Set<BlackboardArtifact> getArtifacts() {
if(accountArtifacts == null) {
accountArtifacts = new HashSet<>();
CommunicationsManager communicationManager;
try {
communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get communications manager from case.", ex); //NON-NLS
return null;
}
final Set<Content> relationshipSources;
try {
relationshipSources = communicationManager.getRelationshipSources(getAccountDevicesInstances(), getCommunicationsFilter());
final Set<Content> relationshipSources = getRelationshipSources();
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
accountArtifacts.add((BlackboardArtifact) content);
});
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get relationship sources.", ex); //NON-NLS
logger.log(Level.SEVERE, "Failed to load relationship sources.", ex); //NON-NLS
return accountArtifacts;
}
}
@ -182,4 +217,24 @@ public final class SelectionInfo {
}
}
/**
* Utility class to represent an edge from the graph visualization.
*/
public static class GraphEdge {
AccountDeviceInstance startNode;
AccountDeviceInstance endNode;
public GraphEdge(AccountDeviceInstance startNode, AccountDeviceInstance endNode) {
this.startNode = startNode;
this.endNode = endNode;
}
public AccountDeviceInstance getStartNode() {
return startNode;
}
public AccountDeviceInstance getEndNode() {
return endNode;
}
}
}

View File

@ -11,7 +11,7 @@
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,3,70,0,0,4,-35"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,4,7,0,0,4,-35"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
@ -38,21 +38,19 @@
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="attachmentsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="messagesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="callLogsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="contactsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="emailLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="attachmentsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="emailDataLabel" min="-2" max="-2" attributes="0"/>
<Component id="attachmentsDataLabel" min="-2" max="-2" attributes="0"/>
<Component id="contactsDataLabel" min="-2" max="-2" attributes="0"/>
<Component id="callLogsDataLabel" min="-2" max="-2" attributes="0"/>
<Component id="messagesDataLabel" min="-2" max="-2" attributes="0"/>
<Component id="attachmentsDataLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace pref="959" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -60,11 +58,6 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="attachmentsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="attachmentsDataLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="messagesLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="messagesDataLabel" alignment="3" min="-2" max="-2" attributes="0"/>
@ -81,8 +74,8 @@
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="emailLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="emailDataLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="attachmentsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="attachmentsDataLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
@ -90,13 +83,6 @@
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="emailLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="SummaryViewer.emailLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="contactsLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -153,13 +139,6 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="emailDataLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="SummaryViewer.emailDataLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel" name="fileReferencesPanel">

View File

@ -47,8 +47,7 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
"SummaryViewer_CaseRefNameColumn_Title=Case Name",
"SummaryViewer_CentralRepository_Message=<Enable Central Resposity to see Other Occurrences>",
"SummaryViewer_Creation_Date_Title=Creation Date",
"SummeryViewer_FileRef_Message=<Select one Accout to see File References>",
})
"SummeryViewer_FileRef_Message=<Select one Accout to see File References>",})
/**
* Creates new form SummaryViewer
@ -108,8 +107,7 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
attachmentsDataLabel.setText(Integer.toString(summaryDetails.getAttachmentCnt()));
callLogsDataLabel.setText(Integer.toString(summaryDetails.getCallLogCnt()));
contactsDataLabel.setText(Integer.toString(summaryDetails.getContactsCnt()));
emailDataLabel.setText(Integer.toString(summaryDetails.getEmailCnt()));
messagesDataLabel.setText(Integer.toString(summaryDetails.getMessagesCnt()));
messagesDataLabel.setText(Integer.toString(summaryDetails.getMessagesCnt() + summaryDetails.getEmailCnt()));
fileReferencesPanel.showOutlineView();
@ -136,7 +134,6 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
attachmentsLabel.setEnabled(enabled);
callLogsLabel.setEnabled(enabled);
contactsLabel.setEnabled(enabled);
emailLabel.setEnabled(enabled);
messagesLabel.setEnabled(enabled);
caseReferencesPanel.setEnabled(enabled);
fileReferencesPanel.setEnabled(enabled);
@ -150,7 +147,6 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
attachmentsDataLabel.setText("");
callLogsDataLabel.setText("");
contactsDataLabel.setText("");
emailDataLabel.setText("");
messagesDataLabel.setText("");
fileReferencesPanel.setNode(new AbstractNode(Children.LEAF));
@ -188,7 +184,6 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
java.awt.GridBagConstraints gridBagConstraints;
countsPanel = new javax.swing.JPanel();
emailLabel = new javax.swing.JLabel();
contactsLabel = new javax.swing.JLabel();
messagesLabel = new javax.swing.JLabel();
callLogsLabel = new javax.swing.JLabel();
@ -197,7 +192,6 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
messagesDataLabel = new javax.swing.JLabel();
callLogsDataLabel = new javax.swing.JLabel();
contactsDataLabel = new javax.swing.JLabel();
emailDataLabel = new javax.swing.JLabel();
fileReferencesPanel = new org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel();
caseReferencesPanel = new org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel();
@ -205,8 +199,6 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
countsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SummaryViewer.class, "SummaryViewer.countsPanel.border.title"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(emailLabel, org.openide.util.NbBundle.getMessage(SummaryViewer.class, "SummaryViewer.emailLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(contactsLabel, org.openide.util.NbBundle.getMessage(SummaryViewer.class, "SummaryViewer.contactsLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(messagesLabel, org.openide.util.NbBundle.getMessage(SummaryViewer.class, "SummaryViewer.messagesLabel.text")); // NOI18N
@ -223,8 +215,6 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
org.openide.awt.Mnemonics.setLocalizedText(contactsDataLabel, org.openide.util.NbBundle.getMessage(SummaryViewer.class, "SummaryViewer.contactsDataLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(emailDataLabel, org.openide.util.NbBundle.getMessage(SummaryViewer.class, "SummaryViewer.emailDataLabel.text")); // NOI18N
javax.swing.GroupLayout countsPanelLayout = new javax.swing.GroupLayout(countsPanel);
countsPanel.setLayout(countsPanelLayout);
countsPanelLayout.setHorizontalGroup(
@ -232,28 +222,22 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
.addGroup(countsPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(countsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(attachmentsLabel)
.addComponent(messagesLabel)
.addComponent(callLogsLabel)
.addComponent(contactsLabel)
.addComponent(emailLabel))
.addComponent(attachmentsLabel))
.addGap(18, 18, 18)
.addGroup(countsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(emailDataLabel)
.addComponent(attachmentsDataLabel)
.addComponent(contactsDataLabel)
.addComponent(callLogsDataLabel)
.addComponent(messagesDataLabel)
.addComponent(attachmentsDataLabel))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(messagesDataLabel))
.addContainerGap(959, Short.MAX_VALUE))
);
countsPanelLayout.setVerticalGroup(
countsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(countsPanelLayout.createSequentialGroup()
.addGap(7, 7, 7)
.addGroup(countsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(attachmentsLabel)
.addComponent(attachmentsDataLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(countsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(messagesLabel)
.addComponent(messagesDataLabel))
@ -267,8 +251,8 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
.addComponent(contactsDataLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(countsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(emailLabel)
.addComponent(emailDataLabel))
.addComponent(attachmentsLabel)
.addComponent(attachmentsDataLabel))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
@ -311,8 +295,6 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
private javax.swing.JLabel contactsDataLabel;
private javax.swing.JLabel contactsLabel;
private javax.swing.JPanel countsPanel;
private javax.swing.JLabel emailDataLabel;
private javax.swing.JLabel emailLabel;
private org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel fileReferencesPanel;
private javax.swing.JLabel messagesDataLabel;
private javax.swing.JLabel messagesLabel;

View File

@ -83,26 +83,16 @@ final class ThreadChildNodeFactory extends ChildFactory<BlackboardArtifact> {
*/
@Override
protected boolean createKeys(List<BlackboardArtifact> list) {
CommunicationsManager communicationManager;
try {
communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get communications manager from case.", ex); //NON-NLS
return false;
}
if(selectionInfo == null) {
return true;
}
final Set<Content> relationshipSources;
try {
relationshipSources = communicationManager.getRelationshipSources(selectionInfo.getAccountDevicesInstances(), selectionInfo.getCommunicationsFilter());
final Set<Content> relationshipSources = selectionInfo.getRelationshipSources();
createRootMessageKeys(list, relationshipSources) ;
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get relationship sources.", ex); //NON-NLS
logger.log(Level.SEVERE, "Failed to load relationship sources.", ex); //NON-NLS
return false;
}
return true;
@ -133,10 +123,16 @@ final class ThreadChildNodeFactory extends ChildFactory<BlackboardArtifact> {
|| fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG
|| fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE) {
// We want all artifacts that do not have "threadIDs" to appear as one thread in the UI
// We want email and message artifacts that do not have "threadIDs" to appear as one thread in the UI
// To achive this assign any artifact that does not have a threadID
// the "UNTHREADED_ID"
String threadID = MessageNode.UNTHREADED_ID;
// All call logs will default to a single call logs thread
String threadID;
if (fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG) {
threadID = MessageNode.CALL_LOG_ID;
} else {
threadID = MessageNode.UNTHREADED_ID;
}
BlackboardAttribute attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID));
if(attribute != null) {
@ -180,13 +176,46 @@ final class ThreadChildNodeFactory extends ChildFactory<BlackboardArtifact> {
if (attribute != null) {
return new ThreadNode(bba, attribute.getValueString(), preferredAction);
} else {
// Only one of these should occur.
return new UnthreadedNode();
if (bba.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()) {
return new CallLogNode();
} else {
// Only one of these should occur.
return new UnthreadedNode();
}
}
}
/**
* An this node represents the "unthreaded" thread.
* This node represents the "call log" thread.
*/
final class CallLogNode extends AbstractNode {
/**
* Construct an instance of a CallLogNode.
*/
CallLogNode() {
super(Children.LEAF);
setDisplayName("Call Logs");
this.setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/unthreaded.png" );
}
@Override
protected Sheet createSheet() {
Sheet sheet = super.createSheet();
Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
if (sheetSet == null) {
sheetSet = Sheet.createPropertiesSet();
sheet.put(sheetSet);
}
// Give this node a threadID of "CALL_LOG_ID"
sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",MessageNode.CALL_LOG_ID));
return sheet;
}
}
/**
* This node represents the "unthreaded" thread.
*/
final class UnthreadedNode extends AbstractNode {
/**

View File

@ -25,7 +25,7 @@ import org.openide.nodes.Sheet;
import org.sleuthkit.datamodel.BlackboardArtifact;
/**
* An AbstractNode subclass which wraps a MessagNode object. Doing this allows
* An AbstractNode subclass which wraps a MessageNode object. Doing this allows
* for the reuse of the createSheet and other function from MessageNode, but
* also some customizing of how a ThreadNode is shown.
*/

View File

@ -42,11 +42,15 @@ MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, aud
MediaPlayerPanel.noSupport=File not supported.
MediaPlayerPanel.timeFormat=%02d:%02d:%02d
MediaPlayerPanel.unknownTime=Unknown
MediaViewImagePanel.createTagOption=Create
MediaViewImagePanel.deleteTagOption=Delete
MediaViewImagePanel.errorLabel.OOMText=Could not load file into Media View: insufficent memory.
MediaViewImagePanel.errorLabel.text=Could not load file into Media View.
MediaViewImagePanel.exportSaveText=Save
MediaViewImagePanel.exportTagOption=Export
MediaViewImagePanel.externalViewerButton.text=Open in External Viewer Ctrl+E
MediaViewImagePanel.fileChooserTitle=Choose a save location
MediaViewImagePanel.hideTagOption=Hide
MediaViewImagePanel.successfulExport=Tagged image was successfully saved.
MediaViewImagePanel.unsuccessfulExport=Unable to export tagged image to disk.
MediaViewVideoPanel.pauseButton.text=\u25ba

View File

@ -83,8 +83,10 @@ import org.sleuthkit.autopsy.contentviewers.imagetagging.ImageTagRegion;
import org.sleuthkit.autopsy.contentviewers.imagetagging.ImageTagCreator;
import org.sleuthkit.autopsy.contentviewers.imagetagging.ImageTag;
import org.sleuthkit.autopsy.contentviewers.imagetagging.ImageTagsGroup;
import org.sleuthkit.autopsy.corelibs.OpenCvLoader;
import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.datamodel.FileNode;
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.datamodel.AbstractFile;
@ -116,7 +118,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
private final ProgressBar progressBar = new ProgressBar();
private final MaskerPane maskerPane = new MaskerPane();
private final JPopupMenu popupMenu = new JPopupMenu();
private final JPopupMenu imageTaggingOptions = new JPopupMenu();
private final JMenuItem createTagMenuItem;
private final JMenuItem deleteTagMenuItem;
private final JMenuItem hideTagsMenuItem;
@ -158,6 +160,12 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
/**
* Creates new form MediaViewImagePanel
*/
@NbBundle.Messages({
"MediaViewImagePanel.createTagOption=Create",
"MediaViewImagePanel.deleteTagOption=Delete",
"MediaViewImagePanel.hideTagOption=Hide",
"MediaViewImagePanel.exportTagOption=Export"
})
public MediaViewImagePanel() {
initComponents();
fxInited = org.sleuthkit.autopsy.core.Installer.isJavaFxInited();
@ -166,29 +174,35 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
exportChooser.setDialogTitle(Bundle.MediaViewImagePanel_fileChooserTitle());
//Build popupMenu when Tags Menu button is pressed.
createTagMenuItem = new JMenuItem("Create");
createTagMenuItem = new JMenuItem(Bundle.MediaViewImagePanel_createTagOption());
createTagMenuItem.addActionListener((event) -> createTag());
popupMenu.add(createTagMenuItem);
imageTaggingOptions.add(createTagMenuItem);
popupMenu.add(new JSeparator());
imageTaggingOptions.add(new JSeparator());
deleteTagMenuItem = new JMenuItem("Delete");
deleteTagMenuItem = new JMenuItem(Bundle.MediaViewImagePanel_deleteTagOption());
deleteTagMenuItem.addActionListener((event) -> deleteTag());
popupMenu.add(deleteTagMenuItem);
imageTaggingOptions.add(deleteTagMenuItem);
popupMenu.add(new JSeparator());
imageTaggingOptions.add(new JSeparator());
hideTagsMenuItem = new JMenuItem("Hide");
hideTagsMenuItem = new JMenuItem(Bundle.MediaViewImagePanel_hideTagOption());
hideTagsMenuItem.addActionListener((event) -> showOrHideTags());
popupMenu.add(hideTagsMenuItem);
imageTaggingOptions.add(hideTagsMenuItem);
popupMenu.add(new JSeparator());
imageTaggingOptions.add(new JSeparator());
exportTagsMenuItem = new JMenuItem("Export");
exportTagsMenuItem = new JMenuItem(Bundle.MediaViewImagePanel_exportTagOption());
exportTagsMenuItem.addActionListener((event) -> exportTags());
popupMenu.add(exportTagsMenuItem);
imageTaggingOptions.add(exportTagsMenuItem);
popupMenu.setPopupSize(300, 150);
imageTaggingOptions.setPopupSize(300, 150);
//Disable image tagging for non-windows users or upon failure to load OpenCV.
if (!PlatformUtil.isWindowsOS() || !OpenCvLoader.hasOpenCvLoaded()) {
tagsMenu.setEnabled(false);
imageTaggingOptions.setEnabled(false);
}
if (fxInited) {
Platform.runLater(new Runnable() {
@ -893,7 +907,9 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
}
private void tagsMenuMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tagsMenuMousePressed
popupMenu.show(tagsMenu, -300 + tagsMenu.getWidth(), tagsMenu.getHeight() + 3);
if (imageTaggingOptions.isEnabled()) {
imageTaggingOptions.show(tagsMenu, -300 + tagsMenu.getWidth(), tagsMenu.getHeight() + 3);
}
}//GEN-LAST:event_tagsMenuMousePressed
/**

View File

@ -48,6 +48,8 @@ public final class ImageTag extends Group {
// Used to tell the 8 edit handles to hide if this tag is no longer selected
private final EventDispatchChainImpl ALL_CHILDREN;
private final PhysicalTag physicalTag;
//Notifies listeners that the user has editted the tag boundaries
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
@ -64,7 +66,7 @@ public final class ImageTag extends Group {
});
ImageTagRegion details = contentViewerTag.getDetails();
PhysicalTag physicalTag = new PhysicalTag(details);
physicalTag = new PhysicalTag(details);
//Defines the max allowable boundary that a user may drag any given handle.
Boundary dragBoundary = (x, y) -> {
@ -132,6 +134,14 @@ public final class ImageTag extends Group {
pcs.addPropertyChangeListener(listener);
}
public double getWidth() {
return physicalTag.getWidth();
}
public double getHeight() {
return physicalTag.getHeight();
}
/**
* Get the content viewer tag that this class represents.
*

View File

@ -23,6 +23,7 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javafx.event.Event;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
@ -65,13 +66,8 @@ public final class ImageTagsGroup extends Group {
return;
}
//Pull out the logical image tag that this node is associated with
Node topLevelChild = e.getPickResult().getIntersectedNode();
while (!this.getChildren().contains(topLevelChild)) {
topLevelChild = topLevelChild.getParent();
}
requestFocus((ImageTag) topLevelChild);
ImageTag selection = getTagToSelect(new Point2D(e.getX(), e.getY()));
requestFocus(selection);
});
}
@ -103,6 +99,31 @@ public final class ImageTagsGroup extends Group {
}
}
/**
* Find which tag to select on a user mouse press. If multiple tags are
* overlapping, pick the smallest one that is determined by the L + W of
* the tag sides.
*
* @param coordinate User mouse press location
* @return The tag to give focus
*/
private ImageTag getTagToSelect(Point2D coordinate) {
ImageTag tagToSelect = null;
double minTagSize = Double.MAX_VALUE;
//Find all intersecting tags, select the absolute min based on L + W.
for (Node node : this.getChildren()) {
ImageTag tag = (ImageTag) node;
double tagSize = tag.getWidth() + tag.getHeight();
if (tag.contains(coordinate) && tagSize < minTagSize) {
tagToSelect = tag;
minTagSize = tagSize;
}
}
return tagToSelect;
}
/**
* Notifies the logical image tag that it is no longer in focus.
*
@ -119,7 +140,7 @@ public final class ImageTagsGroup extends Group {
* @param n
*/
private void requestFocus(ImageTag n) {
if (n.equals(currentFocus)) {
if (n == null || n.equals(currentFocus)) {
return;
} else if (currentFocus != null && !currentFocus.equals(n)) {
resetFocus(currentFocus);

View File

@ -73,7 +73,7 @@ public final class UserPreferences {
private static final int LOG_FILE_NUM_INT = 10;
public static final String GROUP_ITEMS_IN_TREE_BY_DATASOURCE = "GroupItemsInTreeByDataSource"; //NON-NLS
public static final String SHOW_ONLY_CURRENT_USER_TAGS = "ShowOnlyCurrentUserTags";
public static final String HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES = "HideCentralRepoCommentsAndOccurrences";
public static final String HIDE_SCO_COLUMNS = "HideCentralRepoCommentsAndOccurrences"; //The key for this setting pre-dates the settings current functionality //NON-NLS
public static final String DISPLAY_TRANSLATED_NAMES = "DisplayTranslatedNames";
public static final String EXTERNAL_HEX_EDITOR_PATH = "ExternalHexEditorPath";
public static final String SOLR_MAX_JVM_SIZE = "SolrMaxJVMSize";
@ -224,7 +224,6 @@ public final class UserPreferences {
return preferences.getBoolean(SHOW_ONLY_CURRENT_USER_TAGS, false);
}
/**
* Set the user preference which identifies whether tags should be shown for
* only the current user or all users.
@ -236,27 +235,25 @@ public final class UserPreferences {
}
/**
* Get the user preference which identifies whether the Central Repository
* should be called to get comments and occurrences for the (C)omments and
* (O)ccurrences columns in the result view.
* Get the user preference which identifies whether the (S)core, (C)omments,
* and (O)ccurrences columns should be populated and displayed in the result
* view.
*
* @return True if hiding Central Repository data for comments and
* occurrences; otherwise false.
* @return True if hiding SCO columns; otherwise false.
*/
public static boolean hideCentralRepoCommentsAndOccurrences() {
return preferences.getBoolean(HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES, false);
public static boolean getHideSCOColumns() {
return preferences.getBoolean(HIDE_SCO_COLUMNS, false);
}
/**
* Set the user preference which identifies whether the Central Repository
* should be called to get comments and occurrences for the (C)omments and
* (O)ccurrences columns in the result view.
* Set the user preference which identifies whether the (S)core, (C)omments,
* and (O)ccurrences columns should be populated and displayed in the result
* view.
*
* @param value The value of which to assign to the user preference.
*/
public static void setHideCentralRepoCommentsAndOccurrences(boolean value) {
preferences.putBoolean(HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES, value);
public static void setHideSCOColumns(boolean value) {
preferences.putBoolean(HIDE_SCO_COLUMNS, value);
}
public static void setDisplayTranslatedFileNames(boolean value) {
@ -337,11 +334,11 @@ public final class UserPreferences {
preferences.putInt(INDEXING_SERVER_PORT, port);
}
public static void setTextTranslatorName(String textTranslatorName){
public static void setTextTranslatorName(String textTranslatorName) {
preferences.put(TEXT_TRANSLATOR_NAME, textTranslatorName);
}
public static String getTextTranslatorName(){
public static String getTextTranslatorName() {
return preferences.get(TEXT_TRANSLATOR_NAME, null);
}

View File

@ -153,10 +153,7 @@ ViewPreferencesPanel.currentSessionSettingsPanel.border.title=Current Session Se
ViewPreferencesPanel.hideRejectedResultsCheckbox.text=Hide rejected results
ViewPreferencesPanel.selectFileLabel.text=When selecting a file:
ViewPreferencesPanel.globalSettingsPanel.border.title=Global Settings
ViewPreferencesPanel.commentsOccurencesColumnWrapAroundText.text=to reduce loading times
ViewPreferencesPanel.translateTextLabel.text=Translate text:
ViewPreferencesPanel.commentsOccurencesColumnsCheckbox.text=C(omments) and O(ccurences) columns
ViewPreferencesPanel.centralRepoLabel.text=Do not use Central Repository for:
ViewPreferencesPanel.hideOtherUsersTagsLabel.text=Hide other users' tags in the:
ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=Tags area in the tree
ViewPreferencesPanel.useAnotherTimeRadioButton.text=Use another time zone
@ -218,3 +215,6 @@ DataResultViewerTable.pageLabel.text=Page:
ViewPreferencesPanel.maxResultsLabel.text=Maximum number of Results to show in table:
ViewPreferencesPanel.maxResultsLabel.toolTipText=<html>\nSetting this value to 0 will display all results in the results table.\n<br>Note that setting this value to 0 may result in poor UI responsiveness when there are large numbers of results.\n</html>
DataResultViewerTable.exportCSVButton.text=Save table as CSV
ViewPreferencesPanel.scoColumnsCheckbox.text=S(core), C(omments), and O(ccurrences)
ViewPreferencesPanel.scoColumnsWrapAroundText.text=to reduce loading times
ViewPreferencesPanel.scoColumnsLabel.text=Do not add columns for:

View File

@ -207,10 +207,7 @@ ViewPreferencesPanel.currentSessionSettingsPanel.border.title=Current Session Se
ViewPreferencesPanel.hideRejectedResultsCheckbox.text=Hide rejected results
ViewPreferencesPanel.selectFileLabel.text=When selecting a file:
ViewPreferencesPanel.globalSettingsPanel.border.title=Global Settings
ViewPreferencesPanel.commentsOccurencesColumnWrapAroundText.text=to reduce loading times
ViewPreferencesPanel.translateTextLabel.text=Translate text:
ViewPreferencesPanel.commentsOccurencesColumnsCheckbox.text=C(omments) and O(ccurences) columns
ViewPreferencesPanel.centralRepoLabel.text=Do not use Central Repository for:
ViewPreferencesPanel.hideOtherUsersTagsLabel.text=Hide other users' tags in the:
ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=Tags area in the tree
ViewPreferencesPanel.useAnotherTimeRadioButton.text=Use another time zone
@ -272,3 +269,6 @@ DataResultViewerTable.pageLabel.text=Page:
ViewPreferencesPanel.maxResultsLabel.text=Maximum number of Results to show in table:
ViewPreferencesPanel.maxResultsLabel.toolTipText=<html>\nSetting this value to 0 will display all results in the results table.\n<br>Note that setting this value to 0 may result in poor UI responsiveness when there are large numbers of results.\n</html>
DataResultViewerTable.exportCSVButton.text=Save table as CSV
ViewPreferencesPanel.scoColumnsCheckbox.text=S(core), C(omments), and O(ccurrences)
ViewPreferencesPanel.scoColumnsWrapAroundText.text=to reduce loading times
ViewPreferencesPanel.scoColumnsLabel.text=Do not add columns for:

View File

@ -507,7 +507,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private void bnTestDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestDatabaseActionPerformed
lbTestDatabase.setIcon(null);
lbTestDatabase.paintImmediately(lbTestDatabase.getVisibleRect());
lbTestDbWarning.setText("");
lbTestDbWarning.paintImmediately(lbTestDbWarning.getVisibleRect());
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
CaseDbConnectionInfo info = new CaseDbConnectionInfo(
@ -530,7 +532,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private void bnTestMessageServiceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestMessageServiceActionPerformed
lbTestMessageService.setIcon(null);
lbTestMessageService.paintImmediately(lbTestMessageService.getVisibleRect());
lbTestMessageWarning.setText("");
lbTestMessageWarning.paintImmediately(lbTestMessageWarning.getVisibleRect());
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
int port;
@ -561,7 +565,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private void bnTestSolrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestSolrActionPerformed
lbTestSolr.setIcon(null);
lbTestSolr.paintImmediately(lbTestSolr.getVisibleRect());
lbTestSolrWarning.setText("");
lbTestSolrWarning.paintImmediately(lbTestSolrWarning.getVisibleRect());
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);

View File

@ -100,7 +100,7 @@
<Component id="hideOtherUsersTagsCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="centralRepoLabel" min="-2" max="-2" attributes="0"/>
<Component id="scoColumnsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="135" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="272" max="-2" attributes="0"/>
</Group>
@ -129,11 +129,11 @@
</Group>
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="commentsOccurencesColumnsCheckbox" min="-2" max="-2" attributes="0"/>
<Component id="scoColumnsCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="32" max="-2" attributes="0"/>
<Component id="commentsOccurencesColumnWrapAroundText" min="-2" max="-2" attributes="0"/>
<Component id="scoColumnsWrapAroundText" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
@ -185,11 +185,11 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="hideOtherUsersTagsCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="centralRepoLabel" min="-2" max="-2" attributes="0"/>
<Component id="scoColumnsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
<Component id="commentsOccurencesColumnsCheckbox" min="-2" pref="18" max="-2" attributes="0"/>
<Component id="scoColumnsCheckbox" min="-2" pref="18" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="commentsOccurencesColumnWrapAroundText" min="-2" max="-2" attributes="0"/>
<Component id="scoColumnsWrapAroundText" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="selectFileLabel" min="-2" max="-2" attributes="0"/>
@ -353,22 +353,22 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="centralRepoLabel">
<Component class="javax.swing.JLabel" name="scoColumnsLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.centralRepoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.scoColumnsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="commentsOccurencesColumnsCheckbox">
<Component class="javax.swing.JCheckBox" name="scoColumnsCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.commentsOccurencesColumnsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.scoColumnsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="horizontalAlignment" type="int" value="11"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="commentsOccurencesColumnsCheckboxActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="scoColumnsCheckboxActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
@ -400,10 +400,10 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="commentsOccurencesColumnWrapAroundText">
<Component class="javax.swing.JLabel" name="scoColumnsWrapAroundText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.commentsOccurencesColumnWrapAroundText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.scoColumnsWrapAroundText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>

View File

@ -80,9 +80,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
dataSourcesHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree());
viewsHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInViewsTree());
commentsOccurencesColumnsCheckbox.setEnabled(EamDb.isEnabled());
commentsOccurencesColumnWrapAroundText.setEnabled(EamDb.isEnabled());
commentsOccurencesColumnsCheckbox.setSelected(UserPreferences.hideCentralRepoCommentsAndOccurrences());
scoColumnsCheckbox.setSelected(UserPreferences.getHideSCOColumns());
hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags());
fileNameTranslationColumnCheckbox.setSelected(UserPreferences.displayTranslatedFileNames());
@ -119,7 +117,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCheckbox.isSelected());
UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected());
UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected());
UserPreferences.setHideCentralRepoCommentsAndOccurrences(commentsOccurencesColumnsCheckbox.isSelected());
UserPreferences.setHideSCOColumns(scoColumnsCheckbox.isSelected());
UserPreferences.setDisplayTranslatedFileNames(fileNameTranslationColumnCheckbox.isSelected());
UserPreferences.setResultsTablePageSize((int)maxResultsSpinner.getValue());
@ -168,12 +166,12 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
useAnotherTimeRadioButton = new javax.swing.JRadioButton();
hideOtherUsersTagsCheckbox = new javax.swing.JCheckBox();
hideOtherUsersTagsLabel = new javax.swing.JLabel();
centralRepoLabel = new javax.swing.JLabel();
commentsOccurencesColumnsCheckbox = new javax.swing.JCheckBox();
scoColumnsLabel = new javax.swing.JLabel();
scoColumnsCheckbox = new javax.swing.JCheckBox();
jScrollPane1 = new javax.swing.JScrollPane();
timeZoneList = new javax.swing.JList<>();
translateTextLabel = new javax.swing.JLabel();
commentsOccurencesColumnWrapAroundText = new javax.swing.JLabel();
scoColumnsWrapAroundText = new javax.swing.JLabel();
fileNameTranslationColumnCheckbox = new javax.swing.JCheckBox();
maxResultsLabel = new javax.swing.JLabel();
maxResultsSpinner = new javax.swing.JSpinner();
@ -266,13 +264,13 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
org.openide.awt.Mnemonics.setLocalizedText(hideOtherUsersTagsLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideOtherUsersTagsLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(centralRepoLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.centralRepoLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(scoColumnsLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.scoColumnsLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(commentsOccurencesColumnsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.commentsOccurencesColumnsCheckbox.text")); // NOI18N
commentsOccurencesColumnsCheckbox.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
commentsOccurencesColumnsCheckbox.addActionListener(new java.awt.event.ActionListener() {
org.openide.awt.Mnemonics.setLocalizedText(scoColumnsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.scoColumnsCheckbox.text")); // NOI18N
scoColumnsCheckbox.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
scoColumnsCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
commentsOccurencesColumnsCheckboxActionPerformed(evt);
scoColumnsCheckboxActionPerformed(evt);
}
});
@ -285,7 +283,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
org.openide.awt.Mnemonics.setLocalizedText(translateTextLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.translateTextLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(commentsOccurencesColumnWrapAroundText, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.commentsOccurencesColumnWrapAroundText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(scoColumnsWrapAroundText, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.scoColumnsWrapAroundText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(fileNameTranslationColumnCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.fileNameTranslationColumnCheckbox.text")); // NOI18N
fileNameTranslationColumnCheckbox.addActionListener(new java.awt.event.ActionListener() {
@ -315,7 +313,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
.addGap(10, 10, 10)
.addComponent(hideOtherUsersTagsCheckbox))
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
.addComponent(centralRepoLabel)
.addComponent(scoColumnsLabel)
.addGap(135, 135, 135)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(hideOtherUsersTagsLabel)
@ -337,10 +335,10 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
.addComponent(viewsHideKnownCheckbox))))
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(commentsOccurencesColumnsCheckbox))
.addComponent(scoColumnsCheckbox))
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
.addGap(32, 32, 32)
.addComponent(commentsOccurencesColumnWrapAroundText)))
.addComponent(scoColumnsWrapAroundText)))
.addGap(18, 18, 18)
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(displayTimeLabel)
@ -382,11 +380,11 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(hideOtherUsersTagsCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(centralRepoLabel)
.addComponent(scoColumnsLabel)
.addGap(3, 3, 3)
.addComponent(commentsOccurencesColumnsCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(scoColumnsCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(commentsOccurencesColumnWrapAroundText))
.addComponent(scoColumnsWrapAroundText))
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
.addComponent(selectFileLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@ -523,13 +521,13 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
}
}//GEN-LAST:event_timeZoneListValueChanged
private void commentsOccurencesColumnsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_commentsOccurencesColumnsCheckboxActionPerformed
private void scoColumnsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_scoColumnsCheckboxActionPerformed
if (immediateUpdates) {
UserPreferences.setHideCentralRepoCommentsAndOccurrences(commentsOccurencesColumnsCheckbox.isSelected());
UserPreferences.setHideSCOColumns(scoColumnsCheckbox.isSelected());
} else {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
}//GEN-LAST:event_commentsOccurencesColumnsCheckboxActionPerformed
}//GEN-LAST:event_scoColumnsCheckboxActionPerformed
private void hideOtherUsersTagsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideOtherUsersTagsCheckboxActionPerformed
if (immediateUpdates) {
@ -631,9 +629,6 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel centralRepoLabel;
private javax.swing.JLabel commentsOccurencesColumnWrapAroundText;
private javax.swing.JCheckBox commentsOccurencesColumnsCheckbox;
private javax.swing.JPanel currentCaseSettingsPanel;
private javax.swing.JPanel currentSessionSettingsPanel;
private javax.swing.JCheckBox dataSourcesHideKnownCheckbox;
@ -651,6 +646,9 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
private javax.swing.JRadioButton keepCurrentViewerRadioButton;
private javax.swing.JLabel maxResultsLabel;
private javax.swing.JSpinner maxResultsSpinner;
private javax.swing.JCheckBox scoColumnsCheckbox;
private javax.swing.JLabel scoColumnsLabel;
private javax.swing.JLabel scoColumnsWrapAroundText;
private javax.swing.JLabel selectFileLabel;
private javax.swing.JList<String> timeZoneList;
private javax.swing.JLabel translateTextLabel;

View File

@ -22,7 +22,6 @@
package org.sleuthkit.autopsy.coreutils;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.io.Files;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
@ -122,7 +121,7 @@ public class ImageUtils {
}
DEFAULT_THUMBNAIL = tempImage;
boolean tempFfmpegLoaded = false;
if (OpenCvLoader.isOpenCvLoaded()) {
if (OpenCvLoader.hasOpenCvLoaded()) {
try {
if (System.getProperty("os.arch").equals("amd64") || System.getProperty("os.arch").equals("x86_64")) { //NON-NLS
System.loadLibrary("opencv_ffmpeg248_64"); //NON-NLS

View File

@ -199,7 +199,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
//Set the tooltip
this.setShortDescription(content.getName());
updateSheet(new NodeProperty<>(ORIGINAL_NAME.toString(), ORIGINAL_NAME.toString(), NO_DESCR, content.getName()));
} else if (eventType.equals(NodeSpecificEvents.SCO_AVAILABLE.toString())) {
} else if (eventType.equals(NodeSpecificEvents.SCO_AVAILABLE.toString()) && !UserPreferences.getHideSCOColumns()) {
SCOData scoData = (SCOData) evt.getNewValue();
if (scoData.getScoreAndDescription() != null) {
updateSheet(new NodeProperty<>(SCORE.toString(), SCORE.toString(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft()));
@ -207,8 +207,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
if (scoData.getComment() != null) {
updateSheet(new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), NO_DESCR, scoData.getComment()));
}
if (scoData.getCountAndDescription() != null
&& !UserPreferences.hideCentralRepoCommentsAndOccurrences()) {
if (scoData.getCountAndDescription() != null) {
updateSheet(new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
}
}
@ -325,10 +324,12 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
}
// Create place holders for S C O
properties.add(new NodeProperty<>(SCORE.toString(), SCORE.toString(), VALUE_LOADING, ""));
properties.add(new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), VALUE_LOADING, ""));
if (EamDb.isEnabled() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
properties.add(new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), VALUE_LOADING, ""));
if (!UserPreferences.getHideSCOColumns()) {
properties.add(new NodeProperty<>(SCORE.toString(), SCORE.toString(), VALUE_LOADING, ""));
properties.add(new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), VALUE_LOADING, ""));
if (EamDb.isEnabled()) {
properties.add(new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), VALUE_LOADING, ""));
}
}
// Get the SCO columns data in a background task
@ -393,10 +394,11 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
@NbBundle.Messages({
"AbstractAbstractFileNode.createSheet.count.displayName=O",
"AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated",
"# {0} - occurenceCount",
"AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurences of the MD5 correlation value"})
"# {0} - occurrenceCount",
"AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the MD5 correlation value"})
@Override
protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription) {
protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue,
String defaultDescription) {
Long count = -1L; //The column renderer will not display negative values, negative value used when count unavailble to preserve sorting
String description = defaultDescription;
try {
@ -535,7 +537,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
@Override
protected CorrelationAttributeInstance getCorrelationAttributeInstance() {
CorrelationAttributeInstance attribute = null;
if (EamDb.isEnabled() && !UserPreferences.hideCentralRepoCommentsAndOccurrences()) {
if (EamDb.isEnabled() && !UserPreferences.getHideSCOColumns()) {
attribute = EamArtifactUtil.getInstanceFromContent(content);
}
return attribute;

View File

@ -152,7 +152,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
removeListeners();
contentCache.invalidateAll();
}
} else if (eventType.equals(NodeSpecificEvents.SCO_AVAILABLE.toString())) {
} else if (eventType.equals(NodeSpecificEvents.SCO_AVAILABLE.toString()) && !UserPreferences.getHideSCOColumns()) {
SCOData scoData = (SCOData) evt.getNewValue();
if (scoData.getScoreAndDescription() != null) {
updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft()));
@ -160,8 +160,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
if (scoData.getComment() != null) {
updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, scoData.getComment()));
}
if (scoData.getCountAndDescription() != null
&& !UserPreferences.hideCentralRepoCommentsAndOccurrences()) {
if (scoData.getCountAndDescription() != null) {
updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
}
}
@ -364,10 +363,12 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
this.getSourceName()));
// Create place holders for S C O
sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), VALUE_LOADING, ""));
sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), VALUE_LOADING, ""));
if (EamDb.isEnabled() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), VALUE_LOADING, ""));
if (!UserPreferences.getHideSCOColumns()) {
sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), VALUE_LOADING, ""));
sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), VALUE_LOADING, ""));
if (EamDb.isEnabled()) {
sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), VALUE_LOADING, ""));
}
}
// Get the SCO columns data in a background task
@ -747,7 +748,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
"BlackboardArtifactNode.createSheet.count.displayName=O",
"BlackboardArtifactNode.createSheet.count.noCorrelationAttributes.description=No correlation properties found",
"BlackboardArtifactNode.createSheet.count.noCorrelationValues.description=Unable to find other occurrences because no value exists for the available correlation property",
"# {0} - occurenceCount",
"# {0} - occurrenceCount",
"# {1} - attributeType",
"BlackboardArtifactNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the correlation value of type {1}"})
@Deprecated

View File

@ -4,8 +4,8 @@ AbstractAbstractFileNode.changeTimeColLbl=Change Time
AbstractAbstractFileNode.createdTimeColLbl=Created Time
AbstractAbstractFileNode.createSheet.comment.displayName=C
AbstractAbstractFileNode.createSheet.comment.name=C
# {0} - occurenceCount
AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurences of the MD5 correlation value
# {0} - occurrenceCount
AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the MD5 correlation value
AbstractAbstractFileNode.createSheet.count.displayName=O
AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated
AbstractAbstractFileNode.createSheet.count.name=O
@ -53,7 +53,7 @@ BlackboardArtifactNode.createSheet.artifactType.displayName=Result Type
BlackboardArtifactNode.createSheet.artifactType.name=Result Type
BlackboardArtifactNode.createSheet.comment.displayName=C
BlackboardArtifactNode.createSheet.comment.name=C
# {0} - occurenceCount
# {0} - occurrenceCount
# {1} - attributeType
BlackboardArtifactNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the correlation value of type {1}
BlackboardArtifactNode.createSheet.count.displayName=O

View File

@ -72,7 +72,7 @@ class GetSCOTask implements Runnable {
scoData.setScoreAndDescription(contentNode.getScorePropertyAndDescription(tags));
scoData.setComment(contentNode.getCommentProperty(tags, fileAttribute));
if (EamDb.isEnabled() && !UserPreferences.hideCentralRepoCommentsAndOccurrences()) {
if (EamDb.isEnabled() && !UserPreferences.getHideSCOColumns()) {
Type type = null;
String value = null;
String description = Bundle.GetSCOTask_occurrences_defaultDescription();

View File

@ -219,7 +219,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
case UserPreferences.TIME_ZONE_FOR_DISPLAYS:
case UserPreferences.HIDE_KNOWN_FILES_IN_DATA_SRCS_TREE:
case UserPreferences.HIDE_SLACK_FILES_IN_DATA_SRCS_TREE:
case UserPreferences.HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES:
case UserPreferences.HIDE_SCO_COLUMNS:
case UserPreferences.DISPLAY_TRANSLATED_NAMES:
case UserPreferences.KEEP_PREFERRED_VIEWER:
refreshContentTreeSafe();

View File

@ -43,31 +43,21 @@ ConfigVisualPanel2.jCheckBox2.text=jCheckBox2
ConfigVisualPanel2.jTextField1.text=jTextField1
ConfigVisualPanel1.jRadioButton1.text=Create new configuration
ConfigVisualPanel1.jRadioButton2.text=Open existing configuration
ConfigVisualPanel1.jLabel1.text_1=Configuration file:
ConfigVisualPanel1.configFileTextField.text_1=
ConfigVisualPanel2.modifiedDateLabel.text=Modified Within:
ConfigVisualPanel2.folderNamesLabel.text=Folder names:
ConfigVisualPanel2.finalizeImageWriter.text=Continue imaging after searches are performed
ConfigVisualPanel2.filenamesLabel.text=File names:
ConfigVisualPanel2.extensionsTextField.text=
ConfigVisualPanel2.shouldAlertCheckBox.text=Alert in imager console if rule matches
ConfigVisualPanel2.shouldSaveCheckBox.text=Extract file if it matches a rule
ConfigVisualPanel2.deleteRuleButton.text=Delete Rule
ConfigVisualPanel2.descriptionEditTextField.text=
ConfigVisualPanel2.editRuleButton.text=Edit Rule
ConfigVisualPanel2.newRuleButton.text=New Rule
ConfigVisualPanel2.ruleNameEditTextField.text=
ConfigVisualPanel2.flagEncryptionProgramsCheckBox.text=Alert if encryption programs are found
ConfigVisualPanel2.fullPathsLabel.text=Full paths:
ConfigVisualPanel2.daysIncludedLabel.text=day(s)
ConfigVisualPanel2.daysIncludedTextField.text=
ConfigVisualPanel2.configFileTextField.toolTipText=
ConfigVisualPanel2.configFileTextField.text=
ConfigVisualPanel2.filenamesTable.columnModel.title0=
ConfigVisualPanel2.fileSizeLabel.text=File size in bytes:
ConfigVisualPanel2.extensionsLabel.text=Extensions:
ConfigVisualPanel2.descriptionLabel.text=Description:
ConfigVisualPanel2.ruleNameLabel.text=Rule Name:
ConfigVisualPanel2.ruleNameLabel.text=Rule name:
ConfigVisualPanel2.ruleSetFileLabel.text=Configuration rule file:
EditRulePanel.ruleNameLabel.text=Rule Set:
EditRulePanel.descriptionTextField.text=
@ -85,45 +75,48 @@ EditRulePanel.jTable1.columnModel.title3=Title 4
EditRulePanel.jTable1.columnModel.title2=Title 3
EditRulePanel.jTable1.columnModel.title1=Title 2
EditRulePanel.shouldAlertCheckBox.actionCommand=
EditFullPathsRulePanel.ruleNameLabel.text=Rule Name:
EditFullPathsRulePanel.descriptionLabel.text=Description:
EditFullPathsRulePanel.descriptionTextField.text=
EditFullPathsRulePanel.ruleNameLabel.text=Rule name:
EditFullPathsRulePanel.shouldAlertCheckBox.actionCommand=
EditFullPathsRulePanel.shouldAlertCheckBox.text=Alert in imager console if rule matches
EditFullPathsRulePanel.shouldSaveCheckBox.text=Extract file if it matches a rule
EditFullPathsRulePanel.ruleNameTextField.text=
EditFullPathsRulePanel.shouldAlertCheckBox.text=Alert in imager console if a path matches
EditFullPathsRulePanel.shouldSaveCheckBox.text=Extract file if it matches a path
EditFullPathsRulePanel.fullPathsLabel.text=Full paths:
EditFullPathsRulePanel.fullPathsLabel.toolTipText=
EditNonFullPathsRulePanel.ruleNameTextField.text=
EditNonFullPathsRulePanel.ruleNameLabel.text=Rule Name:
EditNonFullPathsRulePanel.descriptionLabel.text=Description:
EditNonFullPathsRulePanel.descriptionTextField.text=
EditNonFullPathsRulePanel.shouldSaveCheckBox.text=Extract file if it matches a rule
EditNonFullPathsRulePanel.ruleNameLabel.text=Rule name:
EditNonFullPathsRulePanel.shouldSaveCheckBox.text=Extract file if it matches a condition
EditNonFullPathsRulePanel.daysIncludedLabel.text=day(s)
EditNonFullPathsRulePanel.modifiedDateLabel.text=Modified Within:
EditNonFullPathsRulePanel.fileSizeLabel.text=File size (bytes):
EditNonFullPathsRulePanel.folderNamesLabel.text=Folder names:
EditNonFullPathsRulePanel.filenamesLabel.text=File names:
EditNonFullPathsRulePanel.extensionsTextField.text=
EditNonFullPathsRulePanel.extensionsLabel.text=Extensions:
EditNonFullPathsRulePanel.shouldAlertCheckBox.actionCommand=
EditNonFullPathsRulePanel.shouldAlertCheckBox.text=Alert in imager console if rule matches
EditNonFullPathsRulePanel.shouldAlertCheckBox.text=Alert in imager console if a condition matches
ConfigVisualPanel1.browseButton.text=Browse
ConfigVisualPanel2.fullPathsTable.columnModel.title0=
ConfigVisualPanel2.folderNamesTable.columnModel.title0=
ConfigVisualPanel2.shouldSaveCheckBox.toolTipText=
NewRuleSetPanel.chooseLabel.text=Choose the type of rule
EditNonFullPathsRulePanel.minSizeLabel.text=Minimum:
EditNonFullPathsRulePanel.maxSizeLabel.text=Maximum:
EditNonFullPathsRulePanel.minSizeTextField.text=
EditNonFullPathsRulePanel.maxSizeTextField.text=
ConfigVisualPanel2.maxSizeTextField.text=
ConfigVisualPanel2.maxSizeLabel.text=Maximum:
ConfigVisualPanel2.minSizeTextField.text=
ConfigVisualPanel2.minSizeLabel.text=Minimum:
EditNonFullPathsRulePanel.minDaysTextField.text=jFormattedTextField1
ConfigVisualPanel1.browseButton.toolTipText=
EditNonFullPathsRulePanel.extensionsRadioButton.text=
EditNonFullPathsRulePanel.filenamesRadioButton.text=
EditNonFullPathsRulePanel.extensionsRadioButton.toolTipText=Extensions and File names are mutually exclusive
EditNonFullPathsRulePanel.filenamesRadioButton.toolTipText=Extensions and File names are mutually exclusive
EditNonFullPathsRulePanel.userFolderNote.text=Starting a folder name with the token [USER_FOLDER] will allow matches of all user folders in the file system.
EditNonFullPathsRulePanel.modifiedWithinCheckbox.text=Modified within:
EditNonFullPathsRulePanel.folderNamesCheckbox.text=Folder names:
EditNonFullPathsRulePanel.fileNamesCheckbox.text=File names:
EditNonFullPathsRulePanel.extensionsCheckbox.text=Extensions:
EditNonFullPathsRulePanel.filenamesScrollPane.toolTipText=
EditNonFullPathsRulePanel.maxSizeCheckbox.text=Maximum size:
EditNonFullPathsRulePanel.minSizeCheckbox.text=Minimum size:
NewRulePanel.chooseLabel.text=Choose the type of rule
ConfigVisualPanel1.configureDriveRadioButton.text_1=Configure selected external drive:
ConfigVisualPanel1.configureFolderRadioButton.text_1=Configure in a folder:
ConfigVisualPanel1.descriptionTextArea.text=Select a location for the Logical Imager. This location will contain the imaging program and a configuration file. If that location already contains a configuration file, it will be loaded to edit. Imaging results will be saved to this location, so ensure it has enough free space.
ConfigVisualPanel1.refreshButton.text=Refresh
ConfigVisualPanel3.saveButton.text=Save
ConfigVisualPanel3.configLabel.text=Logical Imager config file save status:
ConfigVisualPanel3.executableLabel.text=Logical Imager executable save status:
ConfigVisualPanel3.executableStatusLabel.text=
EditFullPathsRulePanel.jLabel1.text=Description (Optional):
EditNonFullPathsRulePanel.jLabel2.text=Folder name matches are case insensitive and occur anywhere in a path.
EditNonFullPathsRulePanel.descriptionLabel.text=Description (Optional):
EditNonFullPathsRulePanel.jLabel1.text=If file is found:
EditFullPathsRulePanel.jLabel2.text=If file is found:
ConfigVisualPanel2.flagEncryptionProgramsCheckBox.text=Alert if encryption programs are found
ConfigVisualPanel2.finalizeImageWriter.text=Continue imaging after searches are performed
EditNonFullPathsRulePanel.fileNamesInfoLabel.text=File names are case insensitive.
EditNonFullPathsRulePanel.extensionsInfoLabel.text=Extensions are case insensitive.

View File

@ -1,4 +1,3 @@
ConfigureLogicalImager.title=Configure Logical Imager
ConfigureLogicalImagerDialog.loadButton.text=Load
ConfigureLogicalImagerDialog.newButton.text=New
ConfigureLogicalImagerDialog.title=Configure Logical Imager
@ -29,22 +28,33 @@ ConfigVisualPanel1.configFileIsEmpty=Configuration file {0} is empty
ConfigVisualPanel1.configurationError=Configuration error
ConfigVisualPanel1.fileNameExtensionFilter=Configuration JSON File
ConfigVisualPanel1.invalidConfigJson=Invalid config JSON:
ConfigVisualPanel1.selectConfigurationFile=Select configuration file
ConfigVisualPanel1.messageLabel.noExternalDriveFound=No drive found
ConfigVisualPanel1.selectConfigurationFile=Select location
ConfigVisualPanel2.cancel=Cancel
ConfigVisualPanel2.deleteRuleSet=Delete rule
ConfigVisualPanel2.deleteRuleSetConfirmation=Delete rule confirmation
ConfigVisualPanel2.editConfiguration=Edit configuration
ConfigVisualPanel2.editConfiguration=Configure imager
ConfigVisualPanel2.editRuleError=Edit rule error
ConfigVisualPanel2.editRuleSet=Edit rule
ConfigVisualPanel2.editRuleSet=Edit Rule
ConfigVisualPanel2.newRule.name=New Rule
ConfigVisualPanel2.ok=OK
ConfigVisualPanel2.rulesTable.columnModel.title0=Rule Name
ConfigVisualPanel2.rulesTable.columnModel.title1=Description
ConfigVisualPanel3.copyStatus.error=Unable to save file
ConfigVisualPanel3.copyStatus.notSaved=File has not been saved
ConfigVisualPanel3.copyStatus.saved=Saved
ConfigVisualPanel3.copyStatus.savingInProgress=Saving file, please wait
# {0} - configurationLocation
ConfigVisualPanel3.description.text=Press Save to write the imaging tool and configuration file to the destination.\nDestination: {0}
ConfigVisualPanel3.errorMsg.cannotFindLogicalImager=Cannot locate logical imager, cannot copy to destination
# {0} - configFilename
ConfigWizardPanel2.failedToSaveConfigMsg=Failed to save configuration file: {0}
ConfigWizardPanel2.failedToSaveExeMsg=Failed to save tsk_logical_imager.exe file
ConfigVisualPanel3.failedToSaveConfigMsg=Failed to save configuration file: {0}
ConfigVisualPanel3.failedToSaveExeMsg=Failed to save tsk_logical_imager.exe file
# {0} - reason
ConfigWizardPanel2.reason=\nReason:
CTL_ConfigureLogicalImager=Create Logical Imager
ConfigVisualPanel3.reason=\nReason: {0}
ConfigVisualPanel3.saveConfigurationFile=Save imager
CreateLogicalImagerAction.title=Create Logical Imager
CTL_CreateLogicalImagerAction=Create Logical Imager
EditFullPathsRulePanel.example=Example:
EditFullPathsRulePanel.fullPaths=Full paths
EditNonFullPathsRulePanel.emptyExtensionException=Extensions cannot have an empty entry
@ -56,16 +66,22 @@ EditNonFullPathsRulePanel.maxFileSizeMustBeNumberException=Maximum file size mus
EditNonFullPathsRulePanel.maxFileSizeNotPositiveException=Maximum file size must be a positive
# {0} - maxFileSize
# {1} - minFileSize
EditNonFullPathsRulePanel.maxFileSizeSmallerThanMinException=Maximum file size: {0} must be bigger than minimum file size: {1}
EditNonFullPathsRulePanel.maxFileSizeSmallerThanMinException=Maximum file size: {0} bytes must be bigger than minimum file size: {1} bytes
# {0} - message
EditNonFullPathsRulePanel.minFileSizeMustBeNumberException=Minimum file size must be a number: {0}
EditNonFullPathsRulePanel.minFileSizeNotPositiveException=Minimum file size must be a positive
# {0} - message
EditNonFullPathsRulePanel.modifiedDaysMustBeNumberException=Modified days must be a number: {0}
EditNonFullPathsRulePanel.modifiedDaysNotPositiveException=Modified days must be a positive
EditNonFullPathsRulePanel.note=NOTE: A special [USER_FOLDER] token at the the start of a folder name to allow matches of all user folders in the file system.
EditNonFullPathsRulePanel.units.bytes=Bytes
EditNonFullPathsRulePanel.units.gigabytes=Gigabytes
EditNonFullPathsRulePanel.units.kilobytes=Kilobytes
EditNonFullPathsRulePanel.units.megabytes=MegaBytes
# {0} - fieldName
EditRulePanel.blankLineException={0} cannot have a blank line
EditRulePanel.emptyRuleName.message=Rule name cannot be empty
# {0} - ruleName
EditRulePanel.reservedRuleName.message=Rule name "{0}" is reserved for use with a predefined rule
EditRulePanel.shouldAlertCheckBox.text=Alert in imager console if rule matches
EditRulePanel.shouldSaveCheckBox.text=Extract file if it matches a rule
EditRulePanel.fullPathsLabel.text=Full paths:
@ -87,31 +103,21 @@ ConfigVisualPanel2.jCheckBox2.text=jCheckBox2
ConfigVisualPanel2.jTextField1.text=jTextField1
ConfigVisualPanel1.jRadioButton1.text=Create new configuration
ConfigVisualPanel1.jRadioButton2.text=Open existing configuration
ConfigVisualPanel1.jLabel1.text_1=Configuration file:
ConfigVisualPanel1.configFileTextField.text_1=
ConfigVisualPanel2.modifiedDateLabel.text=Modified Within:
ConfigVisualPanel2.folderNamesLabel.text=Folder names:
ConfigVisualPanel2.finalizeImageWriter.text=Continue imaging after searches are performed
ConfigVisualPanel2.filenamesLabel.text=File names:
ConfigVisualPanel2.extensionsTextField.text=
ConfigVisualPanel2.shouldAlertCheckBox.text=Alert in imager console if rule matches
ConfigVisualPanel2.shouldSaveCheckBox.text=Extract file if it matches a rule
ConfigVisualPanel2.deleteRuleButton.text=Delete Rule
ConfigVisualPanel2.descriptionEditTextField.text=
ConfigVisualPanel2.editRuleButton.text=Edit Rule
ConfigVisualPanel2.newRuleButton.text=New Rule
ConfigVisualPanel2.ruleNameEditTextField.text=
ConfigVisualPanel2.flagEncryptionProgramsCheckBox.text=Alert if encryption programs are found
ConfigVisualPanel2.fullPathsLabel.text=Full paths:
ConfigVisualPanel2.daysIncludedLabel.text=day(s)
ConfigVisualPanel2.daysIncludedTextField.text=
ConfigVisualPanel2.configFileTextField.toolTipText=
ConfigVisualPanel2.configFileTextField.text=
ConfigVisualPanel2.filenamesTable.columnModel.title0=
ConfigVisualPanel2.fileSizeLabel.text=File size in bytes:
ConfigVisualPanel2.extensionsLabel.text=Extensions:
ConfigVisualPanel2.descriptionLabel.text=Description:
ConfigVisualPanel2.ruleNameLabel.text=Rule Name:
ConfigVisualPanel2.ruleNameLabel.text=Rule name:
ConfigVisualPanel2.ruleSetFileLabel.text=Configuration rule file:
EditRulePanel.ruleNameLabel.text=Rule Set:
EditRulePanel.descriptionTextField.text=
@ -129,52 +135,58 @@ EditRulePanel.jTable1.columnModel.title3=Title 4
EditRulePanel.jTable1.columnModel.title2=Title 3
EditRulePanel.jTable1.columnModel.title1=Title 2
EditRulePanel.shouldAlertCheckBox.actionCommand=
EditFullPathsRulePanel.ruleNameLabel.text=Rule Name:
EditFullPathsRulePanel.descriptionLabel.text=Description:
EditFullPathsRulePanel.descriptionTextField.text=
EditFullPathsRulePanel.ruleNameLabel.text=Rule name:
EditFullPathsRulePanel.shouldAlertCheckBox.actionCommand=
EditFullPathsRulePanel.shouldAlertCheckBox.text=Alert in imager console if rule matches
EditFullPathsRulePanel.shouldSaveCheckBox.text=Extract file if it matches a rule
EditFullPathsRulePanel.ruleNameTextField.text=
EditFullPathsRulePanel.shouldAlertCheckBox.text=Alert in imager console if a path matches
EditFullPathsRulePanel.shouldSaveCheckBox.text=Extract file if it matches a path
EditFullPathsRulePanel.fullPathsLabel.text=Full paths:
EditFullPathsRulePanel.fullPathsLabel.toolTipText=
EditNonFullPathsRulePanel.ruleNameTextField.text=
EditNonFullPathsRulePanel.ruleNameLabel.text=Rule Name:
EditNonFullPathsRulePanel.descriptionLabel.text=Description:
EditNonFullPathsRulePanel.descriptionTextField.text=
EditNonFullPathsRulePanel.shouldSaveCheckBox.text=Extract file if it matches a rule
EditNonFullPathsRulePanel.ruleNameLabel.text=Rule name:
EditNonFullPathsRulePanel.shouldSaveCheckBox.text=Extract file if it matches a condition
EditNonFullPathsRulePanel.daysIncludedLabel.text=day(s)
EditNonFullPathsRulePanel.modifiedDateLabel.text=Modified Within:
EditNonFullPathsRulePanel.fileSizeLabel.text=File size (bytes):
EditNonFullPathsRulePanel.folderNamesLabel.text=Folder names:
EditNonFullPathsRulePanel.filenamesLabel.text=File names:
EditNonFullPathsRulePanel.extensionsTextField.text=
EditNonFullPathsRulePanel.extensionsLabel.text=Extensions:
EditNonFullPathsRulePanel.shouldAlertCheckBox.actionCommand=
EditNonFullPathsRulePanel.shouldAlertCheckBox.text=Alert in imager console if rule matches
EditNonFullPathsRulePanel.shouldAlertCheckBox.text=Alert in imager console if a condition matches
ConfigVisualPanel1.browseButton.text=Browse
ConfigVisualPanel2.fullPathsTable.columnModel.title0=
ConfigVisualPanel2.folderNamesTable.columnModel.title0=
ConfigVisualPanel2.shouldSaveCheckBox.toolTipText=
EditRulePanel.validateRuleNameExceptionMsg=Rule name cannot be empty
ConfigVisualPanel2.maxSizeLabel.text=Maximum:
ConfigVisualPanel2.minSizeLabel.text=Minimum:
EditNonFullPathsRulePanel.minDaysTextField.text=jFormattedTextField1
ConfigVisualPanel1.browseButton.toolTipText=
EditNonFullPathsRulePanel.userFolderNote.text=Starting a folder name with the token [USER_FOLDER] will allow matches of all user folders in the file system.
EditNonFullPathsRulePanel.modifiedWithinCheckbox.text=Modified within:
EditNonFullPathsRulePanel.folderNamesCheckbox.text=Folder names:
EditNonFullPathsRulePanel.fileNamesCheckbox.text=File names:
EditNonFullPathsRulePanel.extensionsCheckbox.text=Extensions:
EditNonFullPathsRulePanel.filenamesScrollPane.toolTipText=
EditNonFullPathsRulePanel.maxSizeCheckbox.text=Maximum size:
EditNonFullPathsRulePanel.minSizeCheckbox.text=Minimum size:
EncryptionProgramsRule.encryptionProgramsRuleDescription=Find encryption programs
EncryptionProgramsRule.encryptionProgramsRuleName=Encryption Programs
LogicalImagerConfigDeserializer.fullPathsException=A rule with full-paths cannot have other rule definitions
LogicalImagerConfigDeserializer.missingRuleSetException=Missing rule-set
# {0} - key
LogicalImagerConfigDeserializer.unsupportedKeyException=Unsupported key: {0}
NewRuleSetPanel.chooseLabel.text=Choose the type of rule
EditNonFullPathsRulePanel.minSizeLabel.text=Minimum:
EditNonFullPathsRulePanel.maxSizeLabel.text=Maximum:
EditNonFullPathsRulePanel.minSizeTextField.text=
EditNonFullPathsRulePanel.maxSizeTextField.text=
ConfigVisualPanel2.maxSizeTextField.text=
ConfigVisualPanel2.maxSizeLabel.text=Maximum:
ConfigVisualPanel2.minSizeTextField.text=
ConfigVisualPanel2.minSizeLabel.text=Minimum:
EditNonFullPathsRulePanel.minDaysTextField.text=jFormattedTextField1
ConfigVisualPanel1.browseButton.toolTipText=
EditNonFullPathsRulePanel.extensionsRadioButton.text=
EditNonFullPathsRulePanel.filenamesRadioButton.text=
EditNonFullPathsRulePanel.extensionsRadioButton.toolTipText=Extensions and File names are mutually exclusive
EditNonFullPathsRulePanel.filenamesRadioButton.toolTipText=Extensions and File names are mutually exclusive
NewRulePanel.chooseLabel.text=Choose the type of rule
ConfigVisualPanel1.configureDriveRadioButton.text_1=Configure selected external drive:
ConfigVisualPanel1.configureFolderRadioButton.text_1=Configure in a folder:
ConfigVisualPanel1.descriptionTextArea.text=Select a location for the Logical Imager. This location will contain the imaging program and a configuration file. If that location already contains a configuration file, it will be loaded to edit. Imaging results will be saved to this location, so ensure it has enough free space.
ConfigVisualPanel1.refreshButton.text=Refresh
ConfigVisualPanel3.saveButton.text=Save
ConfigVisualPanel3.configLabel.text=Logical Imager config file save status:
ConfigVisualPanel3.executableLabel.text=Logical Imager executable save status:
ConfigVisualPanel3.executableStatusLabel.text=
EditFullPathsRulePanel.jLabel1.text=Description (Optional):
EditNonFullPathsRulePanel.jLabel2.text=Folder name matches are case insensitive and occur anywhere in a path.
EditNonFullPathsRulePanel.descriptionLabel.text=Description (Optional):
EditNonFullPathsRulePanel.jLabel1.text=If file is found:
EditFullPathsRulePanel.jLabel2.text=If file is found:
ConfigVisualPanel2.flagEncryptionProgramsCheckBox.text=Alert if encryption programs are found
ConfigVisualPanel2.finalizeImageWriter.text=Continue imaging after searches are performed
EditNonFullPathsRulePanel.fileNamesInfoLabel.text=File names are case insensitive.
EditNonFullPathsRulePanel.extensionsInfoLabel.text=Extensions are case insensitive.
NewRuleSetPanel.attributeRule.description=Search for files based on one or more attributes or metadata fields.
NewRuleSetPanel.attributeRule.name=Attribute
NewRuleSetPanel.fullPathRule.description=Search for files based on full exact match path.
NewRuleSetPanel.fullPathRule.name=Full Path

View File

@ -2,7 +2,7 @@
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="buttonGroup1">
<Component class="javax.swing.ButtonGroup" name="configurationLocationButtonGroup">
</Component>
</NonVisualComponents>
<AuxValues>
@ -20,14 +20,31 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="38" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<Component id="configFileTextField" pref="279" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="browseButton" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="warningLabel" max="32767" attributes="0"/>
<Component id="descriptionScrollPane" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="driveListScrollPane" alignment="1" min="-2" pref="437" max="-2" attributes="0"/>
<Component id="configFileTextField" alignment="0" min="-2" pref="437" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="refreshButton" min="-2" pref="87" max="-2" attributes="0"/>
<Component id="browseButton" min="-2" pref="87" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="configureDriveRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="configureFolderRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@ -35,32 +52,37 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="116" max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="configFileTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="browseButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="descriptionScrollPane" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="13" max="-2" attributes="0"/>
<Component id="configureDriveRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="driveListScrollPane" pref="0" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="refreshButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="95" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace pref="141" max="32767" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="configureFolderRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="configFileTextField" min="-2" max="-2" attributes="0"/>
<Component id="browseButton" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="warningLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="60" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel1.jLabel1.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="configFileTextField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel1.configFileTextField.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="browseButton">
@ -71,10 +93,109 @@
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel1.browseButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="browseButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="descriptionScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="descriptionTextArea">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="columns" type="int" value="20"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="0"/>
</Property>
<Property name="lineWrap" type="boolean" value="true"/>
<Property name="rows" type="int" value="4"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel1.descriptionTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="wrapStyleWord" type="boolean" value="true"/>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JRadioButton" name="configureDriveRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="configurationLocationButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel1.configureDriveRadioButton.text_1" 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="configureDriveRadioButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="configureFolderRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="configurationLocationButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel1.configureFolderRadioButton.text_1" 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="configureFolderRadioButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="driveListScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="driveList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
<StringArray count="0"/>
</Property>
<Property name="selectionMode" type="int" value="0"/>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="mouseReleased" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="driveListMouseReleasedSelection"/>
<EventHandler event="keyReleased" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="driveListKeyReleasedSelection"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="refreshButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel1.refreshButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="refreshButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="warningLabel">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -28,14 +28,25 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;
import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.logicalimager.dsp.DriveListUtils;
/**
* Configuration Visual Panel 1
@ -43,9 +54,11 @@ import org.openide.util.NbBundle;
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
final class ConfigVisualPanel1 extends JPanel {
private LogicalImagerConfig config;
private static final Logger logger = Logger.getLogger(ConfigVisualPanel1.class.getName());
private static final long serialVersionUID = 1L;
private static final String DEFAULT_CONFIG_FILE_NAME = "logical-imager-config.json";
private static final String UPDATE_UI_EVENT_NAME = "UPDATE_UI";
private String configFilename;
private boolean newFile = true;
/**
* Creates new form ConfigVisualPanel1
@ -53,10 +66,14 @@ final class ConfigVisualPanel1 extends JPanel {
ConfigVisualPanel1() {
initComponents();
configFileTextField.getDocument().addDocumentListener(new MyDocumentListener(this));
refreshDriveList();
SwingUtilities.invokeLater(() -> {
updateControls();
});
}
@NbBundle.Messages({
"ConfigVisualPanel1.selectConfigurationFile=Select configuration file"
"ConfigVisualPanel1.selectConfigurationFile=Select location"
})
@Override
public String getName() {
@ -71,47 +88,129 @@ final class ConfigVisualPanel1 extends JPanel {
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
buttonGroup1 = new javax.swing.ButtonGroup();
jLabel1 = new javax.swing.JLabel();
configurationLocationButtonGroup = new javax.swing.ButtonGroup();
configFileTextField = new javax.swing.JTextField();
browseButton = new javax.swing.JButton();
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.jLabel1.text_1")); // NOI18N
descriptionScrollPane = new javax.swing.JScrollPane();
descriptionTextArea = new javax.swing.JTextArea();
configureDriveRadioButton = new javax.swing.JRadioButton();
configureFolderRadioButton = new javax.swing.JRadioButton();
driveListScrollPane = new javax.swing.JScrollPane();
driveList = new javax.swing.JList<>();
refreshButton = new javax.swing.JButton();
warningLabel = new javax.swing.JLabel();
configFileTextField.setEditable(false);
configFileTextField.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.configFileTextField.text_1")); // NOI18N
configFileTextField.setEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.browseButton.text")); // NOI18N
browseButton.setToolTipText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.browseButton.toolTipText")); // NOI18N
browseButton.setEnabled(false);
browseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
browseButtonActionPerformed(evt);
}
});
descriptionTextArea.setEditable(false);
descriptionTextArea.setBackground(new java.awt.Color(240, 240, 240));
descriptionTextArea.setColumns(20);
descriptionTextArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
descriptionTextArea.setLineWrap(true);
descriptionTextArea.setRows(4);
descriptionTextArea.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.descriptionTextArea.text")); // NOI18N
descriptionTextArea.setWrapStyleWord(true);
descriptionTextArea.setEnabled(false);
descriptionScrollPane.setViewportView(descriptionTextArea);
configurationLocationButtonGroup.add(configureDriveRadioButton);
configureDriveRadioButton.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(configureDriveRadioButton, org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.configureDriveRadioButton.text_1")); // NOI18N
configureDriveRadioButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
configureDriveRadioButtonActionPerformed(evt);
}
});
configurationLocationButtonGroup.add(configureFolderRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(configureFolderRadioButton, org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.configureFolderRadioButton.text_1")); // NOI18N
configureFolderRadioButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
configureFolderRadioButtonActionPerformed(evt);
}
});
driveList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
driveList.setEnabled(false);
driveList.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
driveListMouseReleasedSelection(evt);
}
});
driveList.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
driveListKeyReleasedSelection(evt);
}
});
driveListScrollPane.setViewportView(driveList);
org.openide.awt.Mnemonics.setLocalizedText(refreshButton, org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.refreshButton.text")); // NOI18N
refreshButton.setEnabled(false);
refreshButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
refreshButtonActionPerformed(evt);
}
});
warningLabel.setForeground(new java.awt.Color(255, 0, 0));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(38, 38, 38)
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1)
.addComponent(configFileTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(browseButton)
.addComponent(warningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(descriptionScrollPane)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(driveListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 437, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(configFileTextField, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 437, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(browseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addComponent(configureDriveRadioButton)
.addComponent(configureFolderRadioButton))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(116, 116, 116)
.addComponent(jLabel1)
.addContainerGap()
.addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(13, 13, 13)
.addComponent(configureDriveRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(driveListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(refreshButton)
.addGap(0, 95, Short.MAX_VALUE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(configureFolderRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(configFileTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(browseButton))
.addContainerGap(141, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(warningLabel)
.addContainerGap(60, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
@ -119,23 +218,99 @@ final class ConfigVisualPanel1 extends JPanel {
"ConfigVisualPanel1.chooseFileTitle=Select a Logical Imager configuration"
})
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
chooseFile(Bundle.ConfigVisualPanel1_chooseFileTitle());
chooseFile(Bundle.ConfigVisualPanel1_chooseFileTitle());
}//GEN-LAST:event_browseButtonActionPerformed
private void configureFolderRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configureFolderRadioButtonActionPerformed
updateControls();
}//GEN-LAST:event_configureFolderRadioButtonActionPerformed
private void configureDriveRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configureDriveRadioButtonActionPerformed
updateControls();
}//GEN-LAST:event_configureDriveRadioButtonActionPerformed
private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
refreshDriveList();
}//GEN-LAST:event_refreshButtonActionPerformed
private void driveListKeyReleasedSelection(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_driveListKeyReleasedSelection
firePropertyChange(UPDATE_UI_EVENT_NAME, false, true); // NON-NLS
}//GEN-LAST:event_driveListKeyReleasedSelection
private void driveListMouseReleasedSelection(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_driveListMouseReleasedSelection
firePropertyChange(UPDATE_UI_EVENT_NAME, false, true); // NON-NLS
}//GEN-LAST:event_driveListMouseReleasedSelection
/**
* Refresh the list of local drives on the current machine
*/
@Messages({"ConfigVisualPanel1.messageLabel.noExternalDriveFound=No drive found"})
private void refreshDriveList() {
List<String> listData = new ArrayList<>();
File[] roots = File.listRoots();
int firstRemovableDrive = -1;
int i = 0;
for (File root : roots) {
String description = FileSystemView.getFileSystemView().getSystemTypeDescription(root);
long spaceInBytes = root.getTotalSpace();
String sizeWithUnit = DriveListUtils.humanReadableByteCount(spaceInBytes, false);
listData.add(root + " (" + description + ") (" + sizeWithUnit + ")");
if (firstRemovableDrive == -1) {
try {
FileStore fileStore = Files.getFileStore(root.toPath());
if ((boolean) fileStore.getAttribute("volume:isRemovable")) { //NON-NLS
firstRemovableDrive = i;
}
} catch (IOException ignored) {
//unable to get this removable drive for default selection will try and select next removable drive by default
logger.log(Level.INFO, "Unable to select first removable drive found", ignored);
}
}
i++;
}
driveList.setListData(listData.toArray(new String[listData.size()]));
if (!listData.isEmpty()) {
// auto-select the first external drive, if any
driveList.setSelectedIndex(firstRemovableDrive == -1 ? 0 : firstRemovableDrive);
firePropertyChange(UPDATE_UI_EVENT_NAME, false, true); // NON-NLS
driveList.requestFocusInWindow();
warningLabel.setText("");
} else {
warningLabel.setText(Bundle.ConfigVisualPanel1_messageLabel_noExternalDriveFound());
}
}
/**
* Update which controls are enabled to reflect the current radio button
* selection.
*/
private void updateControls() {
browseButton.setEnabled(configureFolderRadioButton.isSelected());
refreshButton.setEnabled(configureDriveRadioButton.isSelected());
driveList.setEnabled(configureDriveRadioButton.isSelected());
driveListScrollPane.setEnabled(configureDriveRadioButton.isSelected());
firePropertyChange(UPDATE_UI_EVENT_NAME, false, true); // NON-NLS
}
/**
* Open a file chooser to allow users to choose a json configuration file in
* a folder.
*
* @param title the dialog title
*/
@NbBundle.Messages({
"ConfigVisualPanel1.fileNameExtensionFilter=Configuration JSON File",
"ConfigVisualPanel1.invalidConfigJson=Invalid config JSON: ",
"ConfigVisualPanel1.configurationError=Configuration error",
})
"ConfigVisualPanel1.configurationError=Configuration error",})
private void chooseFile(String title) {
final String jsonExt = ".json"; // NON-NLS
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle(title);
fileChooser.setDragEnabled(false);
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
FileFilter filter = new FileNameExtensionFilter(Bundle.ConfigVisualPanel1_fileNameExtensionFilter(), new String[] {"json"}); // NON-NLS
FileFilter filter = new FileNameExtensionFilter(Bundle.ConfigVisualPanel1_fileNameExtensionFilter(), new String[]{"json"}); // NON-NLS
fileChooser.setFileFilter(filter);
fileChooser.setSelectedFile(new File("logical-imager-config.json")); // default
fileChooser.setSelectedFile(new File(DEFAULT_CONFIG_FILE_NAME)); // default
fileChooser.setMultiSelectionEnabled(false);
if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
String path = fileChooser.getSelectedFile().getPath();
@ -144,12 +319,11 @@ final class ConfigVisualPanel1 extends JPanel {
loadConfigFile(path);
configFilename = path;
configFileTextField.setText(path);
newFile = false;
} catch (JsonIOException | JsonSyntaxException | IOException ex) {
JOptionPane.showMessageDialog(this,
Bundle.ConfigVisualPanel1_invalidConfigJson() + ex.getMessage() ,
Bundle.ConfigVisualPanel1_configurationError(),
JOptionPane.ERROR_MESSAGE);
Bundle.ConfigVisualPanel1_invalidConfigJson() + ex.getMessage(),
Bundle.ConfigVisualPanel1_configurationError(),
JOptionPane.ERROR_MESSAGE);
}
} else {
if (!path.endsWith(jsonExt)) {
@ -157,55 +331,117 @@ final class ConfigVisualPanel1 extends JPanel {
}
configFilename = path;
configFileTextField.setText(path);
config = new LogicalImagerConfig();
newFile = true;
}
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton browseButton;
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JTextField configFileTextField;
private javax.swing.JLabel jLabel1;
private javax.swing.ButtonGroup configurationLocationButtonGroup;
private javax.swing.JRadioButton configureDriveRadioButton;
private javax.swing.JRadioButton configureFolderRadioButton;
private javax.swing.JScrollPane descriptionScrollPane;
private javax.swing.JTextArea descriptionTextArea;
private javax.swing.JList<String> driveList;
private javax.swing.JScrollPane driveListScrollPane;
private javax.swing.JButton refreshButton;
private javax.swing.JLabel warningLabel;
// End of variables declaration//GEN-END:variables
/**
* Load a json config file specified by the path argument.
*
*
* @param path the path of the json config to load
*
* @return the LogicalImagerConfig which contains the rules from the loaded
* config.
*
* @throws FileNotFoundException
* @throws JsonIOException
* @throws JsonSyntaxException
* @throws IOException
*/
@NbBundle.Messages({
"# {0} - filename",
"ConfigVisualPanel1.configFileIsEmpty=Configuration file {0} is empty",
})
private void loadConfigFile(String path) throws FileNotFoundException, JsonIOException, JsonSyntaxException, IOException {
"ConfigVisualPanel1.configFileIsEmpty=Configuration file {0} is empty",})
private LogicalImagerConfig loadConfigFile(String path) throws FileNotFoundException, JsonIOException, JsonSyntaxException, IOException {
try (FileInputStream is = new FileInputStream(path)) {
InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
GsonBuilder gsonBuilder = new GsonBuilder().setPrettyPrinting();
gsonBuilder.registerTypeAdapter(LogicalImagerConfig.class, new LogicalImagerConfigDeserializer());
Gson gson = gsonBuilder.create();
config = gson.fromJson(reader, LogicalImagerConfig.class);
if (config == null) {
LogicalImagerConfig loadedConfig = gson.fromJson(reader, LogicalImagerConfig.class);
if (loadedConfig == null) {
// This happens if the file is empty. Gson doesn't call the deserializer and doesn't throw any exception.
throw new IOException(Bundle.ConfigVisualPanel1_configFileIsEmpty(path));
}
return loadedConfig;
}
}
/**
* Get the LogicalImagerConfig for the currently selected config file.
*
* @return the LogicalImagerConfig which contains the rules from the loaded
* config.
*/
LogicalImagerConfig getConfig() {
return config;
String configFileName = getConfigPath();
if (configFileName != null && new File(configFileName).exists()) {
try {
return loadConfigFile(configFileName);
} catch (JsonIOException | JsonSyntaxException | IOException ex) {
return new LogicalImagerConfig();
}
} else {
return new LogicalImagerConfig();
}
}
String getConfigFilename() {
return configFilename;
/**
* Get the path of the currently selected json config file.
*
* @return the path of the currently selected config file or null if invalid
* settings are selected
*/
String getConfigPath() {
if (configureFolderRadioButton.isSelected()) {
return configFilename;
} else {
String selectedStr = driveList.getSelectedValue();
if (selectedStr == null) {
return null;
}
return selectedStr.substring(0, 3) + DEFAULT_CONFIG_FILE_NAME;
}
}
boolean isNewFile() {
return newFile;
/**
* The name of the event which signifies an update to the settings reflected
* by ConfigVisualPanel1
*
* @return UPDATE_UI_EVENT_NAME
*/
static String getUpdateEventName() {
return UPDATE_UI_EVENT_NAME;
}
void setConfigFilename(String filename) {
void setConfigFilename(String filename
) {
configFileTextField.setText(filename);
}
/**
* Checks if the current panel has valid settings selected.
*
* @return true if panel has valid settings selected, false otherwise
*/
boolean isPanelValid() {
return (newFile || !configFileTextField.getText().isEmpty());
return !StringUtils.isBlank(getConfigPath()) && ((configureDriveRadioButton.isSelected() && !StringUtils.isBlank(driveList.getSelectedValue()))
|| (configureFolderRadioButton.isSelected() && (!configFileTextField.getText().isEmpty())));
}
/**
@ -235,7 +471,7 @@ final class ConfigVisualPanel1 extends JPanel {
}
private void fireChange() {
panel.firePropertyChange("UPDATE_UI", false, true); // NON-NLS
panel.firePropertyChange(UPDATE_UI_EVENT_NAME, false, true); // NON-NLS
}
}

View File

@ -16,98 +16,86 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="480" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="daysIncludedTextField" min="-2" pref="54" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="daysIncludedLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="ruleNameEditTextField" alignment="0" max="32767" attributes="0"/>
<Component id="descriptionEditTextField" alignment="0" max="32767" attributes="0"/>
<Component id="extensionsTextField" alignment="0" max="32767" attributes="0"/>
<Component id="jScrollPane5" alignment="0" max="32767" attributes="0"/>
<Component id="jScrollPane6" alignment="0" max="32767" attributes="0"/>
<Component id="jScrollPane7" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="jScrollPane1" min="-2" pref="377" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="newRuleButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="editRuleButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="37" max="-2" attributes="0"/>
<Component id="deleteRuleButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="flagEncryptionProgramsCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="finalizeImageWriter" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="393" pref="393" max="-2" attributes="0"/>
<Component id="shouldSaveCheckBox" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="397" pref="397" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="extensionsLabel" min="-2" max="-2" attributes="0"/>
<Component id="filenamesLabel" min="-2" max="-2" attributes="0"/>
<Component id="descriptionLabel" min="-2" max="-2" attributes="0"/>
<Component id="ruleNameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" attributes="0">
<EmptySpace min="397" pref="397" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="modifiedDateLabel" alignment="0" min="-2" pref="79" max="-2" attributes="0"/>
<Component id="fileSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="fullPathsLabel" min="-2" max="-2" attributes="0"/>
<Component id="folderNamesLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
<Component id="minSizeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="minSizeTextField" min="-2" pref="63" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="maxSizeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="maxSizeTextField" min="-2" pref="63" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="393" pref="393" max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
<Component id="ruleSetFileLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="configFileTextField" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
<Component id="ruleSetFileLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="configFileTextField" max="32767" attributes="0"/>
<Component id="newRuleButton" linkSize="3" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="editRuleButton" linkSize="3" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="deleteRuleButton" linkSize="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="rulesScrollPane" alignment="1" min="-2" pref="341" max="-2" attributes="0"/>
</Group>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="flagEncryptionProgramsCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="finalizeImageWriter" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="shouldSaveCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
<Component id="extensionsLabel" min="-2" max="-2" attributes="0"/>
<Component id="filenamesLabel" min="-2" max="-2" attributes="0"/>
<Component id="descriptionLabel" min="-2" max="-2" attributes="0"/>
<Component id="ruleNameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="modifiedDateLabel" alignment="0" min="-2" pref="79" max="-2" attributes="0"/>
<Component id="fileSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="fullPathsLabel" min="-2" max="-2" attributes="0"/>
<Component id="folderNamesLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
<Component id="minSizeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="minSizeTextField" min="-2" pref="63" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="maxSizeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="maxSizeTextField" min="-2" pref="63" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="107" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="129" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="modifiedWithinTextField" min="-2" pref="54" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="daysIncludedLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="ruleNameEditTextField" alignment="0" max="32767" attributes="0"/>
<Component id="descriptionEditTextField" alignment="0" max="32767" attributes="0"/>
<Component id="extensionsTextField" alignment="0" max="32767" attributes="0"/>
<Component id="fullPathsScrollPane" alignment="0" pref="0" max="32767" attributes="0"/>
<Component id="filenamesScrollPane" alignment="0" pref="0" max="32767" attributes="0"/>
<Component id="folderNamesScrollPane" alignment="0" pref="0" max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</Group>
<Group type="102" attributes="0">
<EmptySpace min="397" pref="397" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSeparator1" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -122,7 +110,7 @@
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane1" pref="527" max="32767" attributes="0"/>
<Component id="rulesScrollPane" pref="479" max="32767" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="newRuleButton" alignment="3" min="-2" max="-2" attributes="0"/>
@ -151,7 +139,7 @@
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane6" pref="0" max="32767" attributes="0"/>
<Component id="filenamesScrollPane" pref="0" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="filenamesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
@ -159,7 +147,7 @@
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane7" pref="0" max="32767" attributes="0"/>
<Component id="folderNamesScrollPane" pref="0" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="folderNamesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
@ -172,7 +160,7 @@
<EmptySpace max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="jScrollPane5" pref="0" max="32767" attributes="0"/>
<Component id="fullPathsScrollPane" pref="0" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
</Group>
</Group>
@ -186,14 +174,14 @@
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="2" attributes="0">
<Component id="modifiedDateLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="daysIncludedTextField" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="modifiedWithinTextField" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="daysIncludedLabel" alignment="2" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="shouldSaveCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="jSeparator1" min="-2" pref="2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="flagEncryptionProgramsCheckBox" min="-2" max="-2" attributes="0"/>
@ -214,13 +202,10 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="daysIncludedTextField">
<Component class="javax.swing.JTextField" name="modifiedWithinTextField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="horizontalAlignment" type="int" value="11"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.daysIncludedTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[60, 20]"/>
@ -264,9 +249,6 @@
</Component>
<Component class="javax.swing.JTextField" name="ruleNameEditTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.ruleNameEditTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
@ -305,9 +287,6 @@
</Component>
<Component class="javax.swing.JTextField" name="descriptionEditTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.descriptionEditTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
@ -324,7 +303,7 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteRuleButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane5">
<Container class="javax.swing.JScrollPane" name="fullPathsScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
@ -358,7 +337,7 @@
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JScrollPane" name="jScrollPane6">
<Container class="javax.swing.JScrollPane" name="filenamesScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
@ -396,7 +375,6 @@
</Container>
<Component class="javax.swing.JCheckBox" name="shouldSaveCheckBox">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.shouldSaveCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
@ -408,14 +386,13 @@
</Component>
<Component class="javax.swing.JCheckBox" name="shouldAlertCheckBox">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.shouldAlertCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane7">
<Container class="javax.swing.JScrollPane" name="folderNamesScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
@ -460,9 +437,6 @@
</Component>
<Component class="javax.swing.JTextField" name="extensionsTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.extensionsTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
@ -475,12 +449,7 @@
</Component>
<Component class="javax.swing.JTextField" name="configFileTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.configFileTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.configFileTextField.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
@ -501,7 +470,7 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="finalizeImageWriterActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<Container class="javax.swing.JScrollPane" name="rulesScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
@ -576,9 +545,6 @@
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.editors.AbstractFormatterFactoryEditor">
<Format format="#,###; " subtype="-1" type="0"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.minSizeTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
@ -594,9 +560,6 @@
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.editors.AbstractFormatterFactoryEditor">
<Format format="#,###; " subtype="-1" type="0"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel2.maxSizeTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -30,6 +30,7 @@ import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
/**
* Configuration Visual Panel 2
@ -41,7 +42,7 @@ import org.openide.util.NbBundle;
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
final class ConfigVisualPanel2 extends JPanel {
private static final List<String> EMPTY_LIST = new ArrayList<>();
private static final long serialVersionUID = 1L;
private String configFilename;
private LogicalImagerConfig config = null;
private final JButton okButton = new JButton(Bundle.ConfigVisualPanel2_ok());
@ -59,7 +60,7 @@ final class ConfigVisualPanel2 extends JPanel {
}
@NbBundle.Messages({
"ConfigVisualPanel2.editConfiguration=Edit configuration"
"ConfigVisualPanel2.editConfiguration=Configure imager"
})
@Override
public String getName() {
@ -75,7 +76,7 @@ final class ConfigVisualPanel2 extends JPanel {
private void initComponents() {
modifiedDateLabel = new javax.swing.JLabel();
daysIncludedTextField = new javax.swing.JTextField();
modifiedWithinTextField = new javax.swing.JTextField();
daysIncludedLabel = new javax.swing.JLabel();
fullPathsLabel = new javax.swing.JLabel();
flagEncryptionProgramsCheckBox = new javax.swing.JCheckBox();
@ -86,13 +87,13 @@ final class ConfigVisualPanel2 extends JPanel {
editRuleButton = new javax.swing.JButton();
descriptionEditTextField = new javax.swing.JTextField();
deleteRuleButton = new javax.swing.JButton();
jScrollPane5 = new javax.swing.JScrollPane();
fullPathsScrollPane = new javax.swing.JScrollPane();
fullPathsTable = new javax.swing.JTable();
jScrollPane6 = new javax.swing.JScrollPane();
filenamesScrollPane = new javax.swing.JScrollPane();
filenamesTable = new javax.swing.JTable();
shouldSaveCheckBox = new javax.swing.JCheckBox();
shouldAlertCheckBox = new javax.swing.JCheckBox();
jScrollPane7 = new javax.swing.JScrollPane();
folderNamesScrollPane = new javax.swing.JScrollPane();
folderNamesTable = new javax.swing.JTable();
extensionsLabel = new javax.swing.JLabel();
extensionsTextField = new javax.swing.JTextField();
@ -100,7 +101,7 @@ final class ConfigVisualPanel2 extends JPanel {
configFileTextField = new javax.swing.JTextField();
ruleSetFileLabel = new javax.swing.JLabel();
finalizeImageWriter = new javax.swing.JCheckBox();
jScrollPane1 = new javax.swing.JScrollPane();
rulesScrollPane = new javax.swing.JScrollPane();
rulesTable = new javax.swing.JTable();
folderNamesLabel = new javax.swing.JLabel();
fileSizeLabel = new javax.swing.JLabel();
@ -112,12 +113,11 @@ final class ConfigVisualPanel2 extends JPanel {
org.openide.awt.Mnemonics.setLocalizedText(modifiedDateLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.modifiedDateLabel.text")); // NOI18N
daysIncludedTextField.setEditable(false);
daysIncludedTextField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
daysIncludedTextField.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.daysIncludedTextField.text")); // NOI18N
daysIncludedTextField.setEnabled(false);
daysIncludedTextField.setMinimumSize(new java.awt.Dimension(60, 20));
daysIncludedTextField.setPreferredSize(new java.awt.Dimension(60, 20));
modifiedWithinTextField.setEditable(false);
modifiedWithinTextField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
modifiedWithinTextField.setEnabled(false);
modifiedWithinTextField.setMinimumSize(new java.awt.Dimension(60, 20));
modifiedWithinTextField.setPreferredSize(new java.awt.Dimension(60, 20));
org.openide.awt.Mnemonics.setLocalizedText(daysIncludedLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.daysIncludedLabel.text")); // NOI18N
daysIncludedLabel.setEnabled(false);
@ -133,7 +133,6 @@ final class ConfigVisualPanel2 extends JPanel {
org.openide.awt.Mnemonics.setLocalizedText(ruleNameLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.ruleNameLabel.text")); // NOI18N
ruleNameEditTextField.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.ruleNameEditTextField.text")); // NOI18N
ruleNameEditTextField.setEnabled(false);
newRuleButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N
@ -154,7 +153,6 @@ final class ConfigVisualPanel2 extends JPanel {
}
});
descriptionEditTextField.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.descriptionEditTextField.text")); // NOI18N
descriptionEditTextField.setEnabled(false);
deleteRuleButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete16.png"))); // NOI18N
@ -171,7 +169,7 @@ final class ConfigVisualPanel2 extends JPanel {
fullPathsTable.setShowHorizontalLines(false);
fullPathsTable.setShowVerticalLines(false);
fullPathsTable.getTableHeader().setReorderingAllowed(false);
jScrollPane5.setViewportView(fullPathsTable);
fullPathsScrollPane.setViewportView(fullPathsTable);
fullPathsTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
if (fullPathsTable.getColumnModel().getColumnCount() > 0) {
fullPathsTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.fullPathsTable.columnModel.title0")); // NOI18N
@ -182,17 +180,15 @@ final class ConfigVisualPanel2 extends JPanel {
filenamesTable.setShowHorizontalLines(false);
filenamesTable.setShowVerticalLines(false);
filenamesTable.getTableHeader().setReorderingAllowed(false);
jScrollPane6.setViewportView(filenamesTable);
filenamesScrollPane.setViewportView(filenamesTable);
if (filenamesTable.getColumnModel().getColumnCount() > 0) {
filenamesTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.filenamesTable.columnModel.title0")); // NOI18N
}
shouldSaveCheckBox.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(shouldSaveCheckBox, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.shouldSaveCheckBox.text")); // NOI18N
shouldSaveCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.shouldSaveCheckBox.toolTipText")); // NOI18N
shouldSaveCheckBox.setEnabled(false);
shouldAlertCheckBox.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(shouldAlertCheckBox, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.shouldAlertCheckBox.text")); // NOI18N
shouldAlertCheckBox.setEnabled(false);
@ -201,20 +197,18 @@ final class ConfigVisualPanel2 extends JPanel {
folderNamesTable.setShowHorizontalLines(false);
folderNamesTable.setShowVerticalLines(false);
folderNamesTable.getTableHeader().setReorderingAllowed(false);
jScrollPane7.setViewportView(folderNamesTable);
folderNamesScrollPane.setViewportView(folderNamesTable);
if (folderNamesTable.getColumnModel().getColumnCount() > 0) {
folderNamesTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.folderNamesTable.columnModel.title0")); // NOI18N
}
org.openide.awt.Mnemonics.setLocalizedText(extensionsLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.extensionsLabel.text")); // NOI18N
extensionsTextField.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.extensionsTextField.text")); // NOI18N
extensionsTextField.setEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(filenamesLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.filenamesLabel.text")); // NOI18N
configFileTextField.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.configFileTextField.text")); // NOI18N
configFileTextField.setToolTipText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.configFileTextField.toolTipText")); // NOI18N
configFileTextField.setToolTipText("");
configFileTextField.setEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(ruleSetFileLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.ruleSetFileLabel.text")); // NOI18N
@ -241,7 +235,7 @@ final class ConfigVisualPanel2 extends JPanel {
rulesTableKeyReleased(evt);
}
});
jScrollPane1.setViewportView(rulesTable);
rulesScrollPane.setViewportView(rulesTable);
if (rulesTable.getColumnModel().getColumnCount() > 0) {
rulesTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.rulesTable.columnModel.title0")); // NOI18N
rulesTable.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.rulesTable.columnModel.title1")); // NOI18N
@ -254,13 +248,11 @@ final class ConfigVisualPanel2 extends JPanel {
org.openide.awt.Mnemonics.setLocalizedText(minSizeLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.minSizeLabel.text")); // NOI18N
minSizeTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#,###; "))));
minSizeTextField.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.minSizeTextField.text")); // NOI18N
minSizeTextField.setEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(maxSizeLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.maxSizeLabel.text")); // NOI18N
maxSizeTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#,###; "))));
maxSizeTextField.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel2.class, "ConfigVisualPanel2.maxSizeTextField.text")); // NOI18N
maxSizeTextField.setEnabled(false);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
@ -268,78 +260,73 @@ final class ConfigVisualPanel2 extends JPanel {
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(480, 480, 480)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(daysIncludedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(daysIncludedLabel))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(ruleNameEditTextField, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(descriptionEditTextField, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(extensionsTextField, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane5, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane6, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane7, javax.swing.GroupLayout.Alignment.LEADING))
.addContainerGap())))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 377, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createSequentialGroup()
.addComponent(newRuleButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(editRuleButton)
.addGap(37, 37, 37)
.addComponent(deleteRuleButton)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(flagEncryptionProgramsCheckBox)
.addComponent(finalizeImageWriter)))
.addGroup(layout.createSequentialGroup()
.addGap(393, 393, 393)
.addComponent(shouldSaveCheckBox))
.addGroup(layout.createSequentialGroup()
.addGap(397, 397, 397)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(extensionsLabel)
.addComponent(filenamesLabel)
.addComponent(descriptionLabel)
.addComponent(ruleNameLabel)))
.addGroup(layout.createSequentialGroup()
.addGap(397, 397, 397)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(modifiedDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeLabel)
.addComponent(fullPathsLabel)
.addComponent(folderNamesLabel))
.addGap(4, 4, 4)
.addComponent(minSizeLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(minSizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(maxSizeLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(maxSizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addGap(393, 393, 393)
.addComponent(shouldAlertCheckBox)))
.addGap(17, 17, 17)
.addComponent(ruleSetFileLabel)
.addGap(18, 18, 18)
.addComponent(configFileTextField)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(17, 17, 17)
.addComponent(ruleSetFileLabel)
.addGap(18, 18, 18)
.addComponent(configFileTextField))
.addComponent(newRuleButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(editRuleButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(deleteRuleButton))
.addComponent(rulesScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 341, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(397, 397, 397)
.addComponent(jSeparator1)))
.addGap(10, 10, 10))
.addGap(10, 10, 10)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(flagEncryptionProgramsCheckBox)
.addComponent(finalizeImageWriter)
.addComponent(shouldSaveCheckBox)
.addComponent(shouldAlertCheckBox)
.addComponent(extensionsLabel)
.addComponent(filenamesLabel)
.addComponent(descriptionLabel)
.addComponent(ruleNameLabel)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(modifiedDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeLabel)
.addComponent(fullPathsLabel)
.addComponent(folderNamesLabel))
.addGap(4, 4, 4)
.addComponent(minSizeLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(minSizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(maxSizeLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(maxSizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(107, 107, 107))
.addGroup(layout.createSequentialGroup()
.addGap(129, 129, 129)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(modifiedWithinTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(daysIncludedLabel))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(ruleNameEditTextField, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(descriptionEditTextField, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(extensionsTextField, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(fullPathsScrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(filenamesScrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(folderNamesScrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
.addContainerGap())))))
.addGroup(layout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator1))))
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {deleteRuleButton, editRuleButton, newRuleButton});
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
@ -350,7 +337,7 @@ final class ConfigVisualPanel2 extends JPanel {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 527, Short.MAX_VALUE)
.addComponent(rulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newRuleButton)
@ -372,13 +359,13 @@ final class ConfigVisualPanel2 extends JPanel {
.addComponent(ruleNameLabel)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane6, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(filenamesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(filenamesLabel)
.addGap(0, 0, Short.MAX_VALUE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane7, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(folderNamesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(folderNamesLabel)
.addGap(0, 0, Short.MAX_VALUE)))
@ -388,7 +375,7 @@ final class ConfigVisualPanel2 extends JPanel {
.addComponent(fullPathsLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jScrollPane5, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(fullPathsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGap(11, 11, 11)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
.addComponent(minSizeLabel)
@ -399,13 +386,13 @@ final class ConfigVisualPanel2 extends JPanel {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
.addComponent(modifiedDateLabel)
.addComponent(daysIncludedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(modifiedWithinTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(daysIncludedLabel))
.addGap(3, 3, 3)
.addComponent(shouldAlertCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(shouldSaveCheckBox)
.addGap(18, 18, 18)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(shouldAlertCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(flagEncryptionProgramsCheckBox)
@ -415,31 +402,27 @@ final class ConfigVisualPanel2 extends JPanel {
);
}// </editor-fold>//GEN-END:initComponents
private void finalizeImageWriterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_finalizeImageWriterActionPerformed
config.setFinalizeImageWriter(finalizeImageWriter.isSelected());
}//GEN-LAST:event_finalizeImageWriterActionPerformed
private void rulesTableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_rulesTableKeyReleased
rulesTableSelect();
updateForSelectedRule();
}//GEN-LAST:event_rulesTableKeyReleased
@NbBundle.Messages({
"ConfigVisualPanel2.editRuleSet=Edit rule",
"ConfigVisualPanel2.editRuleSet=Edit Rule",
"ConfigVisualPanel2.editRuleError=Edit rule error"
})
private void editRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editRuleButtonActionPerformed
int row = rulesTable.getSelectedRow();
if (row != -1) {
String ruleName = (String) rulesTable.getModel().getValueAt(row, 0);
LogicalImagerRule rule = getFirstRuleSet().getRules().get(row);
LogicalImagerRule rule = getRuleSetFromCurrentConfig().getRules().get(row);
EditRulePanel editPanel = new EditRulePanel(okButton, cancelButton, ruleName, rule);
editPanel.setEnabled(true);
editPanel.setVisible(true);
while (true) {
int option = JOptionPane.showOptionDialog(this, editPanel.getPanel(), Bundle.ConfigVisualPanel2_editRuleSet(),
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
null, new Object[]{okButton, cancelButton}, okButton);
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
null, new Object[]{okButton, cancelButton}, okButton);
if (option == JOptionPane.OK_OPTION) {
try {
ImmutablePair<String, LogicalImagerRule> ruleMap = editPanel.toRule();
@ -447,9 +430,9 @@ final class ConfigVisualPanel2 extends JPanel {
break;
} catch (IOException | NumberFormatException ex) {
JOptionPane.showMessageDialog(this,
ex.getMessage(),
Bundle.ConfigVisualPanel2_editRuleError(),
JOptionPane.ERROR_MESSAGE);
ex.getMessage(),
Bundle.ConfigVisualPanel2_editRuleError(),
JOptionPane.ERROR_MESSAGE);
// let user fix the error
}
} else {
@ -459,16 +442,17 @@ final class ConfigVisualPanel2 extends JPanel {
}
}//GEN-LAST:event_editRuleButtonActionPerformed
@Messages({"ConfigVisualPanel2.newRule.name=New Rule"})
private void newRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newRuleButtonActionPerformed
NewRuleSetPanel panel;
panel = new NewRuleSetPanel(okButton, cancelButton);
NewRulePanel panel;
panel = new NewRulePanel(okButton, cancelButton);
panel.setEnabled(true);
panel.setVisible(true);
while (true) {
int option = JOptionPane.showOptionDialog(this, panel, "New rule",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
null, new Object[]{okButton, cancelButton}, okButton);
int option = JOptionPane.showOptionDialog(this, panel, Bundle.ConfigVisualPanel2_newRule_name(),
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
null, new Object[]{okButton, cancelButton}, okButton);
if (option == JOptionPane.OK_OPTION) {
try {
// Save the new rule
@ -477,9 +461,9 @@ final class ConfigVisualPanel2 extends JPanel {
break;
} catch (IOException | NumberFormatException ex) {
JOptionPane.showMessageDialog(this,
ex.getMessage(),
"New rule error",
JOptionPane.ERROR_MESSAGE);
ex.getMessage(),
"New rule error",
JOptionPane.ERROR_MESSAGE);
// let user fix the error
}
} else {
@ -490,8 +474,7 @@ final class ConfigVisualPanel2 extends JPanel {
@NbBundle.Messages({
"ConfigVisualPanel2.deleteRuleSet=Delete rule ",
"ConfigVisualPanel2.deleteRuleSetConfirmation=Delete rule confirmation",
})
"ConfigVisualPanel2.deleteRuleSetConfirmation=Delete rule confirmation",})
private void deleteRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteRuleButtonActionPerformed
int index = rulesTable.getSelectedRow();
if (index != -1) {
@ -500,30 +483,41 @@ final class ConfigVisualPanel2 extends JPanel {
int option = JOptionPane.showOptionDialog(this,
Bundle.ConfigVisualPanel2_deleteRuleSet() + ruleName,
Bundle.ConfigVisualPanel2_deleteRuleSetConfirmation(),
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
if (option == JOptionPane.NO_OPTION) {
return;
}
getFirstRuleSet().getRules().remove(index);
getRuleSetFromCurrentConfig().getRules().remove(index);
updatePanel(configFilename, config);
if (rulesTable.getRowCount() > 0) {
rulesTable.setRowSelectionInterval(0, 0);
rulesTableSelect();
updateForSelectedRule();
}
}
}//GEN-LAST:event_deleteRuleButtonActionPerformed
private void flagEncryptionProgramsCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_flagEncryptionProgramsCheckBoxActionPerformed
flagEncryptionPrograms = flagEncryptionProgramsCheckBox.isSelected();
toggleEncryptionProgramsRule(flagEncryptionPrograms);
}//GEN-LAST:event_flagEncryptionProgramsCheckBoxActionPerformed
private void rulesTableMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_rulesTableMouseReleased
rulesTableSelect();
updateForSelectedRule();
}//GEN-LAST:event_rulesTableMouseReleased
private void toggleEncryptionProgramsRule(boolean flagEncryptionPrograms) {
private void flagEncryptionProgramsCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_flagEncryptionProgramsCheckBoxActionPerformed
flagEncryptionPrograms = flagEncryptionProgramsCheckBox.isSelected();
setEnabledEncryptionProgramsRule(flagEncryptionPrograms);
}//GEN-LAST:event_flagEncryptionProgramsCheckBoxActionPerformed
private void finalizeImageWriterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_finalizeImageWriterActionPerformed
config.setFinalizeImageWriter(finalizeImageWriter.isSelected());
}//GEN-LAST:event_finalizeImageWriterActionPerformed
/**
* Set the whether the a rule for detecting encryption programs will be
* added to the rules in this config
*
* @param flagEncryptionPrograms true to have encryption programs rule
* added, false otherwise.
*/
private void setEnabledEncryptionProgramsRule(boolean flagEncryptionPrograms) {
if (flagEncryptionPrograms) {
// add the special rule
ImmutablePair<String, LogicalImagerRule> ruleMap = createEncryptionProgramsRule();
@ -532,11 +526,11 @@ final class ConfigVisualPanel2 extends JPanel {
// remove it
int index = ((RulesTableModel) rulesTable.getModel()).findRow(EncryptionProgramsRule.getName());
if (index != -1) {
getFirstRuleSet().getRules().remove(index);
getRuleSetFromCurrentConfig().getRules().remove(index);
updatePanel(configFilename, config);
if (rulesTable.getRowCount() > 0) {
rulesTable.setRowSelectionInterval(0, 0);
rulesTableSelect();
updateForSelectedRule();
}
}
}
@ -559,7 +553,6 @@ final class ConfigVisualPanel2 extends JPanel {
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTextField configFileTextField;
private javax.swing.JLabel daysIncludedLabel;
private javax.swing.JTextField daysIncludedTextField;
private javax.swing.JButton deleteRuleButton;
private javax.swing.JTextField descriptionEditTextField;
private javax.swing.JLabel descriptionLabel;
@ -568,33 +561,34 @@ final class ConfigVisualPanel2 extends JPanel {
private javax.swing.JTextField extensionsTextField;
private javax.swing.JLabel fileSizeLabel;
private javax.swing.JLabel filenamesLabel;
private javax.swing.JScrollPane filenamesScrollPane;
private javax.swing.JTable filenamesTable;
private javax.swing.JCheckBox finalizeImageWriter;
private javax.swing.JCheckBox flagEncryptionProgramsCheckBox;
private javax.swing.JLabel folderNamesLabel;
private javax.swing.JScrollPane folderNamesScrollPane;
private javax.swing.JTable folderNamesTable;
private javax.swing.JLabel fullPathsLabel;
private javax.swing.JScrollPane fullPathsScrollPane;
private javax.swing.JTable fullPathsTable;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane5;
private javax.swing.JScrollPane jScrollPane6;
private javax.swing.JScrollPane jScrollPane7;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JLabel maxSizeLabel;
private javax.swing.JFormattedTextField maxSizeTextField;
private javax.swing.JLabel minSizeLabel;
private javax.swing.JFormattedTextField minSizeTextField;
private javax.swing.JLabel modifiedDateLabel;
private javax.swing.JTextField modifiedWithinTextField;
private javax.swing.JButton newRuleButton;
private javax.swing.JTextField ruleNameEditTextField;
private javax.swing.JLabel ruleNameLabel;
private javax.swing.JLabel ruleSetFileLabel;
private javax.swing.JScrollPane rulesScrollPane;
private javax.swing.JTable rulesTable;
private javax.swing.JCheckBox shouldAlertCheckBox;
private javax.swing.JCheckBox shouldSaveCheckBox;
// End of variables declaration//GEN-END:variables
private LogicalImagerRuleSet getFirstRuleSet() {
private LogicalImagerRuleSet getRuleSetFromCurrentConfig() {
if (config.getRuleSets().isEmpty()) {
List<LogicalImagerRuleSet> ruleSets = new ArrayList<>();
ruleSets.add(new LogicalImagerRuleSet("no-set-name", new ArrayList<>())); // NON-NLS
@ -603,10 +597,17 @@ final class ConfigVisualPanel2 extends JPanel {
return config.getRuleSets().get(0);
}
/**
* Update the panel to reflect the rules in the current config
*
* @param configFilePath path of the config file being modified
* @param config contents of the config file being modifed
* @param rowSelectionkey the name of the rule to select by default
*/
private void updatePanel(String configFilePath, LogicalImagerConfig config, String rowSelectionkey) {
configFileTextField.setText(configFilePath);
finalizeImageWriter.setSelected(config.isFinalizeImageWriter());
LogicalImagerRuleSet ruleSet = getFirstRuleSet();
LogicalImagerRuleSet ruleSet = getRuleSetFromCurrentConfig();
flagEncryptionProgramsCheckBox.setSelected(ruleSet.find(EncryptionProgramsRule.getName()) != null);
RulesTableModel rulesTableModel = new RulesTableModel();
int row = 0;
@ -628,31 +629,48 @@ final class ConfigVisualPanel2 extends JPanel {
// If there are any rules, select the first one
if (rulesTableModel.getRowCount() > 0) {
rulesTable.setRowSelectionInterval(selectThisRow, selectThisRow);
rulesTableSelect();
updateForSelectedRule();
} else {
updateRuleSetButtons(false);
clearRuleDetails();
updateRuleButtons(false);
}
}
/**
* Private helper method to call updatePanel with no row to select specified
*
* @param configFilePath path of the config file being modified
* @param config contents of the config file being modifed
*/
private void updatePanel(String configFilePath, LogicalImagerConfig config) {
updatePanel(configFilePath, config, null);
}
private void rulesTableSelect() {
/**
* Update the panel to reflect the selected rule
*/
private void updateForSelectedRule() {
int index = rulesTable.getSelectedRow();
if (index != -1) {
String ruleName = (String) rulesTable.getModel().getValueAt(index, 0);
String description = (String) rulesTable.getModel().getValueAt(index, 1);
updateRuleDetails(ruleName, description, config);
updateRuleSetButtons(ruleName.equals(EncryptionProgramsRule.getName()) ? false : true);
updateRuleDetails(ruleName, description);
updateRuleButtons(!ruleName.equals(EncryptionProgramsRule.getName()));
} else {
updateRuleSetButtons(false);
clearRuleDetails();
updateRuleButtons(false);
}
}
private void updateRuleDetails(String ruleName, String description, LogicalImagerConfig config) {
/**
* Update the panel to display details of the specified rule
*
* @param ruleName the name of the rule to display
* @param description the description of the rule to display
*/
private void updateRuleDetails(String ruleName, String description) {
clearRuleDetails();
LogicalImagerRule rule = getFirstRuleSet().find(ruleName);
LogicalImagerRule rule = getRuleSetFromCurrentConfig().find(ruleName);
shouldAlertCheckBox.setSelected(rule.isShouldAlert());
shouldSaveCheckBox.setSelected(rule.isShouldSave());
ruleNameEditTextField.setText(ruleName);
@ -672,18 +690,36 @@ final class ConfigVisualPanel2 extends JPanel {
maxSizeTextField.setText(rule.getMaxFileSize().toString());
}
if (rule.getMinDays() == null) {
daysIncludedTextField.setText("");
modifiedWithinTextField.setText("");
} else {
daysIncludedTextField.setText(Integer.toString(rule.getMinDays()));
modifiedWithinTextField.setText(Integer.toString(rule.getMinDays()));
}
}
/**
* Reset rule details displayed to be blank or default
*/
private void clearRuleDetails() {
ruleNameEditTextField.setText("");
descriptionEditTextField.setText("");
extensionsTextField.setText("");
shouldAlertCheckBox.setSelected(false);
updateExtensions(null);
updateList(filenamesTable, null);
updateList(folderNamesTable, null);
updateList(fullPathsTable, null);
minSizeTextField.setText("");
maxSizeTextField.setText("");
modifiedWithinTextField.setText("");
shouldSaveCheckBox.setSelected(true);
shouldAlertCheckBox.setSelected(false);
}
/**
* Update the extensions displayed
*
* @param extensions the list of extensions to display, null to display
* nothing
*/
private void updateExtensions(List<String> extensions) {
extensionsTextField.setText("");
if (extensions == null) {
@ -698,54 +734,51 @@ final class ConfigVisualPanel2 extends JPanel {
extensionsTextField.setText(content);
}
private void updateList(javax.swing.JTable jTable, List<String> set) {
/**
* Update a JTable to display a list of Strings
*
* @param jTable the JTable to update
* @param list the list of Strings to display, null to display nothing
*/
private void updateList(javax.swing.JTable jTable, List<String> list) {
SingleColumnTableModel tableModel = new SingleColumnTableModel();
jTable.setTableHeader(null);
if (set == null) {
if (list == null) {
jTable.setModel(tableModel);
return;
}
int row = 0;
for (String s : set) {
for (String s : list) {
tableModel.setValueAt(s, row, 0);
row++;
}
jTable.setModel(tableModel);
}
void setConfiguration(String configFilename, LogicalImagerConfig config, boolean newFile) {
void setConfiguration(String configFilename, LogicalImagerConfig config) {
this.configFilename = configFilename;
this.config = config;
if (newFile) {
initPanel();
}
updatePanel(configFilename, config);
}
private void initPanel() {
configFileTextField.setText("");
rulesTable.setModel(new RulesTableModel());
shouldAlertCheckBox.setSelected(false);
shouldSaveCheckBox.setSelected(true);
ruleNameEditTextField.setText("");
descriptionEditTextField.setText("");
extensionsTextField.setText("");
updateList(filenamesTable, EMPTY_LIST);
updateList(folderNamesTable, EMPTY_LIST);
}
private void updateRow(int index, ImmutablePair<String, LogicalImagerRule> ruleMap) {
getFirstRuleSet().getRules().remove(index);
getFirstRuleSet().getRules().add(ruleMap.getValue());
getRuleSetFromCurrentConfig().getRules().remove(index);
getRuleSetFromCurrentConfig().getRules().add(ruleMap.getValue());
updatePanel(configFilename, config, ruleMap.getKey());
}
private void appendRow(ImmutablePair<String, LogicalImagerRule> ruleMap) {
getFirstRuleSet().getRules().add(ruleMap.getValue());
getRuleSetFromCurrentConfig().getRules().add(ruleMap.getValue());
updatePanel(configFilename, config, ruleMap.getKey());
}
private void updateRuleSetButtons(boolean isRowSelected) {
/**
* Adjust the enabled status of the rule buttons to reflect wether there is
* a currently selected rule which can be modified
*
* @param isRowSelected true if a row is selected, false otherwise
*/
private void updateRuleButtons(boolean isRowSelected) {
newRuleButton.setEnabled(true);
editRuleButton.setEnabled(isRowSelected);
deleteRuleButton.setEnabled(isRowSelected);
@ -756,6 +789,7 @@ final class ConfigVisualPanel2 extends JPanel {
*/
private class SortRuleByName implements Comparator<LogicalImagerRule> {
@Override
public int compare(LogicalImagerRule a, LogicalImagerRule b) {
return a.getName().compareToIgnoreCase(b.getName());
}
@ -766,6 +800,7 @@ final class ConfigVisualPanel2 extends JPanel {
*/
private class RulesTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private final List<String> ruleName = new ArrayList<>();
private final List<String> ruleDescription = new ArrayList<>();
private final List<LogicalImagerRule> rule = new ArrayList<>();
@ -855,6 +890,8 @@ final class ConfigVisualPanel2 extends JPanel {
*/
private class SingleColumnTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private final List<String> list = new ArrayList<>();
@Override

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<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" attributes="0">
<Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="configLabel" max="32767" attributes="0"/>
<Component id="executableLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="configStatusLabel" min="-2" pref="237" max="-2" attributes="0"/>
<Component id="executableStatusLabel" min="-2" pref="238" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="10" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="descriptionScrollPane" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="saveButton" min="-2" pref="101" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<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"/>
<Component id="descriptionScrollPane" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="saveButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="configLabel" max="32767" attributes="0"/>
<Component id="configStatusLabel" min="-2" pref="14" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="executableLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="executableStatusLabel" alignment="3" min="-2" pref="14" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="120" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="saveButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel3.saveButton.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="saveButtonActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Container class="javax.swing.JScrollPane" name="descriptionScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="descriptionTextArea">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="columns" type="int" value="20"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="0"/>
</Property>
<Property name="lineWrap" type="boolean" value="true"/>
<Property name="rows" type="int" value="5"/>
<Property name="wrapStyleWord" type="boolean" value="true"/>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="configLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel3.configLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="configStatusLabel">
</Component>
<Component class="javax.swing.JLabel" name="executableLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel3.executableLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="executableStatusLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="ConfigVisualPanel3.executableStatusLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,284 @@
/*
* Autopsy
*
* Copyright 2019 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.logicalimager.configuration;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
import java.awt.Color;
import java.awt.Cursor;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.logicalimager.configuration.CreateLogicalImagerAction.getLogicalImagerExe;
/**
* Configuration visual panel 3
*/
class ConfigVisualPanel3 extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(ConfigVisualPanel3.class.getName());
private static final String SAVED_LOGICAL_IMAGER = "SAVED_LOGICAL_IMAGER";
private static final long serialVersionUID = 1L;
private boolean hasBeenSaved = false;
private String configFilename;
private LogicalImagerConfig config;
/**
* Creates new form ConfigVisualPanel3
*/
@NbBundle.Messages({"ConfigVisualPanel3.copyStatus.notSaved=File has not been saved",
"ConfigVisualPanel3.copyStatus.savingInProgress=Saving file, please wait",
"ConfigVisualPanel3.copyStatus.saved=Saved",
"ConfigVisualPanel3.copyStatus.error=Unable to save file"})
ConfigVisualPanel3() {
initComponents();
}
final void resetPanel() {
hasBeenSaved = false;
configStatusLabel.setText(Bundle.ConfigVisualPanel3_copyStatus_notSaved());
executableStatusLabel.setText(Bundle.ConfigVisualPanel3_copyStatus_notSaved());
}
@NbBundle.Messages({
"ConfigVisualPanel3.saveConfigurationFile=Save imager"
})
@Override
public String getName() {
return Bundle.ConfigVisualPanel3_saveConfigurationFile();
}
/**
* Identifies whether the configuration has been saved
*
* @return true if it has been saved, false otherwise
*/
boolean isSaved() {
return hasBeenSaved;
}
/**
* Save the current configuration file and copy the logical imager
* executable to the same location.
*/
@NbBundle.Messages({
"# {0} - configFilename",
"ConfigVisualPanel3.failedToSaveConfigMsg=Failed to save configuration file: {0}",
"# {0} - reason",
"ConfigVisualPanel3.reason=\nReason: {0}",
"ConfigVisualPanel3.failedToSaveExeMsg=Failed to save tsk_logical_imager.exe file"
})
void saveConfigFile() {
boolean saveSuccess = true;
executableStatusLabel.setForeground(Color.BLACK);
configStatusLabel.setText(Bundle.ConfigVisualPanel3_copyStatus_savingInProgress());
executableStatusLabel.setText(Bundle.ConfigVisualPanel3_copyStatus_savingInProgress());
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
GsonBuilder gsonBuilder = new GsonBuilder()
.setPrettyPrinting()
.excludeFieldsWithoutExposeAnnotation()
.disableHtmlEscaping();
Gson gson = gsonBuilder.create();
String toJson = gson.toJson(config);
try {
List<String> lines = Arrays.asList(toJson.split("\\n"));
FileUtils.writeLines(new File(configFilename), "UTF-8", lines, System.getProperty("line.separator")); // NON-NLS
configStatusLabel.setText(Bundle.ConfigVisualPanel3_copyStatus_saved());
} catch (IOException ex) {
saveSuccess = false;
configStatusLabel.setText(Bundle.ConfigVisualPanel3_copyStatus_error());
configStatusLabel.setForeground(Color.RED);
JOptionPane.showMessageDialog(this, Bundle.ConfigVisualPanel3_failedToSaveConfigMsg(configFilename)
+ Bundle.ConfigVisualPanel3_reason(ex.getMessage()));
} catch (JsonIOException jioe) {
saveSuccess = false;
executableStatusLabel.setText(Bundle.ConfigVisualPanel3_copyStatus_error());
executableStatusLabel.setForeground(Color.RED);
logger.log(Level.SEVERE, "Failed to save configuration file: " + configFilename, jioe); // NON-NLS
JOptionPane.showMessageDialog(this, Bundle.ConfigVisualPanel3_failedToSaveConfigMsg(configFilename)
+ Bundle.ConfigVisualPanel3_reason(jioe.getMessage()));
}
try {
writeTskLogicalImagerExe(Paths.get(configFilename).getParent());
executableStatusLabel.setText(Bundle.ConfigVisualPanel3_copyStatus_saved());
} catch (IOException ex) {
saveSuccess = false;
executableStatusLabel.setText(Bundle.ConfigVisualPanel3_copyStatus_error());
executableStatusLabel.setForeground(Color.RED);
logger.log(Level.SEVERE, "Failed to save tsk_logical_imager.exe file", ex); // NON-NLS
JOptionPane.showMessageDialog(this, Bundle.ConfigVisualPanel3_failedToSaveExeMsg()
+ Bundle.ConfigVisualPanel3_reason(ex.getMessage()));
}
if (saveSuccess) {
hasBeenSaved = true;
firePropertyChange(SAVED_LOGICAL_IMAGER, false, true); // NON-NLS
}
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
/**
* Writes the logical imager executable to the specified location.
*
* @param destDir The destination directory.
*
* @throws IOException If the executable cannot be found or copying fails.
*/
@NbBundle.Messages({
"ConfigVisualPanel3.errorMsg.cannotFindLogicalImager=Cannot locate logical imager, cannot copy to destination"
})
private void writeTskLogicalImagerExe(Path destDir) throws IOException {
File logicalImagerExe = getLogicalImagerExe();
if (logicalImagerExe != null && logicalImagerExe.exists()) {
FileUtils.copyFileToDirectory(getLogicalImagerExe(), destDir.toFile());
} else {
throw new IOException(Bundle.ConfigVisualPanel3_errorMsg_cannotFindLogicalImager());
}
}
/**
* The name of the event which is sent when the configuration and executable
* have been saved.
*
* @return SAVED_LOGICAL_IMAGER
*/
static String getSavedEventName() {
return SAVED_LOGICAL_IMAGER;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
javax.swing.JButton saveButton = new javax.swing.JButton();
descriptionScrollPane = new javax.swing.JScrollPane();
descriptionTextArea = new javax.swing.JTextArea();
javax.swing.JLabel configLabel = new javax.swing.JLabel();
configStatusLabel = new javax.swing.JLabel();
javax.swing.JLabel executableLabel = new javax.swing.JLabel();
executableStatusLabel = new javax.swing.JLabel();
org.openide.awt.Mnemonics.setLocalizedText(saveButton, org.openide.util.NbBundle.getMessage(ConfigVisualPanel3.class, "ConfigVisualPanel3.saveButton.text")); // NOI18N
saveButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveButtonActionPerformed(evt);
}
});
descriptionTextArea.setEditable(false);
descriptionTextArea.setBackground(new java.awt.Color(240, 240, 240));
descriptionTextArea.setColumns(20);
descriptionTextArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
descriptionTextArea.setLineWrap(true);
descriptionTextArea.setRows(5);
descriptionTextArea.setWrapStyleWord(true);
descriptionTextArea.setEnabled(false);
descriptionScrollPane.setViewportView(descriptionTextArea);
org.openide.awt.Mnemonics.setLocalizedText(configLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel3.class, "ConfigVisualPanel3.configLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(executableLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel3.class, "ConfigVisualPanel3.executableLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(executableStatusLabel, org.openide.util.NbBundle.getMessage(ConfigVisualPanel3.class, "ConfigVisualPanel3.executableStatusLabel.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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(configLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(executableLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(configStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 237, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(executableStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 238, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(0, 10, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(descriptionScrollPane)
.addGroup(layout.createSequentialGroup()
.addComponent(saveButton, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(saveButton)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(configLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(configStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(executableLabel)
.addComponent(executableStatusLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(120, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
saveConfigFile();
}//GEN-LAST:event_saveButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel configStatusLabel;
private javax.swing.JScrollPane descriptionScrollPane;
private javax.swing.JTextArea descriptionTextArea;
private javax.swing.JLabel executableStatusLabel;
// End of variables declaration//GEN-END:variables
/**
* Set the information necessary to save the configuration
*
* @param configFile the path to the json configuration file
* @param config the configuration to save
*/
@NbBundle.Messages({
"# {0} - configurationLocation",
"ConfigVisualPanel3.description.text=Press Save to write the imaging tool and configuration file to the destination.\nDestination: {0}"
})
void setConfigInfoForSaving(String configFile, LogicalImagerConfig config) {
this.configFilename = configFile;
this.config = config;
descriptionTextArea.setText(Bundle.ConfigVisualPanel3_description_text(FilenameUtils.getFullPath(configFilename)));
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -52,7 +52,7 @@ final class ConfigWizardPanel1 implements WizardDescriptor.ValidatingPanel<Wizar
component.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("UPDATE_UI")) { // NON-NLS
if (evt.getPropertyName().equals(ConfigVisualPanel1.getUpdateEventName())) { // NON-NLS
valid = component.isPanelValid();
fireChangeEvent();
}
@ -130,9 +130,8 @@ final class ConfigWizardPanel1 implements WizardDescriptor.ValidatingPanel<Wizar
@Override
public void storeSettings(WizardDescriptor wiz) {
// use wiz.putProperty to remember current panel state
wiz.putProperty("configFilename", component.getConfigFilename()); // NON-NLS
wiz.putProperty("configFilename", component.getConfigPath()); // NON-NLS
wiz.putProperty("config", component.getConfig()); // NON-NLS
wiz.putProperty("newFile", component.isNewFile()); // NON-NLS
}
@Override

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -18,32 +18,15 @@
*/
package org.sleuthkit.autopsy.logicalimager.configuration;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeListener;
import org.apache.commons.io.FileUtils;
import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.logicalimager.configuration.ConfigureLogicalImager.getTskLogicalImagerExe;
/**
* Configuration Wizard Panel 2
*/
final class ConfigWizardPanel2 implements WizardDescriptor.Panel<WizardDescriptor> {
private static final Logger LOGGER = Logger.getLogger(ConfigWizardPanel2.class.getName());
/**
* The visual component that displays this panel. If you need to access the
* component from this class, just use getComponent().
@ -87,7 +70,7 @@ final class ConfigWizardPanel2 implements WizardDescriptor.Panel<WizardDescripto
// use wiz.getProperty to retrieve previous panel state
configFilename = (String) wiz.getProperty("configFilename"); // NON-NLS
config = (LogicalImagerConfig) wiz.getProperty("config"); // NON-NLS
component.setConfiguration(configFilename, config, (boolean) wiz.getProperty("newFile"));
component.setConfiguration(configFilename, config);
}
@Override
@ -95,44 +78,6 @@ final class ConfigWizardPanel2 implements WizardDescriptor.Panel<WizardDescripto
// use wiz.putProperty to remember current panel state
}
@NbBundle.Messages({
"# {0} - configFilename",
"ConfigWizardPanel2.failedToSaveConfigMsg=Failed to save configuration file: {0}",
"# {0} - reason",
"ConfigWizardPanel2.reason=\nReason: ",
"ConfigWizardPanel2.failedToSaveExeMsg=Failed to save tsk_logical_imager.exe file",
})
void saveConfigFile() {
GsonBuilder gsonBuilder = new GsonBuilder()
.setPrettyPrinting()
.excludeFieldsWithoutExposeAnnotation()
.disableHtmlEscaping();
Gson gson = gsonBuilder.create();
String toJson = gson.toJson(config);
try {
List<String> lines = Arrays.asList(toJson.split("\\n"));
FileUtils.writeLines(new File(configFilename), "UTF-8", lines, System.getProperty("line.separator")); // NON-NLS
} catch (IOException ex) {
JOptionPane.showMessageDialog(component, Bundle.ConfigWizardPanel2_failedToSaveConfigMsg(configFilename)
+ Bundle.ConfigWizardPanel2_reason(ex.getMessage()));
} catch (JsonIOException jioe) {
LOGGER.log(Level.SEVERE, "Failed to save configuration file: " + configFilename, jioe); // NON-NLS
JOptionPane.showMessageDialog(component, Bundle.ConfigWizardPanel2_failedToSaveConfigMsg(configFilename)
+ Bundle.ConfigWizardPanel2_reason(jioe.getMessage()));
}
try {
writeTskLogicalImagerExe(Paths.get(configFilename).getParent());
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "Failed to save tsk_logical_imager.exe file", ex); // NON-NLS
JOptionPane.showMessageDialog(component, Bundle.ConfigWizardPanel2_failedToSaveExeMsg()
+ Bundle.ConfigWizardPanel2_reason(ex.getMessage()));
}
}
private void writeTskLogicalImagerExe(Path destDir) throws IOException {
FileUtils.copyFileToDirectory(getTskLogicalImagerExe(), destDir.toFile());
}
@Override
public void addChangeListener(ChangeListener cl) {
// Not used

View File

@ -0,0 +1,106 @@
/*
* Autopsy
*
* Copyright 2019 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.logicalimager.configuration;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx;
/**
* Configuration Wizard Panel 3
*/
final class ConfigWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
private final Set<ChangeListener> listeners = new HashSet<>(1); // or can use ChangeSupport in NB 6.0
private ConfigVisualPanel3 component;
@Override
public ConfigVisualPanel3 getComponent() {
if (component == null) {
component = new ConfigVisualPanel3();
component.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(ConfigVisualPanel3.getSavedEventName())) { // NON-NLS
fireChangeEvent();
}
}
});
}
return component;
}
@Override
public HelpCtx getHelp() {
return HelpCtx.DEFAULT_HELP;
}
@Override
public void readSettings(WizardDescriptor wiz) {
String configFilename = (String) wiz.getProperty("configFilename"); // NON-NLS
LogicalImagerConfig config = (LogicalImagerConfig) wiz.getProperty("config"); // NON-NLS
component.setConfigInfoForSaving(configFilename, config);
component.resetPanel();
}
@Override
public void storeSettings(WizardDescriptor data) {
//no settings to store
}
@Override
public boolean isValid() {
return component.isSaved();
}
/**
* Fire an envent to indicate that state of the wizard panel has changed
*/
private void fireChangeEvent() {
Iterator<ChangeListener> it;
synchronized (listeners) {
it = new HashSet<>(listeners).iterator();
}
ChangeEvent ev = new ChangeEvent(this);
while (it.hasNext()) {
it.next().stateChanged(ev);
}
}
@Override
public void addChangeListener(ChangeListener cl) {
synchronized (listeners) {
listeners.add(cl);
}
}
@Override
public void removeChangeListener(ChangeListener cl) {
synchronized (listeners) {
listeners.remove(cl);
}
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -19,7 +19,10 @@
package org.sleuthkit.autopsy.logicalimager.configuration;
import java.awt.Component;
import java.awt.Dialog;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
@ -29,37 +32,44 @@ import org.openide.WizardDescriptor;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.modules.InstalledFileLocator;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction;
import static org.sleuthkit.autopsy.coreutils.PlatformUtil.getInstallModulesPath;
/**
* Configuration Logical Imager
*/
@ActionID(
category = "Tools",
id = "org.sleuthkit.autopsy.configurelogicalimager.ConfigureLogicalImager"
)
@ActionRegistration(displayName = "#CTL_ConfigureLogicalImager", lazy = false)
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.logicalimager.configuration.CreateLogicalImagerAction")
@ActionRegistration(displayName = "#CTL_CreateLogicalImagerAction", lazy = false)
@ActionReference(path = "Menu/Tools", position = 2000, separatorBefore = 1999)
@Messages("CTL_ConfigureLogicalImager=Create Logical Imager")
public final class ConfigureLogicalImager extends CallableSystemAction {
@Messages("CTL_CreateLogicalImagerAction=Create Logical Imager")
public final class CreateLogicalImagerAction extends CallableSystemAction {
private static final String DISPLAY_NAME = Bundle.CTL_ConfigureLogicalImager();
private static final String TSK_LOGICAL_IMAGER_DIR = "tsk_logical_imager"; // NON-NLS
private static final String TSK_LOGICAL_IMAGER_EXE = "tsk_logical_imager.exe"; // NON-NLS
private static final long serialVersionUID = 1L;
private static final String LOGICAL_IMAGER_DIR = "tsk_logical_imager"; // NON-NLS
private static final String LOGICAL_IMAGER_EXE = "tsk_logical_imager.exe"; // NON-NLS
private static final Path LOGICAL_IMAGER_EXE_PATH = Paths.get(LOGICAL_IMAGER_DIR, LOGICAL_IMAGER_EXE);
/**
* Finds the installed logical imager executable.
*
* @return A File object for the executable or null if it is not found.
*/
static File getLogicalImagerExe() {
return InstalledFileLocator.getDefault().locate(LOGICAL_IMAGER_EXE_PATH.toString(), CreateLogicalImagerAction.class.getPackage().getName(), false);
}
@NbBundle.Messages({
"ConfigureLogicalImager.title=Configure Logical Imager"
"CreateLogicalImagerAction.title=Create Logical Imager"
})
@Override
public void performAction() {
List<WizardDescriptor.Panel<WizardDescriptor>> panels = new ArrayList<>();
panels.add(new ConfigWizardPanel1());
panels.add(new ConfigWizardPanel2());
panels.add(new ConfigWizardPanel3());
String[] steps = new String[panels.size()];
for (int i = 0; i < panels.size(); i++) {
Component c = panels.get(i).getComponent();
@ -77,17 +87,14 @@ public final class ConfigureLogicalImager extends CallableSystemAction {
WizardDescriptor wiz = new WizardDescriptor(new WizardDescriptor.ArrayIterator<>(panels));
// {0} will be replaced by WizardDesriptor.Panel.getComponent().getName()
wiz.setTitleFormat(new MessageFormat("{0}")); // NON-NLS
wiz.setTitle(Bundle.ConfigureLogicalImager_title());
if ((DialogDisplayer.getDefault().notify(wiz) == WizardDescriptor.FINISH_OPTION) &&
(panels.get(1) instanceof ConfigWizardPanel2)) {
ConfigWizardPanel2 panel = (ConfigWizardPanel2) panels.get(1);
panel.saveConfigFile();
}
wiz.setTitle(Bundle.CreateLogicalImagerAction_title());
Dialog dialog = DialogDisplayer.getDefault().createDialog(wiz);
dialog.setVisible(true);
}
@Override
public String getName() {
return DISPLAY_NAME;
return Bundle.CTL_CreateLogicalImagerAction();
}
@Override
@ -97,13 +104,8 @@ public final class ConfigureLogicalImager extends CallableSystemAction {
@Override
public boolean isEnabled() {
File tskLogicalImagerExe = getTskLogicalImagerExe();
return tskLogicalImagerExe.exists();
File logicalImagerExe = getLogicalImagerExe();
return logicalImagerExe != null && logicalImagerExe.exists();
}
static public File getTskLogicalImagerExe() {
String installModulesPath = getInstallModulesPath();
File tskLogicalImagerExe = new File(installModulesPath + File.separator + TSK_LOGICAL_IMAGER_DIR + File.separator + TSK_LOGICAL_IMAGER_EXE);
return tskLogicalImagerExe;
}
}

View File

@ -0,0 +1,40 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.logicalimager.configuration;
import java.text.NumberFormat;
import java.text.ParseException;
import javax.swing.text.NumberFormatter;
/**
* Number formatter which will reset to being a null value when an invalid value
* is entered
*/
final class DefaultToEmptyNumberFormatter extends NumberFormatter {
private static final long serialVersionUID = 1L;
/**
* Create a DefaultToEmptyNumberFormatter
*
* @param format the format for the numbers
*/
DefaultToEmptyNumberFormatter(NumberFormat format) {
super(format);
}
@Override
public Object stringToValue(String string)
throws ParseException {
Object returnValue = null;
try {
returnValue = super.stringToValue(string);
} catch (ParseException ignored) {
//reset value to being empty since invalid value was entered
}
return returnValue;
}
}

View File

@ -16,23 +16,31 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="shouldSaveCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
<Component id="jSeparator2" max="32767" attributes="0"/>
<Component id="jSeparator1" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="ruleNameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="descriptionLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="fullPathsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="ruleNameTextField" alignment="0" pref="519" max="32767" attributes="0"/>
<Component id="descriptionTextField" alignment="0" max="32767" attributes="0"/>
<Component id="fullPathsScrollPane" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="ruleNameLabel" linkSize="1" alignment="0" max="32767" attributes="0"/>
<Component id="fullPathsLabel" linkSize="1" alignment="0" max="32767" attributes="0"/>
<Component id="jLabel1" linkSize="1" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="ruleNameTextField" linkSize="2" alignment="0" min="-2" pref="648" max="-2" attributes="0"/>
<Component id="descriptionTextField" linkSize="2" alignment="0" min="-2" pref="648" max="-2" attributes="0"/>
<Component id="fullPathsScrollPane" linkSize="2" min="-2" pref="648" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="shouldSaveCheckBox" min="-2" max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
@ -42,7 +50,7 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="ruleNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="ruleNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
@ -50,20 +58,26 @@
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="descriptionTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="descriptionLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSeparator1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="fullPathsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="167" max="32767" attributes="0"/>
<EmptySpace min="0" pref="115" max="32767" attributes="0"/>
</Group>
<Component id="fullPathsScrollPane" max="32767" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSeparator2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="shouldSaveCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@ -77,6 +91,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditFullPathsRulePanel.shouldSaveCheckBox.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="shouldSaveCheckBoxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="shouldAlertCheckBox">
<Properties>
@ -87,6 +104,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditFullPathsRulePanel.shouldAlertCheckBox.actionCommand" 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="shouldAlertCheckBoxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="fullPathsLabel">
<Properties>
@ -96,39 +116,49 @@
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditFullPathsRulePanel.fullPathsLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 14]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="descriptionTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditFullPathsRulePanel.descriptionTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="descriptionLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditFullPathsRulePanel.descriptionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="ruleNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditFullPathsRulePanel.ruleNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 14]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="ruleNameTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditFullPathsRulePanel.ruleNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="fullPathsScrollPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
</Container>
<Component class="javax.swing.JSeparator" name="jSeparator1">
</Component>
<Component class="javax.swing.JSeparator" name="jSeparator2">
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditFullPathsRulePanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 14]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditFullPathsRulePanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -28,6 +28,10 @@ import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.openide.util.NbBundle;
@ -64,10 +68,45 @@ final class EditFullPathsRulePanel extends javax.swing.JPanel {
EditRulePanel.setTextFieldPrompts(fullPathsTextArea,
"<html>" + Bundle.EditFullPathsRulePanel_example() + "<br>/Program Files/Common Files/system/wab32.dll<br>/Windows/System32/1033/VsGraphicsResources.dll</html>"); // NON-NLS
ruleNameTextField.requestFocus();
addDocumentListeners();
validate();
repaint();
}
/**
* Update the OK button when contents of a field change
*/
private void addDocumentListeners() {
SwingUtilities.invokeLater(() -> {
setOkButton(); //ensure initial state before listeners added is correct
});
DocumentListener docListener;
docListener = new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
setOkButton();
}
@Override
public void insertUpdate(DocumentEvent e) {
setOkButton();
}
@Override
public void removeUpdate(DocumentEvent e) {
setOkButton();
}
};
ruleNameTextField.getDocument().addDocumentListener(docListener);
fullPathsTextArea.getDocument().addDocumentListener(docListener);
}
/**
* Initialize the text area and the scroll pane viewing it
*
* @param pane the JScrollPane which will be viewing the JTextArea
* @param textArea the JTextArea being initialized
*/
private void initTextArea(JScrollPane pane, JTextArea textArea) {
textArea.setColumns(20);
textArea.setRows(5);
@ -100,27 +139,41 @@ final class EditFullPathsRulePanel extends javax.swing.JPanel {
shouldAlertCheckBox = new javax.swing.JCheckBox();
fullPathsLabel = new javax.swing.JLabel();
descriptionTextField = new javax.swing.JTextField();
descriptionLabel = new javax.swing.JLabel();
ruleNameLabel = new javax.swing.JLabel();
ruleNameTextField = new javax.swing.JTextField();
fullPathsScrollPane = new javax.swing.JScrollPane();
jSeparator1 = new javax.swing.JSeparator();
jSeparator2 = new javax.swing.JSeparator();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
shouldSaveCheckBox.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(shouldSaveCheckBox, org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.shouldSaveCheckBox.text")); // NOI18N
shouldSaveCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
shouldSaveCheckBoxActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(shouldAlertCheckBox, org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.shouldAlertCheckBox.text")); // NOI18N
shouldAlertCheckBox.setActionCommand(org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.shouldAlertCheckBox.actionCommand")); // NOI18N
shouldAlertCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
shouldAlertCheckBoxActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(fullPathsLabel, org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.fullPathsLabel.text")); // NOI18N
fullPathsLabel.setToolTipText(org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.fullPathsLabel.toolTipText")); // NOI18N
descriptionTextField.setText(org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.descriptionTextField.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(descriptionLabel, org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.descriptionLabel.text")); // NOI18N
fullPathsLabel.setPreferredSize(new java.awt.Dimension(112, 14));
org.openide.awt.Mnemonics.setLocalizedText(ruleNameLabel, org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.ruleNameLabel.text")); // NOI18N
ruleNameLabel.setPreferredSize(new java.awt.Dimension(112, 14));
ruleNameTextField.setText(org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.ruleNameTextField.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.jLabel1.text")); // NOI18N
jLabel1.setPreferredSize(new java.awt.Dimension(112, 14));
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(EditFullPathsRulePanel.class, "EditFullPathsRulePanel.jLabel2.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
@ -129,51 +182,79 @@ final class EditFullPathsRulePanel extends javax.swing.JPanel {
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(shouldSaveCheckBox)
.addComponent(shouldAlertCheckBox)
.addComponent(jSeparator2)
.addComponent(jSeparator1)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(ruleNameLabel)
.addComponent(descriptionLabel)
.addComponent(fullPathsLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(ruleNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 519, Short.MAX_VALUE)
.addComponent(descriptionTextField)
.addComponent(fullPathsScrollPane))))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(fullPathsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(0, 0, 0)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 648, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(descriptionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 648, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fullPathsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 648, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addComponent(shouldSaveCheckBox)
.addComponent(shouldAlertCheckBox)
.addComponent(jLabel2))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {fullPathsLabel, jLabel1, ruleNameLabel});
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {descriptionTextField, fullPathsScrollPane, ruleNameTextField});
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGap(8, 8, 8)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(ruleNameLabel)
.addComponent(ruleNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(ruleNameTextField, 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.BASELINE)
.addComponent(descriptionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(descriptionLabel))
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator1, 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)
.addGroup(layout.createSequentialGroup()
.addComponent(fullPathsLabel)
.addGap(0, 167, Short.MAX_VALUE))
.addComponent(fullPathsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 115, Short.MAX_VALUE))
.addComponent(fullPathsScrollPane))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(shouldAlertCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(shouldSaveCheckBox)
.addGap(3, 3, 3)
.addComponent(shouldAlertCheckBox)
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void shouldSaveCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_shouldSaveCheckBoxActionPerformed
setOkButton();
}//GEN-LAST:event_shouldSaveCheckBoxActionPerformed
private void shouldAlertCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_shouldAlertCheckBoxActionPerformed
setOkButton();
}//GEN-LAST:event_shouldAlertCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel descriptionLabel;
private javax.swing.JTextField descriptionTextField;
private javax.swing.JLabel fullPathsLabel;
private javax.swing.JScrollPane fullPathsScrollPane;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JSeparator jSeparator2;
private javax.swing.JLabel ruleNameLabel;
private javax.swing.JTextField ruleNameTextField;
private javax.swing.JCheckBox shouldAlertCheckBox;
@ -184,9 +265,9 @@ final class EditFullPathsRulePanel extends javax.swing.JPanel {
* Sets whether or not the OK button should be enabled based upon other UI
* elements
*/
private void setOkButton() {
void setOkButton() {
if (this.okButton != null) {
this.okButton.setEnabled(true);
this.okButton.setEnabled(!StringUtils.isBlank(ruleNameTextField.getText()) && !StringUtils.isBlank(fullPathsTextArea.getText()) && (shouldAlertCheckBox.isSelected() || shouldSaveCheckBox.isSelected()));
}
}
@ -224,9 +305,14 @@ final class EditFullPathsRulePanel extends javax.swing.JPanel {
JOptionPane pane = getOptionPane(cancelButton);
pane.setValue(cancelButton);
});
this.setOkButton();
}
/**
* Set the name description and should alert / should save checkboxes
*
* @param ruleName the name of the rule
* @param rule the LogicalImagerRule
*/
private void setRule(String ruleName, LogicalImagerRule rule) {
ruleNameTextField.setText(ruleName);
descriptionTextField.setText(rule.getDescription());
@ -234,17 +320,31 @@ final class EditFullPathsRulePanel extends javax.swing.JPanel {
shouldSaveCheckBox.setSelected(rule.isShouldSave());
}
private void setTextArea(JTextArea textArea, List<String> set) {
/**
* Set the text of a text area to contain the contents of the list each on
* its own line
*
* @param textArea the text area to set the contents of
* @param list the list of strings to display in the text area
*/
private void setTextArea(JTextArea textArea, List<String> list) {
String text = "";
for (String s : set) {
for (String s : list) {
text += s + System.getProperty("line.separator"); // NON-NLS
}
textArea.setText(text);
}
/**
* Convert the contents of this panel to a rule and return it as well as its
* name.
*
* @return an ImmutablePair containing the name of the rule and the rule
*
* @throws IOException
*/
@NbBundle.Messages({
"EditFullPathsRulePanel.fullPaths=Full paths",
})
"EditFullPathsRulePanel.fullPaths=Full paths",})
ImmutablePair<String, LogicalImagerRule> toRule() throws IOException {
List<String> fullPaths = EditRulePanel.validateTextList(fullPathsTextArea, Bundle.EditFullPathsRulePanel_fullPaths());
String ruleName = EditRulePanel.validRuleName(ruleNameTextField.getText());

View File

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="buttonGroup">
</Component>
</NonVisualComponents>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
@ -21,61 +17,68 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jSeparator2" alignment="0" max="32767" attributes="0"/>
<Component id="jSeparator1" alignment="0" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="extensionsRadioButton" min="-2" max="-2" attributes="0"/>
<Component id="filenamesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="ruleNameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="descriptionLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="extensionsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="filenamesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="folderNamesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="modifiedDateLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="folderNamesScrollPane" alignment="1" max="32767" attributes="0"/>
<Component id="filenamesScrollPane" alignment="1" max="32767" attributes="0"/>
<Component id="extensionsTextField" alignment="1" max="32767" attributes="0"/>
<Component id="descriptionTextField" alignment="1" max="32767" attributes="0"/>
<Component id="ruleNameTextField" alignment="1" max="32767" attributes="0"/>
<Component id="shouldAlertCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="shouldSaveCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="fileNamesCheckbox" linkSize="2" alignment="0" min="-2" pref="112" max="-2" attributes="0"/>
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
<Component id="modifiedWithinCheckbox" linkSize="2" max="32767" attributes="0"/>
<Component id="maxSizeCheckbox" linkSize="2" max="32767" attributes="0"/>
</Group>
<Component id="jLabel1" alignment="0" min="-2" pref="120" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
<Component id="extensionsCheckbox" linkSize="2" alignment="0" max="32767" attributes="0"/>
<Component id="ruleNameLabel" linkSize="2" alignment="0" max="32767" attributes="0"/>
<Component id="descriptionLabel" linkSize="2" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="minSizeCheckbox" linkSize="2" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="folderNamesCheckbox" linkSize="2" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="ruleNameTextField" alignment="1" max="32767" attributes="0"/>
<Component id="descriptionTextField" alignment="1" max="32767" attributes="0"/>
<Component id="extensionsTextField" alignment="1" max="32767" attributes="0"/>
<Component id="folderNamesScrollPane" max="32767" attributes="0"/>
<Component id="filenamesScrollPane" alignment="1" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="shouldSaveCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="108" pref="108" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="minDaysTextField" max="32767" attributes="0"/>
<Component id="minSizeLabel" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="minSizeTextField" min="-2" pref="63" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="maxSizeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="maxSizeTextField" min="-2" pref="63" max="-2" attributes="0"/>
<Component id="fileNamesInfoLabel" min="-2" max="-2" attributes="0"/>
<Component id="extensionsInfoLabel" min="-2" max="-2" attributes="0"/>
<Group type="103" alignment="0" groupAlignment="1" attributes="0">
<Component id="jLabel2" min="-2" pref="522" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="userFolderNote" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Component id="minSizeTextField" linkSize="1" min="-2" pref="63" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="minSizeUnitsCombobox" linkSize="3" min="-2" pref="110" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="modifiedWithinTextField" linkSize="1" min="-2" pref="63" max="-2" attributes="0"/>
<Component id="maxSizeTextField" linkSize="1" min="-2" pref="63" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="maxSizeUnitsCombobox" linkSize="3" min="-2" pref="110" max="-2" attributes="0"/>
<Component id="daysIncludedLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
<Component id="daysIncludedLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="11" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="236" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
@ -85,69 +88,79 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Group type="103" groupAlignment="2" attributes="0">
<Component id="ruleNameLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="ruleNameTextField" alignment="2" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="2" attributes="0">
<Component id="descriptionLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="descriptionTextField" alignment="2" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="descriptionTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="descriptionLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="2" attributes="0">
<Component id="extensionsTextField" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="extensionsLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="extensionsRadioButton" alignment="2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSeparator2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="extensionsTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="extensionsCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="extensionsInfoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="filenamesScrollPane" alignment="0" pref="70" max="32767" attributes="0"/>
<Component id="filenamesScrollPane" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="2" attributes="0">
<Component id="filenamesLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="filenamesRadioButton" alignment="2" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="fileNamesCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="fileNamesInfoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="folderNamesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="folderNamesScrollPane" alignment="0" pref="71" max="32767" attributes="0"/>
<Component id="folderNamesScrollPane" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="folderNamesCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="2" attributes="0">
<Component id="fileSizeLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="minSizeLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="minSizeTextField" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="maxSizeLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="maxSizeTextField" alignment="2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="userFolderNote" min="-2" pref="16" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="minSizeTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="minSizeCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="minSizeUnitsCombobox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="maxSizeTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="maxSizeCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="maxSizeUnitsCombobox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="2" attributes="0">
<Component id="modifiedDateLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="daysIncludedLabel" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="minDaysTextField" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="modifiedWithinTextField" alignment="2" min="-2" max="-2" attributes="0"/>
<Component id="modifiedWithinCheckbox" alignment="2" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSeparator1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="shouldSaveCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="shouldAlertCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="modifiedDateLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.modifiedDateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="daysIncludedLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -162,6 +175,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.shouldSaveCheckBox.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="shouldSaveCheckBoxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="shouldAlertCheckBox">
<Properties>
@ -172,151 +188,227 @@
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.shouldAlertCheckBox.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="extensionsLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.extensionsLabel.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="shouldAlertCheckBoxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="extensionsTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.extensionsTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="filenamesLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.filenamesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="folderNamesLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.folderNamesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="fileSizeLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.fileSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="descriptionTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.descriptionTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="descriptionLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.descriptionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="ruleNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.ruleNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="ruleNameTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.ruleNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 14]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="ruleNameTextField">
</Component>
<Container class="javax.swing.JScrollPane" name="filenamesScrollPane">
<Properties>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.filenamesScrollPane.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
</Container>
<Container class="javax.swing.JScrollPane" name="folderNamesScrollPane">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
</Container>
<Component class="javax.swing.JLabel" name="minSizeLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.minSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JFormattedTextField" name="minSizeTextField">
<Properties>
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.editors.AbstractFormatterFactoryEditor">
<Format format="#,###; " subtype="-1" type="0"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.minSizeTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="maxSizeLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.maxSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.text.DefaultFormatterFactory(new DefaultToEmptyNumberFormatter(new java.text.DecimalFormat(&quot;#,###; &quot;)))" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JFormattedTextField" name="maxSizeTextField">
<Properties>
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.editors.AbstractFormatterFactoryEditor">
<Format format="#,###; " subtype="-1" type="0"/>
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.text.DefaultFormatterFactory(new DefaultToEmptyNumberFormatter(new java.text.DecimalFormat(&quot;#,###; &quot;)))" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JFormattedTextField" name="modifiedWithinTextField">
<Properties>
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.text.DefaultFormatterFactory(new DefaultToEmptyNumberFormatter(new java.text.DecimalFormat(&quot;#,###; &quot;)))" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="userFolderNote">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/info-icon-16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.maxSizeTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.userFolderNote.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JFormattedTextField" name="minDaysTextField">
<Component class="javax.swing.JCheckBox" name="minSizeCheckbox">
<Properties>
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.editors.AbstractFormatterFactoryEditor">
<Format format="####; " subtype="-1" type="0"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="extensionsRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.extensionsRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.minSizeCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.extensionsRadioButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="extensionsRadioButtonActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="minSizeCheckboxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="filenamesRadioButton">
<Component class="javax.swing.JCheckBox" name="maxSizeCheckbox">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.filenamesRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.maxSizeCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.filenamesRadioButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="filenamesRadioButtonActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="maxSizeCheckboxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="modifiedWithinCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.modifiedWithinCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="modifiedWithinCheckboxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="folderNamesCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.folderNamesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="folderNamesCheckboxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="fileNamesCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.fileNamesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fileNamesCheckboxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="extensionsCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.extensionsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="extensionsCheckboxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JComboBox" name="minSizeUnitsCombobox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;String&gt;(new String[] { Bundle.EditNonFullPathsRulePanel_units_bytes(), Bundle.EditNonFullPathsRulePanel_units_kilobytes(), Bundle.EditNonFullPathsRulePanel_units_megabytes(), Bundle.EditNonFullPathsRulePanel_units_gigabytes()})" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JComboBox" name="maxSizeUnitsCombobox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;String&gt;(new String[] { Bundle.EditNonFullPathsRulePanel_units_bytes(), Bundle.EditNonFullPathsRulePanel_units_kilobytes(), Bundle.EditNonFullPathsRulePanel_units_megabytes(), Bundle.EditNonFullPathsRulePanel_units_gigabytes()})" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JSeparator" name="jSeparator1">
</Component>
<Component class="javax.swing.JSeparator" name="jSeparator2">
</Component>
<Component class="javax.swing.JLabel" name="descriptionLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.descriptionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 14]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="extensionsInfoLabel">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/info-icon-16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.extensionsInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="fileNamesInfoLabel">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/info-icon-16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="EditNonFullPathsRulePanel.fileNamesInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -38,17 +38,20 @@ import org.sleuthkit.autopsy.corecomponents.TextPrompt;
*/
final class EditRulePanel extends JPanel {
private EditFullPathsRulePanel editFullPathsRulePanel = null;
private EditNonFullPathsRulePanel editNonFullPathsRulePanel = null;
private static final long serialVersionUID = 1L;
private final EditFullPathsRulePanel editFullPathsRulePanel;
private final EditNonFullPathsRulePanel editNonFullPathsRulePanel;
/**
* Creates new form EditRulePanel
*/
EditRulePanel(JButton okButton, JButton cancelButton, String ruleName, LogicalImagerRule rule) {
EditRulePanel(JButton okButton, JButton cancelButton, String ruleName, LogicalImagerRule rule) {
if (rule.getFullPaths() != null && rule.getFullPaths().size() > 0) {
editFullPathsRulePanel = new EditFullPathsRulePanel(okButton, cancelButton, ruleName, rule, true);
editNonFullPathsRulePanel = null;
} else {
editNonFullPathsRulePanel = new EditNonFullPathsRulePanel(okButton, cancelButton, ruleName, rule, true);
editFullPathsRulePanel = null;
}
}
@ -66,7 +69,7 @@ final class EditRulePanel extends JPanel {
ruleMap = editFullPathsRulePanel.toRule();
} else {
ruleMap = editNonFullPathsRulePanel.toRule();
}
}
return ruleMap;
}
@ -89,30 +92,34 @@ final class EditRulePanel extends JPanel {
}
@NbBundle.Messages({
"EditRulePanel.validateRuleNameExceptionMsg=Rule name cannot be empty"
})
"EditRulePanel.emptyRuleName.message=Rule name cannot be empty",
"# {0} - ruleName",
"EditRulePanel.reservedRuleName.message=Rule name \"{0}\" is reserved for use with a predefined rule"})
static String validRuleName(String name) throws IOException {
if (name.isEmpty()) {
throw new IOException(Bundle.EditRulePanel_validateRuleNameExceptionMsg());
throw new IOException(Bundle.EditRulePanel_emptyRuleName_message());
}
if (name.equals(EncryptionProgramsRule.getName())) {
throw new IOException(Bundle.EditRulePanel_reservedRuleName_message(name));
}
//TODO JIRA-5239 check if rule name exists already
return name;
}
@NbBundle.Messages({
"# {0} - fieldName",
"EditRulePanel.blankLineException={0} cannot have a blank line",
})
"EditRulePanel.blankLineException={0} cannot have a blank line",})
static List<String> validateTextList(JTextArea textArea, String fieldName) throws IOException {
if (isBlank(textArea.getText())) {
return null;
}
List<String> list = new ArrayList<>();
for (String line : textArea.getText().split("\\n")) { // NON-NLS
line = strip(line);
if (line.isEmpty()) {
String strippedLine = strip(line);
if (strippedLine.isEmpty()) {
throw new IOException(Bundle.EditRulePanel_blankLineException(fieldName));
}
list.add(line);
list.add(strippedLine);
}
if (list.isEmpty()) {
return null;

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -35,9 +35,10 @@ final class EncryptionProgramsRule {
private static final String ENCRYPTION_PROGRAMS_RULE_DESCRIPTION = Bundle.EncryptionProgramsRule_encryptionProgramsRuleDescription();
private static final List<String> FILENAMES = new ArrayList<>();
private EncryptionProgramsRule() {}
private EncryptionProgramsRule() {
//private no arg constructor intentionally blank
}
// TODO: Add more files here
static {
// Truecrypt
FILENAMES.add("truecrypt.exe"); // NON-NLS

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -38,8 +38,7 @@ import org.openide.util.NbBundle;
"LogicalImagerConfigDeserializer.missingRuleSetException=Missing rule-set",
"# {0} - key",
"LogicalImagerConfigDeserializer.unsupportedKeyException=Unsupported key: {0}",
"LogicalImagerConfigDeserializer.fullPathsException=A rule with full-paths cannot have other rule definitions",
})
"LogicalImagerConfigDeserializer.fullPathsException=A rule with full-paths cannot have other rule definitions",})
class LogicalImagerConfigDeserializer implements JsonDeserializer<LogicalImagerConfig> {
@Override
@ -64,7 +63,7 @@ class LogicalImagerConfigDeserializer implements JsonDeserializer<LogicalImagerC
}
List<LogicalImagerRuleSet> ruleSets = new ArrayList<>();
for (JsonElement element: asJsonArray) {
for (JsonElement element : asJsonArray) {
String setName = null;
List<LogicalImagerRule> rules = null;
JsonObject asJsonObject = element.getAsJsonObject();
@ -81,7 +80,7 @@ class LogicalImagerConfigDeserializer implements JsonDeserializer<LogicalImagerC
private List<LogicalImagerRule> parseRules(JsonArray asJsonArray) {
List<LogicalImagerRule> rules = new ArrayList<>();
for (JsonElement element: asJsonArray) {
for (JsonElement element : asJsonArray) {
String key1;
Boolean shouldSave = false;
Boolean shouldAlert = true;
@ -91,8 +90,8 @@ class LogicalImagerConfigDeserializer implements JsonDeserializer<LogicalImagerC
List<String> paths = null;
List<String> fullPaths = null;
List<String> filenames = null;
Integer minFileSize = null;
Integer maxFileSize = null;
Long minFileSize = null;
Long maxFileSize = null;
Integer minDays = null;
Integer minDate = null;
Integer maxDate = null;
@ -149,10 +148,10 @@ class LogicalImagerConfigDeserializer implements JsonDeserializer<LogicalImagerC
String sizeKey = entry2.getKey();
switch (sizeKey) {
case "min": // NON-NLS
minFileSize = entry2.getValue().getAsInt();
minFileSize = entry2.getValue().getAsLong();
break;
case "max": // NON-NLS
maxFileSize = entry2.getValue().getAsInt();
maxFileSize = entry2.getValue().getAsLong();
break;
default:
throw new JsonParseException(Bundle.LogicalImagerConfigDeserializer_unsupportedKeyException(sizeKey));
@ -212,7 +211,3 @@ class LogicalImagerConfigDeserializer implements JsonDeserializer<LogicalImagerC
return rules;
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -52,16 +52,16 @@ class LogicalImagerRule {
private List<String> fullPaths = new ArrayList<>();
@SerializedName("size-range")
@Expose(serialize = true)
final private Map<String, Integer> sizeRange = new HashMap<>();
final private Map<String, Long> sizeRange = new HashMap<>();
@SerializedName("date-range")
@Expose(serialize = true)
final private Map<String, Integer> dateRange = new HashMap<>();
// The following fields should not be serialized, internal use only
@Expose(serialize = false)
private Integer minFileSize;
private Long minFileSize;
@Expose(serialize = false)
private Integer maxFileSize;
private Long maxFileSize;
@Expose(serialize = false)
private Integer minDays;
@Expose(serialize = false)
@ -74,8 +74,8 @@ class LogicalImagerRule {
List<String> filenames,
List<String> paths,
List<String> fullPaths,
Integer minFileSize,
Integer maxFileSize,
Long minFileSize,
Long maxFileSize,
Integer minDays,
Integer minDate,
Integer maxDate
@ -140,11 +140,11 @@ class LogicalImagerRule {
return fullPaths;
}
Integer getMinFileSize() {
Long getMinFileSize() {
return minFileSize;
}
Integer getMaxFileSize() {
Long getMaxFileSize() {
return maxFileSize;
}
@ -164,6 +164,7 @@ class LogicalImagerRule {
* Builder class
*/
static class Builder {
private Boolean shouldAlert = null;
private Boolean shouldSave = null;
private String name = null;
@ -172,8 +173,8 @@ class LogicalImagerRule {
private List<String> filenames = null;
private List<String> paths = null;
private List<String> fullPaths = null;
private Integer minFileSize = null;
private Integer maxFileSize = null;
private Long minFileSize = null;
private Long maxFileSize = null;
private Integer minDays = null;
private Integer minDate = null;
private Integer maxDate = null;
@ -218,12 +219,12 @@ class LogicalImagerRule {
return this;
}
Builder getMinFileSize(Integer minFileSize) {
Builder getMinFileSize(Long minFileSize) {
this.minFileSize = minFileSize;
return this;
}
Builder getMaxFileSize(Integer maxFileSize) {
Builder getMaxFileSize(Long maxFileSize) {
this.maxFileSize = maxFileSize;
return this;
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -49,8 +49,8 @@ class LogicalImagerRuleSet {
}
/*
* Find a rule with the given name. Return null if not found.
*/
* Find a rule with the given name. Return null if not found.
*/
LogicalImagerRule find(String name) {
for (LogicalImagerRule rule : rules) {
if (rule.getName().equals(name)) {

View File

@ -22,7 +22,9 @@
<Component id="chooseLabel" max="32767" attributes="0"/>
<Component id="chooseComboBox" max="32767" attributes="0"/>
</Group>
<EmptySpace pref="716" max="32767" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="ruleDescription" min="-2" pref="562" max="-2" attributes="0"/>
<EmptySpace pref="114" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
@ -37,7 +39,10 @@
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="chooseLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="chooseComboBox" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="chooseComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="ruleDescription" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="sharedLayeredPane" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
@ -49,18 +54,15 @@
<Component class="javax.swing.JLabel" name="chooseLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="NewRuleSetPanel.chooseLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties" key="NewRulePanel.chooseLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="chooseComboBox">
<Properties>
<Property name="maximumRowCount" type="int" value="2"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="2">
<StringItem index="0" value="By Attribute"/>
<StringItem index="1" value="By Full Path"/>
</StringArray>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;&gt;(new String[] {Bundle.NewRuleSetPanel_attributeRule_name(), Bundle.NewRuleSetPanel_fullPathRule_name()})" type="code"/>
</Property>
</Properties>
<Events>
@ -80,10 +82,12 @@
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="373" max="32767" attributes="0"/>
<EmptySpace min="0" pref="467" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
</Container>
<Component class="javax.swing.JLabel" name="ruleDescription">
</Component>
</SubComponents>
</Form>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -20,16 +20,20 @@ package org.sleuthkit.autopsy.logicalimager.configuration;
import java.awt.BorderLayout;
import java.io.IOException;
import java.util.logging.Level;
import javax.swing.JButton;
import javax.swing.JPanel;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* New rule set panel
*/
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
class NewRuleSetPanel extends javax.swing.JPanel {
class NewRulePanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(NewRulePanel.class.getName());
private final JPanel nonFullPathsJPanel;
private final EditNonFullPathsRulePanel editNonFullPathsRulePanel;
private final JPanel fullPathsPanel;
@ -38,7 +42,7 @@ class NewRuleSetPanel extends javax.swing.JPanel {
/**
* Creates new form NewRuleSetPanel
*/
NewRuleSetPanel(JButton okButton, JButton cancelButton) {
NewRulePanel(JButton okButton, JButton cancelButton) {
initComponents();
nonFullPathsJPanel = createPanel();
@ -52,12 +56,13 @@ class NewRuleSetPanel extends javax.swing.JPanel {
sharedLayeredPane.add(nonFullPathsJPanel, Integer.valueOf(0));
sharedLayeredPane.add(fullPathsPanel, Integer.valueOf(1));
nonFullPathsJPanel.setVisible(true);
ruleDescription.setText(Bundle.NewRuleSetPanel_attributeRule_description());
fullPathsPanel.setVisible(false);
}
private JPanel createPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setSize(800, 640);
panel.setSize(800, 650);
return panel;
}
@ -66,6 +71,10 @@ class NewRuleSetPanel extends javax.swing.JPanel {
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@Messages({"NewRuleSetPanel.attributeRule.name=Attribute",
"NewRuleSetPanel.fullPathRule.name=Full Path",
"NewRuleSetPanel.attributeRule.description=Search for files based on one or more attributes or metadata fields.",
"NewRuleSetPanel.fullPathRule.description=Search for files based on full exact match path."})
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
@ -73,11 +82,12 @@ class NewRuleSetPanel extends javax.swing.JPanel {
chooseLabel = new javax.swing.JLabel();
chooseComboBox = new javax.swing.JComboBox<>();
sharedLayeredPane = new javax.swing.JLayeredPane();
ruleDescription = new javax.swing.JLabel();
org.openide.awt.Mnemonics.setLocalizedText(chooseLabel, org.openide.util.NbBundle.getMessage(NewRuleSetPanel.class, "NewRuleSetPanel.chooseLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(chooseLabel, org.openide.util.NbBundle.getMessage(NewRulePanel.class, "NewRulePanel.chooseLabel.text")); // NOI18N
chooseComboBox.setMaximumRowCount(2);
chooseComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "By Attribute", "By Full Path" }));
chooseComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] {Bundle.NewRuleSetPanel_attributeRule_name(), Bundle.NewRuleSetPanel_fullPathRule_name()}));
chooseComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chooseComboBoxActionPerformed(evt);
@ -92,7 +102,7 @@ class NewRuleSetPanel extends javax.swing.JPanel {
);
sharedLayeredPaneLayout.setVerticalGroup(
sharedLayeredPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 373, Short.MAX_VALUE)
.addGap(0, 467, Short.MAX_VALUE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
@ -104,7 +114,9 @@ class NewRuleSetPanel extends javax.swing.JPanel {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(chooseLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chooseComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(716, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(ruleDescription, javax.swing.GroupLayout.PREFERRED_SIZE, 562, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(114, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(sharedLayeredPane)
@ -116,7 +128,9 @@ class NewRuleSetPanel extends javax.swing.JPanel {
.addContainerGap()
.addComponent(chooseLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chooseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(chooseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(ruleDescription, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sharedLayeredPane)
.addContainerGap())
@ -125,18 +139,29 @@ class NewRuleSetPanel extends javax.swing.JPanel {
private void chooseComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chooseComboBoxActionPerformed
int index = chooseComboBox.getSelectedIndex();
if (index == 0) {
if (chooseComboBox.getItemAt(index).equals(Bundle.NewRuleSetPanel_attributeRule_name())) {
nonFullPathsJPanel.setVisible(true);
editNonFullPathsRulePanel.setOkButton();
ruleDescription.setText(Bundle.NewRuleSetPanel_attributeRule_description());
fullPathsPanel.setVisible(false);
} else {
} else if (chooseComboBox.getItemAt(index).equals(Bundle.NewRuleSetPanel_fullPathRule_name())) {
nonFullPathsJPanel.setVisible(false);
ruleDescription.setText(Bundle.NewRuleSetPanel_fullPathRule_description());
fullPathsPanel.setVisible(true);
editFullPathsRulePanel.setOkButton();
} else {
logger.log(Level.WARNING, "Rule type selected was not one of the expected rule types");
nonFullPathsJPanel.setVisible(false);
fullPathsPanel.setVisible(false);
ruleDescription.setText("");
}
}//GEN-LAST:event_chooseComboBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JComboBox<String> chooseComboBox;
private javax.swing.JLabel chooseLabel;
private javax.swing.JLabel ruleDescription;
private javax.swing.JLayeredPane sharedLayeredPane;
// End of variables declaration//GEN-END:variables
@ -146,7 +171,7 @@ class NewRuleSetPanel extends javax.swing.JPanel {
ruleMap = editNonFullPathsRulePanel.toRule();
} else {
ruleMap = editFullPathsRulePanel.toRule();
}
}
return ruleMap;
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2013-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -36,10 +36,9 @@ import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A runnable that
* - copy the logical image folder to a destination folder
* - add alert.txt and users.txt files to report
* - add an image data source to the case database.
* A runnable that - copy the logical image folder to a destination folder - add
* alert.txt and users.txt files to report - add an image data source to the
* case database.
*/
final class AddLogicalImageTask extends AddMultipleImageTask {
@ -66,9 +65,8 @@ final class AddLogicalImageTask extends AddMultipleImageTask {
}
/**
* Copy the src directory to dest.
* Add alert.txt and users.txt to the case report
* Adds the image to the case database.
* Copy the src directory to dest. Add alert.txt and users.txt to the case
* report Adds the image to the case database.
*/
@Messages({
"# {0} - src", "# {1} - dest", "AddLogicalImageTask.copyingImageFromTo=Copying image from {0} to {1}",
@ -122,6 +120,7 @@ final class AddLogicalImageTask extends AddMultipleImageTask {
*
* @param reportPath Path to the report to be added
* @param reportName Name associated the report
*
* @returns null if success, or exception message if failure
*
*/

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2013-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -61,10 +61,9 @@ class AddMultipleImageTask implements Runnable {
private volatile boolean cancelled;
/**
* Constructs a runnable that adds multiple image files
* to a case database. If Sleuth Kit fails to find a filesystem
* in any of input image files, the file is added to the case as a
* local/logical file instead.
* Constructs a runnable that adds multiple image files to a case database.
* If Sleuth Kit fails to find a filesystem in any of input image files, the
* file is added to the case as a local/logical file instead.
*
* @param deviceId An ASCII-printable identifier for the device
* associated with the data source that is intended
@ -76,13 +75,13 @@ class AddMultipleImageTask implements Runnable {
* @param progressMonitor Progress monitor for reporting progress during
* processing.
* @param callback Callback to call when processing is done.
* @throws NoCurrentCaseException The exception if there is no open case.
*
* @throws NoCurrentCaseException The exception if there is no open case.
*/
@Messages({
"# {0} - file", "AddMultipleImageTask.addingFileAsLogicalFile=Adding: {0} as logical file",
"# {0} - deviceId", "# {1} - exceptionMessage",
"AddMultipleImageTask.errorAddingImgWithoutFileSystem=Error adding images without file systems for device %s: %s",
})
"AddMultipleImageTask.errorAddingImgWithoutFileSystem=Error adding images without file systems for device %s: %s",})
AddMultipleImageTask(String deviceId, List<String> imageFilePaths, String timeZone,
DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) throws NoCurrentCaseException {
this.deviceId = deviceId;
@ -171,9 +170,9 @@ class AddMultipleImageTask implements Runnable {
* added to this list for eventual return to
* the caller via the callback.
* @param localFileDataSourcePaths If the image cannot be added because
* Sleuth Kit cannot detect a filesystem, the
* image file path is added to this list for
* later addition as a part of a
* Sleuth Kit cannot detect a filesystem,
* the image file path is added to this list
* for later addition as a part of a
* local/logical files data source.
* @param errorMessages If there are any error messages, the
* error messages are added to this list for
@ -184,8 +183,7 @@ class AddMultipleImageTask implements Runnable {
"# {0} - imageFilePath", "AddMultipleImageTask.adding=Adding: {0}",
"# {0} - imageFilePath", "# {1} - deviceId", "# {2} - exceptionMessage", "AddMultipleImageTask.criticalErrorAdding=Critical error adding {0} for device {1}: {2}",
"# {0} - imageFilePath", "# {1} - deviceId", "# {2} - exceptionMessage", "AddMultipleImageTask.criticalErrorReverting=Critical error reverting add image process for {0} for device {1}: {2}",
"# {0} - imageFilePath", "# {1} - deviceId", "# {2} - exceptionMessage", "AddMultipleImageTask.nonCriticalErrorAdding=Non-critical error adding {0} for device {1}: {2}",
})
"# {0} - imageFilePath", "# {1} - deviceId", "# {2} - exceptionMessage", "AddMultipleImageTask.nonCriticalErrorAdding=Non-critical error adding {0} for device {1}: {2}",})
private void addImageToCase(String imageFilePath, List<Content> newDataSources, List<String> localFileDataSourcePaths, List<String> errorMessages) {
/*
* Try to add the image to the case database as a data source.

View File

@ -0,0 +1,51 @@
/*
* Autopsy
*
* Copyright 2019 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.logicalimager.dsp;
/**
* Utility class for displaying a list of drives
*/
public final class DriveListUtils {
/**
* Convert a number of bytes to a human readable string
*
* @param bytes the number of bytes to convert
* @param si whether it takes 1000 or 1024 of a unit to reach the next
* unit
*
* @return a human readable string representing the number of bytes
*/
public static String humanReadableByteCount(long bytes, boolean si) {
int unit = si ? 1000 : 1024;
if (bytes < unit) {
return bytes + " B"; //NON-NLS
}
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); //NON-NLS
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); //NON-NLS
}
/**
* Empty private constructor for util class
*/
private DriveListUtils() {
//empty private constructor for util class
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -38,13 +38,13 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgress
import org.sleuthkit.datamodel.Content;
/**
* A Logical Imager data source processor that implements the DataSourceProcessor service
* provider interface to allow integration with the add data source wizard. It
* also provides a run method overload to allow it to be used independently of
* the wizard.
* A Logical Imager data source processor that implements the
* DataSourceProcessor service provider interface to allow integration with the
* add data source wizard. It also provides a run method overload to allow it to
* be used independently of the wizard.
*/
@ServiceProviders(value={
@ServiceProvider(service=DataSourceProcessor.class)}
@ServiceProviders(value = {
@ServiceProvider(service = DataSourceProcessor.class)}
)
public final class LogicalImagerDSProcessor implements DataSourceProcessor {
@ -131,8 +131,7 @@ public final class LogicalImagerDSProcessor implements DataSourceProcessor {
"# {0} - directory", "LogicalImagerDSProcessor.failToCreateDirectory=Failed to create directory {0}",
"# {0} - directory", "LogicalImagerDSProcessor.directoryAlreadyExists=Directory {0} already exists",
"# {0} - file", "LogicalImagerDSProcessor.failToGetCanonicalPath=Fail to get canonical path for {0}",
"LogicalImagerDSProcessor.noCurrentCase=No current case",
})
"LogicalImagerDSProcessor.noCurrentCase=No current case",})
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
configPanel.storeSettings();
@ -189,8 +188,8 @@ public final class LogicalImagerDSProcessor implements DataSourceProcessor {
String deviceId = UUID.randomUUID().toString();
String timeZone = Calendar.getInstance().getTimeZone().getID();
run(deviceId, imagePaths,
timeZone, src, dest,
progressMonitor, callback);
timeZone, src, dest,
progressMonitor, callback);
} catch (NoCurrentCaseException ex) {
String msg = Bundle.LogicalImagerDSProcessor_noCurrentCase();
errorList.add(msg);
@ -200,25 +199,24 @@ public final class LogicalImagerDSProcessor implements DataSourceProcessor {
}
/**
* Adds a "Logical Imager" data source to the case database using a background task in
* a separate thread and the given settings instead of those provided by the
* selection and configuration panel. Returns as soon as the background task
* is started and uses the callback object to signal task completion and
* return results.
* Adds a "Logical Imager" data source to the case database using a
* background task in a separate thread and the given settings instead of
* those provided by the selection and configuration panel. Returns as soon
* as the background task is started and uses the callback object to signal
* task completion and return results.
*
* @param deviceId An ASCII-printable identifier for the device
* associated with the data source that is
* intended to be unique across multiple cases
* (e.g., a UUID).
* @param imagePaths Paths to the image files.
* @param timeZone The time zone to use when processing dates
* and times for the image, obtained from
* java.util.TimeZone.getID.
* @param src The source directory of image.
* @param dest The destination directory to copy the source.
* @param progressMonitor Progress monitor for reporting progress
* during processing.
* @param callback Callback to call when processing is done.
* @param deviceId An ASCII-printable identifier for the device
* associated with the data source that is intended
* to be unique across multiple cases (e.g., a UUID).
* @param imagePaths Paths to the image files.
* @param timeZone The time zone to use when processing dates and
* times for the image, obtained from
* java.util.TimeZone.getID.
* @param src The source directory of image.
* @param dest The destination directory to copy the source.
* @param progressMonitor Progress monitor for reporting progress during
* processing.
* @param callback Callback to call when processing is done.
*/
private void run(String deviceId, List<String> imagePaths, String timeZone,
File src, File dest,

View File

@ -72,7 +72,7 @@
<Component id="jScrollPane1" min="-2" pref="568" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace pref="338" max="32767" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -89,7 +89,7 @@
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="imageScrollPane" pref="0" max="32767" attributes="0"/>
<Component id="driveListScrollPane" pref="461" max="32767" attributes="0"/>
<Component id="driveListScrollPane" pref="106" max="32767" attributes="0"/>
</Group>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="refreshButton" min="-2" max="-2" attributes="0"/>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
* Autopsy
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -29,6 +29,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JFileChooser;
@ -42,6 +43,7 @@ import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Panel for adding an logical image file from drive letters. Allows the user to
@ -54,6 +56,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
final class LogicalImagerPanel extends JPanel implements DocumentListener {
private static final Logger logger = Logger.getLogger(LogicalImagerPanel.class.getName());
private static final long serialVersionUID = 1L;
private static final String NO_IMAGE_SELECTED = Bundle.LogicalImagerPanel_messageLabel_noImageSelected();
private static final String DRIVE_HAS_NO_IMAGES = Bundle.LogicalImagerPanel_messageLabel_driveHasNoImages();
@ -255,7 +258,7 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener {
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 568, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(338, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -269,7 +272,7 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(imageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(driveListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 461, Short.MAX_VALUE))
.addComponent(driveListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(refreshButton)
.addGap(18, 18, 18)
@ -288,16 +291,6 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener {
);
}// </editor-fold>//GEN-END:initComponents
private static String humanReadableByteCount(long bytes, boolean si) {
int unit = si ? 1000 : 1024;
if (bytes < unit) {
return bytes + " B"; //NON-NLS
}
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); //NON-NLS
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); //NON-NLS
}
@Messages({
"# {0} - sparseImageDirectory",
"LogicalImagerPanel.messageLabel.directoryDoesNotContainSparseImage=Directory {0} does not contain any images",
@ -490,7 +483,7 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener {
for (File root : roots) {
String description = FileSystemView.getFileSystemView().getSystemTypeDescription(root);
long spaceInBytes = root.getTotalSpace();
String sizeWithUnit = humanReadableByteCount(spaceInBytes, false);
String sizeWithUnit = DriveListUtils.humanReadableByteCount(spaceInBytes, false);
listData.add(root + " (" + description + ") (" + sizeWithUnit + ")");
if (firstRemovableDrive == -1) {
try {
@ -498,9 +491,9 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener {
if ((boolean) fileStore.getAttribute("volume:isRemovable")) { //NON-NLS
firstRemovableDrive = i;
}
} catch (IOException ex) {
i++;
continue;
} catch (IOException ignored) {
//unable to get this removable drive for default selection will try and select next removable drive by default
logger.log(Level.INFO, "Unable to select first removable drive found", ignored);
}
}
i++;

View File

@ -258,11 +258,9 @@ CreatePortableCasePanel.outputFolderTextField.text=jTextField1
CreatePortableCasePanel.chooseOutputFolderButton.text=Choose folder
CreatePortableCasePanel.jLabel1.text=Export files tagged as:
CreatePortableCasePanel.jLabel2.text=Select output folder:
CreatePortableCasePanel.compressCheckbox.text=Compress case
CreatePortableCasePanel.chunkSizeLabel.text=Split into chunks of size:
CreatePortableCasePanel.errorLabel.text_1=Windows only
ReportWizardPortableCaseOptionsVisualPanel.errorLabel.text=Windows only
ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.text=Package case into chunks of size:
ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.text=Package case into an archive:
PortableCaseTagsListPanel.deselectButton.text=Deselect All
PortableCaseTagsListPanel.selectButton.text=Select All
PortableCaseInterestingItemsListPanel.selectButton.text=Select All
@ -271,3 +269,4 @@ ReportFileTextConfigurationPanel.tabDelimitedButton.text=Tab delimited
ReportFileTextConfigurationPanel.commaDelimitedButton.text=Comma delimited
PortableCaseTagsListPanel.descLabel.text=Include the following tags:
PortableCaseInterestingItemsListPanel.descLabel.text=Include Interesting Items from these sets:
ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.toolTipText=

View File

@ -318,11 +318,9 @@ CreatePortableCasePanel.outputFolderTextField.text=jTextField1
CreatePortableCasePanel.chooseOutputFolderButton.text=Choose folder
CreatePortableCasePanel.jLabel1.text=Export files tagged as:
CreatePortableCasePanel.jLabel2.text=Select output folder:
CreatePortableCasePanel.compressCheckbox.text=Compress case
CreatePortableCasePanel.chunkSizeLabel.text=Split into chunks of size:
CreatePortableCasePanel.errorLabel.text_1=Windows only
ReportWizardPortableCaseOptionsVisualPanel.errorLabel.text=Windows only
ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.text=Package case into chunks of size:
ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.text=Package case into an archive:
PortableCaseTagsListPanel.deselectButton.text=Deselect All
PortableCaseTagsListPanel.selectButton.text=Select All
PortableCaseInterestingItemsListPanel.selectButton.text=Select All
@ -331,5 +329,6 @@ ReportFileTextConfigurationPanel.tabDelimitedButton.text=Tab delimited
ReportFileTextConfigurationPanel.commaDelimitedButton.text=Comma delimited
PortableCaseTagsListPanel.descLabel.text=Include the following tags:
PortableCaseInterestingItemsListPanel.descLabel.text=Include Interesting Items from these sets:
ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.toolTipText=
ReportWizardPortableCaseOptionsVisualPanel.getName.title=Choose Portable Case settings
TableReportGenerator.StatusColumn.Header=Review Status

View File

@ -983,7 +983,7 @@ class PortableCaseReportModule implements ReportModule {
enum ChunkSize {
NONE("Do not split", ""), // NON-NLS
DVD("4.5 GB (DVD)", "4500m"); // NON-NLS
DVD("Split into 4.5 GB chunks (DVD)", "4500m"); // NON-NLS
private final String displayName;
private final String sevenZipParam;

View File

@ -41,10 +41,10 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="compressCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="chunkSizeComboBox" min="-2" pref="99" max="-2" attributes="0"/>
<Component id="chunkSizeComboBox" min="-2" pref="187" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="97" max="32767" attributes="0"/>
<EmptySpace pref="41" max="32767" attributes="0"/>
</Group>
<Component id="listPanel" alignment="1" max="32767" attributes="0"/>
</Group>
@ -78,6 +78,9 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.toolTipText" 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="compressCheckboxActionPerformed"/>

View File

@ -119,6 +119,7 @@ class ReportWizardPortableCaseOptionsVisualPanel extends javax.swing.JPanel {
});
org.openide.awt.Mnemonics.setLocalizedText(compressCheckbox, org.openide.util.NbBundle.getMessage(ReportWizardPortableCaseOptionsVisualPanel.class, "ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.text")); // NOI18N
compressCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(ReportWizardPortableCaseOptionsVisualPanel.class, "ReportWizardPortableCaseOptionsVisualPanel.compressCheckbox.toolTipText")); // NOI18N
compressCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
compressCheckboxActionPerformed(evt);
@ -147,10 +148,10 @@ class ReportWizardPortableCaseOptionsVisualPanel extends javax.swing.JPanel {
.addContainerGap()
.addComponent(compressCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chunkSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 99, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(chunkSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 187, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(errorLabel)
.addContainerGap(97, Short.MAX_VALUE))
.addContainerGap(41, Short.MAX_VALUE))
.addComponent(listPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(

View File

@ -27,7 +27,7 @@
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-116,0,0,2,-108"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="jPanel1">
<Properties>
@ -36,13 +36,16 @@
<EtchetBorder/>
</Border>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[182, 24]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[250, 81]"/>
<Dimension value="[182, 24]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="North"/>
</Constraint>
</Constraints>
@ -65,7 +68,7 @@
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="3" gridY="1" gridWidth="1" gridHeight="3" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="13" weightX="0.1" weightY="0.0"/>
<GridBagConstraints gridX="3" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="13" weightX="0.1" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
@ -84,7 +87,7 @@
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="5" gridY="1" gridWidth="2" gridHeight="3" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="13" weightX="0.1" weightY="0.0"/>
<GridBagConstraints gridX="5" gridY="0" gridWidth="2" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="13" weightX="0.1" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
@ -97,7 +100,7 @@
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="4" gridY="1" gridWidth="1" gridHeight="3" fill="3" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="13" weightX="0.0" weightY="0.0"/>
<GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="13" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
@ -109,7 +112,7 @@
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="3" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.25" weightY="0.0"/>
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.25" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
@ -121,7 +124,7 @@
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="3" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
<GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
@ -131,15 +134,15 @@
<Properties>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[2000, 2000]"/>
<Dimension value="[20000, 20000]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[660, 344]"/>
<Dimension value="[640, 250]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>

View File

@ -299,18 +299,18 @@ public class TranslationContentPanel extends javax.swing.JPanel {
setName(""); // NOI18N
setPreferredSize(new java.awt.Dimension(100, 58));
setVerifyInputWhenFocusTarget(false);
setLayout(new java.awt.GridBagLayout());
setLayout(new java.awt.BorderLayout());
jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
jPanel1.setPreferredSize(new java.awt.Dimension(250, 81));
jPanel1.setMaximumSize(new java.awt.Dimension(182, 24));
jPanel1.setPreferredSize(new java.awt.Dimension(182, 24));
jPanel1.setLayout(new java.awt.GridBagLayout());
displayTextComboBox.setMinimumSize(new java.awt.Dimension(43, 20));
displayTextComboBox.setPreferredSize(new java.awt.Dimension(43, 20));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 3;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridheight = 3;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
gridBagConstraints.weightx = 0.1;
@ -322,9 +322,8 @@ public class TranslationContentPanel extends javax.swing.JPanel {
ocrDropdown.setName(""); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 5;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.gridheight = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
gridBagConstraints.weightx = 0.1;
@ -335,9 +334,7 @@ public class TranslationContentPanel extends javax.swing.JPanel {
ocrLabel.setEnabled(false);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 4;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridheight = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0);
jPanel1.add(ocrLabel, gridBagConstraints);
@ -345,9 +342,8 @@ public class TranslationContentPanel extends javax.swing.JPanel {
warningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/warning16.png"))); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridheight = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.weightx = 0.25;
jPanel1.add(warningLabel, gridBagConstraints);
@ -355,29 +351,15 @@ public class TranslationContentPanel extends javax.swing.JPanel {
org.openide.awt.Mnemonics.setLocalizedText(showLabel, org.openide.util.NbBundle.getMessage(TranslationContentPanel.class, "TranslationContentPanel.showLabel.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 2;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridheight = 3;
gridBagConstraints.gridy = 0;
jPanel1.add(showLabel, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
add(jPanel1, gridBagConstraints);
add(jPanel1, java.awt.BorderLayout.NORTH);
textScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
textScrollPane.setMaximumSize(new java.awt.Dimension(2000, 2000));
textScrollPane.setPreferredSize(new java.awt.Dimension(660, 344));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 0);
add(textScrollPane, gridBagConstraints);
textScrollPane.setMaximumSize(new java.awt.Dimension(20000, 20000));
textScrollPane.setPreferredSize(new java.awt.Dimension(640, 250));
add(textScrollPane, java.awt.BorderLayout.CENTER);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 Basis Technology Corp.
* Copyright 2018-2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -18,36 +18,45 @@
*/
package org.sleuthkit.autopsy.corelibs;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.opencv.core.Core;
public final class OpenCvLoader {
private static final boolean OPEN_CV_LOADED;
private static final Logger LOGGER = Logger.getLogger(OpenCvLoader.class.getName());
private static boolean openCvLoaded;
private static UnsatisfiedLinkError exception = null;
static {
boolean tempOpenCvLoaded = false;
try {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
tempOpenCvLoaded = true;
} catch (UnsatisfiedLinkError e) {
tempOpenCvLoaded = false;
exception = e; //save relevant error for throwing at appropriate time
openCvLoaded = true;
} catch (UnsatisfiedLinkError ex) {
LOGGER.log(Level.WARNING, "Unable to load OpenCV", ex);
exception = ex; //save relevant error for throwing at appropriate time
openCvLoaded = false;
} catch (SecurityException ex) {
LOGGER.log(Level.WARNING, "Unable to load OpenCV", ex);
openCvLoaded = false;
}
OPEN_CV_LOADED = tempOpenCvLoaded;
}
/**
* Return whether or not the OpenCV library has been loaded.
*
* @return - true if the opencv library is loaded or false if it is not
* @throws UnsatisfiedLinkError - A COPY of the exception that prevented OpenCV from loading.
* Note that the stack trace in the exception can be confusing because it refers to a
* past invocation.
* @throws UnsatisfiedLinkError - A COPY of the exception that prevented
* OpenCV from loading. Note that the stack trace in the exception can be
* confusing because it refers to a past invocation.
*
* @deprecated Use hasOpenCvLoaded instead.
*/
@Deprecated
public static boolean isOpenCvLoaded() throws UnsatisfiedLinkError {
if (!OPEN_CV_LOADED) {
//exception should never be null if the open cv isn't loaded but just in case
if (!openCvLoaded) {
//exception should never be null if the open cv isn't loaded but just in case
if (exception != null) {
throw exception;
} else {
@ -55,6 +64,15 @@ public final class OpenCvLoader {
}
}
return OPEN_CV_LOADED;
return openCvLoaded;
}
/**
* Return whether OpenCV library has been loaded.
*
* @return true if OpenCV library was loaded, false if not.
*/
public static boolean hasOpenCvLoaded() {
return openCvLoaded;
}
}

View File

@ -25,7 +25,7 @@
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="nodeScrollPane" alignment="0" max="32767" attributes="0"/>
<Component id="nodeScrollPane" alignment="0" pref="656" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
@ -49,8 +49,8 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" 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="jLabelSelectInputFolder" min="-2" max="-2" attributes="0"/>
@ -117,8 +117,11 @@
</Group>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="autoIngestModeRadioButton" min="-2" pref="145" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="autoIngestModeRadioButton" min="-2" pref="145" max="-2" attributes="0"/>
<Component id="pnTestMultiUser" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
@ -187,7 +190,9 @@
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="pbTaskInProgress" min="-2" pref="22" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="pnTestMultiUser" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="82" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -460,6 +465,100 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="autoIngestModeRadioButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JPanel" name="pnTestMultiUser">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbTestResultText" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="lbTestMultiUserText" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="236" max="32767" attributes="0"/>
<Component id="bnTestMultiUser" min="-2" pref="83" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="lbMultiUserResult" min="-2" pref="16" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</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="1" attributes="0">
<Component id="lbMultiUserResult" alignment="1" min="-2" pref="23" max="-2" attributes="0"/>
<Group type="103" alignment="1" groupAlignment="3" attributes="0">
<Component id="bnTestMultiUser" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbTestMultiUserText" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbTestResultText" min="-2" pref="16" max="-2" attributes="0"/>
<EmptySpace min="0" pref="16" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbTestMultiUserText">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="lbTestMultiUserText" property="font" relativeSize="false" size="12"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/configuration/Bundle.properties" key="AutoIngestSettingsPanel.lbTestMultiUserText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnTestMultiUser">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="bnTestMultiUser" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/configuration/Bundle.properties" key="AutoIngestSettingsPanel.bnTestMultiUser.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="bnTestMultiUserActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbMultiUserResult">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/configuration/Bundle.properties" key="AutoIngestSettingsPanel.lbMultiUserResult.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbTestResultText">
<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/experimental/configuration/Bundle.properties" key="AutoIngestSettingsPanel.lbTestResultText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.experimental.configuration;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Color;
import java.io.File;
import java.nio.file.Files;
import java.util.List;
@ -35,6 +36,7 @@ import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
import java.awt.Dimension;
import java.nio.file.Paths;
import javax.swing.ImageIcon;
import org.openide.util.ImageUtilities;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
@ -47,8 +49,6 @@ import org.sleuthkit.autopsy.experimental.autoingest.FileExporterSettingsPanel;
/**
* Configuration panel for auto ingest settings.
*/
@Messages({"AutoIngestSettingsPanel.examinerModeRadioButton.text=Examiner mode",
"AutoIngestSettingsPanel.autoIngestModeRadioButton.text=Auto Ingest mode"})
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
public class AutoIngestSettingsPanel extends javax.swing.JPanel {
@ -58,6 +58,8 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(AutoIngestSettingsPanel.class.getName());
private final Integer oldIngestThreads;
private static final String MULTI_USER_SETTINGS_MUST_BE_ENABLED = NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.validationErrMsg.MUdisabled");
private final ImageIcon goodIcon;
private final ImageIcon badIcon;
enum OptionsUiMode {
@ -92,6 +94,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
jLabelTaskDescription.setEnabled(false);
this.oldIngestThreads = UserPreferences.numberOfFileIngestThreads();
goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/experimental/images/good.png", false));
badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/experimental/images/bad.png", false));
}
private class MyDocumentListener implements DocumentListener {
@ -122,6 +127,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
*/
final void load(boolean inStartup) {
lbMultiUserResult.setIcon(null);
lbTestResultText.setText("");
// multi user mode must be enabled
if (!UserPreferences.getIsMultiUserModeEnabled()) {
tbOops.setText(MULTI_USER_SETTINGS_MUST_BE_ENABLED);
@ -448,7 +456,7 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
jLabelInvalidImageFolder.setVisible(true);
jLabelInvalidImageFolder.setText(NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.CannotAccess")
+ " " + inputPath + " "
+ NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.CheckPermissions"));
+ NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.CheckPermissions", System.getProperty("user.name")));
return false;
}
@ -479,7 +487,7 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
jLabelInvalidResultsFolder.setVisible(true);
jLabelInvalidResultsFolder.setText(NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.CannotAccess")
+ " " + outputPath + " "
+ NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.CheckPermissions"));
+ NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.CheckPermissions", System.getProperty("user.name")));
return false;
}
@ -514,7 +522,7 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
sharedSettingsErrorTextField.setVisible(true);
sharedSettingsErrorTextField.setText(NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.CannotAccess")
+ " " + sharedSettingsPath + " "
+ NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.CheckPermissions"));
+ NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.CheckPermissions", System.getProperty("user.name")));
return false;
}
@ -572,6 +580,11 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
downloadButton.setEnabled(mode == OptionsUiMode.AIM && sharedConfigCheckbox.isSelected());
browseSharedSettingsButton.setEnabled(mode == OptionsUiMode.AIM && sharedConfigCheckbox.isSelected());
uploadButton.setEnabled(mode == OptionsUiMode.AIM && sharedConfigCheckbox.isSelected() && masterNodeCheckBox.isSelected());
lbTestMultiUserText.setEnabled(mode == OptionsUiMode.AIM);
bnTestMultiUser.setEnabled(mode == OptionsUiMode.AIM);
lbMultiUserResult.setEnabled(mode == OptionsUiMode.AIM);
lbTestResultText.setEnabled(mode == OptionsUiMode.AIM);
} else {
setEnabledState(false);
}
@ -623,6 +636,11 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
masterNodeCheckBox = new javax.swing.JCheckBox();
examinerModeRadioButton = new javax.swing.JRadioButton();
autoIngestModeRadioButton = new javax.swing.JRadioButton();
pnTestMultiUser = new javax.swing.JPanel();
lbTestMultiUserText = new javax.swing.JLabel();
bnTestMultiUser = new javax.swing.JButton();
lbMultiUserResult = new javax.swing.JLabel();
lbTestResultText = new javax.swing.JLabel();
nodeScrollPane.setMinimumSize(new java.awt.Dimension(0, 0));
@ -761,6 +779,55 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
}
});
pnTestMultiUser.setBorder(javax.swing.BorderFactory.createEtchedBorder());
lbTestMultiUserText.setFont(lbTestMultiUserText.getFont().deriveFont(lbTestMultiUserText.getFont().getStyle() & ~java.awt.Font.BOLD, 12));
org.openide.awt.Mnemonics.setLocalizedText(lbTestMultiUserText, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.lbTestMultiUserText.text")); // NOI18N
bnTestMultiUser.setFont(bnTestMultiUser.getFont().deriveFont(bnTestMultiUser.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(bnTestMultiUser, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.bnTestMultiUser.text")); // NOI18N
bnTestMultiUser.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnTestMultiUserActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(lbMultiUserResult, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.lbMultiUserResult.text")); // NOI18N
lbTestResultText.setForeground(new java.awt.Color(255, 0, 0));
org.openide.awt.Mnemonics.setLocalizedText(lbTestResultText, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.lbTestResultText.text")); // NOI18N
javax.swing.GroupLayout pnTestMultiUserLayout = new javax.swing.GroupLayout(pnTestMultiUser);
pnTestMultiUser.setLayout(pnTestMultiUserLayout);
pnTestMultiUserLayout.setHorizontalGroup(
pnTestMultiUserLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnTestMultiUserLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnTestMultiUserLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbTestResultText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(pnTestMultiUserLayout.createSequentialGroup()
.addComponent(lbTestMultiUserText)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 236, Short.MAX_VALUE)
.addComponent(bnTestMultiUser, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(lbMultiUserResult, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(8, 8, 8)))
.addContainerGap())
);
pnTestMultiUserLayout.setVerticalGroup(
pnTestMultiUserLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnTestMultiUserLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnTestMultiUserLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(lbMultiUserResult, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(pnTestMultiUserLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnTestMultiUser)
.addComponent(lbTestMultiUserText)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lbTestResultText, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 16, Short.MAX_VALUE))
);
javax.swing.GroupLayout nodePanelLayout = new javax.swing.GroupLayout(nodePanel);
nodePanel.setLayout(nodePanelLayout);
nodePanelLayout.setHorizontalGroup(
@ -820,7 +887,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
.addGap(0, 0, Short.MAX_VALUE)))
.addGap(10, 10, 10))
.addGroup(nodePanelLayout.createSequentialGroup()
.addComponent(autoIngestModeRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(autoIngestModeRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(pnTestMultiUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(0, 0, Short.MAX_VALUE))))
);
nodePanelLayout.setVerticalGroup(
@ -875,7 +944,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
.addComponent(jLabelTaskDescription))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pbTaskInProgress, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(pnTestMultiUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(82, Short.MAX_VALUE))
);
nodeScrollPane.setViewportView(nodePanel);
@ -888,7 +959,7 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(nodeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(nodeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 656, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
@ -1075,6 +1146,37 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
controller.changed();
}//GEN-LAST:event_examinerModeRadioButtonActionPerformed
private void bnTestMultiUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestMultiUserActionPerformed
lbTestResultText.setForeground(Color.BLACK);
lbTestResultText.setText(NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.TestRunning"));
lbTestResultText.paintImmediately(lbTestResultText.getVisibleRect());
lbMultiUserResult.setIcon(null);
lbMultiUserResult.paintImmediately(lbMultiUserResult.getVisibleRect());
if (!validateResultsPath()) {
lbMultiUserResult.setIcon(badIcon);
lbTestResultText.setForeground(Color.RED);
lbTestResultText.setText(NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.PathInvalid"));
return;
}
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
String resultsFolderPath = getNormalizedFolderPath(outputPathTextField.getText().trim());
String testResult = MultiUserTestTool.runTest(resultsFolderPath);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
if (testResult.equals(MultiUserTestTool.MULTI_USER_TEST_SUCCESSFUL)) {
// test successful
lbMultiUserResult.setIcon(goodIcon);
lbTestResultText.setText("");
} else {
// test failed
lbMultiUserResult.setIcon(badIcon);
lbTestResultText.setText(testResult);
lbTestResultText.setForeground(Color.RED);
}
}//GEN-LAST:event_bnTestMultiUserActionPerformed
private void enableUI(boolean state) {
enableOptionsBasedOnMode(OptionsUiMode.DOWNLOADING_CONFIGURATION);
downloadButton.setEnabled(state);
@ -1198,6 +1300,7 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
private javax.swing.JButton bnAdvancedSettings;
private javax.swing.JButton bnEditIngestSettings;
private javax.swing.JButton bnFileExport;
private javax.swing.JButton bnTestMultiUser;
private javax.swing.JButton browseInputFolderButton;
private javax.swing.JButton browseOutputFolderButton;
private javax.swing.JButton browseSharedSettingsButton;
@ -1211,12 +1314,16 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel {
private javax.swing.JLabel jLabelSelectInputFolder;
private javax.swing.JLabel jLabelSelectOutputFolder;
private javax.swing.JLabel jLabelTaskDescription;
private javax.swing.JLabel lbMultiUserResult;
private javax.swing.JLabel lbTestMultiUserText;
private javax.swing.JLabel lbTestResultText;
private javax.swing.JCheckBox masterNodeCheckBox;
private javax.swing.ButtonGroup modeSelectionButtonGroup;
private javax.swing.JPanel nodePanel;
private javax.swing.JScrollPane nodeScrollPane;
private javax.swing.JTextField outputPathTextField;
private javax.swing.JProgressBar pbTaskInProgress;
private javax.swing.JPanel pnTestMultiUser;
private javax.swing.JCheckBox sharedConfigCheckbox;
private javax.swing.JTextField sharedSettingsErrorTextField;
private javax.swing.JTextField sharedSettingsTextField;

View File

@ -19,10 +19,7 @@
package org.sleuthkit.autopsy.experimental.configuration;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.core.UserPreferencesException;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.TextConverter;
import org.sleuthkit.autopsy.coreutils.TextConverterException;
/**
* Provides convenient access to a Preferences node for auto ingest user
@ -42,12 +39,6 @@ public final class AutoIngestUserPreferences {
private static final String MAX_NUM_TIMES_TO_PROCESS_IMAGE = "MaxNumTimesToAttemptToProcessImage"; // NON-NLS
private static final int DEFAULT_MAX_TIMES_TO_PROCESS_IMAGE = 0;
private static final String MAX_CONCURRENT_NODES_FOR_ONE_CASE = "MaxConcurrentNodesForOneCase"; // NON-NLS
private static final String STATUS_DATABASE_LOGGING_ENABLED = "StatusDatabaseLoggingEnabled"; // NON-NLS
private static final String LOGGING_DB_HOSTNAME_OR_IP = "LoggingHostnameOrIP"; // NON-NLS
private static final String LOGGING_PORT = "LoggingPort"; // NON-NLS
private static final String LOGGING_USERNAME = "LoggingUsername"; // NON-NLS
private static final String LOGGING_PASSWORD = "LoggingPassword"; // NON-NLS
private static final String LOGGING_DATABASE_NAME = "LoggingDatabaseName"; // NON-NLS
private static final String INPUT_SCAN_INTERVAL_TIME = "IntervalBetweenInputScan"; // NON-NLS
// Prevent instantiation.

View File

@ -21,10 +21,11 @@ AIMIngestSettingsPanel.jLabel1.text=Download the current shared setting (highly
AIMIngestSettingsPanel.lbSecondsBetweenJobs.text=Number of seconds to wait between jobs:
AIMIngestSettingsPanel.lbSecondsBetweenJobs.toolTipText=Increase this value if database locks cause problems. It gives a little more time for finalizing.
AIMIngestSettingsPanel.spSecondsBetweenJobs.toolTipText=Increase this value if database locks cause problems. It gives a little more time for finalizing.
AutoIngestSettingsPanel.examinerModeRadioButton.text=Examiner mode
AutoIngestSettingsPanel.autoIngestModeRadioButton.text=Auto Ingest mode
AutoIngestSettingsPanel.AdvancedAutoIngestSettingsPanel.Title=Advanced Settings
AutoIngestSettingsPanel.browseGlobalSettingsButton.text=Browse
AutoIngestSettingsPanel.CannotAccess=Cannot access
AutoIngestSettingsPanel.CheckPermissions=Check permissions.
AutoIngestSettingsPanel.EmptySettingsDirectory=Enter path to settings directory
AutoIngestSettingsPanel.ErrorSettingDefaultFolder=Error creating default folder
AutoIngestSettingsPanel.FileExportRules.text=File Export Rules
@ -37,7 +38,6 @@ AutoIngestSettingsPanel.KeywordSearchNull=Cannot find Keyword Search service
AutoIngestSettingsPanel.MustRestart=Autopsy must be restarted for new configuration to take effect
AutoIngestSettingsPanel.nodePanel.TabConstraints.tabTitle=Node Configuration
AutoIngestSettingsPanel.NodeStatusLogging.text=Node Status Logging Settings
AutoIngestSettingsPanel.PathInvalid=Path is not valid
AutoIngestSettingsPanel.restartRequiredLabel.text=Application restart required to take effect.
AutoIngestSettingsPanel.restartRequiredLabel.text=Application restart required
AutoIngestSettingsPanel.ResultsDirectoryUnspecified=Shared cases folder must be set
@ -47,6 +47,16 @@ AutoIngestSettingsPanel.validationErrMsg.invalidDatabasePort=Invalid database po
AutoIngestSettingsPanel.validationErrMsg.invalidIndexingServerPort=Invalid Solr server port number
AutoIngestSettingsPanel.validationErrMsg.invalidMessageServicePort=Invalid message service port number
AutoIngestSettingsPanel.validationErrMsg.MUdisabled=Multi user settings must be enabled and saved
AutoIngestSettingsPanel.bnTestMultiUser.text=Test
AutoIngestSettingsPanel.lbTestMultiUserText.text=Test Multi-User Case Creation and Ingest Settings
AutoIngestSettingsPanel.lbMultiUserResult.text=
AutoIngestSettingsPanel.lbTestResultText.text=
AutoIngestSettingsPanel.validationErrMsg.outputPathNotSpecified=Output folder must be set
AutoIngestSettingsPanel.PathInvalid=Case output directory path is not valid
AutoIngestSettingsPanel.CheckPermissions=Ensure that the user account {0} has write permissions in this folder
AutoIngestSettingsPanel.Success=Success
AutoIngestSettingsPanel.TestRunning=Test in progress...
AutoIngestSettingsPanel.servicesDown=Some of the Multi User services are down
GeneralOptionsPanelController.moduleErr.msg=A module caused an error listening to GeneralOptionsPanelController updates. See log to determine which module. Some data could be incomplete.
GeneralOptionsPanelController.moduleErr=Module Error
NodeStatusLogPanel.bnCancel.text=Cancel

View File

@ -21,14 +21,13 @@ AIMIngestSettingsPanel.jLabel1.text=Download the current shared setting (highly
AIMIngestSettingsPanel.lbSecondsBetweenJobs.text=Number of seconds to wait between jobs:
AIMIngestSettingsPanel.lbSecondsBetweenJobs.toolTipText=Increase this value if database locks cause problems. It gives a little more time for finalizing.
AIMIngestSettingsPanel.spSecondsBetweenJobs.toolTipText=Increase this value if database locks cause problems. It gives a little more time for finalizing.
AutoIngestSettingsPanel.AdvancedAutoIngestSettingsPanel.Title=Advanced Settings
AutoIngestSettingsPanel.examinerModeRadioButton.text=Examiner mode
AutoIngestSettingsPanel.autoIngestModeRadioButton.text=Auto Ingest mode
AutoIngestSettingsPanel.AdvancedAutoIngestSettingsPanel.Title=Advanced Settings
AutoIngestSettingsPanel.browseGlobalSettingsButton.text=Browse
AutoIngestSettingsPanel.CannotAccess=Cannot access
AutoIngestSettingsPanel.CheckPermissions=Check permissions.
AutoIngestSettingsPanel.EmptySettingsDirectory=Enter path to settings directory
AutoIngestSettingsPanel.ErrorSettingDefaultFolder=Error creating default folder
AutoIngestSettingsPanel.examinerModeRadioButton.text=Examiner mode
AutoIngestSettingsPanel.FileExportRules.text=File Export Rules
AutoIngestSettingsPanel.globalSettingsErrorTextField.text=
AutoIngestSettingsPanel.globalSettingsTextField.text=
@ -39,7 +38,6 @@ AutoIngestSettingsPanel.KeywordSearchNull=Cannot find Keyword Search service
AutoIngestSettingsPanel.MustRestart=Autopsy must be restarted for new configuration to take effect
AutoIngestSettingsPanel.nodePanel.TabConstraints.tabTitle=Node Configuration
AutoIngestSettingsPanel.NodeStatusLogging.text=Node Status Logging Settings
AutoIngestSettingsPanel.PathInvalid=Path is not valid
AutoIngestSettingsPanel.restartRequiredLabel.text=Application restart required to take effect.
AutoIngestSettingsPanel.restartRequiredLabel.text=Application restart required
AutoIngestSettingsPanel.ResultsDirectoryUnspecified=Shared cases folder must be set
@ -49,8 +47,39 @@ AutoIngestSettingsPanel.validationErrMsg.invalidDatabasePort=Invalid database po
AutoIngestSettingsPanel.validationErrMsg.invalidIndexingServerPort=Invalid Solr server port number
AutoIngestSettingsPanel.validationErrMsg.invalidMessageServicePort=Invalid message service port number
AutoIngestSettingsPanel.validationErrMsg.MUdisabled=Multi user settings must be enabled and saved
AutoIngestSettingsPanel.bnTestMultiUser.text=Test
AutoIngestSettingsPanel.lbTestMultiUserText.text=Test Multi-User Case Creation and Ingest Settings
AutoIngestSettingsPanel.lbMultiUserResult.text=
AutoIngestSettingsPanel.lbTestResultText.text=
AutoIngestSettingsPanel.validationErrMsg.outputPathNotSpecified=Output folder must be set
AutoIngestSettingsPanel.PathInvalid=Path is not valid
AutoIngestSettingsPanel.CheckPermissions=Check permissions.
AutoIngestSettingsPanel.Success=Success
AutoIngestSettingsPanel.TestRunning=Test in progress...
AutoIngestSettingsPanel.servicesDown=Some of the Multi User services are down
GeneralOptionsPanelController.moduleErr.msg=A module caused an error listening to GeneralOptionsPanelController updates. See log to determine which module. Some data could be incomplete.
GeneralOptionsPanelController.moduleErr=Module Error
# {0} - errorMessage
MultiUserTestTool.criticalError=Critical error running data source processor on test data source: {0}
MultiUserTestTool.errorStartingIngestJob=Ingest manager error while starting ingest job
# {0} - cancellationReason
MultiUserTestTool.ingestCancelled=Ingest cancelled due to {0}
MultiUserTestTool.ingestSettingsError=Failed to analyze data source due to ingest settings errors
MultiUserTestTool.noContent=Test data source failed to produce content
# {0} - serviceName
MultiUserTestTool.serviceDown=Multi User service is down: {0}
MultiUserTestTool.startupError=Failed to analyze data source due to ingest job startup error
MultiUserTestTool.unableAddFileAsDataSource=Unable to add test file as data source to case
MultiUserTestTool.unableCreatFile=Unable to create a file in case output directory
# {0} - serviceName
MultiUserTestTool.unableToCheckService=Unable to check Multi User service state: {0}
MultiUserTestTool.unableToCreateCase=Unable to create case
MultiUserTestTool.unableToInitializeDatabase=Case database was not successfully initialized
MultiUserTestTool.unableToReadDatabase=Unable to read from case database
MultiUserTestTool.unableToReadTestFileFromDatabase=Unable to read test file info from case database
MultiUserTestTool.unableToRunIngest=Unable to run ingest on test data source
MultiUserTestTool.unableToUpdateKWSIndex=Unable to write to Keyword Search index
MultiUserTestTool.unexpectedError=Unexpected error while performing Multi User test
NodeStatusLogPanel.bnCancel.text=Cancel
NodeStatusLogPanel.bnOk.text=OK
NodeStatusLogPanel.bnTestDatabase.text=Test

View File

@ -0,0 +1,455 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2019 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.experimental.configuration;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import org.apache.commons.io.FileUtils;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.CaseActionException;
import org.sleuthkit.autopsy.casemodule.CaseDetails;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import static org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeStampUtils;
import org.sleuthkit.autopsy.datasourceprocessors.AddDataSourceCallback;
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSource;
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.casemodule.LocalFilesDSProcessor;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
import org.sleuthkit.autopsy.core.ServicesMonitor;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.ingest.IngestJob;
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestJobStartResult;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestModuleError;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
import org.sleuthkit.datamodel.AbstractFile;
/**
* Test tool that creates a multi user case, database, KWS index, runs ingest,
* etc. If errors are encountered during this process, provides a message
* regarding the problem and possible causes.
*/
class MultiUserTestTool {
private static final String CASE_NAME = "Test_Multi_User_Settings";
private static final Logger LOGGER = Logger.getLogger(MultiUserTestTool.class.getName());
private static final String TEST_FILE_NAME = "AutopsyTempFile";
private static final Object INGEST_LOCK = new Object();
static final String MULTI_USER_TEST_SUCCESSFUL = NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.Success");
private MultiUserTestTool() {
}
@NbBundle.Messages({
"MultiUserTestTool.unableToCreateCase=Unable to create case",
"MultiUserTestTool.unableToInitializeDatabase=Case database was not successfully initialized",
"MultiUserTestTool.unableToReadDatabase=Unable to read from case database",
"MultiUserTestTool.unableCreatFile=Unable to create a file in case output directory",
"MultiUserTestTool.unableAddFileAsDataSource=Unable to add test file as data source to case",
"MultiUserTestTool.unableToReadTestFileFromDatabase=Unable to read test file info from case database",
"MultiUserTestTool.unableToUpdateKWSIndex=Unable to write to Keyword Search index",
"MultiUserTestTool.unableToRunIngest=Unable to run ingest on test data source",
"MultiUserTestTool.unexpectedError=Unexpected error while performing Multi User test",
"# {0} - serviceName",
"MultiUserTestTool.serviceDown=Multi User service is down: {0}",
"# {0} - serviceName",
"MultiUserTestTool.unableToCheckService=Unable to check Multi User service state: {0}"
})
static String runTest(String rootOutputDirectory) {
// run standard tests for all services. this detects many problems sooner.
try {
if (!isServiceUp(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString())) {
return NbBundle.getMessage(MultiUserTestTool.class, "MultiUserTestTool.serviceDown", ServicesMonitor.Service.REMOTE_CASE_DATABASE.getDisplayName());
}
} catch (ServicesMonitor.ServicesMonitorException ex) {
return NbBundle.getMessage(MultiUserTestTool.class, "MultiUserTestTool.unableToCheckService",
ServicesMonitor.Service.REMOTE_CASE_DATABASE.getDisplayName() + ". " + ex.getMessage());
}
try {
if (!isServiceUp(ServicesMonitor.Service.REMOTE_KEYWORD_SEARCH.toString())) {
return NbBundle.getMessage(MultiUserTestTool.class, "MultiUserTestTool.serviceDown", ServicesMonitor.Service.REMOTE_KEYWORD_SEARCH.getDisplayName());
}
} catch (ServicesMonitor.ServicesMonitorException ex) {
return NbBundle.getMessage(MultiUserTestTool.class, "MultiUserTestTool.unableToCheckService",
ServicesMonitor.Service.REMOTE_KEYWORD_SEARCH.getDisplayName() + ". " + ex.getMessage());
}
try {
if (!isServiceUp(ServicesMonitor.Service.MESSAGING.toString())) {
return NbBundle.getMessage(MultiUserTestTool.class, "MultiUserTestTool.serviceDown", ServicesMonitor.Service.MESSAGING.getDisplayName());
}
} catch (ServicesMonitor.ServicesMonitorException ex) {
return NbBundle.getMessage(MultiUserTestTool.class, "MultiUserTestTool.unableToCheckService",
ServicesMonitor.Service.MESSAGING.getDisplayName() + ". " + ex.getMessage());
}
// Create a case in the output folder.
Case caseForJob;
try {
caseForJob = createCase(CASE_NAME, rootOutputDirectory);
} catch (CaseActionException ex) {
LOGGER.log(Level.SEVERE, Bundle.MultiUserTestTool_unableToCreateCase(), ex);
return Bundle.MultiUserTestTool_unableToCreateCase() + ". " + ex.getMessage();
}
if (caseForJob == null) {
LOGGER.log(Level.SEVERE, Bundle.MultiUserTestTool_unableToCreateCase());
return Bundle.MultiUserTestTool_unableToCreateCase();
}
try {
// Verify that DB was created. etc
String getDatabaseInfoQuery = "select * from tsk_db_info";
try (SleuthkitCase.CaseDbQuery queryResult = caseForJob.getSleuthkitCase().executeQuery(getDatabaseInfoQuery)) {
ResultSet resultSet = queryResult.getResultSet();
// check if we got a result
if (resultSet.next() == false) {
// we got a result so we are able to read from the database
return Bundle.MultiUserTestTool_unableToInitializeDatabase();
}
} catch (TskCoreException | SQLException ex) {
LOGGER.log(Level.SEVERE, Bundle.MultiUserTestTool_unableToReadDatabase(), ex);
return Bundle.MultiUserTestTool_unableToReadDatabase() + ". " + ex.getMessage();
}
// Make a text file in Windows TEMP folder
String tempFilePath = System.getProperty("java.io.tmpdir") + TEST_FILE_NAME + "_" + TimeStampUtils.createTimeStamp() + ".txt";
try {
FileUtils.writeStringToFile(new File(tempFilePath), "Test", Charset.forName("UTF-8"));
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, Bundle.MultiUserTestTool_unableCreatFile(), ex);
return Bundle.MultiUserTestTool_unableCreatFile() + ". " + ex.getMessage();
}
// Add it as a logical file set data source.
AutoIngestDataSource dataSource = new AutoIngestDataSource("", Paths.get(tempFilePath));
try {
String error = runLogicalFilesDSP(caseForJob, dataSource);
if (!error.isEmpty()) {
LOGGER.log(Level.SEVERE, error);
return error;
}
} catch (InterruptedException ex) {
LOGGER.log(Level.SEVERE, Bundle.MultiUserTestTool_unableAddFileAsDataSource(), ex);
return Bundle.MultiUserTestTool_unableAddFileAsDataSource() + ". " + ex.getMessage();
}
// Verify that Solr was able to create the core and is able to write to it
FileManager fileManager = caseForJob.getServices().getFileManager();
List<AbstractFile> listOfFiles = null;
try {
listOfFiles = fileManager.findFiles(new File(tempFilePath).getName());
if (listOfFiles == null || listOfFiles.isEmpty()) {
LOGGER.log(Level.SEVERE, Bundle.MultiUserTestTool_unableToReadTestFileFromDatabase());
return Bundle.MultiUserTestTool_unableToReadTestFileFromDatabase();
}
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, Bundle.MultiUserTestTool_unableToReadTestFileFromDatabase(), ex);
return Bundle.MultiUserTestTool_unableToReadTestFileFromDatabase() + ". " + ex.getMessage();
}
AbstractFile file = listOfFiles.get(0);
// write to KWS index
KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
try {
kwsService.index(file);
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, Bundle.MultiUserTestTool_unableToUpdateKWSIndex(), ex);
return Bundle.MultiUserTestTool_unableToUpdateKWSIndex() + ". " + ex.getMessage();
}
// Run ingest on that data source and report errors if the modules could not start.
try {
String error = analyze(dataSource);
if (!error.isEmpty()) {
LOGGER.log(Level.SEVERE, error);
return error;
}
} catch (InterruptedException ex) {
LOGGER.log(Level.SEVERE, Bundle.MultiUserTestTool_unableToRunIngest(), ex);
return Bundle.MultiUserTestTool_unableToRunIngest() + ". " + ex.getMessage();
}
} catch (Exception ex) {
// unexpected exception firewall
LOGGER.log(Level.SEVERE, "Unexpected error while performing Multi User test", ex);
return Bundle.MultiUserTestTool_unexpectedError() + ". " + ex.getMessage();
} finally {
// Close and delete the case.
try {
Case.deleteCurrentCase();
} catch (CaseActionException ex) {
// I don't think this should result in the test being marked as "failed" if everyhitng else went well
LOGGER.log(Level.WARNING, "Unable to delete test case", ex);
}
}
return MULTI_USER_TEST_SUCCESSFUL;
}
/**
* Creates a new multi user case.
*
* @param baseCaseName Case name (will get time stamp appended to it)
* @param rootOutputDirectory Full path to directory in which the case will
* be created
* @return Case object
* @throws CaseActionException
*/
private static Case createCase(String baseCaseName, String rootOutputDirectory) throws CaseActionException {
String caseDirectoryPath = rootOutputDirectory + File.separator + baseCaseName + "_" + TimeStampUtils.createTimeStamp();
// Create the case directory
Case.createCaseDirectory(caseDirectoryPath, Case.CaseType.MULTI_USER_CASE);
CaseDetails caseDetails = new CaseDetails(baseCaseName);
Case.createAsCurrentCase(Case.CaseType.MULTI_USER_CASE, caseDirectoryPath, caseDetails);
return Case.getCurrentCase();
}
/**
* Passes the data source for the current job Logical Files data source
* processor that adds it to the case database.
*
* @param caseForJob The case
* @param dataSource The data source.
*
* @return Error String if there was an error, empty string if the data
* source was added successfully
*
* @throws InterruptedException if the thread running the job processing
* task is interrupted while blocked, i.e., if ingest is shutting down.
*/
@NbBundle.Messages({
"MultiUserTestTool.noContent=Test data source failed to produce content",
"# {0} - errorMessage",
"MultiUserTestTool.criticalError=Critical error running data source processor on test data source: {0}"
})
private static String runLogicalFilesDSP(Case caseForJob, AutoIngestDataSource dataSource) throws InterruptedException {
AutoIngestDataSourceProcessor selectedProcessor = new LocalFilesDSProcessor();
DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor();
synchronized (INGEST_LOCK) {
UUID taskId = UUID.randomUUID();
caseForJob.notifyAddingDataSource(taskId);
DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId, INGEST_LOCK);
caseForJob.notifyAddingDataSource(taskId);
selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), progressMonitor, callBack);
INGEST_LOCK.wait();
// at this point we got the content object(s) from the DSP.
// check whether the data source was processed successfully
if (dataSource.getContent().isEmpty()) {
return Bundle.MultiUserTestTool_noContent();
}
if ((dataSource.getResultDataSourceProcessorResultCode() == CRITICAL_ERRORS)) {
for (String errorMessage : dataSource.getDataSourceProcessorErrorMessages()) {
LOGGER.log(Level.SEVERE, "Critical error running data source processor on test data source: {0}", errorMessage);
}
return NbBundle.getMessage(MultiUserTestTool.class, "MultiUserTestTool.criticalError", dataSource.getDataSourceProcessorErrorMessages().get(0));
}
return "";
}
}
/**
* Analyzes the data source content returned by the data source processor
* using the configured set of data source level and file level analysis
* modules.
*
* @param dataSource The data source to analyze.
*
* @return Error String if there was an error, empty string if the data
* source was analyzed successfully
*
* @throws InterruptedException if the thread running the job processing
* task is interrupted while blocked, i.e., if auto ingest is shutting down.
*/
@NbBundle.Messages({
"# {0} - cancellationReason",
"MultiUserTestTool.ingestCancelled=Ingest cancelled due to {0}",
"MultiUserTestTool.startupError=Failed to analyze data source due to ingest job startup error",
"MultiUserTestTool.errorStartingIngestJob=Ingest manager error while starting ingest job",
"MultiUserTestTool.ingestSettingsError=Failed to analyze data source due to ingest settings errors"
})
private static String analyze(AutoIngestDataSource dataSource) throws InterruptedException {
LOGGER.log(Level.INFO, "Starting ingest modules analysis for {0} ", dataSource.getPath());
IngestJobEventListener ingestJobEventListener = new IngestJobEventListener();
IngestManager.getInstance().addIngestJobEventListener(ingestJobEventListener);
try {
synchronized (INGEST_LOCK) {
IngestJobSettings ingestJobSettings = new IngestJobSettings(AutoIngestUserPreferences.getAutoModeIngestModuleContextString());
List<String> settingsWarnings = ingestJobSettings.getWarnings();
if (settingsWarnings.isEmpty()) {
IngestJobStartResult ingestJobStartResult = IngestManager.getInstance().beginIngestJob(dataSource.getContent(), ingestJobSettings);
IngestJob ingestJob = ingestJobStartResult.getJob();
if (null != ingestJob) {
/*
* Block until notified by the ingest job event
* listener or until interrupted because auto ingest
* is shutting down.
*/
INGEST_LOCK.wait();
LOGGER.log(Level.INFO, "Finished ingest modules analysis for {0} ", dataSource.getPath());
IngestJob.ProgressSnapshot jobSnapshot = ingestJob.getSnapshot();
for (IngestJob.ProgressSnapshot.DataSourceProcessingSnapshot snapshot : jobSnapshot.getDataSourceSnapshots()) {
if (!snapshot.isCancelled()) {
List<String> cancelledModules = snapshot.getCancelledDataSourceIngestModules();
if (!cancelledModules.isEmpty()) {
LOGGER.log(Level.WARNING, String.format("Ingest module(s) cancelled for %s", dataSource.getPath()));
for (String module : snapshot.getCancelledDataSourceIngestModules()) {
LOGGER.log(Level.WARNING, String.format("%s ingest module cancelled for %s", module, dataSource.getPath()));
}
}
LOGGER.log(Level.INFO, "Analysis of data source completed");
} else {
LOGGER.log(Level.WARNING, "Analysis of data source cancelled");
IngestJob.CancellationReason cancellationReason = snapshot.getCancellationReason();
if (IngestJob.CancellationReason.NOT_CANCELLED != cancellationReason && IngestJob.CancellationReason.USER_CANCELLED != cancellationReason) {
return NbBundle.getMessage(MultiUserTestTool.class, "MultiUserTestTool.ingestCancelled", cancellationReason.getDisplayName());
}
}
}
} else if (!ingestJobStartResult.getModuleErrors().isEmpty()) {
for (IngestModuleError error : ingestJobStartResult.getModuleErrors()) {
LOGGER.log(Level.SEVERE, String.format("%s ingest module startup error for %s", error.getModuleDisplayName(), dataSource.getPath()), error.getThrowable());
}
LOGGER.log(Level.SEVERE, "Failed to analyze data source due to ingest job startup error");
return Bundle.MultiUserTestTool_startupError();
} else {
LOGGER.log(Level.SEVERE, String.format("Ingest manager ingest job start error for %s", dataSource.getPath()), ingestJobStartResult.getStartupException());
return Bundle.MultiUserTestTool_errorStartingIngestJob();
}
} else {
for (String warning : settingsWarnings) {
LOGGER.log(Level.SEVERE, "Ingest job settings error for {0}: {1}", new Object[]{dataSource.getPath(), warning});
}
return Bundle.MultiUserTestTool_ingestSettingsError();
}
}
} finally {
IngestManager.getInstance().removeIngestJobEventListener(ingestJobEventListener);
}
// ingest completed successfully
return "";
}
/**
* Tests service of interest to verify that it is running.
*
* @param serviceName Name of the service.
*
* @return True if the service is running, false otherwise.
*
* @throws ServicesMonitorException if there is an error querying the
* services monitor.
*/
private static boolean isServiceUp(String serviceName) throws ServicesMonitor.ServicesMonitorException {
return (ServicesMonitor.getInstance().getServiceStatus(serviceName).equals(ServicesMonitor.ServiceStatus.UP.toString()));
}
/**
* A data source processor progress monitor does nothing. There is currently
* no mechanism for showing or recording data source processor progress
* during an ingest job.
*/
private static class DoNothingDSPProgressMonitor implements DataSourceProcessorProgressMonitor {
/**
* Does nothing.
*
* @param indeterminate
*/
@Override
public void setIndeterminate(final boolean indeterminate) {
}
/**
* Does nothing.
*
* @param progress
*/
@Override
public void setProgress(final int progress) {
}
/**
* Does nothing.
*
* @param text
*/
@Override
public void setProgressText(final String text) {
}
}
/**
* An ingest job event listener that allows the job processing task to block
* until the analysis of a data source by the data source level and file
* level ingest modules is completed.
* <p>
* Note that the ingest job can spawn "child" ingest jobs (e.g., if an
* embedded virtual machine is found), so the job processing task must
* remain blocked until ingest is no longer running.
*/
private static class IngestJobEventListener implements PropertyChangeListener {
/**
* Listens for local ingest job completed or cancelled events and
* notifies the job processing thread when such an event occurs and
* there are no "child" ingest jobs running.
*
* @param event
*/
@Override
public void propertyChange(PropertyChangeEvent event) {
if (AutopsyEvent.SourceType.LOCAL == ((AutopsyEvent) event).getSourceType()) {
String eventType = event.getPropertyName();
if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
synchronized (INGEST_LOCK) {
INGEST_LOCK.notifyAll();
}
}
}
}
};
}

View File

@ -3,5 +3,7 @@ ObjectDetectionFileIngestModule.classifierDetection.text=Classifier detected {0}
# {0} - classifierDir
ObjectDetectionFileIngestModule.noClassifiersFound.message=No classifiers were found in {0}, object detection will not be executed.
ObjectDetectionFileIngestModule.noClassifiersFound.subject=No classifiers found.
ObjectDetectionFileIngestModule.notWindowsError=This module is only available on Windows.
ObjectDetectionFileIngestModule.openCVNotLoaded=OpenCV was not loaded, but is required to run.
ObjectDetectionModuleFactory.moduleDescription.text=Use object classifiers to identify objects in pictures.
ObjectDetectionModuleFactory.moduleName.text=Object Detection

View File

@ -65,14 +65,32 @@ public class ObjectDetectectionFileIngestModule extends FileIngestModuleAdapter
private Blackboard blackboard;
@Messages({"ObjectDetectionFileIngestModule.noClassifiersFound.subject=No classifiers found.",
"# {0} - classifierDir", "ObjectDetectionFileIngestModule.noClassifiersFound.message=No classifiers were found in {0}, object detection will not be executed."})
"# {0} - classifierDir", "ObjectDetectionFileIngestModule.noClassifiersFound.message=No classifiers were found in {0}, object detection will not be executed.",
"ObjectDetectionFileIngestModule.openCVNotLoaded=OpenCV was not loaded, but is required to run.",
"ObjectDetectionFileIngestModule.notWindowsError=This module is only available on Windows."
})
@Override
public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException {
jobId = context.getJobId();
File classifierDir = new File(PlatformUtil.getObjectDetectionClassifierPath());
classifiers = new HashMap<>();
if(!PlatformUtil.isWindowsOS()) {
//Pop-up that catches IngestModuleException will automatically indicate
//the name of the module before the message.
String errorMsg = Bundle.ObjectDetectionFileIngestModule_notWindowsError();
logger.log(Level.SEVERE, errorMsg);
throw new IngestModule.IngestModuleException(errorMsg);
}
if(!OpenCvLoader.hasOpenCvLoaded()) {
String errorMsg = Bundle.ObjectDetectionFileIngestModule_openCVNotLoaded();
logger.log(Level.SEVERE, errorMsg);
throw new IngestModule.IngestModuleException(errorMsg);
}
//Load all classifiers found in PlatformUtil.getObjectDetectionClassifierPath()
if (OpenCvLoader.isOpenCvLoaded() && classifierDir.exists() && classifierDir.isDirectory()) {
if (classifierDir.exists() && classifierDir.isDirectory()) {
for (File classifier : classifierDir.listFiles()) {
if (classifier.isFile() && FilenameUtils.getExtension(classifier.getName()).equalsIgnoreCase("xml")) {
classifiers.put(classifier.getName(), new CascadeClassifier(classifier.getAbsolutePath()));

View File

@ -24,6 +24,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Collectors;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.StringProperty;
@ -32,6 +33,7 @@ import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.TagName;
@ -59,20 +61,22 @@ import org.sleuthkit.datamodel.TagName;
"DrawableAttribute.mimeType=MIME type"})
public class DrawableAttribute<T extends Comparable<T>> {
public final static DrawableAttribute<String> MD5_HASH =
new DrawableAttribute<>(AttributeName.MD5_HASH, Bundle.DrawableAttribute_md5hash(),
private static final Logger logger = Logger.getLogger(DrawableAttribute.class.getName());
public final static DrawableAttribute<String> MD5_HASH
= new DrawableAttribute<>(AttributeName.MD5_HASH, Bundle.DrawableAttribute_md5hash(),
false,
"icon-hashtag.png", // NON-NLS
f -> Collections.singleton(f.getMd5Hash()));
public final static DrawableAttribute<String> NAME =
new DrawableAttribute<>(AttributeName.NAME, Bundle.DrawableAttribute_name(),
public final static DrawableAttribute<String> NAME
= new DrawableAttribute<>(AttributeName.NAME, Bundle.DrawableAttribute_name(),
true,
"folder-rename.png", //NON-NLS
f -> Collections.singleton(f.getName()));
public final static DrawableAttribute<Boolean> ANALYZED =
new DrawableAttribute<>(AttributeName.ANALYZED, Bundle.DrawableAttribute_analyzed(),
public final static DrawableAttribute<Boolean> ANALYZED
= new DrawableAttribute<>(AttributeName.ANALYZED, Bundle.DrawableAttribute_analyzed(),
true,
"",
f -> Collections.singleton(f.isAnalyzed()));
@ -85,89 +89,89 @@ public class DrawableAttribute<T extends Comparable<T>> {
* //TODO: this has lead to awkward hard to maintain code, and little
* advantage. move categories into DrawableDB?
*/
public final static DrawableAttribute<DhsImageCategory> CATEGORY =
new DrawableAttribute<DhsImageCategory>(AttributeName.CATEGORY, Bundle.DrawableAttribute_category(),
public final static DrawableAttribute<DhsImageCategory> CATEGORY
= new DrawableAttribute<DhsImageCategory>(AttributeName.CATEGORY, Bundle.DrawableAttribute_category(),
false,
"category-icon.png", //NON-NLS
f -> Collections.singleton(f.getCategory())) {
@Override
public Node getGraphicForValue(DhsImageCategory val) {
return val.getGraphic();
}
};
@Override
public Node getGraphicForValue(DhsImageCategory val) {
return val.getGraphic();
}
};
public final static DrawableAttribute<TagName> TAGS =
new DrawableAttribute<>(AttributeName.TAGS, Bundle.DrawableAttribute_tags(),
public final static DrawableAttribute<TagName> TAGS
= new DrawableAttribute<>(AttributeName.TAGS, Bundle.DrawableAttribute_tags(),
false,
"tag_red.png", //NON-NLS
DrawableFile::getTagNames);
public final static DrawableAttribute<String> PATH =
new DrawableAttribute<>(AttributeName.PATH, Bundle.DrawableAttribute_path(),
public final static DrawableAttribute<String> PATH
= new DrawableAttribute<>(AttributeName.PATH, Bundle.DrawableAttribute_path(),
true,
"folder_picture.png", //NON-NLS
f -> Collections.singleton(f.getDrawablePath()));
public final static DrawableAttribute<String> CREATED_TIME =
new DrawableAttribute<>(AttributeName.CREATED_TIME, Bundle.DrawableAttribute_createdTime(),
public final static DrawableAttribute<String> CREATED_TIME
= new DrawableAttribute<>(AttributeName.CREATED_TIME, Bundle.DrawableAttribute_createdTime(),
true,
"clock--plus.png", //NON-NLS
f -> Collections.singleton(ContentUtils.getStringTime(f.getCrtime(), f.getAbstractFile())));
public final static DrawableAttribute<String> MODIFIED_TIME =
new DrawableAttribute<>(AttributeName.MODIFIED_TIME, Bundle.DrawableAttribute_modifiedTime(),
public final static DrawableAttribute<String> MODIFIED_TIME
= new DrawableAttribute<>(AttributeName.MODIFIED_TIME, Bundle.DrawableAttribute_modifiedTime(),
true,
"clock--pencil.png", //NON-NLS
f -> Collections.singleton(ContentUtils.getStringTime(f.getMtime(), f.getAbstractFile())));
public final static DrawableAttribute<String> MAKE =
new DrawableAttribute<>(AttributeName.MAKE, Bundle.DrawableAttribute_cameraMake(),
public final static DrawableAttribute<String> MAKE
= new DrawableAttribute<>(AttributeName.MAKE, Bundle.DrawableAttribute_cameraMake(),
true,
"camera.png", //NON-NLS
f -> Collections.singleton(f.getMake()));
public final static DrawableAttribute<String> MODEL =
new DrawableAttribute<>(AttributeName.MODEL, Bundle.DrawableAttribute_cameraModel(),
public final static DrawableAttribute<String> MODEL
= new DrawableAttribute<>(AttributeName.MODEL, Bundle.DrawableAttribute_cameraModel(),
true,
"camera.png", //NON-NLS
f -> Collections.singleton(f.getModel()));
public final static DrawableAttribute<String> HASHSET =
new DrawableAttribute<>(AttributeName.HASHSET, Bundle.DrawableAttribute_hashSet(),
public final static DrawableAttribute<String> HASHSET
= new DrawableAttribute<>(AttributeName.HASHSET, Bundle.DrawableAttribute_hashSet(),
true,
"hashset_hits.png", //NON-NLS
DrawableFile::getHashSetNamesUnchecked);
public final static DrawableAttribute<Long> OBJ_ID =
new DrawableAttribute<>(AttributeName.OBJ_ID, Bundle.DrawableAttribute_intObjID(),
public final static DrawableAttribute<Long> OBJ_ID
= new DrawableAttribute<>(AttributeName.OBJ_ID, Bundle.DrawableAttribute_intObjID(),
true,
"",
f -> Collections.singleton(f.getId()));
public final static DrawableAttribute<Double> WIDTH =
new DrawableAttribute<>(AttributeName.WIDTH, Bundle.DrawableAttribute_width(),
public final static DrawableAttribute<Double> WIDTH
= new DrawableAttribute<>(AttributeName.WIDTH, Bundle.DrawableAttribute_width(),
false,
"arrow-resize.png", //NON-NLS
f -> Collections.singleton(f.getWidth()));
public final static DrawableAttribute<Double> HEIGHT =
new DrawableAttribute<>(AttributeName.HEIGHT, Bundle.DrawableAttribute_height(),
public final static DrawableAttribute<Double> HEIGHT
= new DrawableAttribute<>(AttributeName.HEIGHT, Bundle.DrawableAttribute_height(),
false,
"arrow-resize-090.png", //NON-NLS
f -> Collections.singleton(f.getHeight()));
public final static DrawableAttribute<String> MIME_TYPE =
new DrawableAttribute<>(AttributeName.MIME_TYPE, Bundle.DrawableAttribute_mimeType(),
public final static DrawableAttribute<String> MIME_TYPE
= new DrawableAttribute<>(AttributeName.MIME_TYPE, Bundle.DrawableAttribute_mimeType(),
false,
"mime_types.png", //NON-NLS
f -> Collections.singleton(f.getMIMEType()));
final private static List< DrawableAttribute<?>> groupables =
Arrays.asList(PATH, HASHSET, CATEGORY, TAGS, MAKE, MODEL, MIME_TYPE);
final private static List< DrawableAttribute<?>> groupables
= Arrays.asList(PATH, HASHSET, CATEGORY, TAGS, MAKE, MODEL, MIME_TYPE);
final private static List<DrawableAttribute<?>> values =
Arrays.asList(NAME, ANALYZED, CATEGORY, TAGS, PATH, CREATED_TIME,
final private static List<DrawableAttribute<?>> values
= Arrays.asList(NAME, ANALYZED, CATEGORY, TAGS, PATH, CREATED_TIME,
MODIFIED_TIME, MD5_HASH, HASHSET, MAKE, MODEL, OBJ_ID, WIDTH, HEIGHT, MIME_TYPE);
private final Function<DrawableFile, Collection<T>> extractor;
@ -226,9 +230,17 @@ public class DrawableAttribute<T extends Comparable<T>> {
}
public Collection<T> getValue(DrawableFile f) {
return extractor.apply(f).stream()
.filter(value -> (value != null && value.toString().isEmpty()== false) )
.collect(Collectors.toSet());
try {
return extractor.apply(f).stream()
.filter(value -> (value != null && value.toString().isEmpty() == false))
.collect(Collectors.toSet());
} catch (Exception ex) {
/* There is a catch-all here because the code in the try block executes third-party
library calls that throw unchecked exceptions. See JIRA-5144, where an IllegalStateException
was thrown because a file's MIME type was incorrectly identified as a picture type. */
logger.log(Level.WARNING, "Exception while getting image attributes", ex); //NON-NLS
return Collections.EMPTY_SET;
}
}
public static enum AttributeName {

View File

@ -8,7 +8,7 @@
<property name="i586" location="${basedir}/Core/release/modules/lib/i586" />
<property name="i686" location="${basedir}/Core/release/modules/lib/i686"/>
<property name="crt" location="${basedir}/thirdparty/crt" />
<property name="tsk_logical_imager_dir" location="${basedir}/Core/release/modules/tsk_logical_imager"/>
<property name="tsk_logical_imager_dir" location="${basedir}/Core/release/tsk_logical_imager"/>
<import file="build-windows-installer.xml" />

View File

@ -1,20 +1,20 @@
/*! \page content_viewer_page Content Viewer
The Content Viewer lives in the lower right-hand side of the Autopsy main screen and shows pictures, video, hex, text, extracted strings, metadata, etc. The Content Viewer is enabled when you select an entry in the \ref ui_results.
The Content Viewer lives in the lower right-hand side of the Autopsy main screen and shows pictures, video, hex, text, extracted strings, metadata, etc. The Content Viewer is populated when you select an entry in the \ref ui_results.
The Content Viewer is context-aware, meaning different tabs will be enabled depending on the type of content selected and which ingest modules have been run. It will default to what it considers the "most specific" tab. For example, selecting a JPG will cause the Content Viewer to automatically select the "Application" tab and will display the image there. If you instead would like the Content Viewer to stay on the previously selected tab when you change to a different content object, go to the \ref view_options_page panel through Tools->Options->Application Tab and select the "Stay on the same file viewer" option.
\image html content_viewer_options_panel.png
When a Result type is selected in the Result Viewer (as opposed to a file), most of the tabs will correspond to the file associated with the result and not the result itself. For example, when selecting a Keyword Hit, the "Hex", "Strings", and "File Metadata" tabs will show data from the file where the keyword was found. The descriptions below will generally assume a file has been selected, but most also apply when we have a file associated with a selected result.
When a result item is selected in the Result Viewer (as opposed to a file), most of the tabs will correspond to the file associated with the result and not the result itself. For example, when selecting a keyword hit, the "Hex", "Strings", and "File Metadata" tabs will show data from the file where the keyword was found. The descriptions below will generally assume a file has been selected, but most also apply when we have a file associated with a selected result.
\section cv_hex Hex
The Hex Content Viewer is nearly always available and shows you the raw and exact contents of a file. In this content viewer, the data of the file is represented as hexadecimal values grouped in 2 groups of 8 bytes, followed by one group of 16 ASCII characters which are derived from each pair of hex values (each byte). Non-printable ASCII characters and characters that would take more than one character space are typically represented by a dot (".") in the following ASCII field.
The Hex tab is nearly always available and shows you the raw and exact contents of a file. In this tab, the data of the file is represented as hexadecimal values grouped in 2 groups of 8 bytes, followed by one group of 16 ASCII characters which are derived from each pair of hex values (each byte). Non-printable ASCII characters and characters that would take more than one character space are typically represented by a dot (".") in the following ASCII field.
\image html content_viewer_hex.png
If desired, you can open the file in an external hex editor. This is configured through the "External Viewer" tab on the options panel. HxD has been tested to work, but alternate hex editors may also be compatible.
If desired, you can open the file in an external hex editor. This is configured through the "External Viewer" tab on the options panel. HxD has been verified to work with Autopsy, but alternate hex editors may also be compatible.
\image html content_viewer_hex_editor_setup.png
@ -22,12 +22,30 @@ Note that this process saves the file to disk before launching the hex editor. A
\image html content_viewer_hxd_progress.png
\section cv_strings Strings
\section cv_text Text
The Strings tab shows all text strings found in the file. Different scripts can be chosen from the drop-down menu to display results for non-Latin alphabets.
The Text tab has three sub tabs for displaying the text contained in the selected item.
\subsection cv_strings Strings
The Strings tab shows all text strings found in the file for the given script selected in the upper right. By default Latin text is used.
\image html content_viewer_strings_latin.png
Different scripts can be chosen from the drop-down menu to display results for non-Latin alphabets.
\image html content_viewer_strings_cyrillic.png
\subsection cv_indexed_text Indexed Text
The Indexed Text tab shows the text that has been indexed by the \ref keyword_search_page. You can switch the "Text Source" field to "Result Text" to see the text that has been indexed for the results associated with a file.
\image html content_viewer_indexed_text.png
\subsection cv_translation Translation
If you have a translation service enabled, the Translation tab allows you to translate the text. See the \ref machine_translation_page page for more information.
\section cv_app Application
For certain file types, the Application tab can display the contents in a user friendly format. The following screenshots show some examples of what the Application tab will display.
@ -48,11 +66,9 @@ HTML files can be displayed closer to their original form:
\image html content_viewer_html.png
\section cv_indexed_text Indexed Text
Registry hive files can be viewed in a format similar to a registry editor.
The Indexed Text tab shows the text that has been indexed by the Keyword Search module. You can switch the "Text Source" Field to "Result Text" to see which text has been indexed for associated results.
\image html content_viewer_indexed_text.png
\image html content_viewer_registry.png
\section cv_message Message
@ -68,7 +84,7 @@ The File Metadata tab displays basic information about the file, such as type, s
\section cv_results Results
The Results tab is active when selecting entries that are part of the Results tree, such as keyword hits, call logs, and messages. It is also active when looking at a file that has results associated with it. The exact fields displayed depend on the type of entry. The two images below show the Results tab for a call log and a web bookmark.
The Results tab is active when selecting items with associated results such as keyword hits, call logs, and messages. The exact fields displayed depend on the type of result. The two images below show the Results tab for a call log and a web bookmark.
\image html content_viewer_results_call.png
<br>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 KiB

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Some files were not shown because too many files have changed in this diff Show More