From e352817801ade27d55784c3bd388f2b89874a7eb Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 27 Aug 2018 13:33:17 -0400 Subject: [PATCH 001/273] 4163 add caches to case, type, and datasource for eamdb queries --- .../datamodel/AbstractSqlEamDb.java | 188 +++++++++++------- 1 file changed, 114 insertions(+), 74 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 288363fe95..0ce4941c09 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.centralrepository.datamodel; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; @@ -34,6 +36,8 @@ import java.time.LocalDate; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import org.sleuthkit.autopsy.casemodule.Case; import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil.updateSchemaVersion; @@ -57,6 +61,15 @@ abstract class AbstractSqlEamDb implements EamDb { private int bulkArtifactsCount; protected int bulkArtifactsThreshold; private final Map> bulkArtifacts; + private static final int CASE_CACHE_TIMEOUT = 5; + private static final int DATA_SOURCE_CACHE_TIMEOUT = 5; + private static final Cache typeCache = CacheBuilder.newBuilder().build(); + private static final Cache caseCache = CacheBuilder.newBuilder() + .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES). + build(); + private static final Cache dataSourceCache = CacheBuilder.newBuilder() + .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES). + build(); // Maximum length for the value column in the instance tables static final int MAX_VALUE_LENGTH = 256; @@ -88,7 +101,7 @@ abstract class AbstractSqlEamDb implements EamDb { /** * Add a new name/value pair in the db_info table. * - * @param name Key to set + * @param name Key to set * @param value Value to set * * @throws EamDbException @@ -149,10 +162,19 @@ abstract class AbstractSqlEamDb implements EamDb { return value; } + /** + * Reset the contents of the caches associated with EamDb results. + */ + protected final void clearCaches() { + typeCache.invalidateAll(); + caseCache.invalidateAll(); + dataSourceCache.invalidateAll(); + } + /** * Update the value for a name in the name/value db_info table. * - * @param name Name to find + * @param name Name to find * @param value Value to assign to name. * * @throws EamDbException @@ -278,7 +300,11 @@ abstract class AbstractSqlEamDb implements EamDb { @Override public CorrelationCase getCase(Case autopsyCase) throws EamDbException { - return getCaseByUUID(autopsyCase.getName()); + try { + return caseCache.get(autopsyCase.getName(), () -> getCaseByUUID(autopsyCase.getName())); + } catch (ExecutionException ex) { + throw new EamDbException("Error getting autopsy case from Central repo", ex); + } } /** @@ -505,51 +531,57 @@ abstract class AbstractSqlEamDb implements EamDb { /** * Retrieves Data Source details based on data source device ID * - * @param correlationCase the current CorrelationCase used for ensuring - * uniqueness of DataSource + * @param correlationCase the current CorrelationCase used for ensuring + * uniqueness of DataSource * @param dataSourceDeviceId the data source device ID number * * @return The data source */ @Override public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { + if (correlationCase == null) { throw new EamDbException("Correlation case is null"); } - - Connection conn = connect(); - - CorrelationDataSource eamDataSourceResult = null; - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - - String sql = "SELECT * FROM data_sources WHERE device_id=? AND case_id=?"; // NON-NLS - try { - preparedStatement = conn.prepareStatement(sql); - preparedStatement.setString(1, dataSourceDeviceId); - preparedStatement.setInt(2, correlationCase.getID()); - resultSet = preparedStatement.executeQuery(); - if (resultSet.next()) { - eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); - } - } catch (SQLException ex) { - throw new EamDbException("Error getting data source.", ex); // NON-NLS - } finally { - EamDbUtil.closeStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); - } + return dataSourceCache.get(correlationCase.getCaseUUID() + dataSourceDeviceId, () -> { + Connection conn = connect(); - return eamDataSourceResult; + CorrelationDataSource eamDataSourceResult = null; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + String sql = "SELECT * FROM data_sources WHERE device_id=? AND case_id=?"; // NON-NLS + + try { + preparedStatement = conn.prepareStatement(sql); + preparedStatement.setString(1, dataSourceDeviceId); + preparedStatement.setInt(2, correlationCase.getID()); + resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); + } + } catch (SQLException ex) { + throw new EamDbException("Error getting data source.", ex); // NON-NLS + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + + return eamDataSourceResult; + }); + } catch (ExecutionException ex) { + throw new EamDbException("Error getting data source from central repository", ex); + } } /** * Retrieves Data Source details based on data source ID * * @param correlationCase the current CorrelationCase used for ensuring - * uniqueness of DataSource - * @param dataSourceId the data source ID number + * uniqueness of DataSource + * @param dataSourceId the data source ID number * * @return The data source */ @@ -764,7 +796,7 @@ abstract class AbstractSqlEamDb implements EamDb { * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath * - * @param aType EamArtifact.Type to search for + * @param aType EamArtifact.Type to search for * @param filePath File path to search for * * @return List of 0 or more EamArtifactInstances @@ -831,7 +863,7 @@ abstract class AbstractSqlEamDb implements EamDb { * @param value The correlation value * * @return Number of artifact instances having ArtifactType and - * ArtifactValue. + * ArtifactValue. */ @Override public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException { @@ -960,11 +992,11 @@ abstract class AbstractSqlEamDb implements EamDb { * associated with the caseDisplayName and dataSource of the given * eamArtifact instance. * - * @param caseUUID Case ID to search for + * @param caseUUID Case ID to search for * @param dataSourceID Data source ID to search for * * @return Number of artifact instances having caseDisplayName and - * dataSource + * dataSource */ @Override public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException { @@ -1227,7 +1259,7 @@ abstract class AbstractSqlEamDb implements EamDb { * associated CorrelationAttribute object. * * @param eamArtifact The correlation attribute whose database instance will - * be updated. + * be updated. * * @throws EamDbException */ @@ -1277,11 +1309,11 @@ abstract class AbstractSqlEamDb implements EamDb { * Find a correlation attribute in the Central Repository database given the * instance type, case, data source, value, and file path. * - * @param type The type of instance. - * @param correlationCase The case tied to the instance. + * @param type The type of instance. + * @param correlationCase The case tied to the instance. * @param correlationDataSource The data source tied to the instance. - * @param value The value tied to the instance. - * @param filePath The file path tied to the instance. + * @param value The value tied to the instance. + * @param filePath The file path tied to the instance. * * @return The correlation attribute if it exists; otherwise null. * @@ -1356,7 +1388,7 @@ abstract class AbstractSqlEamDb implements EamDb { * * @param eamArtifact Artifact containing exactly one (1) ArtifactInstance. * @param knownStatus The status to change the artifact to. Should never be - * KNOWN + * KNOWN */ @Override public void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) throws EamDbException { @@ -1618,7 +1650,7 @@ abstract class AbstractSqlEamDb implements EamDb { * @param value Value to search for * * @return List of cases containing this artifact with instances marked as - * bad + * bad * * @throws EamDbException */ @@ -1858,7 +1890,7 @@ abstract class AbstractSqlEamDb implements EamDb { /** * Process the Artifact instance in the EamDb * - * @param type EamArtifact.Type to search for + * @param type EamArtifact.Type to search for * @param instanceTableCallback callback to process the instance * * @throws EamDbException @@ -1897,9 +1929,10 @@ abstract class AbstractSqlEamDb implements EamDb { /** * Process the Artifact instance in the EamDb give a where clause * - * @param type EamArtifact.Type to search for + * @param type EamArtifact.Type to search for * @param instanceTableCallback callback to process the instance - * @param whereClause query string to execute + * @param whereClause query string to execute + * * @throws EamDbException */ @Override @@ -2081,7 +2114,7 @@ abstract class AbstractSqlEamDb implements EamDb { * Update an existing organization. * * @param updatedOrganization the values the Organization with the same ID - * will be updated to in the database. + * will be updated to in the database. * * @throws EamDbException */ @@ -2284,7 +2317,8 @@ abstract class AbstractSqlEamDb implements EamDb { * Add a new reference instance * * @param eamGlobalFileInstance The reference instance to add - * @param correlationType Correlation Type that this Reference Instance is + * @param correlationType Correlation Type that this Reference + * Instance is * * @throws EamDbException */ @@ -2412,7 +2446,7 @@ abstract class AbstractSqlEamDb implements EamDb { /** * Get all reference entries having a given correlation type and value * - * @param aType Type to use for matching + * @param aType Type to use for matching * @param aValue Value to use for matching * * @return List of all global file instances with a type and value @@ -2613,7 +2647,7 @@ abstract class AbstractSqlEamDb implements EamDb { * artifacts. * * @return List of enabled EamArtifact.Type's. If none are defined in the - * database, the default list will be returned. + * database, the default list will be returned. * * @throws EamDbException */ @@ -2648,7 +2682,7 @@ abstract class AbstractSqlEamDb implements EamDb { * correlate artifacts. * * @return List of supported EamArtifact.Type's. If none are defined in the - * database, the default list will be returned. + * database, the default list will be returned. * * @throws EamDbException */ @@ -2721,30 +2755,36 @@ abstract class AbstractSqlEamDb implements EamDb { */ @Override public CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId) throws EamDbException { - Connection conn = connect(); - - CorrelationAttributeInstance.Type aType; - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - String sql = "SELECT * FROM correlation_types WHERE id=?"; - try { - preparedStatement = conn.prepareStatement(sql); - preparedStatement.setInt(1, typeId); - resultSet = preparedStatement.executeQuery(); - if (resultSet.next()) { - aType = getCorrelationTypeFromResultSet(resultSet); - return aType; - } else { - throw new EamDbException("Failed to find entry for correlation type ID = " + typeId); - } + return typeCache.get(CorrelationAttributeInstance.FILES_TYPE_ID, () -> { + Connection conn = connect(); - } catch (SQLException ex) { - throw new EamDbException("Error getting correlation type by id.", ex); // NON-NLS - } finally { - EamDbUtil.closeStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); + CorrelationAttributeInstance.Type aType; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + String sql = "SELECT * FROM correlation_types WHERE id=?"; + + try { + preparedStatement = conn.prepareStatement(sql); + preparedStatement.setInt(1, typeId); + resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + aType = getCorrelationTypeFromResultSet(resultSet); + return aType; + } else { + throw new EamDbException("Failed to find entry for correlation type ID = " + typeId); + } + + } catch (SQLException ex) { + throw new EamDbException("Error getting correlation type by id.", ex); // NON-NLS + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + }); + } catch (ExecutionException ex) { + throw new EamDbException("Error getting correlation type", ex); } } @@ -2752,7 +2792,7 @@ abstract class AbstractSqlEamDb implements EamDb { * Convert a ResultSet to a EamCase object * * @param resultSet A resultSet with a set of values to create a EamCase - * object. + * object. * * @return fully populated EamCase object, or null * @@ -2822,7 +2862,7 @@ abstract class AbstractSqlEamDb implements EamDb { * Convert a ResultSet to a EamArtifactInstance object * * @param resultSet A resultSet with a set of values to create a - * EamArtifactInstance object. + * EamArtifactInstance object. * * @return fully populated EamArtifactInstance, or null * From 2e195cf16efb6db69d056759bf1b50061f1aeac1 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 27 Aug 2018 13:34:23 -0400 Subject: [PATCH 002/273] 4163 reset caches when CR connections are shutdown --- .../autopsy/centralrepository/datamodel/PostgresEamDb.java | 1 + .../autopsy/centralrepository/datamodel/SqliteEamDb.java | 1 + 2 files changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java index 5db232b51e..9e701fad3a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java @@ -78,6 +78,7 @@ final class PostgresEamDb extends AbstractSqlEamDb { connectionPool.close(); connectionPool = null; // force it to be re-created on next connect() } + clearCaches(); } } catch (SQLException ex) { throw new EamDbException("Failed to close existing database connections.", ex); // NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index d300964b5f..34157dea68 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -85,6 +85,7 @@ final class SqliteEamDb extends AbstractSqlEamDb { connectionPool.close(); connectionPool = null; // force it to be re-created on next connect() } + clearCaches(); } } catch (SQLException ex) { throw new EamDbException("Failed to close existing database connections.", ex); // NON-NLS From 0b3a9fab0eaf3520ff30f9effc6c086757b1a2a0 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 27 Aug 2018 13:47:33 -0400 Subject: [PATCH 003/273] 4163 move queries to helper functions when caching for readability --- .../datamodel/AbstractSqlEamDb.java | 135 +++++++++++------- 1 file changed, 81 insertions(+), 54 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 0ce4941c09..825c61f837 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -536,6 +536,8 @@ abstract class AbstractSqlEamDb implements EamDb { * @param dataSourceDeviceId the data source device ID number * * @return The data source + * + * @throws EamDbException */ @Override public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { @@ -544,38 +546,52 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException("Correlation case is null"); } try { - return dataSourceCache.get(correlationCase.getCaseUUID() + dataSourceDeviceId, () -> { - Connection conn = connect(); - - CorrelationDataSource eamDataSourceResult = null; - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - - String sql = "SELECT * FROM data_sources WHERE device_id=? AND case_id=?"; // NON-NLS - - try { - preparedStatement = conn.prepareStatement(sql); - preparedStatement.setString(1, dataSourceDeviceId); - preparedStatement.setInt(2, correlationCase.getID()); - resultSet = preparedStatement.executeQuery(); - if (resultSet.next()) { - eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); - } - } catch (SQLException ex) { - throw new EamDbException("Error getting data source.", ex); // NON-NLS - } finally { - EamDbUtil.closeStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); - } - - return eamDataSourceResult; - }); + return dataSourceCache.get(correlationCase.getCaseUUID() + dataSourceDeviceId, () -> getDataSourceFromCr(correlationCase, dataSourceDeviceId)); } catch (ExecutionException ex) { throw new EamDbException("Error getting data source from central repository", ex); } } + /** + * Gets the Data Source details based on data source device ID from the + * central repository. + * + * @param correlationCase the current CorrelationCase used for ensuring + * uniqueness of DataSource + * @param dataSourceDeviceId the data source device ID number + * + * @return The data source + * + * @throws EamDbException + */ + private CorrelationDataSource getDataSourceFromCr(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { + Connection conn = connect(); + + CorrelationDataSource eamDataSourceResult = null; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + String sql = "SELECT * FROM data_sources WHERE device_id=? AND case_id=?"; // NON-NLS + + try { + preparedStatement = conn.prepareStatement(sql); + preparedStatement.setString(1, dataSourceDeviceId); + preparedStatement.setInt(2, correlationCase.getID()); + resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); + } + } catch (SQLException ex) { + throw new EamDbException("Error getting data source.", ex); // NON-NLS + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + + return eamDataSourceResult; + } + /** * Retrieves Data Source details based on data source ID * @@ -2756,37 +2772,48 @@ abstract class AbstractSqlEamDb implements EamDb { @Override public CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId) throws EamDbException { try { - return typeCache.get(CorrelationAttributeInstance.FILES_TYPE_ID, () -> { - Connection conn = connect(); - - CorrelationAttributeInstance.Type aType; - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - String sql = "SELECT * FROM correlation_types WHERE id=?"; - - try { - preparedStatement = conn.prepareStatement(sql); - preparedStatement.setInt(1, typeId); - resultSet = preparedStatement.executeQuery(); - if (resultSet.next()) { - aType = getCorrelationTypeFromResultSet(resultSet); - return aType; - } else { - throw new EamDbException("Failed to find entry for correlation type ID = " + typeId); - } - - } catch (SQLException ex) { - throw new EamDbException("Error getting correlation type by id.", ex); // NON-NLS - } finally { - EamDbUtil.closeStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); - } - }); + return typeCache.get(CorrelationAttributeInstance.FILES_TYPE_ID, () ->getCorrelationTypeByIdFromCr(typeId)); } catch (ExecutionException ex) { throw new EamDbException("Error getting correlation type", ex); } } + + /** + * Get the EamArtifact.Type that has the given Type.Id from the central repo + * + * @param typeId Type.Id of Correlation Type to get + * + * @return EamArtifact.Type or null if it doesn't exist. + * + * @throws EamDbException + */ + private CorrelationAttributeInstance.Type getCorrelationTypeByIdFromCr(int typeId) throws EamDbException { + Connection conn = connect(); + + CorrelationAttributeInstance.Type aType; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + String sql = "SELECT * FROM correlation_types WHERE id=?"; + + try { + preparedStatement = conn.prepareStatement(sql); + preparedStatement.setInt(1, typeId); + resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + aType = getCorrelationTypeFromResultSet(resultSet); + return aType; + } else { + throw new EamDbException("Failed to find entry for correlation type ID = " + typeId); + } + + } catch (SQLException ex) { + throw new EamDbException("Error getting correlation type by id.", ex); // NON-NLS + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + } /** * Convert a ResultSet to a EamCase object From 288391f7d0dc4a211323eafed6e70af9eaa234d9 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 27 Aug 2018 17:13:45 -0400 Subject: [PATCH 004/273] 4163 cache based on both criteria we use to get case and datasource --- .../datamodel/AbstractSqlEamDb.java | 135 +++++++++++++++--- 1 file changed, 112 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 825c61f837..d088cd76d6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -45,6 +45,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.healthmonitor.HealthMonitor; import org.sleuthkit.autopsy.healthmonitor.TimingMetric; import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; +import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; /** @@ -64,13 +65,18 @@ abstract class AbstractSqlEamDb implements EamDb { private static final int CASE_CACHE_TIMEOUT = 5; private static final int DATA_SOURCE_CACHE_TIMEOUT = 5; private static final Cache typeCache = CacheBuilder.newBuilder().build(); - private static final Cache caseCache = CacheBuilder.newBuilder() + private static final Cache caseCacheByUUID = CacheBuilder.newBuilder() .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES). build(); - private static final Cache dataSourceCache = CacheBuilder.newBuilder() + private static final Cache caseCacheById = CacheBuilder.newBuilder() + .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES). + build(); + private static final Cache dataSourceCacheByDeviceId = CacheBuilder.newBuilder() + .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES). + build(); + private static final Cache dataSourceCacheById = CacheBuilder.newBuilder() .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES). build(); - // Maximum length for the value column in the instance tables static final int MAX_VALUE_LENGTH = 256; @@ -167,8 +173,10 @@ abstract class AbstractSqlEamDb implements EamDb { */ protected final void clearCaches() { typeCache.invalidateAll(); - caseCache.invalidateAll(); - dataSourceCache.invalidateAll(); + caseCacheByUUID.invalidateAll(); + caseCacheById.invalidateAll(); + dataSourceCacheByDeviceId.invalidateAll(); + dataSourceCacheById.invalidateAll(); } /** @@ -225,7 +233,7 @@ abstract class AbstractSqlEamDb implements EamDb { + getConflictClause(); try { - preparedStatement = conn.prepareStatement(sql); + preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); preparedStatement.setString(1, eamCase.getCaseUUID()); if (null == eamCase.getOrg()) { @@ -262,6 +270,17 @@ abstract class AbstractSqlEamDb implements EamDb { } preparedStatement.executeUpdate(); + //update the case in the caches + ResultSet resultSet = preparedStatement.getGeneratedKeys(); + if (!resultSet.next()) { + throw new EamDbException(String.format("Failed to INSERT case %s in central repo", eamCase.getCaseUUID())); + } + int caseID = resultSet.getInt(1); //last_insert_rowid() + CorrelationCase correlationCase = new CorrelationCase(caseID, eamCase.getCaseUUID(), eamCase.getOrg(), + eamCase.getDisplayName(), eamCase.getCreationDate(), eamCase.getCaseNumber(), eamCase.getExaminerName(), + eamCase.getExaminerEmail(), eamCase.getExaminerPhone(), eamCase.getNotes()); + caseCacheByUUID.put(eamCase.getCaseUUID(), correlationCase); + caseCacheById.put(caseID, correlationCase); } catch (SQLException ex) { throw new EamDbException("Error inserting new case.", ex); // NON-NLS } finally { @@ -300,11 +319,7 @@ abstract class AbstractSqlEamDb implements EamDb { @Override public CorrelationCase getCase(Case autopsyCase) throws EamDbException { - try { - return caseCache.get(autopsyCase.getName(), () -> getCaseByUUID(autopsyCase.getName())); - } catch (ExecutionException ex) { - throw new EamDbException("Error getting autopsy case from Central repo", ex); - } + return getCaseByUUID(autopsyCase.getName()); } /** @@ -365,6 +380,9 @@ abstract class AbstractSqlEamDb implements EamDb { preparedStatement.setString(9, eamCase.getCaseUUID()); preparedStatement.executeUpdate(); + //update the case in the cache + caseCacheById.put(eamCase.getID(), eamCase); + caseCacheByUUID.put(eamCase.getCaseUUID(), eamCase); } catch (SQLException ex) { throw new EamDbException("Error updating case.", ex); // NON-NLS } finally { @@ -373,6 +391,22 @@ abstract class AbstractSqlEamDb implements EamDb { } } + /** + * Retrieves Case details based on Case UUID from the central repo + * + * @param caseUUID unique identifier for a case + * + * @return The retrieved case + */ + @Override + public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException { + try { + return caseCacheByUUID.get(caseUUID, () -> getCaseByUUIDFromCr(caseUUID)); + } catch (ExecutionException ex) { + throw new EamDbException("Error getting autopsy case from Central repo", ex); + } + } + /** * Retrieves Case details based on Case UUID * @@ -380,10 +414,7 @@ abstract class AbstractSqlEamDb implements EamDb { * * @return The retrieved case */ - @Override - public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException { - // @@@ We should have a cache here... - + private CorrelationCase getCaseByUUIDFromCr(String caseUUID) throws EamDbException { Connection conn = connect(); CorrelationCase eamCaseResult = null; @@ -403,6 +434,10 @@ abstract class AbstractSqlEamDb implements EamDb { if (resultSet.next()) { eamCaseResult = getEamCaseFromResultSet(resultSet); } + if (eamCaseResult != null) { + //Update the version in the other cache + caseCacheById.put(eamCaseResult.getID(), eamCaseResult); + } } catch (SQLException ex) { throw new EamDbException("Error getting case details.", ex); // NON-NLS } finally { @@ -423,8 +458,21 @@ abstract class AbstractSqlEamDb implements EamDb { */ @Override public CorrelationCase getCaseById(int caseId) throws EamDbException { - // @@@ We should have a cache here... + try { + return caseCacheById.get(caseId, () -> getCaseByIdFromCr(caseId)); + } catch (ExecutionException ex) { + throw new EamDbException("Error getting autopsy case from Central repo", ex); + } + } + /** + * Retrieves Case details based on Case ID + * + * @param caseID unique identifier for a case + * + * @return The retrieved case + */ + private CorrelationCase getCaseByIdFromCr(int caseId) throws EamDbException { Connection conn = connect(); CorrelationCase eamCaseResult = null; @@ -436,7 +484,6 @@ abstract class AbstractSqlEamDb implements EamDb { + "FROM cases " + "LEFT JOIN organizations ON cases.org_id=organizations.id " + "WHERE cases.id=?"; - try { preparedStatement = conn.prepareStatement(sql); preparedStatement.setInt(1, caseId); @@ -444,6 +491,10 @@ abstract class AbstractSqlEamDb implements EamDb { if (resultSet.next()) { eamCaseResult = getEamCaseFromResultSet(resultSet); } + if (eamCaseResult != null) { + //Update the version in the other cache + caseCacheByUUID.put(eamCaseResult.getCaseUUID(), eamCaseResult); + } } catch (SQLException ex) { throw new EamDbException("Error getting case details.", ex); // NON-NLS } finally { @@ -492,6 +543,14 @@ abstract class AbstractSqlEamDb implements EamDb { return cases; } + private static String getDataSourceCacheKey(int caseId, String dataSourceDeviceId) { + return "Case" + caseId + "DeviceId" + dataSourceDeviceId; + } + + private static String getDataSourceCacheKey(int caseId, int dataSourceId) { + return "Case" + caseId + "Id" + dataSourceId; + } + /** * Creates new Data Source in the database * @@ -513,13 +572,21 @@ abstract class AbstractSqlEamDb implements EamDb { + getConflictClause(); try { - preparedStatement = conn.prepareStatement(sql); + preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); preparedStatement.setString(1, eamDataSource.getDeviceID()); preparedStatement.setInt(2, eamDataSource.getCaseID()); preparedStatement.setString(3, eamDataSource.getName()); preparedStatement.executeUpdate(); + ResultSet resultSet = preparedStatement.getGeneratedKeys(); + if (!resultSet.next()) { + throw new EamDbException(String.format("Failed to INSERT data source %s in central repo", eamDataSource.getName())); + } + int dataSourceId = resultSet.getInt(1); //last_insert_rowid() + CorrelationDataSource dataSource = new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName()); + dataSourceCacheByDeviceId.put(getDataSourceCacheKey(dataSource.getCaseID(), dataSource.getDeviceID()), dataSource); + dataSourceCacheById.put(getDataSourceCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource); } catch (SQLException ex) { throw new EamDbException("Error inserting new data source.", ex); // NON-NLS } finally { @@ -546,7 +613,7 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException("Correlation case is null"); } try { - return dataSourceCache.get(correlationCase.getCaseUUID() + dataSourceDeviceId, () -> getDataSourceFromCr(correlationCase, dataSourceDeviceId)); + return dataSourceCacheByDeviceId.get(getDataSourceCacheKey(correlationCase.getID(), dataSourceDeviceId), () -> getDataSourceFromCr(correlationCase, dataSourceDeviceId)); } catch (ExecutionException ex) { throw new EamDbException("Error getting data source from central repository", ex); } @@ -581,6 +648,9 @@ abstract class AbstractSqlEamDb implements EamDb { if (resultSet.next()) { eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); } + if (eamDataSourceResult != null) { + dataSourceCacheById.put(getDataSourceCacheKey(correlationCase.getID(), eamDataSourceResult.getID()), eamDataSourceResult); + } } catch (SQLException ex) { throw new EamDbException("Error getting data source.", ex); // NON-NLS } finally { @@ -606,7 +676,23 @@ abstract class AbstractSqlEamDb implements EamDb { if (correlationCase == null) { throw new EamDbException("Correlation case is null"); } + try { + return dataSourceCacheByDeviceId.get(getDataSourceCacheKey(correlationCase.getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId)); + } catch (ExecutionException ex) { + throw new EamDbException("Error getting data source from central repository", ex); + } + } + /** + * Retrieves Data Source details based on data source ID + * + * @param correlationCase the current CorrelationCase used for ensuring + * uniqueness of DataSource + * @param dataSourceId the data source ID number + * + * @return The data source + */ + private CorrelationDataSource getDataSourceByIdFromCr(CorrelationCase correlationCase, int dataSourceId) throws EamDbException { Connection conn = connect(); CorrelationDataSource eamDataSourceResult = null; @@ -623,6 +709,9 @@ abstract class AbstractSqlEamDb implements EamDb { if (resultSet.next()) { eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); } + if (eamDataSourceResult != null) { + dataSourceCacheByDeviceId.put(getDataSourceCacheKey(correlationCase.getID(), eamDataSourceResult.getDeviceID()), eamDataSourceResult); + } } catch (SQLException ex) { throw new EamDbException("Error getting data source.", ex); // NON-NLS } finally { @@ -2750,7 +2839,7 @@ abstract class AbstractSqlEamDb implements EamDb { preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0); preparedStatement.setInt(5, aType.getId()); preparedStatement.executeUpdate(); - + typeCache.put(aType.getId(), aType); } catch (SQLException ex) { throw new EamDbException("Error updating correlation type.", ex); // NON-NLS } finally { @@ -2772,13 +2861,13 @@ abstract class AbstractSqlEamDb implements EamDb { @Override public CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId) throws EamDbException { try { - return typeCache.get(CorrelationAttributeInstance.FILES_TYPE_ID, () ->getCorrelationTypeByIdFromCr(typeId)); + return typeCache.get(CorrelationAttributeInstance.FILES_TYPE_ID, () -> getCorrelationTypeByIdFromCr(typeId)); } catch (ExecutionException ex) { throw new EamDbException("Error getting correlation type", ex); } } - - /** + + /** * Get the EamArtifact.Type that has the given Type.Id from the central repo * * @param typeId Type.Id of Correlation Type to get From fc4e549dd160cfed31b84ca9293bb0da30774b79 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 27 Aug 2018 17:15:54 -0400 Subject: [PATCH 005/273] 4163 remove unused import --- .../autopsy/centralrepository/datamodel/AbstractSqlEamDb.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index d088cd76d6..be1518cb42 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -45,7 +45,6 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.healthmonitor.HealthMonitor; import org.sleuthkit.autopsy.healthmonitor.TimingMetric; import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; -import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; /** From ebcac1eb244ef04676b8c639eef6bbfb2a69714a Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 28 Aug 2018 12:01:39 -0400 Subject: [PATCH 006/273] 4163 comments and refactoring for clarity with new caches --- .../datamodel/AbstractSqlEamDb.java | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index be1518cb42..cfa39a8f32 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -542,12 +542,27 @@ abstract class AbstractSqlEamDb implements EamDb { return cases; } - private static String getDataSourceCacheKey(int caseId, String dataSourceDeviceId) { - return "Case" + caseId + "DeviceId" + dataSourceDeviceId; + /** + * Create a key to the DataSourceCacheByDeviceId + * + * @param caseId - the id of the CorrelationCase in the Central Repository + * @param dataSourceDeviceId - the device Id of the data source + * + * @return a String to be used as a key for the dataSourceCacheByDeviceId + */ + private static String getDataSourceByDeviceIdCacheKey(int caseId, String dataSourceDeviceId) { + return "Case" + caseId + "DeviceId" + dataSourceDeviceId; //NON-NLS } - private static String getDataSourceCacheKey(int caseId, int dataSourceId) { - return "Case" + caseId + "Id" + dataSourceId; + /** + * Create a key to the DataSourceCacheById + * + * @param caseId - the id of the CorrelationCase in the Central Repository + * @param dataSourceId - the id of the datasource in the central repository + * @return a String to be used as a key for the dataSourceCacheById + */ + private static String getDataSourceByIdCacheKey(int caseId, int dataSourceId) { + return "Case" + caseId + "Id" + dataSourceId; //NON-NLS } /** @@ -584,8 +599,8 @@ abstract class AbstractSqlEamDb implements EamDb { } int dataSourceId = resultSet.getInt(1); //last_insert_rowid() CorrelationDataSource dataSource = new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName()); - dataSourceCacheByDeviceId.put(getDataSourceCacheKey(dataSource.getCaseID(), dataSource.getDeviceID()), dataSource); - dataSourceCacheById.put(getDataSourceCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource); + dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(dataSource.getCaseID(), dataSource.getDeviceID()), dataSource); + dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource); } catch (SQLException ex) { throw new EamDbException("Error inserting new data source.", ex); // NON-NLS } finally { @@ -612,7 +627,7 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException("Correlation case is null"); } try { - return dataSourceCacheByDeviceId.get(getDataSourceCacheKey(correlationCase.getID(), dataSourceDeviceId), () -> getDataSourceFromCr(correlationCase, dataSourceDeviceId)); + return dataSourceCacheByDeviceId.get(getDataSourceByDeviceIdCacheKey(correlationCase.getID(), dataSourceDeviceId), () -> getDataSourceFromCr(correlationCase, dataSourceDeviceId)); } catch (ExecutionException ex) { throw new EamDbException("Error getting data source from central repository", ex); } @@ -648,7 +663,7 @@ abstract class AbstractSqlEamDb implements EamDb { eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); } if (eamDataSourceResult != null) { - dataSourceCacheById.put(getDataSourceCacheKey(correlationCase.getID(), eamDataSourceResult.getID()), eamDataSourceResult); + dataSourceCacheById.put(getDataSourceByIdCacheKey(correlationCase.getID(), eamDataSourceResult.getID()), eamDataSourceResult); } } catch (SQLException ex) { throw new EamDbException("Error getting data source.", ex); // NON-NLS @@ -676,7 +691,7 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException("Correlation case is null"); } try { - return dataSourceCacheByDeviceId.get(getDataSourceCacheKey(correlationCase.getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId)); + return dataSourceCacheByDeviceId.get(getDataSourceByIdCacheKey(correlationCase.getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId)); } catch (ExecutionException ex) { throw new EamDbException("Error getting data source from central repository", ex); } @@ -709,7 +724,7 @@ abstract class AbstractSqlEamDb implements EamDb { eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); } if (eamDataSourceResult != null) { - dataSourceCacheByDeviceId.put(getDataSourceCacheKey(correlationCase.getID(), eamDataSourceResult.getDeviceID()), eamDataSourceResult); + dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(correlationCase.getID(), eamDataSourceResult.getDeviceID()), eamDataSourceResult); } } catch (SQLException ex) { throw new EamDbException("Error getting data source.", ex); // NON-NLS From 056f4e953430fb275355e623d8881b8f1078a1bf Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 28 Aug 2018 12:04:15 -0400 Subject: [PATCH 007/273] 4163 update copyright dates --- .../autopsy/centralrepository/datamodel/PostgresEamDb.java | 2 +- .../autopsy/centralrepository/datamodel/SqliteEamDb.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java index 9e701fad3a..97abd1dec9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2015-2017 Basis Technology Corp. + * Copyright 2015-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 34157dea68..e4d7b7bd9d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2015-2017 Basis Technology Corp. + * Copyright 2015-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); From 2f57b436768c0bdedd17336c99504f9f5b34bd3f Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 28 Aug 2018 12:52:42 -0400 Subject: [PATCH 008/273] 4163 fix bug using wrong cache --- .../autopsy/centralrepository/datamodel/AbstractSqlEamDb.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index cfa39a8f32..68f1b4587a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -691,7 +691,7 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException("Correlation case is null"); } try { - return dataSourceCacheByDeviceId.get(getDataSourceByIdCacheKey(correlationCase.getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId)); + return dataSourceCacheById.get(getDataSourceByIdCacheKey(correlationCase.getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId)); } catch (ExecutionException ex) { throw new EamDbException("Error getting data source from central repository", ex); } From ced6607b4c5a5de746b954240ee8f1b46fb205ba Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 31 Aug 2018 18:04:21 -0400 Subject: [PATCH 009/273] Functional text extractor, looks functionally good. Need to test to make sure its good and also refactor and comment and clean up. this is first commit --- .../autopsy/contentviewers/SQLiteViewer.java | 9 ++---- .../tabulardatareader/AbstractReader.java | 30 +++++++++++++++++-- .../tabulardatareader/ExcelReader.java | 7 +++-- .../tabulardatareader/FileReaderFactory.java | 11 ++++--- .../tabulardatareader/SQLiteReader.java | 8 ++--- .../KeywordSearchIngestModule.java | 2 ++ .../keywordsearch/TikaTextExtractor.java | 3 ++ 7 files changed, 48 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java index 47a33dc578..74b2a90c86 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java @@ -361,10 +361,8 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { private void processSQLiteFile() { tablesDropdownList.removeAllItems(); try { - String localDiskPath = Case.getCurrentCaseThrows().getTempDirectory() + - File.separator + sqliteDbFile.getName(); - sqliteReader = FileReaderFactory.createReader(SUPPORTED_MIMETYPES[0], sqliteDbFile, localDiskPath); + sqliteReader = FileReaderFactory.createReader(SUPPORTED_MIMETYPES[0], sqliteDbFile); Map dbTablesMap = sqliteReader.getTableSchemas(); @@ -376,9 +374,6 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { tablesDropdownList.addItem(tableName); }); } - } catch (NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Current case has been closed", ex); //NON-NLS - MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_errorMessage_noCurrentCase()); } catch (FileReaderException ex) { logger.log(Level.SEVERE, String.format( "Failed to get tables from DB file '%s' (objId=%d)", //NON-NLS @@ -387,7 +382,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { Bundle.SQLiteViewer_errorMessage_failedToQueryDatabase()); } catch (FileReaderInitException ex) { logger.log(Level.SEVERE, String.format( - "Failed to create a SQLiteReader '%s' (objId=%d)", //NON-NLS + "Failed to create a SQLiteReader for file: '%s' (objId=%d)", //NON-NLS sqliteDbFile.getName(), sqliteDbFile.getId()), ex); } } diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java index cb74819142..b5a3edb02e 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java @@ -22,6 +22,9 @@ import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; @@ -32,10 +35,33 @@ import org.sleuthkit.datamodel.TskCoreException; */ public abstract class AbstractReader implements AutoCloseable { - public AbstractReader(AbstractFile file, String localDiskPath) + public AbstractReader(AbstractFile file) throws FileReaderInitException { - writeDataSourceToLocalDisk(file, localDiskPath); + try { + writeDataSourceToLocalDisk(file, getLocalDiskPath(file)); + } catch (FileReaderException ex) { + throw new FileReaderInitException(ex); + } + + } + + /** + * Generates a local disk path for abstract file contents to be copied. + * All file sources must be copied to local disk to be opened by + * abstract reader. + * + * @param file The database abstract file + * @return Valid local path for copying + * @throws NoCurrentCaseException if the current case has been closed. + */ + final String getLocalDiskPath(AbstractFile file) throws FileReaderException { + try { + return Case.getCurrentCaseThrows().getTempDirectory() + + File.separator + file.getName(); + } catch (NoCurrentCaseException ex) { + throw new FileReaderException(ex); + } } /** diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java index cf3ba49388..de76e39040 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java @@ -58,13 +58,14 @@ public final class ExcelReader extends AbstractReader { private final static String EMPTY_CELL_STRING = ""; private Map headerCache; - public ExcelReader(AbstractFile file, String localDiskPath, String mimeType) + public ExcelReader(AbstractFile file, String mimeType) throws FileReaderInitException { - super(file, localDiskPath); + super(file); try { + final String localDiskPath = super.getLocalDiskPath(file); this.workbook = createWorkbook(localDiskPath, mimeType); headerCache = new HashMap<>(); - } catch (IOException ex) { + } catch (IOException | FileReaderException ex) { throw new FileReaderInitException(ex); } } diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java index e6af1673b2..2887f1cd95 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java @@ -34,20 +34,19 @@ public final class FileReaderFactory { * is not supported. * * @param mimeType mimeType passed in from the ingest module -g * @param file current file under inspection - * @param localDiskPath path for abstract file contents to be written + * @param file current file under inspection * @return The correct reader class needed to read the file contents * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException */ - public static AbstractReader createReader(String mimeType, AbstractFile file, - String localDiskPath) throws FileReaderInitException { + public static AbstractReader createReader(String mimeType, AbstractFile file) + throws FileReaderInitException { switch (mimeType) { case "application/x-sqlite3": - return new SQLiteReader(file, localDiskPath); + return new SQLiteReader(file); case "application/vnd.ms-excel": case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": try { - return new ExcelReader(file, localDiskPath, mimeType); + return new ExcelReader(file, mimeType); //Catches runtime exceptions being emitted from Apache //POI (such as EncryptedDocumentException) and wraps them //into FileReaderInitException to be caught and logged diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java index c08f571280..42c89c77c1 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java @@ -58,19 +58,19 @@ public final class SQLiteReader extends AbstractReader { * connection. * * @param sqliteDbFile Data source abstract file - * @param localDiskPath Location for database contents to be copied to * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException */ - public SQLiteReader(AbstractFile sqliteDbFile, String localDiskPath) throws FileReaderInitException { - super(sqliteDbFile, localDiskPath); + public SQLiteReader(AbstractFile sqliteDbFile) throws FileReaderInitException { + super(sqliteDbFile); try { + final String localDiskPath = super.getLocalDiskPath(sqliteDbFile); // Look for any meta files associated with this DB - WAL, SHM, etc. findAndCopySQLiteMetaFile(sqliteDbFile, sqliteDbFile.getName() + "-wal"); findAndCopySQLiteMetaFile(sqliteDbFile, sqliteDbFile.getName() + "-shm"); connection = getDatabaseConnection(localDiskPath); } catch (ClassNotFoundException | SQLException |IOException | - NoCurrentCaseException | TskCoreException ex) { + NoCurrentCaseException | TskCoreException | FileReaderException ex) { throw new FileReaderInitException(ex); } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java index 01d95efe53..7eccd061ac 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java @@ -249,6 +249,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule { textExtractors = new ArrayList<>(); //order matters, more specific extractors first textExtractors.add(new HtmlTextExtractor()); + textExtractors.add(new SqliteTextExtractor()); textExtractors.add(new TikaTextExtractor()); indexer = new Indexer(); @@ -438,6 +439,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule { //go over available text extractors in order, and pick the first one (most specific one) for (ContentTextExtractor fe : textExtractors) { if (fe.isSupported(aFile, detectedFormat)) { + System.out.println(fe); extractor = fe; break; } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java index 0da7cb4b10..ea306ff9a9 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java @@ -193,13 +193,16 @@ class TikaTextExtractor extends ContentTextExtractor { @Override public boolean isSupported(Content content, String detectedFormat) { + final String SQLITE_MIMETYPE = "application/x-sqlite3"; if (detectedFormat == null || ContentTextExtractor.BLOB_MIME_TYPES.contains(detectedFormat) //any binary unstructured blobs (string extraction will be used) || ContentTextExtractor.ARCHIVE_MIME_TYPES.contains(detectedFormat) || (detectedFormat.startsWith("video/") && !detectedFormat.equals("video/x-flv")) //skip video other than flv (tika supports flv only) //NON-NLS + || detectedFormat.equals(SQLITE_MIMETYPE) //Skip sqlite files, Tika cannot handle virtual tables and will fail with an exception. See SqliteTextExtractor class ) { return false; } + System.out.println(detectedFormat); return TIKA_SUPPORTED_TYPES.contains(detectedFormat); } From 532bace6c25fde69861bfe7605689c4f91dd80aa Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 31 Aug 2018 18:04:53 -0400 Subject: [PATCH 010/273] Almost forgot this file too --- .../keywordsearch/SqliteTextExtractor.java | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100755 KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java new file mode 100755 index 0000000000..09be770bd5 --- /dev/null +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -0,0 +1,121 @@ +/* + * 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.keywordsearch; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import org.sleuthkit.autopsy.tabulardatareader.AbstractReader; +import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException; +import org.sleuthkit.autopsy.tabulardatareader.SQLiteReader; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * + * @author dsmyda + */ +public class SqliteTextExtractor extends ContentTextExtractor { + + private final String SQLITE_MIMETYPE = "application/x-sqlite3"; + + @Override + boolean isContentTypeSpecific() { + return true; + } + + @Override + boolean isSupported(Content file, String detectedFormat) { + return SQLITE_MIMETYPE.equals(detectedFormat); + } + + @Override + public Reader getReader(Content source) throws TextExtractorException { + return new InputStreamReader(new SqliteTextReader(source)); + } + + @Override + public boolean isDisabled() { + return false; + } + + @Override + public void logWarning(String msg, Exception ex) { + //TODO - come back. + } + + private final class SqliteTextReader extends InputStream { + + private final Content source; + private final SQLiteReader reader; + private StringBuffer fileData; + private int currIndex; + private final int NO_CONTENT_LEFT = -1; + + public SqliteTextReader(Content source) throws TextExtractorException { + this.source = source; + try { + this.reader = new SQLiteReader((AbstractFile) source.getDataSource()); + } catch (TskCoreException ex) { + throw new TextExtractorException( + String.format("Encountered a TskCoreException when getting " + + "root data source for Content with id:[%s], name:[%s].", + source.getId(), source.getName())); + } catch (FileReaderInitException ex) { + throw new TextExtractorException( + String.format("Encountered a FileReaderInitException when trying " + + "to initialize a SQLiteReader for Content with id:[%s], " + + "name:[%s].", source.getId(), source.getName())); + } + this.fileData = new StringBuffer(); + //Fill the entire buffer on instantiation + copySqliteFileIntoStringBuffer(source); + } + + private void copySqliteFileIntoStringBuffer(Content source){ + Map tables; + try { + //Table name to table schema mapping + tables = reader.getTableSchemas(); + for(String tableName : tables.keySet()) { + try { + List> rowsInTable = reader.getRowsFromTable(tableName); + for(Map row : rowsInTable) { + //Only interested in row values, not the column name + row.values().forEach(cell -> { + fileData.append(cell.toString()); + }); + } + } catch(AbstractReader.FileReaderException ex) { + // logger.log(Level.WARNING, + // String.format("Error attempting to read file table: [%s]" //NON-NLS + // + " for file: [%s] (id=%d).", tableName, //NON-NLS + // source.getName(), source.getId()), + // ex); + } + } + } catch (AbstractReader.FileReaderException ex) { + //logger.log(Level.WARNING, String.format("Error attempting to get tables from " //NON-NLS + // + "file: [%s] (id=%d).", //NON-NLS + // source.getName(), source.getId()), ex); + } + } + + @Override + public int read() throws IOException { + if (currIndex == fileData.length() - 1) { + return NO_CONTENT_LEFT; + } + return fileData.charAt(currIndex++); + } + } + +} From 2ab4c04dcd8d6773e93e575fbc65df1770d01715 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 5 Sep 2018 16:05:41 -0400 Subject: [PATCH 011/273] Generalized the tabulardatareader package so that it can work with a Content object and not just AbstractFile object, added a dedicated SqliteTextExtractor to handle sqlite databases during keyword search --- .../tabulardatareader/AbstractReader.java | 7 +- .../tabulardatareader/ExcelReader.java | 3 +- .../tabulardatareader/FileReaderFactory.java | 3 +- .../tabulardatareader/SQLiteReader.java | 11 +- .../KeywordSearchIngestModule.java | 3 +- .../keywordsearch/SqliteTextExtractor.java | 392 +++++++++++++++--- .../keywordsearch/TikaTextExtractor.java | 2 +- 7 files changed, 347 insertions(+), 74 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java index b5a3edb02e..917b862749 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java @@ -27,6 +27,7 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.TskCoreException; /** @@ -35,7 +36,7 @@ import org.sleuthkit.datamodel.TskCoreException; */ public abstract class AbstractReader implements AutoCloseable { - public AbstractReader(AbstractFile file) + public AbstractReader(Content file) throws FileReaderInitException { try { @@ -55,7 +56,7 @@ public abstract class AbstractReader implements AutoCloseable { * @return Valid local path for copying * @throws NoCurrentCaseException if the current case has been closed. */ - final String getLocalDiskPath(AbstractFile file) throws FileReaderException { + final String getLocalDiskPath(Content file) throws FileReaderException { try { return Case.getCurrentCaseThrows().getTempDirectory() + File.separator + file.getName(); @@ -74,7 +75,7 @@ public abstract class AbstractReader implements AutoCloseable { * @throws NoCurrentCaseException Current case closed during file copying * @throws TskCoreException Exception finding files from abstract file */ - private void writeDataSourceToLocalDisk(AbstractFile file, String localDiskPath) + private void writeDataSourceToLocalDisk(Content file, String localDiskPath) throws FileReaderInitException { try { diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java index de76e39040..711d4c0c60 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java @@ -39,6 +39,7 @@ import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.datamodel.AbstractFile; import com.monitorjbl.xlsx.StreamingReader; import org.apache.poi.hssf.OldExcelFormatException; +import org.sleuthkit.datamodel.Content; /** * Reads excel files and implements the abstract reader api for interfacing with @@ -58,7 +59,7 @@ public final class ExcelReader extends AbstractReader { private final static String EMPTY_CELL_STRING = ""; private Map headerCache; - public ExcelReader(AbstractFile file, String mimeType) + public ExcelReader(Content file, String mimeType) throws FileReaderInitException { super(file); try { diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java index 2887f1cd95..56707617ff 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.tabulardatareader; import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; /** * Factory for creating the correct reader given the mime type of a file. @@ -38,7 +39,7 @@ public final class FileReaderFactory { * @return The correct reader class needed to read the file contents * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException */ - public static AbstractReader createReader(String mimeType, AbstractFile file) + public static AbstractReader createReader(String mimeType, Content file) throws FileReaderInitException { switch (mimeType) { case "application/x-sqlite3": diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java index 42c89c77c1..1b4743faea 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java @@ -41,6 +41,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; @@ -60,7 +61,7 @@ public final class SQLiteReader extends AbstractReader { * @param sqliteDbFile Data source abstract file * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException */ - public SQLiteReader(AbstractFile sqliteDbFile) throws FileReaderInitException { + public SQLiteReader(Content sqliteDbFile) throws FileReaderInitException { super(sqliteDbFile); try { final String localDiskPath = super.getLocalDiskPath(sqliteDbFile); @@ -85,17 +86,17 @@ public final class SQLiteReader extends AbstractReader { * @throws TskCoreException fileManager cannot find AbstractFile files. * @throws IOException Issue during writing to file. */ - private void findAndCopySQLiteMetaFile(AbstractFile sqliteFile, + private void findAndCopySQLiteMetaFile(Content sqliteFile, String metaFileName) throws NoCurrentCaseException, TskCoreException, IOException { Case openCase = Case.getCurrentCaseThrows(); SleuthkitCase sleuthkitCase = openCase.getSleuthkitCase(); Services services = new Services(sleuthkitCase); FileManager fileManager = services.getFileManager(); - + List metaFiles = fileManager.findFiles( - sqliteFile.getDataSource(), metaFileName, - sqliteFile.getParent().getName()); + sqliteFile.getDataSource(), metaFileName, + sqliteFile.getParent().getName()); if (metaFiles != null) { for (AbstractFile metaFile : metaFiles) { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java index 7eccd061ac..3c6b641eab 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java @@ -249,6 +249,8 @@ public final class KeywordSearchIngestModule implements FileIngestModule { textExtractors = new ArrayList<>(); //order matters, more specific extractors first textExtractors.add(new HtmlTextExtractor()); + //Add sqlite text extractor to be default for sqlite files, since tika stuggles + //with them. See SqliteTextExtractor class for specifics textExtractors.add(new SqliteTextExtractor()); textExtractors.add(new TikaTextExtractor()); @@ -439,7 +441,6 @@ public final class KeywordSearchIngestModule implements FileIngestModule { //go over available text extractors in order, and pick the first one (most specific one) for (ContentTextExtractor fe : textExtractors) { if (fe.isSupported(aFile, detectedFormat)) { - System.out.println(fe); extractor = fe; break; } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java index 09be770bd5..50cd4143ab 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -1,7 +1,20 @@ /* - * 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. + * Autopsy Forensic Browser + * + * Copyright 2018-2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.keywordsearch; @@ -9,34 +22,63 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.tabulardatareader.AbstractReader; import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException; -import org.sleuthkit.autopsy.tabulardatareader.SQLiteReader; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.TskCoreException; +import org.apache.commons.lang3.StringUtils; +import org.sleuthkit.autopsy.tabulardatareader.FileReaderFactory; /** + * Dedicated SqliteTextExtractor to solve the problems associated with Tika's + * Sqlite parser. + * + * Tika problems: + * 1) Tika fails to open virtual tables + * 2) Tika fails to open tables with spaces in table name + * 3) Tika fails to include the table names in output (except for the first table it parses) + * 4) BasisTech > Apache * - * @author dsmyda */ public class SqliteTextExtractor extends ContentTextExtractor { - + private final String SQLITE_MIMETYPE = "application/x-sqlite3"; + private static final Logger logger = Logger.getLogger(SqliteTextExtractor.class.getName()); @Override boolean isContentTypeSpecific() { return true; } + /** + * Supports only the sqlite mimetypes + * + * @param file Content file + * @param detectedFormat Mimetype of content file + * + * @return true if x-sqlite3 + */ @Override boolean isSupported(Content file, String detectedFormat) { return SQLITE_MIMETYPE.equals(detectedFormat); } + /** + * Returns an input stream that will read from a sqlite database. + * + * @param source Content file + * + * @return An InputStream that reads from a Sqlite database. + * + * @throws + * org.sleuthkit.autopsy.keywordsearch.TextExtractor.TextExtractorException + */ @Override public Reader getReader(Content source) throws TextExtractorException { return new InputStreamReader(new SqliteTextReader(source)); @@ -49,73 +91,299 @@ public class SqliteTextExtractor extends ContentTextExtractor { @Override public void logWarning(String msg, Exception ex) { - //TODO - come back. + logger.log(Level.WARNING, msg, ex); //NON-NLS } - + + /** + * InputStream that is returned from the getReader method. This stream opens + * a sqlite file and loads its contents into a buffer that can be read from + * the read function. + */ private final class SqliteTextReader extends InputStream { - - private final Content source; - private final SQLiteReader reader; - private StringBuffer fileData; - private int currIndex; + + private StringBuilder databaseBuffer; + private int currReadIndex; private final int NO_CONTENT_LEFT = -1; - + + /** + * The buffer is filled during initialization, meaning the whole sqlite + * file is read during construction. + * + * @param source Content file that is the sqlite database + * + * @throws + * org.sleuthkit.autopsy.keywordsearch.TextExtractor.TextExtractorException + */ public SqliteTextReader(Content source) throws TextExtractorException { - this.source = source; - try { - this.reader = new SQLiteReader((AbstractFile) source.getDataSource()); - } catch (TskCoreException ex) { - throw new TextExtractorException( - String.format("Encountered a TskCoreException when getting " - + "root data source for Content with id:[%s], name:[%s].", - source.getId(), source.getName())); + try (AbstractReader reader = FileReaderFactory.createReader( + SQLITE_MIMETYPE, source)) { + this.databaseBuffer = new StringBuilder(); + //Fill the entire buffer upon instantiation + copyDatabaseIntoBuffer(source, reader); } catch (FileReaderInitException ex) { throw new TextExtractorException( - String.format("Encountered a FileReaderInitException when trying " - + "to initialize a SQLiteReader for Content with id:[%s], " - + "name:[%s].", source.getId(), source.getName())); - } - this.fileData = new StringBuffer(); - //Fill the entire buffer on instantiation - copySqliteFileIntoStringBuffer(source); - } - - private void copySqliteFileIntoStringBuffer(Content source){ - Map tables; - try { - //Table name to table schema mapping - tables = reader.getTableSchemas(); - for(String tableName : tables.keySet()) { - try { - List> rowsInTable = reader.getRowsFromTable(tableName); - for(Map row : rowsInTable) { - //Only interested in row values, not the column name - row.values().forEach(cell -> { - fileData.append(cell.toString()); - }); - } - } catch(AbstractReader.FileReaderException ex) { - // logger.log(Level.WARNING, - // String.format("Error attempting to read file table: [%s]" //NON-NLS - // + " for file: [%s] (id=%d).", tableName, //NON-NLS - // source.getName(), source.getId()), - // ex); - } - } - } catch (AbstractReader.FileReaderException ex) { - //logger.log(Level.WARNING, String.format("Error attempting to get tables from " //NON-NLS - // + "file: [%s] (id=%d).", //NON-NLS - // source.getName(), source.getId()), ex); + String.format("Encountered a FileReaderInitException" //NON-NLS + + " when trying to initialize a SQLiteReader" //NON-NLS + + " for Content with id:[%s], name:[%s].", //NON-NLS + source.getId(), source.getName())); } } + /** + * Queries the sqlite database and adds all tables and rows to a + * TableBuilder, which formats the strings into a table view for clean + * results while searching for keywords in the application. + * + * @param reader + */ + private void copyDatabaseIntoBuffer(Content source, AbstractReader reader) { + try { + Map tables = reader.getTableSchemas(); + iterateTablesAndPopulateBuffer(tables, reader, source); + } catch (AbstractReader.FileReaderException ex) { + logger.log(Level.WARNING, String.format( + "Error attempting to get tables from file: " //NON-NLS + + "[%s] (id=%d).", source.getName(), //NON-NLS + source.getId()), ex); + } + } + + /** + * Iterates all of the tables and passes the rows to a helper function + * for reading. + * + * @param tables A map of table names to table schemas + * @param reader SqliteReader for interfacing with the database + * @param source Source database file for logging + */ + private void iterateTablesAndPopulateBuffer(Map tables, + AbstractReader reader, Content source) { + + for (String tableName : tables.keySet()) { + TableBuilder tableBuilder = new TableBuilder(); + tableBuilder.addSection(tableName); + try { + List> rowsInTable + = reader.getRowsFromTable(tableName); + addRowsToTableBuilder(tableBuilder, rowsInTable); + } catch (AbstractReader.FileReaderException ex) { + logger.log(Level.WARNING, String.format( + "Error attempting to read file table: [%s]" //NON-NLS + + " for file: [%s] (id=%d).", tableName, //NON-NLS + source.getName(), source.getId()), ex); + } + } + } + + /** + * Iterates all rows in the table and adds the rows to the TableBuilder + * class which formats the input into a table view. + * + * @param tableBuilder + * @param rowsInTable list of rows from the sqlite table + */ + private void addRowsToTableBuilder(TableBuilder tableBuilder, + List> rowsInTable) { + if (!rowsInTable.isEmpty()) { + //Create a collection from the header set, so that the TableBuilder + //can easily format it + tableBuilder.addHeader(new ArrayList<>( + rowsInTable.get(0).keySet())); + for (Map row : rowsInTable) { + tableBuilder.addRow(row.values()); + } + } + //If rowsInTable was empty, just append the table as is + databaseBuffer.append(tableBuilder); + } + + /** + * Returns one byte of the buffer at a time. This buffer was completely + * loaded during construction. Consider a lazy approach or a + * multi-threaded one if too slow. + * + * @return @throws IOException + */ @Override public int read() throws IOException { - if (currIndex == fileData.length() - 1) { + //End of the buffer if true + if (currReadIndex == databaseBuffer.length() - 1) { return NO_CONTENT_LEFT; } - return fileData.charAt(currIndex++); + + return databaseBuffer.charAt(currReadIndex++); + } + } + + /* + * Formats input so that it reads as a table in the console or in a text + * viewer + */ + private class TableBuilder { + + private List rows = new LinkedList<>(); + + //Formatters + private final String HORIZONTAL_DELIMITER = "-"; + private final String VERTICAL_DELIMITER = "|"; + private final String HEADER_CORNER = "+"; + + private final String TAB = "\t"; + private final String NEW_LINE = "\n"; + private final String SPACE = " "; + + private String section = ""; + + /** + * Add the section to the top left corner of the table. This is where + * the name of the table should go. + * + * @param section Table name + */ + public void addSection(String section) { + this.section = section + NEW_LINE + NEW_LINE; + } + + /** + * Creates a horizontal bar given the length param. These are used to + * box the header up and at the bottom of the table. + * + * @return Ex: \t+----------------------+\n + */ + private String buildHorizontalBar(int length) { + if (length == 0) { + return ""; + } + //Output: \t+----------------------+\n + return TAB + HEADER_CORNER + StringUtils.repeat( + HORIZONTAL_DELIMITER, length) + HEADER_CORNER + NEW_LINE; + } + + /** + * Add header row to underlying list collection, which will be formatted + * when toString is called. + * + * @param vals + */ + public void addHeader(Collection vals) { + addRow(vals); + } + + /** + * Add a row to the underlying list collection, which will be formatted + * when toString is called. + * + * @param vals + */ + public void addRow(Collection vals) { + List rowValues = new ArrayList<>(); + vals.forEach((val) -> { + rowValues.add(String.valueOf(val)); + }); + rows.add(rowValues.toArray( + new String[rowValues.size()])); + } + + /** + * Gets the max width of a cell in each column and the max number of + * columns in any given row. This ensures that there is enough space for + * even the longest entry and enough columns. + * + * @return + */ + private int[] getMaxWidthPerColumn() { + int maxNumberOfColumns = 0; + for (String[] row : rows) { + maxNumberOfColumns = Math.max( + maxNumberOfColumns, row.length); + } + + int[] widths = new int[maxNumberOfColumns]; + for (String[] row : rows) { + for (int colNum = 0; colNum < row.length; colNum++) { + widths[colNum] = Math.max( + widths[colNum], + StringUtils.length(row[colNum]) + ); + } + } + + return widths; + } + + /** + * Returns a string version of the table, when printed to console it + * will be fully formatted. + * + * @return + */ + @Override + public String toString() { + StringBuilder outputTable = new StringBuilder(); + + int barLength = 0; + int[] colMaxWidths = getMaxWidthPerColumn(); + boolean header = true; + for (String[] row : rows) { + addFormattedRowToBuffer(row, colMaxWidths, outputTable); + if (header) { + //Get the length of the horizontal bar from the length of the + //formatted header, minus the one tab added at the beginning + //of the row (we want to count the vertical delimiters since + //we want it all to line up. + barLength = outputTable.length() - 2; + } + addFormattedHeaderToBuffer(outputTable, barLength, header); + header = false; + } + outputTable.append(buildHorizontalBar(barLength)); + outputTable.append(NEW_LINE); + + return outputTable.toString(); + } + + /** + * Outputs a fully formatted row in the table + * + * Example: \t| John | 12345678 | john@email.com |\n + * + * @param row + * @param colMaxWidths + * @param buf + */ + private void addFormattedRowToBuffer(String[] row, + int[] colMaxWidths, StringBuilder outputTable) { + outputTable.append(TAB); + for (int colNum = 0; colNum < row.length; colNum++) { + outputTable.append(VERTICAL_DELIMITER); + outputTable.append(SPACE); + outputTable.append(StringUtils.rightPad( + StringUtils.defaultString(row[colNum]), + colMaxWidths[colNum])); + outputTable.append(SPACE); + } + outputTable.append(VERTICAL_DELIMITER); + outputTable.append(NEW_LINE); + } + + /** + * Outputs a fully formatted header. + * + * Example: \t+----------------------+\n + * \t| Email | Phone | Name |\n + * \t+----------------------+\n + * + * @param buf + * @param barLength + * @param header + */ + private void addFormattedHeaderToBuffer(StringBuilder outputTable, + int barLength, boolean header) { + if (header) { + outputTable.insert(0, buildHorizontalBar(barLength)); + outputTable.insert(0, section); + outputTable.append(buildHorizontalBar(barLength)); + } } } - } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java index ea306ff9a9..512f28a599 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java @@ -198,7 +198,7 @@ class TikaTextExtractor extends ContentTextExtractor { || ContentTextExtractor.BLOB_MIME_TYPES.contains(detectedFormat) //any binary unstructured blobs (string extraction will be used) || ContentTextExtractor.ARCHIVE_MIME_TYPES.contains(detectedFormat) || (detectedFormat.startsWith("video/") && !detectedFormat.equals("video/x-flv")) //skip video other than flv (tika supports flv only) //NON-NLS - || detectedFormat.equals(SQLITE_MIMETYPE) //Skip sqlite files, Tika cannot handle virtual tables and will fail with an exception. See SqliteTextExtractor class + || detectedFormat.equals(SQLITE_MIMETYPE) //Skip sqlite files, Tika cannot handle virtual tables and will fail with an exception. //NON-NLS ) { return false; } From 333910f16b270c89b88800882c6f66b74be983ca Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 5 Sep 2018 16:06:47 -0400 Subject: [PATCH 012/273] Fixed the off by 2 error --- .../sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java index 50cd4143ab..f88be01bee 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -331,7 +331,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { //formatted header, minus the one tab added at the beginning //of the row (we want to count the vertical delimiters since //we want it all to line up. - barLength = outputTable.length() - 2; + barLength = outputTable.length() - 4; } addFormattedHeaderToBuffer(outputTable, barLength, header); header = false; From f838a9a8c40b075c28f7cd3d7a93c84c567212f3 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 6 Sep 2018 09:56:14 -0400 Subject: [PATCH 013/273] Initial panel. --- .../casemodule/ViewPreferencesPanel.form | 28 ++++++++++++ .../casemodule/ViewPreferencesPanel.java | 45 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.form create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.form new file mode 100755 index 0000000000..4f9abb50dc --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.form @@ -0,0 +1,28 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.java new file mode 100755 index 0000000000..c9e8f59d1a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.java @@ -0,0 +1,45 @@ +/* + * 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.casemodule; + +/** + * + * @author dgrove + */ +public class ViewPreferencesPanel extends javax.swing.JPanel { + + /** + * Creates new form ViewPreferencesPanel + */ + public ViewPreferencesPanel() { + initComponents(); + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 300, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} From 341ae826fe38b4f6ed188df1aaf4f446a2fdd68d Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 7 Sep 2018 08:40:35 -0400 Subject: [PATCH 014/273] Fixed the collision during writing in temp storage. Need to still fix arabic issues and investigate streaming of database files to speed up keyword search. --- .../org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java | 2 +- .../org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java | 2 +- .../sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java index 917b862749..248a6f0e25 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java @@ -59,7 +59,7 @@ public abstract class AbstractReader implements AutoCloseable { final String getLocalDiskPath(Content file) throws FileReaderException { try { return Case.getCurrentCaseThrows().getTempDirectory() + - File.separator + file.getName(); + File.separator + file.getId() + "-" + file.getName(); } catch (NoCurrentCaseException ex) { throw new FileReaderException(ex); } diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java index 1b4743faea..7ce8260c6e 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java @@ -101,7 +101,7 @@ public final class SQLiteReader extends AbstractReader { if (metaFiles != null) { for (AbstractFile metaFile : metaFiles) { String tmpMetafilePathName = openCase.getTempDirectory() + - File.separator + metaFile.getName(); + File.separator + metaFile.getId() + "-" + metaFile.getName(); File tmpMetafile = new File(tmpMetafilePathName); ContentUtils.writeToFile(metaFile, tmpMetafile); } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java index f88be01bee..7305aac511 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; From a942b87adbe450eb2d78fdb625e021965e50f263 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 7 Sep 2018 13:27:14 -0400 Subject: [PATCH 015/273] Fixed arabic not rendering, I was using the wrong input stream.... CharSource was the way to go --- .../tabulardatareader/AbstractReader.java | 2 +- .../tabulardatareader/SQLiteReader.java | 2 +- .../keywordsearch/SqliteTextExtractor.java | 190 ++++++++---------- .../keywordsearch/TikaTextExtractor.java | 1 - 4 files changed, 84 insertions(+), 111 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java index 248a6f0e25..f39f4c85ba 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java @@ -59,7 +59,7 @@ public abstract class AbstractReader implements AutoCloseable { final String getLocalDiskPath(Content file) throws FileReaderException { try { return Case.getCurrentCaseThrows().getTempDirectory() + - File.separator + file.getId() + "-" + file.getName(); + File.separator + file.getId() + file.getName(); } catch (NoCurrentCaseException ex) { throw new FileReaderException(ex); } diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java index 7ce8260c6e..10e49d6f0b 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java @@ -101,7 +101,7 @@ public final class SQLiteReader extends AbstractReader { if (metaFiles != null) { for (AbstractFile metaFile : metaFiles) { String tmpMetafilePathName = openCase.getTempDirectory() + - File.separator + metaFile.getId() + "-" + metaFile.getName(); + File.separator + metaFile.getId() + metaFile.getName(); File tmpMetafile = new File(tmpMetafilePathName); ContentUtils.writeToFile(metaFile, tmpMetafile); } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java index 7305aac511..8d4f16b50f 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -18,11 +18,9 @@ */ package org.sleuthkit.autopsy.keywordsearch; +import com.google.common.io.CharSource; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.Reader; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; @@ -82,30 +80,8 @@ public class SqliteTextExtractor extends ContentTextExtractor { */ @Override public Reader getReader(Content source) throws TextExtractorException { - return new InputStreamReader(new SqliteTextReader(source)); - } - - @Override - public boolean isDisabled() { - return false; - } - - @Override - public void logWarning(String msg, Exception ex) { - logger.log(Level.WARNING, msg, ex); //NON-NLS - } - - /** - * InputStream that is returned from the getReader method. This stream opens - * a sqlite file and loads its contents into a buffer that can be read from - * the read function. - */ - private final class SqliteTextReader extends InputStream { - - private StringBuilder databaseBuffer; - private int currReadIndex; - private final int NO_CONTENT_LEFT = -1; - + StringBuilder databaseBuffer = new StringBuilder(); + /** * The buffer is filled during initialization, meaning the whole sqlite * file is read during construction. @@ -115,12 +91,11 @@ public class SqliteTextExtractor extends ContentTextExtractor { * @throws * org.sleuthkit.autopsy.keywordsearch.TextExtractor.TextExtractorException */ - public SqliteTextReader(Content source) throws TextExtractorException { - try (AbstractReader reader = FileReaderFactory.createReader( + try (AbstractReader reader = FileReaderFactory.createReader( SQLITE_MIMETYPE, source)) { - this.databaseBuffer = new StringBuilder(); + databaseBuffer = new StringBuilder(); //Fill the entire buffer upon instantiation - copyDatabaseIntoBuffer(source, reader); + copyDatabaseIntoBuffer(source, reader, databaseBuffer); } catch (FileReaderInitException ex) { throw new TextExtractorException( String.format("Encountered a FileReaderInitException" //NON-NLS @@ -128,92 +103,91 @@ public class SqliteTextExtractor extends ContentTextExtractor { + " for Content with id:[%s], name:[%s].", //NON-NLS source.getId(), source.getName())); } + + try { + return CharSource.wrap(databaseBuffer.toString()).openStream(); + } catch (IOException ex) { + throw new TextExtractorException(String.format("Unable to open CharSource stream on the databaseBuffer" + + "for content source name: [%s] with id: [%d]", source.getName(), source.getId())); } + } + + /** + * Queries the sqlite database and adds all tables and rows to a + * TableBuilder, which formats the strings into a table view for clean + * results while searching for keywords in the application. + * + * @param reader + */ + private void copyDatabaseIntoBuffer(Content source, AbstractReader reader, StringBuilder databaseBuffer) { + try { + Map tables = reader.getTableSchemas(); + iterateTablesAndPopulateBuffer(tables, reader, source, databaseBuffer); + } catch (AbstractReader.FileReaderException ex) { + logger.log(Level.WARNING, String.format( + "Error attempting to get tables from file: " //NON-NLS + + "[%s] (id=%d).", source.getName(), //NON-NLS + source.getId()), ex); + } + } - /** - * Queries the sqlite database and adds all tables and rows to a - * TableBuilder, which formats the strings into a table view for clean - * results while searching for keywords in the application. - * - * @param reader - */ - private void copyDatabaseIntoBuffer(Content source, AbstractReader reader) { + /** + * Iterates all of the tables and passes the rows to a helper function + * for reading. + * + * @param tables A map of table names to table schemas + * @param reader SqliteReader for interfacing with the database + * @param source Source database file for logging + */ + private void iterateTablesAndPopulateBuffer(Map tables, + AbstractReader reader, Content source, StringBuilder databaseBuffer) { + + for (String tableName : tables.keySet()) { + TableBuilder tableBuilder = new TableBuilder(); + tableBuilder.addSection(tableName); try { - Map tables = reader.getTableSchemas(); - iterateTablesAndPopulateBuffer(tables, reader, source); + List> rowsInTable + = reader.getRowsFromTable(tableName); + addRowsToTableBuilder(tableBuilder, rowsInTable, databaseBuffer); } catch (AbstractReader.FileReaderException ex) { logger.log(Level.WARNING, String.format( - "Error attempting to get tables from file: " //NON-NLS - + "[%s] (id=%d).", source.getName(), //NON-NLS - source.getId()), ex); + "Error attempting to read file table: [%s]" //NON-NLS + + " for file: [%s] (id=%d).", tableName, //NON-NLS + source.getName(), source.getId()), ex); } } - - /** - * Iterates all of the tables and passes the rows to a helper function - * for reading. - * - * @param tables A map of table names to table schemas - * @param reader SqliteReader for interfacing with the database - * @param source Source database file for logging - */ - private void iterateTablesAndPopulateBuffer(Map tables, - AbstractReader reader, Content source) { - - for (String tableName : tables.keySet()) { - TableBuilder tableBuilder = new TableBuilder(); - tableBuilder.addSection(tableName); - try { - List> rowsInTable - = reader.getRowsFromTable(tableName); - addRowsToTableBuilder(tableBuilder, rowsInTable); - } catch (AbstractReader.FileReaderException ex) { - logger.log(Level.WARNING, String.format( - "Error attempting to read file table: [%s]" //NON-NLS - + " for file: [%s] (id=%d).", tableName, //NON-NLS - source.getName(), source.getId()), ex); - } + } + + /** + * Iterates all rows in the table and adds the rows to the TableBuilder + * class which formats the input into a table view. + * + * @param tableBuilder + * @param rowsInTable list of rows from the sqlite table + */ + private void addRowsToTableBuilder(TableBuilder tableBuilder, + List> rowsInTable, StringBuilder databaseBuffer) { + if (!rowsInTable.isEmpty()) { + //Create a collection from the header set, so that the TableBuilder + //can easily format it + tableBuilder.addHeader(new ArrayList<>( + rowsInTable.get(0).keySet())); + for (Map row : rowsInTable) { + tableBuilder.addRow(row.values()); } } + //If rowsInTable was empty, just append the table as is + databaseBuffer.append(tableBuilder); + } + + @Override + public boolean isDisabled() { + return false; + } - /** - * Iterates all rows in the table and adds the rows to the TableBuilder - * class which formats the input into a table view. - * - * @param tableBuilder - * @param rowsInTable list of rows from the sqlite table - */ - private void addRowsToTableBuilder(TableBuilder tableBuilder, - List> rowsInTable) { - if (!rowsInTable.isEmpty()) { - //Create a collection from the header set, so that the TableBuilder - //can easily format it - tableBuilder.addHeader(new ArrayList<>( - rowsInTable.get(0).keySet())); - for (Map row : rowsInTable) { - tableBuilder.addRow(row.values()); - } - } - //If rowsInTable was empty, just append the table as is - databaseBuffer.append(tableBuilder); - } - - /** - * Returns one byte of the buffer at a time. This buffer was completely - * loaded during construction. Consider a lazy approach or a - * multi-threaded one if too slow. - * - * @return @throws IOException - */ - @Override - public int read() throws IOException { - //End of the buffer if true - if (currReadIndex == databaseBuffer.length() - 1) { - return NO_CONTENT_LEFT; - } - - return databaseBuffer.charAt(currReadIndex++); - } + @Override + public void logWarning(String msg, Exception ex) { + logger.log(Level.WARNING, msg, ex); //NON-NLS } /* @@ -279,7 +253,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { public void addRow(Collection vals) { List rowValues = new ArrayList<>(); vals.forEach((val) -> { - rowValues.add(String.valueOf(val)); + rowValues.add(val.toString()); }); rows.add(rowValues.toArray( new String[rowValues.size()])); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java index 512f28a599..679bd5b9cc 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java @@ -202,7 +202,6 @@ class TikaTextExtractor extends ContentTextExtractor { ) { return false; } - System.out.println(detectedFormat); return TIKA_SUPPORTED_TYPES.contains(detectedFormat); } From 8e0cd3b70056bb07648cfc4e9e4f16f5b14c3a87 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 7 Sep 2018 14:45:01 -0400 Subject: [PATCH 016/273] Fixed the unicode errors, cleaned up some of the reader code. Unicode will still cause formatting issues, but the keyword search module works --- .../tabulardatareader/AbstractReader.java | 2 - .../tabulardatareader/ExcelReader.java | 1 - .../tabulardatareader/FileReaderFactory.java | 1 - .../tabulardatareader/SQLiteReader.java | 4 +- .../keywordsearch/SqliteTextExtractor.java | 159 ++++++++---------- 5 files changed, 75 insertions(+), 92 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java index f39f4c85ba..b488bd6aa8 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java @@ -22,11 +22,9 @@ import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.datamodel.ContentUtils; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java index 711d4c0c60..b1a5b40cfd 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java @@ -36,7 +36,6 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.IngestServices; -import org.sleuthkit.datamodel.AbstractFile; import com.monitorjbl.xlsx.StreamingReader; import org.apache.poi.hssf.OldExcelFormatException; import org.sleuthkit.datamodel.Content; diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java index 56707617ff..ffd152c80d 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/FileReaderFactory.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.tabulardatareader; import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; /** diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java index 10e49d6f0b..408193b2b3 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java @@ -51,8 +51,8 @@ import org.sleuthkit.datamodel.TskCoreException; public final class SQLiteReader extends AbstractReader { private final Connection connection; - private final static IngestServices services = IngestServices.getInstance(); - private final static Logger logger = services.getLogger(SQLiteReader.class.getName()); + private final static IngestServices ingestServices = IngestServices.getInstance(); + private final static Logger logger = ingestServices.getLogger(SQLiteReader.class.getName()); /** * Writes data source file contents to local disk and opens a sqlite JDBC diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java index 8d4f16b50f..4569438175 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -55,6 +55,16 @@ public class SqliteTextExtractor extends ContentTextExtractor { return true; } + @Override + public boolean isDisabled() { + return false; + } + + @Override + public void logWarning(String msg, Exception ex) { + logger.log(Level.WARNING, msg, ex); //NON-NLS + } + /** * Supports only the sqlite mimetypes * @@ -81,48 +91,39 @@ public class SqliteTextExtractor extends ContentTextExtractor { @Override public Reader getReader(Content source) throws TextExtractorException { StringBuilder databaseBuffer = new StringBuilder(); - - /** - * The buffer is filled during initialization, meaning the whole sqlite - * file is read during construction. - * - * @param source Content file that is the sqlite database - * - * @throws - * org.sleuthkit.autopsy.keywordsearch.TextExtractor.TextExtractorException - */ + try (AbstractReader reader = FileReaderFactory.createReader( - SQLITE_MIMETYPE, source)) { - databaseBuffer = new StringBuilder(); - //Fill the entire buffer upon instantiation - copyDatabaseIntoBuffer(source, reader, databaseBuffer); - } catch (FileReaderInitException ex) { - throw new TextExtractorException( - String.format("Encountered a FileReaderInitException" //NON-NLS - + " when trying to initialize a SQLiteReader" //NON-NLS - + " for Content with id:[%s], name:[%s].", //NON-NLS - source.getId(), source.getName())); - } - - try { + SQLITE_MIMETYPE, source)) { + databaseBuffer = new StringBuilder(); + //Fill the buffer with table names and table data + copyDatabaseIntoBuffer(source, reader, databaseBuffer); + //Once the buffer is full, wrap it into a CharSource and open the reader + //This is necessary to maintain integrity of unicode string. Returning + //character by character will not work. return CharSource.wrap(databaseBuffer.toString()).openStream(); - } catch (IOException ex) { - throw new TextExtractorException(String.format("Unable to open CharSource stream on the databaseBuffer" - + "for content source name: [%s] with id: [%d]", source.getName(), source.getId())); + } catch (FileReaderInitException | IOException ex) { + throw new TextExtractorException( + String.format("Encountered a FileReaderInitException" //NON-NLS + + " when trying to initialize a SQLiteReader" //NON-NLS + + " for Content with id: [%s], name: [%s].", //NON-NLS + source.getId(), source.getName())); } } - + /** - * Queries the sqlite database and adds all tables and rows to a - * TableBuilder, which formats the strings into a table view for clean - * results while searching for keywords in the application. - * - * @param reader - */ - private void copyDatabaseIntoBuffer(Content source, AbstractReader reader, StringBuilder databaseBuffer) { + * Queries the sqlite database and adds all tables and rows to a + * TableBuilder, which formats the strings into a table view for clean + * results while searching for keywords in the application. + * + * @param reader Sqlite reader for the content source + * @param source Sqlite file source + * @param databaseBuffer Buffer containing all of the database content + */ + private void copyDatabaseIntoBuffer(Content source, AbstractReader reader, + StringBuilder databaseBuffer) { try { Map tables = reader.getTableSchemas(); - iterateTablesAndPopulateBuffer(tables, reader, source, databaseBuffer); + copyDatabaseIntoBuffer(tables, reader, source, databaseBuffer); } catch (AbstractReader.FileReaderException ex) { logger.log(Level.WARNING, String.format( "Error attempting to get tables from file: " //NON-NLS @@ -132,14 +133,16 @@ public class SqliteTextExtractor extends ContentTextExtractor { } /** - * Iterates all of the tables and passes the rows to a helper function - * for reading. - * - * @param tables A map of table names to table schemas - * @param reader SqliteReader for interfacing with the database - * @param source Source database file for logging - */ - private void iterateTablesAndPopulateBuffer(Map tables, + * Iterates all of the tables and populate the TableBuilder with all of the + * rows from the table. This TableBuilder object string will be added to the + * databaseBuffer. + * + * @param tables A map of table names to table schemas + * @param reader SqliteReader for interfacing with the database + * @param source Source database file for logging + * @param databaseBuffer Buffer containing all of the database content + */ + private void copyDatabaseIntoBuffer(Map tables, AbstractReader reader, Content source, StringBuilder databaseBuffer) { for (String tableName : tables.keySet()) { @@ -148,7 +151,17 @@ public class SqliteTextExtractor extends ContentTextExtractor { try { List> rowsInTable = reader.getRowsFromTable(tableName); - addRowsToTableBuilder(tableBuilder, rowsInTable, databaseBuffer); + if (!rowsInTable.isEmpty()) { + //Create a collection from the header set, so that the TableBuilder + //can easily format it + tableBuilder.addHeader(new ArrayList<>( + rowsInTable.get(0).keySet())); + for (Map row : rowsInTable) { + tableBuilder.addRow(row.values()); + } + } + //If rowsInTable was empty, just append the table as is + databaseBuffer.append(tableBuilder); } catch (AbstractReader.FileReaderException ex) { logger.log(Level.WARNING, String.format( "Error attempting to read file table: [%s]" //NON-NLS @@ -157,38 +170,6 @@ public class SqliteTextExtractor extends ContentTextExtractor { } } } - - /** - * Iterates all rows in the table and adds the rows to the TableBuilder - * class which formats the input into a table view. - * - * @param tableBuilder - * @param rowsInTable list of rows from the sqlite table - */ - private void addRowsToTableBuilder(TableBuilder tableBuilder, - List> rowsInTable, StringBuilder databaseBuffer) { - if (!rowsInTable.isEmpty()) { - //Create a collection from the header set, so that the TableBuilder - //can easily format it - tableBuilder.addHeader(new ArrayList<>( - rowsInTable.get(0).keySet())); - for (Map row : rowsInTable) { - tableBuilder.addRow(row.values()); - } - } - //If rowsInTable was empty, just append the table as is - databaseBuffer.append(tableBuilder); - } - - @Override - public boolean isDisabled() { - return false; - } - - @Override - public void logWarning(String msg, Exception ex) { - logger.log(Level.WARNING, msg, ex); //NON-NLS - } /* * Formats input so that it reads as a table in the console or in a text @@ -262,7 +243,9 @@ public class SqliteTextExtractor extends ContentTextExtractor { /** * Gets the max width of a cell in each column and the max number of * columns in any given row. This ensures that there is enough space for - * even the longest entry and enough columns. + * even the longest entry and enough columns. The length of the string + * seems to be different from the length of the print statement in some + * languages. For instance, arabic will cause the table to look off. * * @return */ @@ -278,7 +261,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { for (int colNum = 0; colNum < row.length; colNum++) { widths[colNum] = Math.max( widths[colNum], - StringUtils.length(row[colNum]) + row[colNum].length() ); } } @@ -322,9 +305,10 @@ public class SqliteTextExtractor extends ContentTextExtractor { * * Example: \t| John | 12345678 | john@email.com |\n * - * @param row - * @param colMaxWidths - * @param buf + * @param row Array containing unformatted row content + * @param colMaxWidths An array of column maximum widths, so that + * everything is pretty printed. + * @param outputTable Buffer that formatted contents are written to */ private void addFormattedRowToBuffer(String[] row, int[] colMaxWidths, StringBuilder outputTable) { @@ -348,13 +332,16 @@ public class SqliteTextExtractor extends ContentTextExtractor { * \t| Email | Phone | Name |\n * \t+----------------------+\n * - * @param buf - * @param barLength - * @param header + * @param outputTable Buffer that formatted contents are written to + * @param barLength Length of the bar (i.e. +---------+) that will + * surround the header, based off of the length of + * the formatted header row + * @param needsHeader Boolean denoting if the header has been added to + * the buffer */ private void addFormattedHeaderToBuffer(StringBuilder outputTable, - int barLength, boolean header) { - if (header) { + int barLength, boolean needsHeader) { + if (needsHeader) { outputTable.insert(0, buildHorizontalBar(barLength)); outputTable.insert(0, section); outputTable.append(buildHorizontalBar(barLength)); From b4628e745f99e1e1079789879c336ced26f2cde0 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 10 Sep 2018 11:37:41 -0400 Subject: [PATCH 017/273] Major speed improvements, still need to comment and refactor and clean up --- .../keywordsearch/SqliteTextExtractor.java | 95 ++++++++++++------- 1 file changed, 60 insertions(+), 35 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java index 4569438175..efdb9f72cf 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -27,6 +27,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.logging.Level; +import javax.swing.text.Segment; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.tabulardatareader.AbstractReader; import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException; @@ -38,17 +39,21 @@ import org.sleuthkit.autopsy.tabulardatareader.FileReaderFactory; * Dedicated SqliteTextExtractor to solve the problems associated with Tika's * Sqlite parser. * - * Tika problems: - * 1) Tika fails to open virtual tables - * 2) Tika fails to open tables with spaces in table name - * 3) Tika fails to include the table names in output (except for the first table it parses) - * 4) BasisTech > Apache + * Tika problems: + * 1) Tika fails to open virtual tables + * 2) Tika fails to open tables with spaces in table name + * 3) Tika fails to include the table names in output (except for the + * first table it parses) * */ public class SqliteTextExtractor extends ContentTextExtractor { private final String SQLITE_MIMETYPE = "application/x-sqlite3"; private static final Logger logger = Logger.getLogger(SqliteTextExtractor.class.getName()); + private final CharSequence EMPTY_CHARACTER_SEQUENCE = ""; + + LinkedList databaseContents; + Integer characterCount = 0; @Override boolean isContentTypeSpecific() { @@ -90,17 +95,11 @@ public class SqliteTextExtractor extends ContentTextExtractor { */ @Override public Reader getReader(Content source) throws TextExtractorException { - StringBuilder databaseBuffer = new StringBuilder(); - try (AbstractReader reader = FileReaderFactory.createReader( SQLITE_MIMETYPE, source)) { - databaseBuffer = new StringBuilder(); - //Fill the buffer with table names and table data - copyDatabaseIntoBuffer(source, reader, databaseBuffer); - //Once the buffer is full, wrap it into a CharSource and open the reader - //This is necessary to maintain integrity of unicode string. Returning - //character by character will not work. - return CharSource.wrap(databaseBuffer.toString()).openStream(); + final CharSequence databaseContents = getDatabaseContents(source, reader); + //CharSource will maintain unicode strings correctly + return CharSource.wrap(databaseContents).openStream(); } catch (FileReaderInitException | IOException ex) { throw new TextExtractorException( String.format("Encountered a FileReaderInitException" //NON-NLS @@ -117,19 +116,43 @@ public class SqliteTextExtractor extends ContentTextExtractor { * * @param reader Sqlite reader for the content source * @param source Sqlite file source - * @param databaseBuffer Buffer containing all of the database content */ - private void copyDatabaseIntoBuffer(Content source, AbstractReader reader, - StringBuilder databaseBuffer) { + private CharSequence getDatabaseContents(Content source, AbstractReader reader) { try { Map tables = reader.getTableSchemas(); - copyDatabaseIntoBuffer(tables, reader, source, databaseBuffer); + databaseContents = new LinkedList<>(); + copyDatabaseIntoBuffer(tables, reader, source, databaseContents); + return databaseContentsToCharSequence(); } catch (AbstractReader.FileReaderException ex) { logger.log(Level.WARNING, String.format( "Error attempting to get tables from file: " //NON-NLS + "[%s] (id=%d).", source.getName(), //NON-NLS source.getId()), ex); } + + //Failed to get tables from file + return EMPTY_CHARACTER_SEQUENCE; + } + + /** + * Copy linkedList elements into a character array to be wrapped into a + * CharSequence. + * + * @return A character seqeunces of the database contents + */ + private CharSequence databaseContentsToCharSequence() { + final char[] databaseCharacters = new char[characterCount]; + + int currSequenceIndex = 0; + for (String table : databaseContents) { + System.arraycopy(table.toCharArray(), 0, databaseCharacters, currSequenceIndex, table.length()); + currSequenceIndex += table.length(); + } + + //Segment class does not make an internal copy of the character array + //being passed in (more efficient). It also implements a CharSequences + //necessary for the CharSource class to create a compatible reader. + return new Segment(databaseCharacters, 0, characterCount); } /** @@ -140,10 +163,10 @@ public class SqliteTextExtractor extends ContentTextExtractor { * @param tables A map of table names to table schemas * @param reader SqliteReader for interfacing with the database * @param source Source database file for logging - * @param databaseBuffer Buffer containing all of the database content + * @param databaseContents List containing all of the database content */ private void copyDatabaseIntoBuffer(Map tables, - AbstractReader reader, Content source, StringBuilder databaseBuffer) { + AbstractReader reader, Content source, LinkedList databaseContents) { for (String tableName : tables.keySet()) { TableBuilder tableBuilder = new TableBuilder(); @@ -152,16 +175,16 @@ public class SqliteTextExtractor extends ContentTextExtractor { List> rowsInTable = reader.getRowsFromTable(tableName); if (!rowsInTable.isEmpty()) { - //Create a collection from the header set, so that the TableBuilder - //can easily format it tableBuilder.addHeader(new ArrayList<>( rowsInTable.get(0).keySet())); for (Map row : rowsInTable) { tableBuilder.addRow(row.values()); } } - //If rowsInTable was empty, just append the table as is - databaseBuffer.append(tableBuilder); + + String formattedTable = tableBuilder.toString(); + characterCount += formattedTable.length(); + databaseContents.add(formattedTable); } catch (AbstractReader.FileReaderException ex) { logger.log(Level.WARNING, String.format( "Error attempting to read file table: [%s]" //NON-NLS @@ -177,7 +200,8 @@ public class SqliteTextExtractor extends ContentTextExtractor { */ private class TableBuilder { - private List rows = new LinkedList<>(); + private final List rows = new LinkedList<>(); + private Integer characterCount = 0; //Formatters private final String HORIZONTAL_DELIMITER = "-"; @@ -188,6 +212,9 @@ public class SqliteTextExtractor extends ContentTextExtractor { private final String NEW_LINE = "\n"; private final String SPACE = " "; + //Number of escape sequences in the header row + private final int ESCAPE_SEQUENCES = 4; + private String section = ""; /** @@ -235,6 +262,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { List rowValues = new ArrayList<>(); vals.forEach((val) -> { rowValues.add(val.toString()); + characterCount += val.toString().length(); }); rows.add(rowValues.toArray( new String[rowValues.size()])); @@ -242,10 +270,8 @@ public class SqliteTextExtractor extends ContentTextExtractor { /** * Gets the max width of a cell in each column and the max number of - * columns in any given row. This ensures that there is enough space for - * even the longest entry and enough columns. The length of the string - * seems to be different from the length of the print statement in some - * languages. For instance, arabic will cause the table to look off. + * columns in any given row. This ensures that there are enough columns + * and enough space for even the longest entry. * * @return */ @@ -277,7 +303,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { */ @Override public String toString() { - StringBuilder outputTable = new StringBuilder(); + StringBuilder outputTable = new StringBuilder(characterCount); int barLength = 0; int[] colMaxWidths = getMaxWidthPerColumn(); @@ -289,7 +315,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { //formatted header, minus the one tab added at the beginning //of the row (we want to count the vertical delimiters since //we want it all to line up. - barLength = outputTable.length() - 4; + barLength = outputTable.length() - ESCAPE_SEQUENCES; } addFormattedHeaderToBuffer(outputTable, barLength, header); header = false; @@ -328,9 +354,8 @@ public class SqliteTextExtractor extends ContentTextExtractor { /** * Outputs a fully formatted header. * - * Example: \t+----------------------+\n - * \t| Email | Phone | Name |\n - * \t+----------------------+\n + * Example: \t+----------------------+\n \t| Email | Phone | Name |\n + * \t+----------------------+\n * * @param outputTable Buffer that formatted contents are written to * @param barLength Length of the bar (i.e. +---------+) that will @@ -348,4 +373,4 @@ public class SqliteTextExtractor extends ContentTextExtractor { } } } -} +} \ No newline at end of file From 169fb9928f9753bff297733dc4c83f8eea2f3c08 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 10 Sep 2018 15:45:40 -0400 Subject: [PATCH 018/273] Cleaned up code, refactored, improved efficiency --- .../keywordsearch/ContentTextExtractor.java | 2 +- .../keywordsearch/SqliteTextExtractor.java | 214 +++++++++--------- .../keywordsearch/TikaTextExtractor.java | 4 +- 3 files changed, 112 insertions(+), 108 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ContentTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ContentTextExtractor.java index b855ae317f..bba2df2ced 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ContentTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ContentTextExtractor.java @@ -30,7 +30,7 @@ import org.sleuthkit.datamodel.Content; abstract class ContentTextExtractor implements TextExtractor { - static final List BLOB_MIME_TYPES + static final List BINARY_MIME_TYPES = Arrays.asList( //ignore binary blob data, for which string extraction will be used "application/octet-stream", //NON-NLS diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java index efdb9f72cf..c45dc3920b 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -39,12 +40,10 @@ import org.sleuthkit.autopsy.tabulardatareader.FileReaderFactory; * Dedicated SqliteTextExtractor to solve the problems associated with Tika's * Sqlite parser. * - * Tika problems: - * 1) Tika fails to open virtual tables - * 2) Tika fails to open tables with spaces in table name - * 3) Tika fails to include the table names in output (except for the - * first table it parses) - * + * Tika problems: + * 1) Tika fails to open virtual tables + * 2) Tika fails to open tables with spaces in table name + * 3) Tika fails to include the table names in output (except for the first table it parses) */ public class SqliteTextExtractor extends ContentTextExtractor { @@ -52,9 +51,6 @@ public class SqliteTextExtractor extends ContentTextExtractor { private static final Logger logger = Logger.getLogger(SqliteTextExtractor.class.getName()); private final CharSequence EMPTY_CHARACTER_SEQUENCE = ""; - LinkedList databaseContents; - Integer characterCount = 0; - @Override boolean isContentTypeSpecific() { return true; @@ -97,9 +93,9 @@ public class SqliteTextExtractor extends ContentTextExtractor { public Reader getReader(Content source) throws TextExtractorException { try (AbstractReader reader = FileReaderFactory.createReader( SQLITE_MIMETYPE, source)) { - final CharSequence databaseContents = getDatabaseContents(source, reader); + final CharSequence databaseContent = getDatabaseContents(source, reader); //CharSource will maintain unicode strings correctly - return CharSource.wrap(databaseContents).openStream(); + return CharSource.wrap(databaseContent).openStream(); } catch (FileReaderInitException | IOException ex) { throw new TextExtractorException( String.format("Encountered a FileReaderInitException" //NON-NLS @@ -114,15 +110,18 @@ public class SqliteTextExtractor extends ContentTextExtractor { * TableBuilder, which formats the strings into a table view for clean * results while searching for keywords in the application. * - * @param reader Sqlite reader for the content source - * @param source Sqlite file source + * @param reader Sqlite reader for the content source + * @param source Sqlite file source */ private CharSequence getDatabaseContents(Content source, AbstractReader reader) { try { Map tables = reader.getTableSchemas(); - databaseContents = new LinkedList<>(); - copyDatabaseIntoBuffer(tables, reader, source, databaseContents); - return databaseContentsToCharSequence(); + LinkedList databaseStorage = new LinkedList<>(); + + Integer charactersCopied = loadDatabaseIntoList(databaseStorage, + tables, reader, source); + + return toCharSequence(databaseStorage, charactersCopied); } catch (AbstractReader.FileReaderException ex) { logger.log(Level.WARNING, String.format( "Error attempting to get tables from file: " //NON-NLS @@ -134,64 +133,67 @@ public class SqliteTextExtractor extends ContentTextExtractor { return EMPTY_CHARACTER_SEQUENCE; } - /** - * Copy linkedList elements into a character array to be wrapped into a - * CharSequence. - * - * @return A character seqeunces of the database contents - */ - private CharSequence databaseContentsToCharSequence() { - final char[] databaseCharacters = new char[characterCount]; - - int currSequenceIndex = 0; - for (String table : databaseContents) { - System.arraycopy(table.toCharArray(), 0, databaseCharacters, currSequenceIndex, table.length()); - currSequenceIndex += table.length(); - } - - //Segment class does not make an internal copy of the character array - //being passed in (more efficient). It also implements a CharSequences - //necessary for the CharSource class to create a compatible reader. - return new Segment(databaseCharacters, 0, characterCount); - } - /** * Iterates all of the tables and populate the TableBuilder with all of the - * rows from the table. This TableBuilder object string will be added to the - * databaseBuffer. + * rows from the table. The table string will be added to the list of + * contents. * - * @param tables A map of table names to table schemas - * @param reader SqliteReader for interfacing with the database - * @param source Source database file for logging - * @param databaseContents List containing all of the database content + * @param databaseStorage List containing all of the database content + * @param tables A map of table names to table schemas + * @param reader SqliteReader for interfacing with the database + * @param source Source database file for logging */ - private void copyDatabaseIntoBuffer(Map tables, - AbstractReader reader, Content source, LinkedList databaseContents) { + private int loadDatabaseIntoList(LinkedList databaseStorage, + Map tables, AbstractReader reader, Content source) { + int charactersCopied = 0; for (String tableName : tables.keySet()) { TableBuilder tableBuilder = new TableBuilder(); - tableBuilder.addSection(tableName); + tableBuilder.setTableName(tableName); + try { - List> rowsInTable - = reader.getRowsFromTable(tableName); + List> rowsInTable = reader.getRowsFromTable(tableName); if (!rowsInTable.isEmpty()) { - tableBuilder.addHeader(new ArrayList<>( - rowsInTable.get(0).keySet())); + tableBuilder.addHeader(new ArrayList<>(rowsInTable.get(0).keySet())); for (Map row : rowsInTable) { tableBuilder.addRow(row.values()); } } - - String formattedTable = tableBuilder.toString(); - characterCount += formattedTable.length(); - databaseContents.add(formattedTable); } catch (AbstractReader.FileReaderException ex) { logger.log(Level.WARNING, String.format( "Error attempting to read file table: [%s]" //NON-NLS + " for file: [%s] (id=%d).", tableName, //NON-NLS source.getName(), source.getId()), ex); } + + String formattedTable = tableBuilder.toString(); + charactersCopied += formattedTable.length(); + databaseStorage.add(formattedTable); } + return charactersCopied; + } + + /** + * Copy linkedList elements into a CharSequence + * + * @return A character seqeunces of the database contents + */ + private CharSequence toCharSequence(LinkedList databaseStorage, + int characterCount) { + + final char[] databaseCharArray = new char[characterCount]; + + int currIndex = 0; + for (String table : databaseStorage) { + System.arraycopy(table.toCharArray(), 0, databaseCharArray, + currIndex, table.length()); + currIndex += table.length(); + } + + //Segment class does not make an internal copy of the character array + //being passed in (more efficient). It also implements a CharSequences + //necessary for the CharSource class to create a compatible reader. + return new Segment(databaseCharArray, 0, characterCount); } /* @@ -201,7 +203,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { private class TableBuilder { private final List rows = new LinkedList<>(); - private Integer characterCount = 0; + private Integer charactersAdded = 0; //Formatters private final String HORIZONTAL_DELIMITER = "-"; @@ -215,29 +217,24 @@ public class SqliteTextExtractor extends ContentTextExtractor { //Number of escape sequences in the header row private final int ESCAPE_SEQUENCES = 4; - private String section = ""; + private String tableName = ""; /** * Add the section to the top left corner of the table. This is where * the name of the table should go. * - * @param section Table name + * @param tableName Table name */ - public void addSection(String section) { - this.section = section + NEW_LINE + NEW_LINE; + public void setTableName(String tableName) { + this.tableName = tableName + NEW_LINE + NEW_LINE; } /** - * Creates a horizontal bar given the length param. These are used to - * box the header up and at the bottom of the table. + * Creates a border given the length param. * * @return Ex: \t+----------------------+\n */ - private String buildHorizontalBar(int length) { - if (length == 0) { - return ""; - } - //Output: \t+----------------------+\n + private String createBorder(int length) { return TAB + HEADER_CORNER + StringUtils.repeat( HORIZONTAL_DELIMITER, length) + HEADER_CORNER + NEW_LINE; } @@ -262,7 +259,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { List rowValues = new ArrayList<>(); vals.forEach((val) -> { rowValues.add(val.toString()); - characterCount += val.toString().length(); + charactersAdded += val.toString().length(); }); rows.add(rowValues.toArray( new String[rowValues.size()])); @@ -270,10 +267,10 @@ public class SqliteTextExtractor extends ContentTextExtractor { /** * Gets the max width of a cell in each column and the max number of - * columns in any given row. This ensures that there are enough columns + * columns in any given row. This ensures that there are enough columns * and enough space for even the longest entry. * - * @return + * @return array of column widths */ private int[] getMaxWidthPerColumn() { int maxNumberOfColumns = 0; @@ -296,32 +293,31 @@ public class SqliteTextExtractor extends ContentTextExtractor { } /** - * Returns a string version of the table, when printed to console it - * will be fully formatted. + * Returns a string version of the table, with all of the formatters and + * escape sequences necessary to print nicely in the console output. * * @return */ @Override public String toString() { - StringBuilder outputTable = new StringBuilder(characterCount); - - int barLength = 0; + StringBuilder outputTable = new StringBuilder(charactersAdded); int[] colMaxWidths = getMaxWidthPerColumn(); - boolean header = true; - for (String[] row : rows) { - addFormattedRowToBuffer(row, colMaxWidths, outputTable); - if (header) { - //Get the length of the horizontal bar from the length of the - //formatted header, minus the one tab added at the beginning - //of the row (we want to count the vertical delimiters since - //we want it all to line up. - barLength = outputTable.length() - ESCAPE_SEQUENCES; + int headerLength = 0; + + Iterator rowIterator = rows.iterator(); + if (rowIterator.hasNext()) { + //Length of the header defines the table boundaries + headerLength = appendFormattedHeader(rowIterator.next(), + colMaxWidths, outputTable); + + while (rowIterator.hasNext()) { + appendFormattedRow(rowIterator.next(), colMaxWidths, outputTable); } - addFormattedHeaderToBuffer(outputTable, barLength, header); - header = false; + + outputTable.insert(0, tableName); + outputTable.append(createBorder(headerLength)); + outputTable.append(NEW_LINE); } - outputTable.append(buildHorizontalBar(barLength)); - outputTable.append(NEW_LINE); return outputTable.toString(); } @@ -336,7 +332,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { * everything is pretty printed. * @param outputTable Buffer that formatted contents are written to */ - private void addFormattedRowToBuffer(String[] row, + private void appendFormattedRow(String[] row, int[] colMaxWidths, StringBuilder outputTable) { outputTable.append(TAB); for (int colNum = 0; colNum < row.length; colNum++) { @@ -352,25 +348,33 @@ public class SqliteTextExtractor extends ContentTextExtractor { } /** - * Outputs a fully formatted header. + * Adds a fully formatted header to the table builder and returns the + * length of this header. The length of the header is needed to set the + * table boundaries * - * Example: \t+----------------------+\n \t| Email | Phone | Name |\n - * \t+----------------------+\n + * Example: \t+----------------------+\n + * \t| Email | Phone | Name |\n + * \t+----------------------+\n * - * @param outputTable Buffer that formatted contents are written to - * @param barLength Length of the bar (i.e. +---------+) that will - * surround the header, based off of the length of - * the formatted header row - * @param needsHeader Boolean denoting if the header has been added to - * the buffer + * @param row Array of contents in each column + * @param colMaxWidths Widths for each column in the table + * @param outputTable Output stringbuilder + * + * @return length of the formatted header, this length will be needed to + * correctly print the bottom table border. */ - private void addFormattedHeaderToBuffer(StringBuilder outputTable, - int barLength, boolean needsHeader) { - if (needsHeader) { - outputTable.insert(0, buildHorizontalBar(barLength)); - outputTable.insert(0, section); - outputTable.append(buildHorizontalBar(barLength)); - } + private int appendFormattedHeader(String[] row, int[] colMaxWidths, StringBuilder outputTable) { + appendFormattedRow(row, colMaxWidths, outputTable); + //Printable table dimensions are equal to the length of the header minus + //the number of escape sequences used to for formatting. + int barLength = outputTable.length() - ESCAPE_SEQUENCES; + String border = createBorder(barLength); + + //Surround the header with borders above and below. + outputTable.insert(0, border); + outputTable.append(border); + + return barLength; } } -} \ No newline at end of file +} diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java index 679bd5b9cc..ca4b09a5c1 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java @@ -57,6 +57,7 @@ class TikaTextExtractor extends ContentTextExtractor { static final private Logger logger = Logger.getLogger(TikaTextExtractor.class.getName()); private final ExecutorService tikaParseExecutor = Executors.newSingleThreadExecutor(); + private final String SQLITE_MIMETYPE = "application/x-sqlite3"; private final AutoDetectParser parser = new AutoDetectParser(); @@ -193,9 +194,8 @@ class TikaTextExtractor extends ContentTextExtractor { @Override public boolean isSupported(Content content, String detectedFormat) { - final String SQLITE_MIMETYPE = "application/x-sqlite3"; if (detectedFormat == null - || ContentTextExtractor.BLOB_MIME_TYPES.contains(detectedFormat) //any binary unstructured blobs (string extraction will be used) + || ContentTextExtractor.BINARY_MIME_TYPES.contains(detectedFormat) //any binary unstructured blobs (string extraction will be used) || ContentTextExtractor.ARCHIVE_MIME_TYPES.contains(detectedFormat) || (detectedFormat.startsWith("video/") && !detectedFormat.equals("video/x-flv")) //skip video other than flv (tika supports flv only) //NON-NLS || detectedFormat.equals(SQLITE_MIMETYPE) //Skip sqlite files, Tika cannot handle virtual tables and will fail with an exception. //NON-NLS From ddd923add54cd73bec9a2b0c99a6c6e1c8f80dfa Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 10 Sep 2018 15:51:34 -0400 Subject: [PATCH 019/273] Changed 1 variable name --- .../autopsy/keywordsearch/SqliteTextExtractor.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java index c45dc3920b..9ced18fea6 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -302,12 +302,12 @@ public class SqliteTextExtractor extends ContentTextExtractor { public String toString() { StringBuilder outputTable = new StringBuilder(charactersAdded); int[] colMaxWidths = getMaxWidthPerColumn(); - int headerLength = 0; + int borderLength = 0; Iterator rowIterator = rows.iterator(); if (rowIterator.hasNext()) { //Length of the header defines the table boundaries - headerLength = appendFormattedHeader(rowIterator.next(), + borderLength = appendFormattedHeader(rowIterator.next(), colMaxWidths, outputTable); while (rowIterator.hasNext()) { @@ -315,7 +315,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { } outputTable.insert(0, tableName); - outputTable.append(createBorder(headerLength)); + outputTable.append(createBorder(borderLength)); outputTable.append(NEW_LINE); } @@ -367,14 +367,14 @@ public class SqliteTextExtractor extends ContentTextExtractor { appendFormattedRow(row, colMaxWidths, outputTable); //Printable table dimensions are equal to the length of the header minus //the number of escape sequences used to for formatting. - int barLength = outputTable.length() - ESCAPE_SEQUENCES; - String border = createBorder(barLength); + int borderLength = outputTable.length() - ESCAPE_SEQUENCES; + String border = createBorder(borderLength); //Surround the header with borders above and below. outputTable.insert(0, border); outputTable.append(border); - return barLength; + return borderLength; } } } From 2a49a171649ae9f97f5ccd2d3557e93b33bb4b08 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Tue, 11 Sep 2018 23:56:35 -0400 Subject: [PATCH 020/273] Partial implementation. --- .../autopsy/casemodule/Bundle.properties | 2 + .../autopsy/casemodule/CasePreferences.java | 93 +++++ .../casemodule/ViewPreferencesPanel.form | 28 -- .../casemodule/ViewPreferencesPanel.java | 45 --- .../services/TagsOptionsPanelController.java | 2 +- .../EamOptionsPanelController.java | 2 +- .../autopsy/core/UserPreferences.java | 4 +- .../corecomponents/AutopsyOptionsPanel.form | 92 ++--- .../corecomponents/AutopsyOptionsPanel.java | 228 +++++------ .../autopsy/corecomponents/Bundle.properties | 46 ++- .../corecomponents/Bundle_ja.properties | 27 +- .../MultiUserSettingsPanelController.java | 2 +- .../corecomponents/ViewPreferencesDialog.form | 78 ++++ .../corecomponents/ViewPreferencesDialog.java | 133 +++++++ .../corecomponents/ViewPreferencesPanel.form | 335 ++++++++++++++++ .../corecomponents/ViewPreferencesPanel.java | 362 ++++++++++++++++++ .../ViewPreferencesPanelController.java | 149 +++++++ .../datamodel/AutopsyTreeChildFactory.java | 18 +- .../autopsy/datamodel/ExtractedContent.java | 22 +- .../autopsy/datamodel/accounts/Accounts.java | 27 +- .../autopsy/directorytree/Bundle.properties | 7 +- .../DirectoryTreeTopComponent.form | 78 ++-- .../DirectoryTreeTopComponent.java | 120 +++--- .../ExternalViewerOptionsPanelController.java | 2 +- .../directorytree/ViewContextAction.java | 18 +- .../directorytree/view-preferences-24.png | Bin 0 -> 2039 bytes .../autopsy/images/view-preferences-32.png | Bin 0 -> 873 bytes .../ingest/IngestOptionsPanelController.java | 2 +- ...FileExtMismatchOptionsPanelController.java | 2 +- .../FileTypeIdOptionsPanelController.java | 2 +- .../HashDatabaseOptionsPanelController.java | 2 +- ...restingItemDefsOptionsPanelController.java | 2 +- .../AutoIngestSettingsPanelController.java | 2 +- .../configuration/SharedConfiguration.java | 5 +- .../ImageGalleryOptionsPanelController.java | 2 +- .../KeywordSearchOptionsPanelController.java | 2 +- 36 files changed, 1571 insertions(+), 370 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java delete mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.form delete mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.java create mode 100755 Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.form create mode 100755 Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.java create mode 100755 Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form create mode 100755 Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java create mode 100755 Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanelController.java create mode 100755 Core/src/org/sleuthkit/autopsy/directorytree/view-preferences-24.png create mode 100755 Core/src/org/sleuthkit/autopsy/images/view-preferences-32.png diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index 4154a913b9..a89ea845dd 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -233,3 +233,5 @@ LocalDiskSelectionDialog.okButton.text=OK LocalDiskPanel.localDiskLabel.text=Local Disk: LocalDiskPanel.imageWriterErrorLabel.text=Error Label LocalDiskSelectionDialog.title=Select Local Disk +ViewPreferencesDialog.okButton.text=OK +ViewPreferencesDialog.cancelButton.text=Cancel diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java new file mode 100755 index 0000000000..8d40b23538 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java @@ -0,0 +1,93 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.casemodule; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; + +/** + * Read and update case preference file values. + */ +public final class CasePreferences { + + private static final String SETTINGS_FILE = "CasePreferences.properties"; //NON-NLS + public static final String GROUP_ITEMS_IN_TREE_BY_DATASOURCE = "GroupItemsInTreeByDataSource"; //NON-NLS + + private static final Logger logger = Logger.getLogger(CasePreferences.class.getName()); + + private Boolean groupItemsInTreeByDataSource = null; + + //DLG: + public CasePreferences(Case currentCase) { + loadFromStorage(currentCase); + } + + public Boolean getGroupItemsInTreeByDataSource() { + return groupItemsInTreeByDataSource; + } + + public void setGroupItemsInTreeByDataSource(boolean value) { + groupItemsInTreeByDataSource = value; + } + + /** + * Load case preferences from the settings file. + */ + private void loadFromStorage(Case currentCase) { + Path settingsFile = Paths.get(currentCase.getConfigDirectory(), SETTINGS_FILE); //NON-NLS + if (settingsFile.toFile().exists()) { + // Read the settings + try (InputStream inputStream = Files.newInputStream(settingsFile)) { + Properties props = new Properties(); + props.load(inputStream); + if (props.getProperty("groupByDataSource", "false").equals("true")) { + groupItemsInTreeByDataSource = true; + } else { + groupItemsInTreeByDataSource = false; + } + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error reading settings file", ex); + } + } + } + + /** + * Store case preferences in the settings file. + */ + public void saveToStorage(Case currentCase) { + Path settingsFile = Paths.get(currentCase.getConfigDirectory(), SETTINGS_FILE); //NON-NLS + Properties props = new Properties(); + if (groupItemsInTreeByDataSource != null) { + props.setProperty("groupByDataSource", (groupItemsInTreeByDataSource ? "true" : "false")); + } + + try (OutputStream fos = Files.newOutputStream(settingsFile)) { + props.store(fos, ""); //NON-NLS + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error writing settings file", ex); + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.form deleted file mode 100755 index 4f9abb50dc..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.form +++ /dev/null @@ -1,28 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.java deleted file mode 100755 index c9e8f59d1a..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/ViewPreferencesPanel.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.casemodule; - -/** - * - * @author dgrove - */ -public class ViewPreferencesPanel extends javax.swing.JPanel { - - /** - * Creates new form ViewPreferencesPanel - */ - public ViewPreferencesPanel() { - initComponents(); - } - - /** - * 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") - // //GEN-BEGIN:initComponents - private void initComponents() { - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 400, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 300, Short.MAX_VALUE) - ); - }// //GEN-END:initComponents - - - // Variables declaration - do not modify//GEN-BEGIN:variables - // End of variables declaration//GEN-END:variables -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java index fcd2131f90..8fa16928d4 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java @@ -31,7 +31,7 @@ import org.openide.util.Lookup; iconBase = "org/sleuthkit/autopsy/casemodule/services/tag-options-panel-icon.png", keywords = "#OptionsCategory_TagNames", keywordsCategory = "CustomTagNames", - position = 11 + position = 12 ) public final class TagsOptionsPanelController extends OptionsPanelController { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamOptionsPanelController.java index dab04c255f..045afe99b5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamOptionsPanelController.java @@ -35,7 +35,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; */ @OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_Central_Repository_Options", iconBase = "org/sleuthkit/autopsy/centralrepository/images/options-icon.png", - position = 14, + position = 15, keywords = "#OptionsCategory_Keywords_Central_Repository_Options", keywordsCategory = "CentralRepository") public final class EamOptionsPanelController extends OptionsPanelController { diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 78b726111e..3b92e24481 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -189,11 +189,11 @@ public final class UserPreferences { preferences.putInt(NUMBER_OF_FILE_INGEST_THREADS, value); } - public static boolean groupItemsInTreeByDatasource() { + public static boolean groupItemsInTreeByDatasource() { //DLG: Replace use of this with the equivallent method in CasePreferences return preferences.getBoolean(GROUP_ITEMS_IN_TREE_BY_DATASOURCE, false); } - public static void setGroupItemsInTreeByDatasource(boolean value) { + public static void setGroupItemsInTreeByDatasource(boolean value) { //DLG: Replace use of this with the equivallent method in CasePreferences preferences.putBoolean(GROUP_ITEMS_IN_TREE_BY_DATASOURCE, value); } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form index a9ead822e7..b63f0c6f8b 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form @@ -69,7 +69,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -232,12 +232,12 @@ - + - + @@ -254,19 +254,19 @@ - - - - - + + + + + - - - + + + @@ -291,27 +291,27 @@ - + - + - + - + - + - + - + - + @@ -324,36 +324,36 @@ - + - + - + - + - + - + - + - + @@ -363,24 +363,24 @@ - + - + - + - + - + - + @@ -390,24 +390,24 @@ - + - + - + - + - + - + @@ -417,30 +417,30 @@ - + - + - + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java index 6c5a67a3f7..2bdf9dd7ea 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java @@ -286,15 +286,15 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { */ void load() { boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer(); - keepCurrentViewerRB.setSelected(keepPreferredViewer); - useBestViewerRB.setSelected(!keepPreferredViewer); - dataSourcesHideKnownCB.setSelected(UserPreferences.hideKnownFilesInDataSourcesTree()); - viewsHideKnownCB.setSelected(UserPreferences.hideKnownFilesInViewsTree()); - dataSourcesHideSlackCB.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree()); - viewsHideSlackCB.setSelected(UserPreferences.hideSlackFilesInViewsTree()); + oldKeepCurrentViewerRB.setSelected(keepPreferredViewer); + oldUseBestViewerRB.setSelected(!keepPreferredViewer); + oldDataSourcesHideKnownCB.setSelected(UserPreferences.hideKnownFilesInDataSourcesTree()); + oldViewsHideKnownCB.setSelected(UserPreferences.hideKnownFilesInViewsTree()); + oldDataSourcesHideSlackCB.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree()); + oldViewsHideSlackCB.setSelected(UserPreferences.hideSlackFilesInViewsTree()); boolean useLocalTime = UserPreferences.displayTimesInLocalTime(); - useLocalTimeRB.setSelected(useLocalTime); - useGMTTimeRB.setSelected(!useLocalTime); + oldUseLocalTimeRB.setSelected(useLocalTime); + oldUseGMTTimeRB.setSelected(!useLocalTime); String path = ModuleSettings.getConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP); boolean useDefault = (path == null || path.isEmpty()); defaultLogoRB.setSelected(useDefault); @@ -350,12 +350,12 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { * Store the current user preferences. */ void store() { - UserPreferences.setKeepPreferredContentViewer(keepCurrentViewerRB.isSelected()); - UserPreferences.setHideKnownFilesInDataSourcesTree(dataSourcesHideKnownCB.isSelected()); - UserPreferences.setHideKnownFilesInViewsTree(viewsHideKnownCB.isSelected()); - UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCB.isSelected()); - UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCB.isSelected()); - UserPreferences.setDisplayTimesInLocalTime(useLocalTimeRB.isSelected()); + UserPreferences.setKeepPreferredContentViewer(oldKeepCurrentViewerRB.isSelected()); + UserPreferences.setHideKnownFilesInDataSourcesTree(oldDataSourcesHideKnownCB.isSelected()); + UserPreferences.setHideKnownFilesInViewsTree(oldViewsHideKnownCB.isSelected()); + UserPreferences.setHideSlackFilesInDataSourcesTree(oldDataSourcesHideSlackCB.isSelected()); + UserPreferences.setHideSlackFilesInViewsTree(oldViewsHideSlackCB.isSelected()); + UserPreferences.setDisplayTimesInLocalTime(oldUseLocalTimeRB.isSelected()); UserPreferences.setLogFileCount(Integer.parseInt(logFileCount.getText())); if (!agencyLogoPathField.getText().isEmpty()) { File file = new File(agencyLogoPathField.getText()); @@ -535,19 +535,19 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { defaultLogoRB = new javax.swing.JRadioButton(); specifyLogoRB = new javax.swing.JRadioButton(); agencyLogoPathFieldValidationLabel = new javax.swing.JLabel(); - viewPanel = new javax.swing.JPanel(); + oldViewPanel = new javax.swing.JPanel(); jLabelSelectFile = new javax.swing.JLabel(); - useBestViewerRB = new javax.swing.JRadioButton(); - keepCurrentViewerRB = new javax.swing.JRadioButton(); + oldUseBestViewerRB = new javax.swing.JRadioButton(); + oldKeepCurrentViewerRB = new javax.swing.JRadioButton(); jLabelHideKnownFiles = new javax.swing.JLabel(); - dataSourcesHideKnownCB = new javax.swing.JCheckBox(); - viewsHideKnownCB = new javax.swing.JCheckBox(); + oldDataSourcesHideKnownCB = new javax.swing.JCheckBox(); + oldViewsHideKnownCB = new javax.swing.JCheckBox(); jLabelHideSlackFiles = new javax.swing.JLabel(); - dataSourcesHideSlackCB = new javax.swing.JCheckBox(); - viewsHideSlackCB = new javax.swing.JCheckBox(); + oldDataSourcesHideSlackCB = new javax.swing.JCheckBox(); + oldViewsHideSlackCB = new javax.swing.JCheckBox(); jLabelTimeDisplay = new javax.swing.JLabel(); - useLocalTimeRB = new javax.swing.JRadioButton(); - useGMTTimeRB = new javax.swing.JRadioButton(); + oldUseLocalTimeRB = new javax.swing.JRadioButton(); + oldUseGMTTimeRB = new javax.swing.JRadioButton(); runtimePanel = new javax.swing.JPanel(); maxMemoryLabel = new javax.swing.JLabel(); maxMemoryUnitsLabel = new javax.swing.JLabel(); @@ -643,137 +643,137 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGap(0, 0, Short.MAX_VALUE)) ); - viewPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.viewPanel.border.title"))); // NOI18N + oldViewPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldViewPanel.border.title"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jLabelSelectFile, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelSelectFile.text")); // NOI18N - fileSelectionButtonGroup.add(useBestViewerRB); - org.openide.awt.Mnemonics.setLocalizedText(useBestViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useBestViewerRB.text")); // NOI18N - useBestViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useBestViewerRB.toolTipText")); // NOI18N - useBestViewerRB.addActionListener(new java.awt.event.ActionListener() { + fileSelectionButtonGroup.add(oldUseBestViewerRB); + org.openide.awt.Mnemonics.setLocalizedText(oldUseBestViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldUseBestViewerRB.text")); // NOI18N + oldUseBestViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldUseBestViewerRB.toolTipText")); // NOI18N + oldUseBestViewerRB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - useBestViewerRBActionPerformed(evt); + oldUseBestViewerRBActionPerformed(evt); } }); - fileSelectionButtonGroup.add(keepCurrentViewerRB); - org.openide.awt.Mnemonics.setLocalizedText(keepCurrentViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.keepCurrentViewerRB.text")); // NOI18N - keepCurrentViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText")); // NOI18N - keepCurrentViewerRB.addActionListener(new java.awt.event.ActionListener() { + fileSelectionButtonGroup.add(oldKeepCurrentViewerRB); + org.openide.awt.Mnemonics.setLocalizedText(oldKeepCurrentViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldKeepCurrentViewerRB.text")); // NOI18N + oldKeepCurrentViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldKeepCurrentViewerRB.toolTipText")); // NOI18N + oldKeepCurrentViewerRB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - keepCurrentViewerRBActionPerformed(evt); + oldKeepCurrentViewerRBActionPerformed(evt); } }); org.openide.awt.Mnemonics.setLocalizedText(jLabelHideKnownFiles, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelHideKnownFiles.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideKnownCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.dataSourcesHideKnownCB.text")); // NOI18N - dataSourcesHideKnownCB.addActionListener(new java.awt.event.ActionListener() { + org.openide.awt.Mnemonics.setLocalizedText(oldDataSourcesHideKnownCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldDataSourcesHideKnownCB.text")); // NOI18N + oldDataSourcesHideKnownCB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - dataSourcesHideKnownCBActionPerformed(evt); + oldDataSourcesHideKnownCBActionPerformed(evt); } }); - org.openide.awt.Mnemonics.setLocalizedText(viewsHideKnownCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.viewsHideKnownCB.text")); // NOI18N - viewsHideKnownCB.addActionListener(new java.awt.event.ActionListener() { + org.openide.awt.Mnemonics.setLocalizedText(oldViewsHideKnownCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldViewsHideKnownCB.text")); // NOI18N + oldViewsHideKnownCB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - viewsHideKnownCBActionPerformed(evt); + oldViewsHideKnownCBActionPerformed(evt); } }); org.openide.awt.Mnemonics.setLocalizedText(jLabelHideSlackFiles, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelHideSlackFiles.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideSlackCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.dataSourcesHideSlackCB.text")); // NOI18N - dataSourcesHideSlackCB.addActionListener(new java.awt.event.ActionListener() { + org.openide.awt.Mnemonics.setLocalizedText(oldDataSourcesHideSlackCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldDataSourcesHideSlackCB.text")); // NOI18N + oldDataSourcesHideSlackCB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - dataSourcesHideSlackCBActionPerformed(evt); + oldDataSourcesHideSlackCBActionPerformed(evt); } }); - org.openide.awt.Mnemonics.setLocalizedText(viewsHideSlackCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.viewsHideSlackCB.text")); // NOI18N - viewsHideSlackCB.addActionListener(new java.awt.event.ActionListener() { + org.openide.awt.Mnemonics.setLocalizedText(oldViewsHideSlackCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldViewsHideSlackCB.text")); // NOI18N + oldViewsHideSlackCB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - viewsHideSlackCBActionPerformed(evt); + oldViewsHideSlackCBActionPerformed(evt); } }); org.openide.awt.Mnemonics.setLocalizedText(jLabelTimeDisplay, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelTimeDisplay.text")); // NOI18N - displayTimesButtonGroup.add(useLocalTimeRB); - org.openide.awt.Mnemonics.setLocalizedText(useLocalTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useLocalTimeRB.text")); // NOI18N - useLocalTimeRB.addActionListener(new java.awt.event.ActionListener() { + displayTimesButtonGroup.add(oldUseLocalTimeRB); + org.openide.awt.Mnemonics.setLocalizedText(oldUseLocalTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldUseLocalTimeRB.text")); // NOI18N + oldUseLocalTimeRB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - useLocalTimeRBActionPerformed(evt); + oldUseLocalTimeRBActionPerformed(evt); } }); - displayTimesButtonGroup.add(useGMTTimeRB); - org.openide.awt.Mnemonics.setLocalizedText(useGMTTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useGMTTimeRB.text")); // NOI18N - useGMTTimeRB.addActionListener(new java.awt.event.ActionListener() { + displayTimesButtonGroup.add(oldUseGMTTimeRB); + org.openide.awt.Mnemonics.setLocalizedText(oldUseGMTTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldUseGMTTimeRB.text")); // NOI18N + oldUseGMTTimeRB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - useGMTTimeRBActionPerformed(evt); + oldUseGMTTimeRBActionPerformed(evt); } }); - javax.swing.GroupLayout viewPanelLayout = new javax.swing.GroupLayout(viewPanel); - viewPanel.setLayout(viewPanelLayout); - viewPanelLayout.setHorizontalGroup( - viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, viewPanelLayout.createSequentialGroup() + javax.swing.GroupLayout oldViewPanelLayout = new javax.swing.GroupLayout(oldViewPanel); + oldViewPanel.setLayout(oldViewPanelLayout); + oldViewPanelLayout.setHorizontalGroup( + oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, oldViewPanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(viewPanelLayout.createSequentialGroup() + .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(oldViewPanelLayout.createSequentialGroup() .addGap(10, 10, 10) - .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(viewPanelLayout.createSequentialGroup() - .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(useGMTTimeRB) - .addComponent(keepCurrentViewerRB) - .addComponent(useBestViewerRB) - .addComponent(dataSourcesHideKnownCB) - .addComponent(viewsHideKnownCB)) + .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(oldViewPanelLayout.createSequentialGroup() + .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(oldUseGMTTimeRB) + .addComponent(oldKeepCurrentViewerRB) + .addComponent(oldUseBestViewerRB) + .addComponent(oldDataSourcesHideKnownCB) + .addComponent(oldViewsHideKnownCB)) .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(viewPanelLayout.createSequentialGroup() - .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideSlackCB) - .addComponent(viewsHideSlackCB) - .addComponent(useLocalTimeRB)) + .addGroup(oldViewPanelLayout.createSequentialGroup() + .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(oldDataSourcesHideSlackCB) + .addComponent(oldViewsHideSlackCB) + .addComponent(oldUseLocalTimeRB)) .addContainerGap(158, Short.MAX_VALUE)))) - .addGroup(viewPanelLayout.createSequentialGroup() - .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(oldViewPanelLayout.createSequentialGroup() + .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabelHideSlackFiles) .addComponent(jLabelTimeDisplay) .addComponent(jLabelHideKnownFiles) .addComponent(jLabelSelectFile)) .addGap(30, 30, 30)))) ); - viewPanelLayout.setVerticalGroup( - viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, viewPanelLayout.createSequentialGroup() + oldViewPanelLayout.setVerticalGroup( + oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, oldViewPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(jLabelSelectFile) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(useBestViewerRB) + .addComponent(oldUseBestViewerRB) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(keepCurrentViewerRB) + .addComponent(oldKeepCurrentViewerRB) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jLabelHideKnownFiles) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(dataSourcesHideKnownCB) + .addComponent(oldDataSourcesHideKnownCB) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(viewsHideKnownCB) + .addComponent(oldViewsHideKnownCB) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabelHideSlackFiles) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(dataSourcesHideSlackCB) + .addComponent(oldDataSourcesHideSlackCB) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(viewsHideSlackCB) + .addComponent(oldViewsHideSlackCB) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabelTimeDisplay) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(useLocalTimeRB) + .addComponent(oldUseLocalTimeRB) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(useGMTTimeRB)) + .addComponent(oldUseGMTTimeRB)) ); runtimePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.runtimePanel.border.title"))); // NOI18N @@ -889,7 +889,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1010, Short.MAX_VALUE) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(viewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(oldViewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap()) @@ -899,7 +899,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGroup(jPanel1Layout.createSequentialGroup() .addGap(0, 0, 0) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(viewPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(oldViewPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -940,37 +940,37 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_memFieldKeyReleased - private void useGMTTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useGMTTimeRBActionPerformed + private void oldUseGMTTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldUseGMTTimeRBActionPerformed firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_useGMTTimeRBActionPerformed + }//GEN-LAST:event_oldUseGMTTimeRBActionPerformed - private void useLocalTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useLocalTimeRBActionPerformed + private void oldUseLocalTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldUseLocalTimeRBActionPerformed firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_useLocalTimeRBActionPerformed + }//GEN-LAST:event_oldUseLocalTimeRBActionPerformed - private void viewsHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideSlackCBActionPerformed + private void oldViewsHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldViewsHideSlackCBActionPerformed firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_viewsHideSlackCBActionPerformed + }//GEN-LAST:event_oldViewsHideSlackCBActionPerformed - private void dataSourcesHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideSlackCBActionPerformed + private void oldDataSourcesHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldDataSourcesHideSlackCBActionPerformed firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_dataSourcesHideSlackCBActionPerformed + }//GEN-LAST:event_oldDataSourcesHideSlackCBActionPerformed - private void viewsHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideKnownCBActionPerformed + private void oldViewsHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldViewsHideKnownCBActionPerformed firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_viewsHideKnownCBActionPerformed + }//GEN-LAST:event_oldViewsHideKnownCBActionPerformed - private void dataSourcesHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideKnownCBActionPerformed + private void oldDataSourcesHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldDataSourcesHideKnownCBActionPerformed firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_dataSourcesHideKnownCBActionPerformed + }//GEN-LAST:event_oldDataSourcesHideKnownCBActionPerformed - private void keepCurrentViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keepCurrentViewerRBActionPerformed + private void oldKeepCurrentViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldKeepCurrentViewerRBActionPerformed firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_keepCurrentViewerRBActionPerformed + }//GEN-LAST:event_oldKeepCurrentViewerRBActionPerformed - private void useBestViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useBestViewerRBActionPerformed + private void oldUseBestViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldUseBestViewerRBActionPerformed firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_useBestViewerRBActionPerformed + }//GEN-LAST:event_oldUseBestViewerRBActionPerformed private void specifyLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyLogoRBActionPerformed agencyLogoPathField.setEnabled(true); @@ -1028,8 +1028,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JLabel agencyLogoPathFieldValidationLabel; private javax.swing.JLabel agencyLogoPreview; private javax.swing.JButton browseLogosButton; - private javax.swing.JCheckBox dataSourcesHideKnownCB; - private javax.swing.JCheckBox dataSourcesHideSlackCB; private javax.swing.JRadioButton defaultLogoRB; private javax.swing.ButtonGroup displayTimesButtonGroup; private javax.swing.ButtonGroup fileSelectionButtonGroup; @@ -1039,7 +1037,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JLabel jLabelTimeDisplay; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JRadioButton keepCurrentViewerRB; private javax.swing.JTextField logFileCount; private javax.swing.JTextField logNumAlert; private javax.swing.JPanel logoPanel; @@ -1050,17 +1047,20 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JLabel maxMemoryUnitsLabel1; private javax.swing.JTextField memField; private javax.swing.JLabel memFieldValidationLabel; + private javax.swing.JCheckBox oldDataSourcesHideKnownCB; + private javax.swing.JCheckBox oldDataSourcesHideSlackCB; + private javax.swing.JRadioButton oldKeepCurrentViewerRB; + private javax.swing.JRadioButton oldUseBestViewerRB; + private javax.swing.JRadioButton oldUseGMTTimeRB; + private javax.swing.JRadioButton oldUseLocalTimeRB; + private javax.swing.JPanel oldViewPanel; + private javax.swing.JCheckBox oldViewsHideKnownCB; + private javax.swing.JCheckBox oldViewsHideSlackCB; private javax.swing.JLabel restartNecessaryWarning; private javax.swing.JPanel runtimePanel; private javax.swing.JRadioButton specifyLogoRB; private javax.swing.JLabel systemMemoryTotal; private javax.swing.JLabel totalMemoryLabel; - private javax.swing.JRadioButton useBestViewerRB; - private javax.swing.JRadioButton useGMTTimeRB; - private javax.swing.JRadioButton useLocalTimeRB; - private javax.swing.JPanel viewPanel; - private javax.swing.JCheckBox viewsHideKnownCB; - private javax.swing.JCheckBox viewsHideSlackCB; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index bb98cc90f6..1a83101f5e 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -96,14 +96,6 @@ DataResultViewerThumbnail.comboBox.mediumThumbnails=Medium Thumbnails DataResultViewerThumbnail.comboBox.largeThumbnails=Large Thumbnails DataResultViewerThumbnail.switchPage.done.errMsg=Error making thumbnails\: {0} AboutWindowPanel.actVerboseLogging.text=Activate verbose logging -AutopsyOptionsPanel.viewsHideKnownCB.text=Views area -AutopsyOptionsPanel.dataSourcesHideKnownCB.text=Data Sources area (the directory hierarchy) -AutopsyOptionsPanel.useBestViewerRB.toolTipText=For example, change from Hex to Media when a JPEG is selected. -AutopsyOptionsPanel.useBestViewerRB.text=Change to the most specific file viewer -AutopsyOptionsPanel.useGMTTimeRB.text=Use GMT -AutopsyOptionsPanel.useLocalTimeRB.text=Use local time zone -AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText=For example, stay in Hex view when a JPEG is selected. -AutopsyOptionsPanel.keepCurrentViewerRB.text=Stay on the same file viewer AutopsyOptionsPanel.jLabelSelectFile.text=When selecting a file: AutopsyOptionsPanel.jLabelHideKnownFiles.text=Hide known files (i.e. those in the NIST NSRL) in the: AutopsyOptionsPanel.jLabelTimeDisplay.text=When displaying times: @@ -154,8 +146,6 @@ MultiUserSettingsPanel.lbTestDbWarning.text= MultiUserSettingsPanel.KeywordSearchNull=Cannot find keyword search service MultiUserSettingsPanel.InvalidPortNumber=Invalid port number AutopsyOptionsPanel.jLabelHideSlackFiles.text=Hide slack files in the: -AutopsyOptionsPanel.dataSourcesHideSlackCB.text=Data Sources area (the directory hierarchy) -AutopsyOptionsPanel.viewsHideSlackCB.text=Views area AutopsyOptionsPanel.agencyLogoImageLabel.toolTipText= AutopsyOptionsPanel.agencyLogoPathField.text= SortChooserDialog.label=remove @@ -177,7 +167,41 @@ AutopsyOptionsPanel.specifyLogoRB.text=Specify a logo AutopsyOptionsPanel.agencyLogoPreview.text=
No logo
selected
AutopsyOptionsPanel.logoPanel.border.title=Logo AutopsyOptionsPanel.runtimePanel.border.title=Runtime -AutopsyOptionsPanel.viewPanel.border.title=View DataResultPanel.matchLabel.text=Results DataResultPanel.numberOfChildNodesLabel.text=0 DataResultPanel.descriptionLabel.text=directoryPath +ViewPreferencesPanel.selectFileLabel.text=When selecting a file: +ViewPreferencesPanel.globalSettingsPanel.border.title=Global Settings +ViewPreferencesPanel.displayTimeLabel.text=When displaying times: +ViewPreferencesPanel.hideSlackFilesLabel.text=Hide slack files in the: +ViewPreferencesPanel.groupByDataSourceCheckbox.text=Group by data source +ViewPreferencesPanel.hideKnownFilesLabel.text=Hide known files (i.e. those in the NIST NSRL) in the: +ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=Hide other user's tags +ViewPreferencesPanel.currentCaseSettingsPanel.border.title=Current Case Settings +OptionsCategory_Name_View=View +OptionsCategory_Keywords_View=View +ViewPreferencesDialog.okButton.text=OK +ViewPreferencesDialog.cancelButton.text=Cancel +AutopsyOptionsPanel.oldViewPanel.border.title=View +AutopsyOptionsPanel.oldUseBestViewerRB.toolTipText=For example, change from Hex to Media when a JPEG is selected. +AutopsyOptionsPanel.oldUseBestViewerRB.text=Change to the most specific file viewer +AutopsyOptionsPanel.oldKeepCurrentViewerRB.toolTipText=For example, stay in Hex view when a JPEG is selected. +AutopsyOptionsPanel.oldKeepCurrentViewerRB.text=Stay on the same file viewer +AutopsyOptionsPanel.oldDataSourcesHideKnownCB.text=Data Sources area (the directory hierarchy) +AutopsyOptionsPanel.oldViewsHideKnownCB.text=Views area +AutopsyOptionsPanel.oldDataSourcesHideSlackCB.text=Data Sources area (the directory hierarchy) +AutopsyOptionsPanel.oldViewsHideSlackCB.text=Views area +AutopsyOptionsPanel.oldUseLocalTimeRB.text=Use local time zone +AutopsyOptionsPanel.oldUseGMTTimeRB.text=Use GMT +ViewPreferencesPanel.useBestViewerRadioButton.toolTipText=For example, change from Hex to Media when a JPEG is selected. +ViewPreferencesPanel.useBestViewerRadioButton.text=Change to the most specific file viewer +ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText=For example, stay in Hex view when a JPEG is selected. +ViewPreferencesPanel.keepCurrentViewerRadioButton.text=Stay on the same file viewer +ViewPreferencesPanel.useLocalTimeRadioButton.text=Use local time zone +ViewPreferencesPanel.useGMTTimeRadioButton.text=Use GMT +ViewPreferencesPanel.dataSourcesHideKnownCheckbox.text=Data Sources area (the directory hierarchy) +ViewPreferencesPanel.viewsHideKnownCheckbox.text=Views area +ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text=Data Sources area (the directory hierarchy) +ViewPreferencesPanel.viewsHideSlackCheckbox.text=Views area +ViewPreferencesPanel.currentSessionSettingsPanel.border.title=Current Session Settings +ViewPreferencesPanel.hideRejectedResultsCheckbox.text=Hide rejected results diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties index cbdabb3747..0eadc6458b 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties @@ -79,14 +79,6 @@ DataResultViewerThumbnail.comboBox.mediumThumbnails=\u30b5\u30e0\u30cd\u30a4\u30 DataResultViewerThumbnail.comboBox.largeThumbnails=\u30b5\u30e0\u30cd\u30a4\u30eb\uff08\u5927\uff09 DataResultViewerThumbnail.switchPage.done.errMsg=\u30b5\u30e0\u30cd\u30a4\u30eb\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a {0} AboutWindowPanel.actVerboseLogging.text=Verbose\u30ed\u30b0\u3092\u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8 -AutopsyOptionsPanel.viewsHideKnownCB.text=\u30d3\u30e5\u30fc\u30a8\u30ea\u30a2 -AutopsyOptionsPanel.dataSourcesHideKnownCB.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a8\u30ea\u30a2\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u968e\u5c64\uff09 -AutopsyOptionsPanel.useBestViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u306fHEX\u304b\u3089\u30e1\u30c7\u30a3\u30a2\u306b\u5909\u66f4\u3059\u308b\u3002 -AutopsyOptionsPanel.useBestViewerRB.text=\u6700\u3082\u5c02\u9580\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u306b\u5909\u66f4 -AutopsyOptionsPanel.useGMTTimeRB.text=GMT\u3092\u4f7f\u7528 -AutopsyOptionsPanel.useLocalTimeRB.text=\u30ed\u30fc\u30ab\u30eb\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u4f7f\u7528 -AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u305d\u306e\u307e\u307eHEX\u30d3\u30e5\u30fc\u3092\u4f7f\u7528\u3002 -AutopsyOptionsPanel.keepCurrentViewerRB.text=\u305d\u306e\u307e\u307e\u540c\u3058\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u3092\u4f7f\u7528 AutopsyOptionsPanel.jLabelSelectFile.text=\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3059\u308b\u5834\u5408\uff1a AutopsyOptionsPanel.jLabelHideKnownFiles.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\uff08NIST NSRL\u5185\u306e\uff09\u3092\u6b21\u306b\u96a0\u3059\uff1a AutopsyOptionsPanel.jLabelTimeDisplay.text=\u6642\u9593\u3092\u8868\u793a\u3059\u308b\u5834\u5408\uff1a @@ -131,3 +123,22 @@ MediaViewImagePanel.externalViewerButton.text=\u5916\u90e8\u30d3\u30e5\u30fc\u30 DataResultPanel.matchLabel.text=\u7d50\u679c DataResultPanel.numberOfChildNodesLabel.text=0 DataResultPanel.descriptionLabel.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30d1\u30b9 +ViewPreferencesPanel.selectFileLabel.text=\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3059\u308b\u5834\u5408\uff1a +ViewPreferencesPanel.displayTimeLabel.text=\u6642\u9593\u3092\u8868\u793a\u3059\u308b\u5834\u5408\uff1a +ViewPreferencesPanel.hideKnownFilesLabel.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\uff08NIST NSRL\u5185\u306e\uff09\u3092\u6b21\u306b\u96a0\u3059\uff1a +AutopsyOptionsPanel.oldUseBestViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u306fHEX\u304b\u3089\u30e1\u30c7\u30a3\u30a2\u306b\u5909\u66f4\u3059\u308b\u3002 +AutopsyOptionsPanel.oldUseBestViewerRB.text=\u6700\u3082\u5c02\u9580\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u306b\u5909\u66f4 +AutopsyOptionsPanel.oldKeepCurrentViewerRB.text=\u305d\u306e\u307e\u307e\u540c\u3058\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u3092\u4f7f\u7528 +AutopsyOptionsPanel.oldKeepCurrentViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u305d\u306e\u307e\u307eHEX\u30d3\u30e5\u30fc\u3092\u4f7f\u7528\u3002 +AutopsyOptionsPanel.oldDataSourcesHideKnownCB.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a8\u30ea\u30a2\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u968e\u5c64\uff09 +AutopsyOptionsPanel.oldViewsHideKnownCB.text=\u30d3\u30e5\u30fc\u30a8\u30ea\u30a2 +AutopsyOptionsPanel.oldUseLocalTimeRB.text=\u30ed\u30fc\u30ab\u30eb\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u4f7f\u7528 +AutopsyOptionsPanel.oldUseGMTTimeRB.text=GMT\u3092\u4f7f\u7528 +ViewPreferencesPanel.useBestViewerRadioButton.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u306fHEX\u304b\u3089\u30e1\u30c7\u30a3\u30a2\u306b\u5909\u66f4\u3059\u308b\u3002 +ViewPreferencesPanel.useBestViewerRadioButton.text=\u6700\u3082\u5c02\u9580\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u306b\u5909\u66f4 +ViewPreferencesPanel.keepCurrentViewerRadioButton.text=\u305d\u306e\u307e\u307e\u540c\u3058\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u3092\u4f7f\u7528 +ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u305d\u306e\u307e\u307eHEX\u30d3\u30e5\u30fc\u3092\u4f7f\u7528\u3002 +ViewPreferencesPanel.useLocalTimeRadioButton.text=\u30ed\u30fc\u30ab\u30eb\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u4f7f\u7528 +ViewPreferencesPanel.useGMTTimeRadioButton.text=GMT\u3092\u4f7f\u7528 +ViewPreferencesPanel.dataSourcesHideKnownCheckbox.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a8\u30ea\u30a2\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u968e\u5c64\uff09 +ViewPreferencesPanel.viewsHideKnownCheckbox.text=\u30d3\u30e5\u30fc\u30a8\u30ea\u30a2 diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanelController.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanelController.java index 9c23379975..212bfa7dcd 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanelController.java @@ -31,7 +31,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; @OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_Multi_User_Settings", iconBase = "org/sleuthkit/autopsy/images/User-Group-icon-green32.png", - position = 3, + position = 4, keywords = "#OptionsCategory_Keywords_Multi_User_Options", keywordsCategory = "Multi-User") public final class MultiUserSettingsPanelController extends OptionsPanelController { diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.form new file mode 100755 index 0000000000..d57d767a1e --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.form @@ -0,0 +1,78 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.java new file mode 100755 index 0000000000..bab69e596b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.java @@ -0,0 +1,133 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.corecomponents; + +import java.awt.Dialog; +import org.openide.util.NbBundle; +import org.openide.windows.WindowManager; + +/** + * Popup dialog for hosting the ViewPreferencesPanel. This is intended to be + * used from the DirectoryTreeTopComponent. + */ +final public class ViewPreferencesDialog extends javax.swing.JDialog { + + /** + * Creates new form ViewPreferencesDialog + */ + @NbBundle.Messages({ + "ViewPreferencesDialog.title.text=View Preferences" + }) + public ViewPreferencesDialog() { + super(WindowManager.getDefault().getMainWindow(), + Bundle.ViewPreferencesDialog_title_text(), + Dialog.ModalityType.APPLICATION_MODAL); + initComponents(); + viewPreferencesPanel.load(); + } + + /** + * Show the dialog. + */ + public void display() { + setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + setVisible(true); + } + + /** + * Close the dialog. + */ + private void close() { + setVisible(false); + dispose(); + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + okButton = new javax.swing.JButton(); + cancelButton = new javax.swing.JButton(); + viewPreferencesPanel = new org.sleuthkit.autopsy.corecomponents.ViewPreferencesPanel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(ViewPreferencesDialog.class, "ViewPreferencesDialog.okButton.text")); // NOI18N + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(ViewPreferencesDialog.class, "ViewPreferencesDialog.cancelButton.text")); // NOI18N + cancelButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cancelButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(viewPreferencesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(viewPreferencesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(okButton) + .addComponent(cancelButton)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed + viewPreferencesPanel.store(); + close(); + }//GEN-LAST:event_okButtonActionPerformed + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed + close(); + }//GEN-LAST:event_cancelButtonActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton cancelButton; + private javax.swing.JButton okButton; + private org.sleuthkit.autopsy.corecomponents.ViewPreferencesPanel viewPreferencesPanel; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form new file mode 100755 index 0000000000..1fcbee8b23 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form @@ -0,0 +1,335 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java new file mode 100755 index 0000000000..1e9b1fcbbd --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -0,0 +1,362 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.corecomponents; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; +import java.util.Properties; +import java.util.logging.Level; +import javax.swing.JPanel; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.core.UserPreferences; +import org.sleuthkit.autopsy.coreutils.Logger; + +/** + * Panel for configuring view preferences. + */ +public class ViewPreferencesPanel extends JPanel implements OptionsPanel { + + private static final Logger logger = Logger.getLogger(ViewPreferencesPanel.class.getName()); + + private Case currentCase = null; + private CasePreferences casePreferences = null; + + /** + * Creates new form ViewPreferencesPanel + */ + public ViewPreferencesPanel() { + initComponents(); + } + + @Override + public void load() { + boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer(); + keepCurrentViewerRadioButton.setSelected(keepPreferredViewer); + useBestViewerRadioButton.setSelected(!keepPreferredViewer); + + boolean useLocalTime = UserPreferences.displayTimesInLocalTime(); + useLocalTimeRadioButton.setSelected(useLocalTime); + useGMTTimeRadioButton.setSelected(!useLocalTime); + + dataSourcesHideKnownCheckbox.setSelected(UserPreferences.hideKnownFilesInDataSourcesTree()); + viewsHideKnownCheckbox.setSelected(UserPreferences.hideKnownFilesInViewsTree()); + + dataSourcesHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree()); + viewsHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInViewsTree()); + + hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags() == false); + + try { + currentCase = Case.getCurrentCaseThrows(); + casePreferences = new CasePreferences(currentCase); + + groupByDataSourceCheckbox.setSelected(Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true)); + } catch (NoCurrentCaseException ex) { + // No open case. + } + } + + @Override + public void store() { + UserPreferences.setKeepPreferredContentViewer(keepCurrentViewerRadioButton.isSelected()); + UserPreferences.setDisplayTimesInLocalTime(useLocalTimeRadioButton.isSelected()); + UserPreferences.setHideKnownFilesInDataSourcesTree(dataSourcesHideKnownCheckbox.isSelected()); + UserPreferences.setHideKnownFilesInViewsTree(viewsHideKnownCheckbox.isSelected()); + UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCheckbox.isSelected()); + UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected()); + + UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected()); + + if (currentCase != null) { + /* + * Only write the value if it has already been previously stored, or + * if the checkbox is selected. This allows GroupDataSourcesDialog + * to work. + */ + if (casePreferences.getGroupItemsInTreeByDataSource() != null || groupByDataSourceCheckbox.isSelected()) { + firePropertyChange( + CasePreferences.GROUP_ITEMS_IN_TREE_BY_DATASOURCE, + casePreferences.getGroupItemsInTreeByDataSource(), Boolean.valueOf(groupByDataSourceCheckbox.isSelected())); + casePreferences.setGroupItemsInTreeByDataSource(groupByDataSourceCheckbox.isSelected()); + } + casePreferences.saveToStorage(currentCase); + } + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + globalSettingsPanel = new javax.swing.JPanel(); + selectFileLabel = new javax.swing.JLabel(); + useBestViewerRadioButton = new javax.swing.JRadioButton(); + keepCurrentViewerRadioButton = new javax.swing.JRadioButton(); + hideKnownFilesLabel = new javax.swing.JLabel(); + dataSourcesHideKnownCheckbox = new javax.swing.JCheckBox(); + viewsHideKnownCheckbox = new javax.swing.JCheckBox(); + hideSlackFilesLabel = new javax.swing.JLabel(); + dataSourcesHideSlackCheckbox = new javax.swing.JCheckBox(); + viewsHideSlackCheckbox = new javax.swing.JCheckBox(); + displayTimeLabel = new javax.swing.JLabel(); + useLocalTimeRadioButton = new javax.swing.JRadioButton(); + useGMTTimeRadioButton = new javax.swing.JRadioButton(); + currentCaseSettingsPanel = new javax.swing.JPanel(); + hideOtherUsersTagsCheckbox = new javax.swing.JCheckBox(); + groupByDataSourceCheckbox = new javax.swing.JCheckBox(); + currentSessionSettingsPanel = new javax.swing.JPanel(); + hideRejectedResultsCheckbox = new javax.swing.JCheckBox(); + + globalSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.globalSettingsPanel.border.title"))); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(selectFileLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.selectFileLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(useBestViewerRadioButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.useBestViewerRadioButton.text")); // NOI18N + useBestViewerRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.useBestViewerRadioButton.toolTipText")); // NOI18N + useBestViewerRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + useBestViewerRadioButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(keepCurrentViewerRadioButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.keepCurrentViewerRadioButton.text")); // NOI18N + keepCurrentViewerRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText")); // NOI18N + keepCurrentViewerRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + keepCurrentViewerRadioButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(hideKnownFilesLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideKnownFilesLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideKnownCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.dataSourcesHideKnownCheckbox.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(viewsHideKnownCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.viewsHideKnownCheckbox.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(hideSlackFilesLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideSlackFilesLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideSlackCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(viewsHideSlackCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.viewsHideSlackCheckbox.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(displayTimeLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.displayTimeLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(useLocalTimeRadioButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.useLocalTimeRadioButton.text")); // NOI18N + useLocalTimeRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + useLocalTimeRadioButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(useGMTTimeRadioButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.useGMTTimeRadioButton.text")); // NOI18N + useGMTTimeRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + useGMTTimeRadioButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout globalSettingsPanelLayout = new javax.swing.GroupLayout(globalSettingsPanel); + globalSettingsPanel.setLayout(globalSettingsPanelLayout); + globalSettingsPanelLayout.setHorizontalGroup( + globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, globalSettingsPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(displayTimeLabel) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(keepCurrentViewerRadioButton) + .addComponent(useBestViewerRadioButton) + .addComponent(useGMTTimeRadioButton) + .addComponent(useLocalTimeRadioButton))) + .addComponent(selectFileLabel)) + .addGap(18, 18, 18) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(hideKnownFilesLabel) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideSlackCheckbox) + .addComponent(viewsHideSlackCheckbox))) + .addComponent(hideSlackFilesLabel)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideKnownCheckbox) + .addComponent(viewsHideKnownCheckbox))))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + globalSettingsPanelLayout.setVerticalGroup( + globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, globalSettingsPanelLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addComponent(hideKnownFilesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dataSourcesHideKnownCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(viewsHideKnownCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(hideSlackFilesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dataSourcesHideSlackCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(viewsHideSlackCheckbox)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addComponent(selectFileLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(useBestViewerRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(keepCurrentViewerRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(displayTimeLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(useLocalTimeRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(useGMTTimeRadioButton)))) + ); + + currentCaseSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentCaseSettingsPanel.border.title"))); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(hideOtherUsersTagsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(groupByDataSourceCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.groupByDataSourceCheckbox.text")); // NOI18N + + javax.swing.GroupLayout currentCaseSettingsPanelLayout = new javax.swing.GroupLayout(currentCaseSettingsPanel); + currentCaseSettingsPanel.setLayout(currentCaseSettingsPanelLayout); + currentCaseSettingsPanelLayout.setHorizontalGroup( + currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(currentCaseSettingsPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(hideOtherUsersTagsCheckbox) + .addComponent(groupByDataSourceCheckbox)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + currentCaseSettingsPanelLayout.setVerticalGroup( + currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(currentCaseSettingsPanelLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(hideOtherUsersTagsCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(groupByDataSourceCheckbox) + .addGap(20, 20, 20)) + ); + + currentSessionSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentSessionSettingsPanel.border.title"))); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(hideRejectedResultsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideRejectedResultsCheckbox.text")); // NOI18N + + javax.swing.GroupLayout currentSessionSettingsPanelLayout = new javax.swing.GroupLayout(currentSessionSettingsPanel); + currentSessionSettingsPanel.setLayout(currentSessionSettingsPanelLayout); + currentSessionSettingsPanelLayout.setHorizontalGroup( + currentSessionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(currentSessionSettingsPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(hideRejectedResultsCheckbox) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + currentSessionSettingsPanelLayout.setVerticalGroup( + currentSessionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(currentSessionSettingsPanelLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(hideRejectedResultsCheckbox)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(currentSessionSettingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(globalSettingsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(globalSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(currentSessionSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void useBestViewerRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useBestViewerRadioButtonActionPerformed + useBestViewerRadioButton.setSelected(true); + keepCurrentViewerRadioButton.setSelected(false); + }//GEN-LAST:event_useBestViewerRadioButtonActionPerformed + + private void keepCurrentViewerRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keepCurrentViewerRadioButtonActionPerformed + useBestViewerRadioButton.setSelected(false); + keepCurrentViewerRadioButton.setSelected(true); + }//GEN-LAST:event_keepCurrentViewerRadioButtonActionPerformed + + private void useLocalTimeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useLocalTimeRadioButtonActionPerformed + useLocalTimeRadioButton.setSelected(true); + useGMTTimeRadioButton.setSelected(false); + }//GEN-LAST:event_useLocalTimeRadioButtonActionPerformed + + private void useGMTTimeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useGMTTimeRadioButtonActionPerformed + useLocalTimeRadioButton.setSelected(false); + useGMTTimeRadioButton.setSelected(true); + }//GEN-LAST:event_useGMTTimeRadioButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel currentCaseSettingsPanel; + private javax.swing.JPanel currentSessionSettingsPanel; + private javax.swing.JCheckBox dataSourcesHideKnownCheckbox; + private javax.swing.JCheckBox dataSourcesHideSlackCheckbox; + private javax.swing.JLabel displayTimeLabel; + private javax.swing.JPanel globalSettingsPanel; + private javax.swing.JCheckBox groupByDataSourceCheckbox; + private javax.swing.JLabel hideKnownFilesLabel; + private javax.swing.JCheckBox hideOtherUsersTagsCheckbox; + private javax.swing.JCheckBox hideRejectedResultsCheckbox; + private javax.swing.JLabel hideSlackFilesLabel; + private javax.swing.JRadioButton keepCurrentViewerRadioButton; + private javax.swing.JLabel selectFileLabel; + private javax.swing.JRadioButton useBestViewerRadioButton; + private javax.swing.JRadioButton useGMTTimeRadioButton; + private javax.swing.JRadioButton useLocalTimeRadioButton; + private javax.swing.JCheckBox viewsHideKnownCheckbox; + private javax.swing.JCheckBox viewsHideSlackCheckbox; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanelController.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanelController.java new file mode 100755 index 0000000000..40efcd0149 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanelController.java @@ -0,0 +1,149 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.corecomponents; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import javax.swing.JComponent; +import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.HelpCtx; +import org.openide.util.Lookup; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; +import java.util.logging.Level; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.coreutils.Logger; + +/** + * Controller for the main settings panel + */ +@OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_View", + iconBase = "org/sleuthkit/autopsy/images/view-preferences-32.png", + position = 2, + keywords = "#OptionsCategory_Keywords_View", + keywordsCategory = "View") +public final class ViewPreferencesPanelController extends OptionsPanelController { + + private ViewPreferencesPanel panel; + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + private boolean changed; + private static final Logger logger = Logger.getLogger(ViewPreferencesPanelController.class.getName()); + + @Override + public void update() { + getPanel().load(); + changed = false; + } + + @Override + public void applyChanges() { + getPanel().store(); + changed = false; + } + + @Override + public void cancel() { + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public boolean isChanged() { + return changed; + } + + @Override + public HelpCtx getHelpCtx() { + return null; + } + + @Override + public JComponent getComponent(Lookup masterLookup) { + return getPanel(); + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener l) { + if (pcs.getPropertyChangeListeners().length == 0) { + pcs.addPropertyChangeListener(l); + } + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener l) { + /** + * Note the NetBeans Framework does not appear to call this at all. We + * are using NetBeans 7.3.1 Build 201306052037. Perhaps in a future + * version of the Framework this will be resolved, but for now, simply + * don't unregister anything and add one time only in the + * addPropertyChangeListener() method above. + */ + } + + /** + * Retrieve an instance of the ViewPreferencesPanel. + * + * @return A ViewPreferencesPanel instance. + */ + private ViewPreferencesPanel getPanel() { + if (panel == null) { + panel = new ViewPreferencesPanel(); + panel.addPropertyChangeListener((PropertyChangeEvent evt) -> { + if (evt.getPropertyName().equals(OptionsPanelController.PROP_CHANGED)) { + changed(); + } + }); + } + return panel; + } + + /** + * Executed whenever a property change occurs. + */ + @Messages({"ViewOptionsController.moduleErr=Error processing value changes.", + "ViewOptionsController.moduleErr.msg=Value change processing failed."}) + void changed() { + if (!changed) { + changed = true; + + try { + pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); + } catch (Exception ex) { + logger.log(Level.SEVERE, "Error processing property change", ex); //NON-NLS + MessageNotifyUtil.Notify.show( + Bundle.ViewOptionsController_moduleErr(), + Bundle.ViewOptionsController_moduleErr_msg(), + MessageNotifyUtil.MessageType.ERROR); + } + } + + try { + pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); + } catch (Exception e) { + logger.log(Level.SEVERE, "Error processing property change validation.", e); //NON-NLS + MessageNotifyUtil.Notify.show( + Bundle.ViewOptionsController_moduleErr(), + Bundle.ViewOptionsController_moduleErr_msg(), + MessageNotifyUtil.MessageType.ERROR); + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java index 70f0ca3ce6..6fd17f6c4c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java @@ -24,10 +24,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import java.util.Objects; import java.util.logging.Level; import org.openide.nodes.ChildFactory; import org.openide.nodes.Node; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @@ -52,11 +54,17 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable list) { try { + Case currentCase = Case.getCurrentCaseThrows(); + CasePreferences casePreferences = new CasePreferences(currentCase); SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true)) { List dataSources = tskCase.getDataSources(); List keys = new ArrayList<>(); dataSources.forEach((datasource) -> { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java index 366aa12979..dc19f0ecb1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java @@ -26,6 +26,7 @@ import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; import java.util.List; +import java.util.Objects; import java.util.logging.Level; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; @@ -34,6 +35,7 @@ import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @@ -288,10 +290,11 @@ public class ExtractedContent implements AutopsyVisitableItem { @Override protected boolean createKeys(List list) { - //TEST COMMENT if (skCase != null) { try { - List types = (UserPreferences.groupItemsInTreeByDatasource()) ? + Case currentCase = Case.getCurrentCaseThrows(); + CasePreferences casePreferences = new CasePreferences(currentCase); + List types = Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true) ? blackboard.getArtifactTypesInUse(datasourceObjId) : skCase.getArtifactTypesInUse() ; @@ -313,6 +316,8 @@ public class ExtractedContent implements AutopsyVisitableItem { node.updateDisplayName(); } } + } catch (NoCurrentCaseException ex) { + Logger.getLogger(TypeFactory.class.getName()).log(Level.SEVERE, "No current case open: " + ex.getLocalizedMessage()); //NON-NLS } catch (TskCoreException ex) { Logger.getLogger(TypeFactory.class.getName()).log(Level.SEVERE, "Error getting list of artifacts in use: " + ex.getLocalizedMessage()); //NON-NLS } @@ -356,9 +361,14 @@ public class ExtractedContent implements AutopsyVisitableItem { // a performance increase might be had by adding a // "getBlackboardArtifactCount()" method to skCase try { - this.childCount = UserPreferences.groupItemsInTreeByDatasource() ? + Case currentCase = Case.getCurrentCaseThrows(); + CasePreferences casePreferences = new CasePreferences(currentCase); + this.childCount = Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true) ? blackboard.getArtifactsCount(type.getTypeID(), datasourceObjId) : skCase.getBlackboardArtifactsTypeCount(type.getTypeID()); + } catch (NoCurrentCaseException ex) { + Logger.getLogger(TypeNode.class.getName()) + .log(Level.WARNING, "No current case open.", ex); //NON-NLS } catch (TskException ex) { Logger.getLogger(TypeNode.class.getName()) .log(Level.WARNING, "Error getting child count", ex); //NON-NLS @@ -480,11 +490,15 @@ public class ExtractedContent implements AutopsyVisitableItem { protected boolean createKeys(List list) { if (skCase != null) { try { + Case currentCase = Case.getCurrentCaseThrows(); + CasePreferences casePreferences = new CasePreferences(currentCase); List arts = - UserPreferences.groupItemsInTreeByDatasource() ? + Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true) ? blackboard.getArtifacts(type.getTypeID(), datasourceObjId) : skCase.getBlackboardArtifacts(type.getTypeID()); list.addAll(arts); + } catch (NoCurrentCaseException ex) { + Logger.getLogger(ArtifactFactory.class.getName()).log(Level.SEVERE, "No current case open.", ex); //NON-NLS } catch (TskException ex) { Logger.getLogger(ArtifactFactory.class.getName()).log(Level.SEVERE, "Couldn't get blackboard artifacts from database", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 557e6582ca..ff34985bc7 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -57,6 +57,7 @@ import org.openide.util.NbBundle; import org.openide.util.Utilities; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; @@ -152,9 +153,17 @@ final public class Accounts implements AutopsyVisitableItem { * based on the UserPreferences groupItemsInTreeByDatasource setting */ private String getFilterByDataSourceClause() { - return (UserPreferences.groupItemsInTreeByDatasource()) ? - " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId + " " - : " "; + try { + Case currentCase = Case.getCurrentCaseThrows(); + CasePreferences casePreferences = new CasePreferences(currentCase); + if (Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true)) { + return " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId + " "; + } + } catch (NoCurrentCaseException ex) { + LOGGER.log(Level.SEVERE, "No current case open.", ex); //DLG: Review this change. How should we return out of this??? + } + + return " "; } /** @@ -164,6 +173,7 @@ final public class Accounts implements AutopsyVisitableItem { * @return An Action that will toggle whether rejected artifacts are shown * in the tree rooted by this Accounts instance. */ + //DLG: Remove this! public Action newToggleShowRejectedAction() { return new ToggleShowRejected(); } @@ -1686,6 +1696,7 @@ final public class Accounts implements AutopsyVisitableItem { } + //DLG: Remove this! private final class ToggleShowRejected extends AbstractAction { @NbBundle.Messages("ToggleShowRejected.name=Show Rejected Results") @@ -1699,6 +1710,16 @@ final public class Accounts implements AutopsyVisitableItem { reviewStatusBus.post(new ReviewStatusChangeEvent(Collections.emptySet(), null)); } } + + /** + * Update the user interface to show or hide rejected artifacts. + * + * @param showRejected Show rejected artifacts? Yes if true; otherwise no. + */ + public void setShowRejected(boolean showRejected) { + this.showRejected = showRejected; + reviewStatusBus.post(new ReviewStatusChangeEvent(Collections.emptySet(), null)); + } private abstract class ReviewStatusAction extends AbstractAction { diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties index b90711b8d9..10bd0622cb 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties @@ -59,7 +59,7 @@ DirectoryTreeFilterNode.action.collapseAll.text=Collapse All DirectoryTreeFilterNode.action.openFileSrcByAttr.text=Open File Search by Attributes DirectoryTreeFilterNode.action.runIngestMods.text=Run Ingest Modules DirectoryTreeTopComponent.action.viewArtContent.text=View Artifact Content -DirectoryTreeTopComponent.showRejectedCheckBox.text=Show Rejected Results +DirectoryTreeTopComponent.showRejectedCheckBox.text=Show Rejected ExplorerNodeActionVisitor.action.imgDetails.title=Image Details ExplorerNodeActionVisitor.action.extUnallocToSingleFiles=Extract Unallocated Space to Single Files ExplorerNodeActionVisitor.action.fileSystemDetails.title=File System Details @@ -119,10 +119,11 @@ AddExternalViewerRulePanel.browseButton.text=Browse AddExternalViewerRulePanel.exePathTextField.text= AddExternalViewerRulePanel.exePathLabel.text=Path of the program to use for files with this type or extension AddExternalViewerRulePanel.extRadioButton.text=Extension -DirectoryTreeTopComponent.groupByDatasourceCheckBox.text=Group by Data Source +DirectoryTreeTopComponent.groupByDatasourceCheckBox.text=Group Data Source GroupDataSourcesDialog.dataSourceCountLabel.text=jLabel1 GroupDataSourcesDialog.queryLabel.text=Would you like to group by data source for faster loading? GroupDataSourcesDialog.yesButton.text=Yes GroupDataSourcesDialog.noButton.text=No GroupDataSourcesDialog.title=Group by Data Source? -DirectoryTreeTopComponent.showOnlyCurrentUserTagsCheckbox.text=Hide Other User's Tags +DirectoryTreeTopComponent.showOnlyCurrentUserTagsCheckbox.text=Hide Other Tags +DirectoryTreeTopComponent.openViewPreferencesButton.text= diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form index 8fa8265e06..bacd1d8903 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form @@ -18,44 +18,44 @@ - - - - - - + - - + + + + + + + + + + + + + + - + + - - - - - - - - - - - - - - - - + + + + + + + + + - - + @@ -139,12 +139,36 @@
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 17cac06732..880ebce710 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -60,7 +60,9 @@ import org.openide.util.NbBundle.Messages; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.corecomponents.ViewPreferencesDialog; import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl; @@ -111,6 +113,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat private static final Logger LOGGER = Logger.getLogger(DirectoryTreeTopComponent.class.getName()); private AutopsyTreeChildFactory autopsyTreeChildFactory; private Children autopsyTreeChildren; + private Accounts accounts; private static final long DEFAULT_DATASOURCE_GROUPING_THRESHOLD = 5; // Threshold for prompting the user about grouping by data source private static final String GROUPING_THRESHOLD_NAME = "GroupDataSourceThreshold"; private static final String SETTINGS_FILE = "CasePreferences.properties"; //NON-NLS @@ -151,7 +154,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat switch (evt.getKey()) { case UserPreferences.HIDE_KNOWN_FILES_IN_DATA_SRCS_TREE: case UserPreferences.HIDE_SLACK_FILES_IN_DATA_SRCS_TREE: - case UserPreferences.GROUP_ITEMS_IN_TREE_BY_DATASOURCE: + //DLG: case UserPreferences.GROUP_ITEMS_IN_TREE_BY_DATASOURCE: refreshContentTreeSafe(); break; case UserPreferences.SHOW_ONLY_CURRENT_USER_TAGS: @@ -194,6 +197,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat treeView = new BeanTreeView(); backButton = new javax.swing.JButton(); forwardButton = new javax.swing.JButton(); + openViewPreferencesButton = new javax.swing.JButton(); showRejectedCheckBox = new javax.swing.JCheckBox(); groupByDatasourceCheckBox = new javax.swing.JCheckBox(); showOnlyCurrentUserTagsCheckbox = new javax.swing.JCheckBox(); @@ -232,7 +236,22 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat } }); + openViewPreferencesButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/view-preferences-24.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(openViewPreferencesButton, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.openViewPreferencesButton.text")); // NOI18N + openViewPreferencesButton.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED)); + openViewPreferencesButton.setPreferredSize(new java.awt.Dimension(30, 30)); + openViewPreferencesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + openViewPreferencesButtonActionPerformed(evt); + } + }); + org.openide.awt.Mnemonics.setLocalizedText(showRejectedCheckBox, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.showRejectedCheckBox.text")); // NOI18N + showRejectedCheckBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + showRejectedCheckBoxActionPerformed(evt); + } + }); org.openide.awt.Mnemonics.setLocalizedText(groupByDatasourceCheckBox, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.groupByDatasourceCheckBox.text")); // NOI18N groupByDatasourceCheckBox.addActionListener(new java.awt.event.ActionListener() { @@ -254,36 +273,37 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(treeView) .addGroup(layout.createSequentialGroup() - .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(showOnlyCurrentUserTagsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(1, 1, 1) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(showRejectedCheckBox) - .addComponent(groupByDatasourceCheckBox)) - .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addComponent(showOnlyCurrentUserTagsCheckbox) + .addGap(18, 18, 18) + .addComponent(showRejectedCheckBox) + .addGap(18, 18, 18) + .addComponent(groupByDatasourceCheckBox)) + .addGroup(layout.createSequentialGroup() + .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(254, 254, 254) + .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() + .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(5, 5, 5) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(showRejectedCheckBox) - .addComponent(showOnlyCurrentUserTagsCheckbox)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(groupByDatasourceCheckBox)) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(forwardButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(9, 9, 9) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(showOnlyCurrentUserTagsCheckbox) + .addComponent(showRejectedCheckBox) + .addComponent(groupByDatasourceCheckBox)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(treeView, javax.swing.GroupLayout.DEFAULT_SIZE, 843, Short.MAX_VALUE) - .addGap(0, 0, 0)) + .addComponent(treeView, javax.swing.GroupLayout.DEFAULT_SIZE, 870, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -337,17 +357,27 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat }//GEN-LAST:event_forwardButtonActionPerformed private void groupByDatasourceCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_groupByDatasourceCheckBoxActionPerformed - UserPreferences.setGroupItemsInTreeByDatasource(this.groupByDatasourceCheckBox.isSelected()); + UserPreferences.setGroupItemsInTreeByDatasource(this.groupByDatasourceCheckBox.isSelected()); //DLG: Remove this checkbox }//GEN-LAST:event_groupByDatasourceCheckBoxActionPerformed private void showOnlyCurrentUserTagsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showOnlyCurrentUserTagsCheckboxActionPerformed - UserPreferences.setShowOnlyCurrentUserTags(this.showOnlyCurrentUserTagsCheckbox.isSelected()); + UserPreferences.setShowOnlyCurrentUserTags(this.showOnlyCurrentUserTagsCheckbox.isSelected()); //DLG: Remove this checkbox }//GEN-LAST:event_showOnlyCurrentUserTagsCheckboxActionPerformed + private void showRejectedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showRejectedCheckBoxActionPerformed + //DLG: Remove this checkbox + }//GEN-LAST:event_showRejectedCheckBoxActionPerformed + + private void openViewPreferencesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openViewPreferencesButtonActionPerformed + ViewPreferencesDialog dialog = new ViewPreferencesDialog(); + dialog.display(); + }//GEN-LAST:event_openViewPreferencesButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton backButton; private javax.swing.JButton forwardButton; private javax.swing.JCheckBox groupByDatasourceCheckBox; + private javax.swing.JButton openViewPreferencesButton; private javax.swing.JCheckBox showOnlyCurrentUserTagsCheckbox; private javax.swing.JCheckBox showRejectedCheckBox; private javax.swing.JScrollPane treeView; @@ -410,40 +440,20 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat * @param dataSourceCount */ private void promptForDataSourceGrouping(Case currentCase, int dataSourceCount) { - Path settingsFile = Paths.get(currentCase.getConfigDirectory(), SETTINGS_FILE); //NON-NLS - if (settingsFile.toFile().exists()) { - // Read the setting - try (InputStream inputStream = Files.newInputStream(settingsFile)) { - Properties props = new Properties(); - props.load(inputStream); - if (props.getProperty("groupByDataSource", "false").equals("true")) { - UserPreferences.setGroupItemsInTreeByDatasource(true); - groupByDatasourceCheckBox.setSelected(true); - } - } catch (IOException ex) { - LOGGER.log(Level.SEVERE, "Error reading settings file", ex); - } - } else { + CasePreferences casePreferences = new CasePreferences(currentCase); + + if (casePreferences.getGroupItemsInTreeByDataSource() == null) { GroupDataSourcesDialog dialog = new GroupDataSourcesDialog(dataSourceCount); dialog.display(); if (dialog.groupByDataSourceSelected()) { - UserPreferences.setGroupItemsInTreeByDatasource(true); - groupByDatasourceCheckBox.setSelected(true); + casePreferences.setGroupItemsInTreeByDataSource(true); + refreshContentTreeSafe(); //DLG: Consider an event. + } else { + casePreferences.setGroupItemsInTreeByDataSource(false); } // Save the response - Properties props = new Properties(); - if (dialog.groupByDataSourceSelected()) { - props.setProperty("groupByDataSource", "true"); - } else { - props.setProperty("groupByDataSource", "false"); - } - - try (OutputStream fos = Files.newOutputStream(settingsFile)) { - props.store(fos, ""); //NON-NLS - } catch (IOException ex) { - LOGGER.log(Level.SEVERE, "Error writing settings file", ex); - } + casePreferences.saveToStorage(currentCase); } } @@ -545,7 +555,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat Children resultsChildren = results.getChildren(); Arrays.stream(resultsChildren.getNodes()).forEach(tree::expandNode); - Accounts accounts = resultsChildren.findChild(Accounts.NAME).getLookup().lookup(Accounts.class); + accounts = resultsChildren.findChild(Accounts.NAME).getLookup().lookup(Accounts.class); if (!Objects.isNull(accounts)) { showRejectedCheckBox.setAction(accounts.newToggleShowRejectedAction()); showRejectedCheckBox.setSelected(false); diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExternalViewerOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExternalViewerOptionsPanelController.java index 35523a65dc..bbbac25bdd 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExternalViewerOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExternalViewerOptionsPanelController.java @@ -34,7 +34,7 @@ import org.openide.util.Lookup; iconBase = "org/sleuthkit/autopsy/directorytree/external-viewer-rules-32x32.png", keywords = "#OptionsCategory_Keywords_ExternalViewer", keywordsCategory = "ExternalViewer", - position = 12 + position = 13 ) public final class ExternalViewerOptionsPanelController extends OptionsPanelController { diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index f4da3a3edf..585241c4f8 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,7 @@ import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; @@ -138,15 +139,24 @@ public class ViewContextAction extends AbstractAction { */ DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance(); ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager(); + Case currentCase; + try { + currentCase = Case.getCurrentCaseThrows(); + } catch (NoCurrentCaseException ex) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); + logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS + return; + } Node parentTreeViewNode; - if (UserPreferences.groupItemsInTreeByDatasource()) { // 'Group by Data Source' view + CasePreferences casePreferences = new CasePreferences(currentCase); + if (Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true)) { // 'Group by Data Source' view SleuthkitCase skCase; String dsname; try { // get the objid/name of the datasource of the selected content. - skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + skCase = currentCase.getSleuthkitCase(); long contentDSObjid = content.getDataSource().getId(); DataSource datasource = skCase.getDataSource(contentDSObjid); dsname = datasource.getName(); @@ -162,7 +172,7 @@ public class ViewContextAction extends AbstractAction { logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS return; } - } catch (NoCurrentCaseException| TskDataException | TskCoreException ex) { + } catch (TskDataException | TskCoreException ex) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS return; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/view-preferences-24.png b/Core/src/org/sleuthkit/autopsy/directorytree/view-preferences-24.png new file mode 100755 index 0000000000000000000000000000000000000000..b18a37372d7c1061c0aa69297bbb3709e064881a GIT binary patch literal 2039 zcmbVN4Qvx-81BFc45mRbDnq>-!5_l)e%kBLg$_qM=+KV34z>vhU+=zakG6NWyW7?+ z1Oq5U!-9c1BOwHl7;%XFY-l2chyeuooiZ`#20>t;GG-!(sQ6vm)ybd4CfDz~?|Z)Y zectDNzxQ4XmQK#k8<}UZSn^B!zA`jEVm^cKLH|?c|Ei;5i0ZFGXpVAm42@-eIP#_mB3I^{l<|e$Jb2VF zRE{L;>gud@HmjmVNZRdolN3WT41o}YUN0LUNyz%>J_|mm^O~d@k|JZKMG#hM3=fW& zrb9@mS+la9kqHS#CV@)QR>}-11r+!!POZ`6Ddz%D!Z=Jo+0YS|&SKT5Vkml4xsB=U z_P-n;X#;_*k6Us{B(g4aqqr7@krCvUXuZ5%g=87jl^TtQ#kGj$Xfqm>^J)+nidL>D z@xDX_`zT{xubCJZ_H+R7l5EEDOutjm2Mp-JO$0%?3CdYcvm9&VXd6MY%-8!6ycZ@(?EbLk#z&eJS_2fa3qdZk^~Mod6BX~H{s&lcEWCFXu=Id z2jOr+)&`vvEArvK^FD>IF-yQapS}%(!Xq31Fk@+l+u>vd!e*xh!r`(zh%jq&5Hy1p z0Yi(7Ev*}3GgXt&g#_{bR!vp{vgl+1aD|;T!P*3tu-hmX;c^3pa6(aVA`uxI1I@Be zRTAfybd=-z%tZ>p>dY)IVX5Nb0B>Fj56+v_00lg=EZstnyYielUl)bQ=p70q?Oj(y zqYh}WD1x-RyDB7a7l96H@67-1@|h-fGyfZ^_J8xw2*gK$9D%6UlDHWWX?CS_ddM3y zm)h&s!TR8+Et=D8KSnRvjt*sHT0{N%{MlU{7E8|B5?@idtFf_tb1d}2h`qg2!$q4m zitjg-E?m#A$>}Ov7#mvp7*iGhaqR2Ii$)!*3=aCNy?y#S*Prbk_t3nFuPl{DJoVOe z=Ho@7QQGXz*e`FaKHu4O^{+#oE1jWF663^q6%!Ay>gx4xaUE(IyI}c+B*Sj_mKrkF z`{972$GQWp&Hh)9w1>zen&^V}9Y;Qj}^yGK`o=XRg z1}~o2GG~8N?u_5PJ5JZnb+r}zz_Ts)t#Vb*nRc-Hi=TE!)-N~{+;Q>J%z`BsPBrC# zT}wZhl6?E;;iGy%Ya;hd_nX@~e7_wlvg_oD)&Z;6R2(?js^?d=H91FKZ(RG5Sg{Xo znfp=n(DF>!GC*&<6I+WS*P6zq_Sz$5-1A=XLMdx~Tcy%>(l;A6$0wTHd4hu&#B@ zGjh(K==gfl?zPu)&iUEGz_5bH&(ywL*tzHa70vT!S=Fozd1^Jy%-y bthjDTPLl>N>S$VLews^)OMM$B&RO_3x-!sL literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/images/view-preferences-32.png b/Core/src/org/sleuthkit/autopsy/images/view-preferences-32.png new file mode 100755 index 0000000000000000000000000000000000000000..45611a8d65080cf6686ce0c7f0b6b54e46b38820 GIT binary patch literal 873 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5m^kh={g8AI%&+V01C2~c>21sKjP#PX5na5I;0HLWbWzW7~*k!X{ckiu%krn{T#i$ zAzmNSs)O~TQj{}yb+({`xJnL?T++|4#?y4n*9y7zv-ts>7ck)uvxT=b4+RN8o53@~mTQb4uX7m}xf|qjf zN372E{*^tCxI$&jmGd?SEo$)6q0Q9m>{yj}U^fXwZ%><`IWl^ze5Pv|)=6`=i> zclRDSYo=eEUJu01XGNzUcdkTiicR8^19;&zduD<-XuxhIpQn z;d5&u_(H1v=7k+(P5Y$O%9t3d6L`_G!|Rsif<<>8@3Y`#^xk}o>Cz3Mou9p5y?f~L zV)B}!Z1?!@L`{#>@8O#j#JA_l$;K@H-9kAFGfUpcwpnX+%KPrJj*~x_oqSegc7}mm zs>MSI;}_~`7mqLQIrWOk*JQzI!T_RfKl z$DvQtELwkRJ`H*(T@kru`K0Z8*CZ9(_+Yf}sDI3HwW#DtVrDO;V&d(7MY1(yEr+qAXP8F VD1G)j8!4b722WQ%mvv4FO#pW5S`z>O literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestOptionsPanelController.java index 69c88d63c4..056f93d719 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestOptionsPanelController.java @@ -30,7 +30,7 @@ import org.openide.util.Lookup; @OptionsPanelController.TopLevelRegistration( categoryName = "#OptionsCategory_Name_IngestOptions", iconBase = "org/sleuthkit/autopsy/images/file_ingest_filter32x32.png", - position = 2, + position = 3, keywords = "#OptionsCategory_Keywords_IngestOptions", keywordsCategory = "IngestOptions") diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchOptionsPanelController.java index e15ea5a6e9..042c49ed3b 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchOptionsPanelController.java @@ -30,7 +30,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; @OptionsPanelController.TopLevelRegistration( categoryName = "#OptionsCategory_Name_FileExtMismatchOptions", iconBase = "org/sleuthkit/autopsy/modules/fileextmismatch/options-icon.png", - position = 8, + position = 9, keywords = "#OptionsCategory_FileExtMismatch", keywordsCategory = "KeywordSearchOptions") public final class FileExtMismatchOptionsPanelController extends OptionsPanelController { diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdOptionsPanelController.java index 08979c124e..e724a74856 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdOptionsPanelController.java @@ -31,7 +31,7 @@ import org.openide.util.Lookup; iconBase = "org/sleuthkit/autopsy/modules/filetypeid/user-defined-file-types-settings.png", keywords = "#OptionsCategory_Keywords_FileTypeId", keywordsCategory = "FileTypeId", - position = 9 + position = 10 ) public final class FileTypeIdOptionsPanelController extends OptionsPanelController { diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDatabaseOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDatabaseOptionsPanelController.java index a4d85eef9b..41de451c67 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDatabaseOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDatabaseOptionsPanelController.java @@ -30,7 +30,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; @OptionsPanelController.TopLevelRegistration( categoryName = "#OptionsCategory_Name_HashDatabase", iconBase = "org/sleuthkit/autopsy/modules/hashdatabase/options_icon.png", - position = 7, + position = 8, keywords = "#OptionsCategory_Keywords_HashDatabase", keywordsCategory = "HashDatabase", id = "HashDatabase") diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsOptionsPanelController.java index 7087b6c013..6d239ae78d 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsOptionsPanelController.java @@ -32,7 +32,7 @@ import org.openide.util.Lookup; iconBase = "org/sleuthkit/autopsy/images/interesting_item_32x32.png", keywords = "#OptionsCategory_Keywords_InterestingItemDefinitions", keywordsCategory = "InterestingItemDefinitions", - position = 10 + position = 11 ) public final class InterestingItemDefsOptionsPanelController extends OptionsPanelController { diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanelController.java b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanelController.java index 50e2e18e4c..c616403ce6 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanelController.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanelController.java @@ -31,7 +31,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; @OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_Auto_Ingest", iconBase = "org/sleuthkit/autopsy/experimental/images/autoIngest32.png", - position = 4, + position = 5, keywords = "#OptionsCategory_Keywords_Auto_Ingest_Settings", keywordsCategory = "Auto Ingest") public final class AutoIngestSettingsPanelController extends OptionsPanelController { diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/SharedConfiguration.java b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/SharedConfiguration.java index 106e521142..f9dba08034 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/SharedConfiguration.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/SharedConfiguration.java @@ -102,7 +102,6 @@ public class SharedConfiguration { private boolean hideKnownFilesInViews; private boolean hideSlackFilesInDataSource; private boolean hideSlackFilesInViews; - private boolean groupDatasources; private boolean keepPreferredViewer; /** @@ -353,7 +352,6 @@ public class SharedConfiguration { fileIngestThreads = UserPreferences.numberOfFileIngestThreads(); hideSlackFilesInDataSource = UserPreferences.hideSlackFilesInDataSourcesTree(); hideSlackFilesInViews = UserPreferences.hideSlackFilesInViewsTree(); - groupDatasources = UserPreferences.groupItemsInTreeByDatasource(); } /** @@ -369,8 +367,7 @@ public class SharedConfiguration { UserPreferences.setKeepPreferredContentViewer(keepPreferredViewer); UserPreferences.setNumberOfFileIngestThreads(fileIngestThreads); UserPreferences.setHideSlackFilesInDataSourcesTree(hideSlackFilesInDataSource); - UserPreferences.setHideSlackFilesInViewsTree(hideSlackFilesInViews); - UserPreferences.setGroupItemsInTreeByDatasource(groupDatasources); + UserPreferences.setHideSlackFilesInViewsTree(hideSlackFilesInViews); } /** diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java index 0ffcaf194c..af91181287 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java @@ -34,7 +34,7 @@ import org.openide.util.Lookup; iconBase = "org/sleuthkit/autopsy/imagegallery/images/btn_icon_image_gallery_32.png", keywords = "#OptionsCategory_Keywords_Options", keywordsCategory = "Options", - position = 14 + position = 15 ) @org.openide.util.NbBundle.Messages({"OptionsCategory_Name_Options=Image / Video Gallery", "OptionsCategory_Keywords_Options=image video gallery category "}) public final class ImageGalleryOptionsPanelController extends OptionsPanelController { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchOptionsPanelController.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchOptionsPanelController.java index 91f5b504d4..40c7c2d938 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchOptionsPanelController.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchOptionsPanelController.java @@ -30,7 +30,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; @OptionsPanelController.TopLevelRegistration( categoryName = "#OptionsCategory_Name_KeywordSearchOptions", iconBase = "org/sleuthkit/autopsy/keywordsearch/options-icon.png", - position = 5, + position = 6, keywords = "#OptionsCategory_Keywords_KeywordSearchOptions", keywordsCategory = "KeywordSearchOptions") public final class KeywordSearchOptionsPanelController extends OptionsPanelController { From 4542b6de041125cdcb58a2a264f029ead2c3fafd Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 12 Sep 2018 15:11:47 -0400 Subject: [PATCH 021/273] Added a getColumnsFromTable method to all reader classes --- .../tabulardatareader/AbstractReader.java | 8 ++++ .../tabulardatareader/ExcelReader.java | 37 +++++++++++++++ .../tabulardatareader/SQLiteReader.java | 47 ++++++++++++++++++- 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java index cb74819142..fd88f4a45d 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java @@ -88,6 +88,14 @@ public abstract class AbstractReader implements AutoCloseable { */ public abstract List> getRowsFromTable(String tableName) throws FileReaderException; + /** + * + * @param tableName + * @return + * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException + */ + public abstract Map> getColumnsFromTable(String tableName) throws FileReaderException; + /** * Returns a window of rows starting at the offset and ending when the number of rows read * equals the 'numRowsToRead' parameter or there is nothing left to read. diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java index cf3ba49388..064724e451 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java @@ -157,6 +157,43 @@ public final class ExcelReader extends AbstractReader { return rowList; } + + /** + * + * @param tableName + * @return + * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException + */ + @Override + public Map> getColumnsFromTable(String tableName) throws FileReaderException { + Map> columnViewOfSheet = new HashMap<>(); + + Iterator sheetIter = workbook.getSheet(tableName).rowIterator(); + if (headerCache.containsKey(tableName)) { + Row header = headerCache.get(tableName); + for(Cell cell : header) { + String index = String.valueOf(cell.getColumnIndex()); + columnViewOfSheet.put(index, new ArrayList(){{ + add(getCellValue(cell)); + }}); + } + } + + while(sheetIter.hasNext()) { + Row r = sheetIter.next(); + for(Cell cell : r) { + String index = String.valueOf(cell.getColumnIndex()); + if(columnViewOfSheet.containsKey(index)) { + columnViewOfSheet.get(index).add(getCellValue(cell)); + } else { + columnViewOfSheet.put(index, new ArrayList(){{ + add(getCellValue(cell)); + }}); + } + } + } + return columnViewOfSheet; + } /** * Currently not supported. Returns a window of rows starting at the offset diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java index c08f571280..d30116be86 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java @@ -27,11 +27,14 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.logging.Level; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -272,8 +275,50 @@ public final class SQLiteReader extends AbstractReader { return rowMap; } - + /** + * + * @param tableName + * @return + * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException + */ + public Map> getColumnsFromTable(String tableName) + throws FileReaderException { + + String quotedTableName = wrapTableNameStringWithQuotes(tableName); + try(Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery( + "SELECT * FROM " + quotedTableName)) { //NON-NLS + + Map> columnView = new HashMap<>(); + ResultSetMetaData metaData = resultSet.getMetaData(); + int columns = metaData.getColumnCount(); + for(int i = 1; i <= columns; i++) { + columnView.put(metaData.getColumnName(i), new LinkedList<>()); + } + + while (resultSet.next()) { + for(int i = 1; i <= columns; i++) { + if (resultSet.getObject(i) == null) { + columnView.get(metaData.getColumnName(i)).add(""); + } else { + if (metaData.getColumnTypeName(i).compareToIgnoreCase("blob") == 0) { + columnView.get(metaData.getColumnName(i)).add( + Bundle.SQLiteReader_BlobNotShown_message()); + } else { + columnView.get(metaData.getColumnName(i)).add( + resultSet.getObject(i)); + } + } + } + } + + return columnView; + } catch (SQLException ex) { + throw new FileReaderException(ex); + } + } + /** * Closes underlying JDBC connection. */ From 5fb00a04b16da8f2625c4349a9f642aca68c3982 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 12 Sep 2018 15:12:23 -0400 Subject: [PATCH 022/273] Added comments --- .../sleuthkit/autopsy/tabulardatareader/AbstractReader.java | 3 ++- .../org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java | 1 + .../org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java index fd88f4a45d..f37bcf08ab 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java @@ -89,9 +89,10 @@ public abstract class AbstractReader implements AutoCloseable { public abstract List> getRowsFromTable(String tableName) throws FileReaderException; /** + * Returns a map of column names to a list of column values. * * @param tableName - * @return + * @return A map of column names to a list of column values * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException */ public abstract Map> getColumnsFromTable(String tableName) throws FileReaderException; diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java index 064724e451..0515539009 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/ExcelReader.java @@ -159,6 +159,7 @@ public final class ExcelReader extends AbstractReader { } /** + * Returns a map of column numbers to a list of column values. * * @param tableName * @return diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java index d30116be86..cb67bdacc1 100755 --- a/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java +++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/SQLiteReader.java @@ -34,7 +34,6 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.logging.Level; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -277,11 +276,14 @@ public final class SQLiteReader extends AbstractReader { } /** + * Returns a column view of the table. Maps the column name to a list of that + * column's values. * * @param tableName * @return * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException */ + @Override public Map> getColumnsFromTable(String tableName) throws FileReaderException { From 91d08d5565c632cfe3e855fb0014a47b328ec7ee Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 12 Sep 2018 15:55:57 -0400 Subject: [PATCH 023/273] 4167 replace GUI common attribute search gui --- .../commonfilesearch/Bundle.properties | 51 ++- .../CommonAttributePanel.form | 253 +++-------- .../CommonAttributePanel.java | 393 ++++++------------ .../CommonAttributeSearchAction.java | 40 +- .../commonfilesearch/InterCasePanel.form | 172 ++++++-- .../commonfilesearch/InterCasePanel.java | 300 ++++++++----- .../commonfilesearch/IntraCasePanel.form | 152 +++++-- .../commonfilesearch/IntraCasePanel.java | 232 +++++++---- 8 files changed, 847 insertions(+), 746 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index fb0e22ba54..035e165ae4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -1,37 +1,42 @@ CommonFilesPanel.commonFilesSearchLabel.text=Find files in multiple data sources in the current case. CommonFilesPanel.text=Indicate which data sources to consider while searching for duplicates: CommonFilesPanel.jRadioButton1.text=jRadioButton1 -CommonFilesPanel.jRadioButton2.text=With previous cases in the Central Repository +CommonFilesPanel.jRadioButton2.text=Between current case and cases in Central Repository CommonFilesPanel.intraCaseRadio.label=Correlate within current case only CommonFilesPanel.interCaseRadio.label=Correlate amongst all known cases (uses Central Repo) -IntraCasePanel.allDataSourcesRadioButton.text=Matches may be from any data source -IntraCasePanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below: IntraCasePanel.selectDataSourceComboBox.actionCommand= -InterCasePanel.specificCentralRepoCaseRadio.text=Matches must be from the following Central Repo case: -InterCasePanel.anyCentralRepoCaseRadio.text=Matches may be from any Central Repo case CommonAttributePanel.jCheckBox1.text=Hide files found in over CommonAttributePanel.jLabel1.text=% of data sources in central repository. -CommonAttributePanel.percentageThresholdTextTwo.text_1=% of data sources in central repository. -CommonAttributePanel.percentageThresholdTextOne.text=20 CommonAttributePanel.percentageThresholdCheck.text_1=Hide files found in over -CommonAttributePanel.intraCaseRadio.text=Within current case -CommonAttributePanel.commonFilesSearchLabel1.text=Find common files to correlate data soures or cases. -CommonAttributePanel.errorText.text=In order to search, you must select a file category. -CommonAttributePanel.categoriesLabel.text=File Types To Include: -CommonAttributePanel.documentsCheckbox.text=Documents -CommonAttributePanel.pictureVideoCheckbox.text=Pictures and Videos -CommonAttributePanel.selectedFileCategoriesButton.toolTipText=Select from the options below... -CommonAttributePanel.selectedFileCategoriesButton.text=Only the selected file types: -CommonAttributePanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results... -CommonAttributePanel.allFileCategoriesRadioButton.text=All file types -CommonAttributePanel.cancelButton.actionCommand=Cancel -CommonAttributePanel.cancelButton.text=Cancel -CommonAttributePanel.searchButton.text=Search CommonAttributePanel.jCheckBox1.text=Hide files found in over CommonAttributePanel.jLabel1.text=% of data sources in central repository. CommonAttributePanel.percentageThreshold.text=20 CommonAttributePanel.jLabel1.text_1=% of data sources in central repository. -CommonAttributePanel.percentageThresholdCheck.text_1=Hide files found in over -InterCasePanel.comboBoxLabel.text=Select correlation type to search: InterCasePanel.correlationTypeComboBox.toolTipText=Selected Correlation Type -CommonAttributePanel.commonFilesSearchLabel2.text=Scope of Search +IntraCasePanel.selectedFileCategoriesButton.text=Only the selected file types: +IntraCasePanel.categoriesLabel.text=File Types To Show: +IntraCasePanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results... +IntraCasePanel.allFileCategoriesRadioButton.text=All file types +IntraCasePanel.documentsCheckbox.text=Documents +IntraCasePanel.pictureVideoCheckbox.text=Pictures and Videos +IntraCasePanel.selectedFileCategoriesButton.toolTipText=Select from the options below... +CommonAttributePanel.percentageThresholdTextTwo.text_1=% of data sources in central repository. +CommonAttributePanel.percentageThresholdTextOne.text=20 +CommonAttributePanel.percentageThresholdCheck.text_1_1=Hide files found in over +CommonAttributePanel.intraCaseRadio.text=Between data sources in current case +CommonAttributePanel.errorText.text=In order to search, you must select a file category. +CommonAttributePanel.searchButton.text=Search +InterCasePanel.categoriesLabel.text=File Types To Show: +InterCasePanel.documentsCheckbox.text=Documents +InterCasePanel.pictureVideoCheckbox.text=Pictures and Videos +InterCasePanel.selectedFileCategoriesButton.toolTipText=Select from the options below... +InterCasePanel.selectedFileCategoriesButton.text=Only the selected file types: +InterCasePanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results... +InterCasePanel.allFileCategoriesRadioButton.text=All file types +InterCasePanel.specificCentralRepoCaseCheckbox.text=Only specific case in Central Repository +IntraCasePanel.onlySpecificDataSourceCheckbox.text=Only specific data source in current case +CommonAttributePanel.interCasePanel.border.title=Central Repository Options +CommonAttributePanel.intraCasePanel.border.title=Current Case Options +CommonAttributePanel.commonItemSearchDescription.text=Find items that exist in multipel data sources or cases +CommonAttributePanel.scopeLabel.text=Scope of Search +InterCasePanel.correlationComboBoxLabel.text=Select correlation type to search: diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form index ff9799dc7d..834b42a763 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form @@ -2,15 +2,10 @@
- - - - - @@ -32,7 +27,7 @@ - + @@ -40,13 +35,13 @@ - + - + - + @@ -59,55 +54,44 @@ - + + + - + + + - - - - - - - - - + + + + + + + - - - - - - - + + - - - - + + + + - - - - - - - - - - - + + + - + @@ -117,42 +101,27 @@ - - - + + + - - - - - - - - - - - + + + - - - - - - - - - - - + + + + @@ -160,10 +129,10 @@ - + - + @@ -180,85 +149,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -270,10 +160,10 @@ - + - + @@ -305,30 +195,10 @@ - - - - - - - - - - - - - - - - - - - - - + @@ -337,6 +207,7 @@ + @@ -358,25 +229,39 @@ - + - - + + + + + + + + + + + + - - - - + - - + + + + + + + + + + + + - - - diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index c4027d74cf..fc4ce620ba 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -25,6 +25,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Observable; +import java.util.Observer; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JFrame; @@ -56,7 +58,7 @@ import org.sleuthkit.datamodel.TskCoreException; * logic. Nested within CommonFilesDialog. */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives -public final class CommonAttributePanel extends javax.swing.JDialog { +final class CommonAttributePanel extends javax.swing.JDialog implements Observer { private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName()); private static final long serialVersionUID = 1L; @@ -65,10 +67,6 @@ public final class CommonAttributePanel extends javax.swing.JDialog { private final UserInputErrorManager errorManager; - private boolean pictureViewCheckboxState; - - private boolean documentsCheckboxState; - private int percentageThresholdValue = 20; /** @@ -78,15 +76,16 @@ public final class CommonAttributePanel extends javax.swing.JDialog { "CommonAttributePanel.title=Common Attribute Panel", "CommonAttributePanel.exception=Unexpected Exception loading DataSources.", "CommonAttributePanel.frame.title=Find Common Attributes", - "CommonAttributePanel.frame.msg=Find Common Attributes"}) - public CommonAttributePanel() { + "CommonAttributePanel.frame.msg=Find Common Attributes", + "CommonAttributePanel.intraCasePanel.title=Curren Case Options"}) + CommonAttributePanel() { super(new JFrame(Bundle.CommonAttributePanel_frame_title()), Bundle.CommonAttributePanel_frame_msg(), true); initComponents(); - this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); this.setupDataSources(); - + intraCasePanel.setVisible(true); + interCasePanel.setVisible(false); if (CommonAttributePanel.isEamDbAvailableForIntercaseSearch()) { this.setupCases(); this.interCasePanel.setupCorrelationTypeFilter(); @@ -94,16 +93,12 @@ public final class CommonAttributePanel extends javax.swing.JDialog { this.disableIntercaseSearch(); } - if (CommonAttributePanel.isEamDbAvailableForPercentageFrequencyCalculations()) { - this.enablePercentageOptions(); - } else { - this.disablePercentageOptions(); - } + this.enablePercentageOptions(CommonAttributePanel.isEamDbAvailableForPercentageFrequencyCalculations()); this.errorManager = new UserInputErrorManager(); - - this.percentageThresholdTextOne.getDocument().addDocumentListener(new DocumentListener(){ - + + this.percentageThresholdTextOne.getDocument().addDocumentListener(new DocumentListener() { + private Dimension preferredSize = CommonAttributePanel.this.percentageThresholdTextOne.getPreferredSize(); private void maintainSize() { @@ -130,7 +125,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog { }); } - private static boolean isEamDbAvailableForIntercaseSearch() { + static boolean isEamDbAvailableForIntercaseSearch() { try { return EamDb.isEnabled() && EamDb.getInstance() != null @@ -144,7 +139,12 @@ public final class CommonAttributePanel extends javax.swing.JDialog { return false; } - private static boolean isEamDbAvailableForPercentageFrequencyCalculations() { + @Override + public void update(Observable o, Object arg) { + checkFileTypeCheckBoxState(); + } + + static boolean isEamDbAvailableForPercentageFrequencyCalculations() { try { return EamDb.isEnabled() && EamDb.getInstance() != null @@ -191,7 +191,6 @@ public final class CommonAttributePanel extends javax.swing.JDialog { } @Override - @SuppressWarnings({"BoxedValueEquality", "NumberEquality"}) protected CommonAttributeSearchResults doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { progress = ProgressHandle.createHandle(Bundle.CommonAttributePanel_search_done_searchProgressGathering()); progress.start(); @@ -205,14 +204,6 @@ public final class CommonAttributePanel extends javax.swing.JDialog { boolean filterByMedia = false; boolean filterByDocuments = false; - if (selectedFileCategoriesButton.isSelected()) { - if (pictureVideoCheckbox.isSelected()) { - filterByMedia = true; - } - if (documentsCheckbox.isSelected()) { - filterByDocuments = true; - } - } int percentageThreshold = CommonAttributePanel.this.percentageThresholdValue; @@ -223,6 +214,10 @@ public final class CommonAttributePanel extends javax.swing.JDialog { if (CommonAttributePanel.this.interCaseRadio.isSelected()) { CorrelationAttributeInstance.Type corType = interCasePanel.getSelectedCorrelationType(); + if (interCasePanel.fileCategoriesButtonIsSelected()) { + filterByMedia = interCasePanel.pictureVideoCheckboxIsSelected(); + filterByDocuments = interCasePanel.documentsCheckboxIsSelected(); + } if (corType == null) { corType = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(0); } @@ -232,7 +227,12 @@ public final class CommonAttributePanel extends javax.swing.JDialog { builder = new SingleInterCaseCommonAttributeSearcher(caseId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, corType, percentageThreshold); } + } else { + if (intraCasePanel.fileCategoriesButtonIsSelected()) { + filterByMedia = intraCasePanel.pictureVideoCheckboxIsSelected(); + filterByDocuments = intraCasePanel.documentsCheckboxIsSelected(); + } if (dataSourceId == CommonAttributePanel.NO_DATA_SOURCE_SELECTED) { builder = new AllIntraCaseCommonAttributeSearcher(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold); @@ -242,6 +242,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog { setTitleForSingleSource(dataSourceId); } + } metadata = builder.findMatches(); this.tabTitle = builder.buildTabTitle(); @@ -302,7 +303,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog { * future usage. * * @return a mapping of data correlationCase ids to data correlationCase - * names + * names */ @NbBundle.Messages({ "CommonAttributePanel.setupDataSources.done.tskCoreException=Unable to run query against DB.", @@ -326,9 +327,12 @@ public final class CommonAttributePanel extends javax.swing.JDialog { dataSourcesNames = dataSourceMap.values().toArray(dataSourcesNames); CommonAttributePanel.this.intraCasePanel.setDataModel(new DataSourceComboBoxModel(dataSourcesNames)); - boolean multipleDataSources = this.caseHasMultipleSources(); - CommonAttributePanel.this.intraCasePanel.rigForMultipleDataSources(multipleDataSources); - + if (!this.caseHasMultipleSources()) { //disable intra case search when only 1 data source in current case + intraCaseRadio.setEnabled(false); + interCaseRadio.setSelected(true); + intraCasePanel.setVisible(false); + interCasePanel.setVisible(true); + } CommonAttributePanel.this.updateErrorTextAndSearchBox(); } } @@ -391,10 +395,6 @@ public final class CommonAttributePanel extends javax.swing.JDialog { if (caseNames.length > 0) { caseNames = caseMap.values().toArray(caseNames); CommonAttributePanel.this.interCasePanel.setCaseList(new DataSourceComboBoxModel(caseNames)); - - boolean multipleCases = this.centralRepoHasMultipleCases(); - CommonAttributePanel.this.interCasePanel.rigForMultipleCases(multipleCases); - } else { CommonAttributePanel.this.disableIntercaseSearch(); } @@ -436,10 +436,6 @@ public final class CommonAttributePanel extends javax.swing.JDialog { } } - private boolean centralRepoHasMultipleCases() { - return CommonAttributePanel.this.interCasePanel.centralRepoHasMultipleCases(); - } - }.execute(); } @@ -452,31 +448,20 @@ public final class CommonAttributePanel extends javax.swing.JDialog { // //GEN-BEGIN:initComponents private void initComponents() { - fileTypeFilterButtonGroup = new javax.swing.ButtonGroup(); interIntraButtonGroup = new javax.swing.ButtonGroup(); jPanel1 = new javax.swing.JPanel(); - commonFilesSearchLabel2 = new javax.swing.JLabel(); + scopeLabel = new javax.swing.JLabel(); searchButton = new javax.swing.JButton(); - cancelButton = new javax.swing.JButton(); - allFileCategoriesRadioButton = new javax.swing.JRadioButton(); - selectedFileCategoriesButton = new javax.swing.JRadioButton(); - pictureVideoCheckbox = new javax.swing.JCheckBox(); - documentsCheckbox = new javax.swing.JCheckBox(); - categoriesLabel = new javax.swing.JLabel(); errorText = new javax.swing.JLabel(); - commonFilesSearchLabel1 = new javax.swing.JLabel(); + commonItemSearchDescription = new javax.swing.JLabel(); intraCaseRadio = new javax.swing.JRadioButton(); interCaseRadio = new javax.swing.JRadioButton(); - layoutPanel = new java.awt.Panel(); - intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); - interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); percentageThresholdCheck = new javax.swing.JCheckBox(); percentageThresholdTextOne = new javax.swing.JTextField(); percentageThresholdTextTwo = new javax.swing.JLabel(); - filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767)); - filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767)); + intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); + interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); - setMaximumSize(new java.awt.Dimension(450, 440)); setMinimumSize(new java.awt.Dimension(450, 440)); setResizable(false); addWindowListener(new java.awt.event.WindowAdapter() { @@ -485,13 +470,13 @@ public final class CommonAttributePanel extends javax.swing.JDialog { } }); - jPanel1.setMaximumSize(new java.awt.Dimension(450, 440)); - jPanel1.setMinimumSize(new java.awt.Dimension(450, 440)); - jPanel1.setPreferredSize(new java.awt.Dimension(450, 440)); + jPanel1.setMaximumSize(new java.awt.Dimension(450, 400)); + jPanel1.setMinimumSize(new java.awt.Dimension(450, 400)); + jPanel1.setPreferredSize(new java.awt.Dimension(450, 400)); jPanel1.setRequestFocusEnabled(false); - org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonFilesSearchLabel2.text")); // NOI18N - commonFilesSearchLabel2.setFocusable(false); + org.openide.awt.Mnemonics.setLocalizedText(scopeLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.scopeLabel.text")); // NOI18N + scopeLabel.setFocusable(false); org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.searchButton.text")); // NOI18N searchButton.setEnabled(false); @@ -502,61 +487,12 @@ public final class CommonAttributePanel extends javax.swing.JDialog { } }); - org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.cancelButton.text")); // NOI18N - cancelButton.setActionCommand(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.cancelButton.actionCommand")); // NOI18N - cancelButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); - cancelButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - cancelButtonActionPerformed(evt); - } - }); - - fileTypeFilterButtonGroup.add(allFileCategoriesRadioButton); - allFileCategoriesRadioButton.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(allFileCategoriesRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.allFileCategoriesRadioButton.text")); // NOI18N - allFileCategoriesRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.allFileCategoriesRadioButton.toolTipText")); // NOI18N - allFileCategoriesRadioButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - allFileCategoriesRadioButtonActionPerformed(evt); - } - }); - - fileTypeFilterButtonGroup.add(selectedFileCategoriesButton); - org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.selectedFileCategoriesButton.text")); // NOI18N - selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.selectedFileCategoriesButton.toolTipText")); // NOI18N - selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - selectedFileCategoriesButtonActionPerformed(evt); - } - }); - - pictureVideoCheckbox.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(pictureVideoCheckbox, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.pictureVideoCheckbox.text")); // NOI18N - pictureVideoCheckbox.setEnabled(false); - pictureVideoCheckbox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - pictureVideoCheckboxActionPerformed(evt); - } - }); - - documentsCheckbox.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(documentsCheckbox, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.documentsCheckbox.text")); // NOI18N - documentsCheckbox.setEnabled(false); - documentsCheckbox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - documentsCheckboxActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(categoriesLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.categoriesLabel.text")); // NOI18N - categoriesLabel.setName(""); // NOI18N - errorText.setForeground(new java.awt.Color(255, 0, 0)); org.openide.awt.Mnemonics.setLocalizedText(errorText, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.errorText.text")); // NOI18N errorText.setVerticalAlignment(javax.swing.SwingConstants.TOP); - org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel1, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonFilesSearchLabel1.text")); // NOI18N - commonFilesSearchLabel1.setFocusable(false); + org.openide.awt.Mnemonics.setLocalizedText(commonItemSearchDescription, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonItemSearchDescription.text")); // NOI18N + commonItemSearchDescription.setFocusable(false); interIntraButtonGroup.add(intraCaseRadio); intraCaseRadio.setSelected(true); @@ -575,17 +511,14 @@ public final class CommonAttributePanel extends javax.swing.JDialog { } }); - layoutPanel.setLayout(new java.awt.CardLayout()); - layoutPanel.add(intraCasePanel, "card3"); - layoutPanel.add(interCasePanel, "card2"); - - org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdCheck, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdCheck.text_1")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdCheck, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdCheck.text_1_1")); // NOI18N percentageThresholdCheck.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { percentageThresholdCheckActionPerformed(evt); } }); + percentageThresholdTextOne.setHorizontalAlignment(javax.swing.JTextField.TRAILING); percentageThresholdTextOne.setText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdTextOne.text")); // NOI18N percentageThresholdTextOne.setMaximumSize(new java.awt.Dimension(40, 24)); percentageThresholdTextOne.setMinimumSize(new java.awt.Dimension(40, 24)); @@ -593,6 +526,14 @@ public final class CommonAttributePanel extends javax.swing.JDialog { org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdTextTwo, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdTextTwo.text_1")); // NOI18N + intraCasePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.intraCasePanel.border.title"))); // NOI18N + intraCasePanel.setMinimumSize(new java.awt.Dimension(204, 204)); + intraCasePanel.setPreferredSize(new java.awt.Dimension(430, 204)); + + interCasePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.interCasePanel.border.title"))); // NOI18N + interCasePanel.setMinimumSize(new java.awt.Dimension(430, 249)); + interCasePanel.setPreferredSize(new java.awt.Dimension(430, 249)); + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( @@ -600,81 +541,62 @@ public final class CommonAttributePanel extends javax.swing.JDialog { .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addComponent(searchButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(80, 80, 80) - .addComponent(filler2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(errorText))) .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(0, 0, 0) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(commonFilesSearchLabel2) - .addComponent(intraCaseRadio) - .addComponent(interCaseRadio) - .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(categoriesLabel) - .addComponent(selectedFileCategoriesButton) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(29, 29, 29) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(documentsCheckbox) - .addComponent(pictureVideoCheckbox))) - .addComponent(allFileCategoriesRadioButton) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addGap(10, 10, 10) - .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(errorText, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addGap(65, 65, 65) + .addComponent(searchButton) + .addContainerGap()) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(percentageThresholdCheck) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(percentageThresholdTextOne, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(percentageThresholdTextTwo))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() + .addGap(20, 20, 20) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(intraCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(interCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE)))) + .addGap(0, 0, Short.MAX_VALUE)))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(percentageThresholdCheck) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(percentageThresholdTextOne, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(scopeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(37, 37, 37)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(interCasePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(intraCasePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(0, 0, 0)))) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() - .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(commonFilesSearchLabel2) + .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(scopeLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(intraCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(interCaseRadio) - .addGap(2, 2, 2) - .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(categoriesLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(selectedFileCategoriesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pictureVideoCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(documentsCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(allFileCategoriesRadioButton) + .addComponent(interCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 197, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(percentageThresholdCheck) .addComponent(percentageThresholdTextOne, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(percentageThresholdTextTwo)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(filler2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(searchButton) - .addComponent(cancelButton) - .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 50, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(searchButton) + .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); @@ -696,42 +618,15 @@ public final class CommonAttributePanel extends javax.swing.JDialog { }//GEN-LAST:event_percentageThresholdCheckActionPerformed private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed - ((java.awt.CardLayout) this.layoutPanel.getLayout()).last(this.layoutPanel); - this.categoriesLabel.setEnabled(false); - this.selectedFileCategoriesButton.setEnabled(false); - this.allFileCategoriesRadioButton.setEnabled(false); - this.allFileCategoriesRadioButton.setSelected(true); - this.documentsCheckbox.setEnabled(false); - this.pictureVideoCheckbox.setEnabled(false); + intraCasePanel.setVisible(false); + interCasePanel.setVisible(true); }//GEN-LAST:event_interCaseRadioActionPerformed private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed - ((java.awt.CardLayout) this.layoutPanel.getLayout()).first(this.layoutPanel); - this.categoriesLabel.setEnabled(true); - this.selectedFileCategoriesButton.setEnabled(true); - this.allFileCategoriesRadioButton.setEnabled(true); + intraCasePanel.setVisible(true); + interCasePanel.setVisible(false); }//GEN-LAST:event_intraCaseRadioActionPerformed - private void documentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsCheckboxActionPerformed - this.handleFileTypeCheckBoxState(); - }//GEN-LAST:event_documentsCheckboxActionPerformed - - private void pictureVideoCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pictureVideoCheckboxActionPerformed - this.handleFileTypeCheckBoxState(); - }//GEN-LAST:event_pictureVideoCheckboxActionPerformed - - private void selectedFileCategoriesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectedFileCategoriesButtonActionPerformed - this.handleFileTypeCheckBoxState(); - }//GEN-LAST:event_selectedFileCategoriesButtonActionPerformed - - private void allFileCategoriesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allFileCategoriesRadioButtonActionPerformed - this.handleFileTypeCheckBoxState(); - }//GEN-LAST:event_allFileCategoriesRadioButtonActionPerformed - - private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed - SwingUtilities.windowForComponent(this).dispose(); - }//GEN-LAST:event_cancelButtonActionPerformed - private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed search(); SwingUtilities.windowForComponent(this).dispose(); @@ -743,7 +638,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog { try { this.percentageThresholdValue = Integer.parseInt(percentageString); - } catch (NumberFormatException exception) { + } catch (NumberFormatException ignored) { this.percentageThresholdValue = -1; } @@ -751,7 +646,6 @@ public final class CommonAttributePanel extends javax.swing.JDialog { } private void updateErrorTextAndSearchBox() { - if (this.errorManager.anyErrors()) { this.searchButton.setEnabled(false); //grab the first error error and show it @@ -763,48 +657,11 @@ public final class CommonAttributePanel extends javax.swing.JDialog { } } - private void enablePercentageOptions() { - this.percentageThresholdTextOne.setEnabled(true); - this.percentageThresholdCheck.setEnabled(true); - this.percentageThresholdCheck.setSelected(true); - this.percentageThresholdTextTwo.setEnabled(true); - } - - private void disablePercentageOptions() { - this.percentageThresholdTextOne.setEnabled(false); - this.percentageThresholdCheck.setEnabled(false); - this.percentageThresholdCheck.setSelected(false); - this.percentageThresholdTextTwo.setEnabled(false); - } - - private void handleFileTypeCheckBoxState() { - - this.pictureViewCheckboxState = this.pictureVideoCheckbox.isSelected(); - this.documentsCheckboxState = this.documentsCheckbox.isSelected(); - - if (this.allFileCategoriesRadioButton.isSelected()) { - this.pictureVideoCheckbox.setEnabled(false); - this.documentsCheckbox.setEnabled(false); - - this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false); - } - - if (this.selectedFileCategoriesButton.isSelected()) { - - this.pictureVideoCheckbox.setSelected(this.pictureViewCheckboxState); - this.documentsCheckbox.setSelected(this.documentsCheckboxState); - - this.pictureVideoCheckbox.setEnabled(true); - this.documentsCheckbox.setEnabled(true); - - if (!this.pictureVideoCheckbox.isSelected() && !this.documentsCheckbox.isSelected() && !this.allFileCategoriesRadioButton.isSelected()) { - this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, true); - } else { - this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false); - } - } - - this.updateErrorTextAndSearchBox(); + private void enablePercentageOptions(boolean enabled) { + this.percentageThresholdTextOne.setEnabled(enabled); + this.percentageThresholdCheck.setEnabled(enabled); + this.percentageThresholdCheck.setSelected(enabled); + this.percentageThresholdTextTwo.setEnabled(enabled); } private void handleFrequencyPercentageState() { @@ -813,33 +670,47 @@ public final class CommonAttributePanel extends javax.swing.JDialog { } else { this.errorManager.setError(UserInputErrorManager.FREQUENCY_PERCENTAGE_OUT_OF_RANGE_KEY, true); } - this.updateErrorTextAndSearchBox(); } // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JRadioButton allFileCategoriesRadioButton; - private javax.swing.JButton cancelButton; - private javax.swing.JLabel categoriesLabel; - private javax.swing.JLabel commonFilesSearchLabel1; - private javax.swing.JLabel commonFilesSearchLabel2; - private javax.swing.JCheckBox documentsCheckbox; + private javax.swing.JLabel commonItemSearchDescription; private javax.swing.JLabel errorText; - private javax.swing.ButtonGroup fileTypeFilterButtonGroup; - private javax.swing.Box.Filler filler1; - private javax.swing.Box.Filler filler2; private org.sleuthkit.autopsy.commonfilesearch.InterCasePanel interCasePanel; private javax.swing.JRadioButton interCaseRadio; private javax.swing.ButtonGroup interIntraButtonGroup; private org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel intraCasePanel; private javax.swing.JRadioButton intraCaseRadio; private javax.swing.JPanel jPanel1; - private java.awt.Panel layoutPanel; private javax.swing.JCheckBox percentageThresholdCheck; private javax.swing.JTextField percentageThresholdTextOne; private javax.swing.JLabel percentageThresholdTextTwo; - private javax.swing.JCheckBox pictureVideoCheckbox; + private javax.swing.JLabel scopeLabel; private javax.swing.JButton searchButton; - private javax.swing.JRadioButton selectedFileCategoriesButton; // End of variables declaration//GEN-END:variables + + void observeSubPanels() { + intraCasePanel.addObserver(this); + interCasePanel.addObserver(this); + } + + private void checkFileTypeCheckBoxState() { + boolean validCheckBoxState = true; + if (CommonAttributePanel.this.interCaseRadio.isSelected()) { + if (interCasePanel.fileCategoriesButtonIsSelected()) { + validCheckBoxState = interCasePanel.pictureVideoCheckboxIsSelected() || interCasePanel.documentsCheckboxIsSelected(); + } + } else { + if (intraCasePanel.fileCategoriesButtonIsSelected()) { + validCheckBoxState = intraCasePanel.pictureVideoCheckboxIsSelected() || intraCasePanel.documentsCheckboxIsSelected(); + } + } + if (validCheckBoxState) { + this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false); + } else { + this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, true); + } + this.updateErrorTextAndSearchBox(); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java index 61dfd8d578..d5a7c9df80 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java @@ -24,8 +24,6 @@ import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.coreutils.Logger; @@ -35,36 +33,28 @@ import org.sleuthkit.autopsy.coreutils.Logger; final public class CommonAttributeSearchAction extends CallableSystemAction { private static final Logger LOGGER = Logger.getLogger(CommonAttributeSearchAction.class.getName()); - + private static CommonAttributeSearchAction instance = null; private static final long serialVersionUID = 1L; - + CommonAttributeSearchAction() { super(); this.setEnabled(false); } @Override - public boolean isEnabled(){ + public boolean isEnabled() { boolean shouldBeEnabled = false; try { //dont refactor any of this to pull out common expressions - order of evaluation of each expression is significant - shouldBeEnabled = - (Case.isCaseOpen() && - Case.getCurrentCase().getDataSources().size() > 1) - || - (EamDb.isEnabled() && - EamDb.getInstance() != null && - EamDb.getInstance().getCases().size() > 1 && - Case.isCaseOpen() && - Case.getCurrentCase() != null && - EamDb.getInstance().getCase(Case.getCurrentCase()) != null); - - } catch(TskCoreException ex) { + shouldBeEnabled + = (Case.isCaseOpen() + && Case.getCurrentCase().getDataSources().size() > 1) + || CommonAttributePanel.isEamDbAvailableForIntercaseSearch(); + + } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error getting data sources for action enabled check", ex); - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error getting CR cases for action enabled check", ex); - } + } return super.isEnabled() && shouldBeEnabled; } @@ -77,12 +67,18 @@ final public class CommonAttributeSearchAction extends CallableSystemAction { @Override public void actionPerformed(ActionEvent event) { - new CommonAttributePanel().setVisible(true); + createAndShowPanel(); } @Override public void performAction() { - new CommonAttributePanel().setVisible(true); + createAndShowPanel(); + } + + private void createAndShowPanel() { + CommonAttributePanel commonAttributePanel = new CommonAttributePanel(); + commonAttributePanel.observeSubPanels(); + commonAttributePanel.setVisible(true); } @NbBundle.Messages({ diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form index bfe2c9823c..d38bea0c01 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form @@ -20,71 +20,72 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - + - - - + + - + - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -96,10 +97,10 @@ - + - + @@ -112,9 +113,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index a86521411a..76eb3c6b97 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -1,16 +1,16 @@ /* - * + * * Autopsy Forensic Browser - * + * * Copyright 2018 Basis Technology Corp. * Contact: carrier sleuthkit 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. @@ -24,6 +24,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Observable; +import java.util.Observer; import javax.swing.ComboBoxModel; import org.openide.util.Exceptions; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; @@ -33,44 +35,61 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; * UI controls for Common Files Search scenario where the user intends to find * common files between cases in addition to the present case. */ -public class InterCasePanel extends javax.swing.JPanel { - +public final class InterCasePanel extends javax.swing.JPanel { + private static final long serialVersionUID = 1L; - + private final Observable fileTypeFilterObservable; static final int NO_CASE_SELECTED = -1; - + private ComboBoxModel casesList = new DataSourceComboBoxModel(); - + private final Map caseMap; - - //True if we are looking in any or all cases, - // false if we must find matches in a given case plus the current case - private boolean anyCase; - + private Map correlationTypeFilters; - + /** * Creates new form InterCasePanel */ public InterCasePanel() { initComponents(); this.caseMap = new HashMap<>(); - this.anyCase = true; - - + fileTypeFilterObservable = new Observable() { + @Override + public void notifyObservers() { + //set changed before notify observers + //we want this observerable to always cause the observer to update when notified + this.setChanged(); + super.notifyObservers(); + } + }; } - private void specificCaseSelected(boolean selected) { - this.specificCentralRepoCaseRadio.setEnabled(selected); - if (this.specificCentralRepoCaseRadio.isEnabled()) { - this.caseComboBox.setEnabled(true); + void addObserver(Observer observer) { + fileTypeFilterObservable.addObserver(observer); + } + + void specificCaseSelected(boolean selected) { + this.caseComboBox.setEnabled(selected); + if (selected) { this.caseComboBox.setSelectedIndex(0); } } - + + boolean fileCategoriesButtonIsSelected() { + return selectedFileCategoriesButton.isEnabled() && selectedFileCategoriesButton.isSelected(); + } + + boolean pictureVideoCheckboxIsSelected() { + return pictureVideoCheckbox.isEnabled() && pictureVideoCheckbox.isSelected(); + } + + boolean documentsCheckboxIsSelected() { + return documentsCheckbox.isEnabled() && documentsCheckbox.isSelected(); + } + /** - * If the EamDB is enabled, the UI will populate the correlation type ComboBox with - * available types in the CR. + * If the EamDB is enabled, the UI will populate the correlation type + * ComboBox with available types in the CR. */ void setupCorrelationTypeFilter() { this.correlationTypeFilters = new HashMap<>(); @@ -84,7 +103,6 @@ public class InterCasePanel extends javax.swing.JPanel { Exceptions.printStackTrace(ex); } this.correlationTypeComboBox.setSelectedIndex(0); - } /** @@ -97,92 +115,182 @@ public class InterCasePanel extends javax.swing.JPanel { private void initComponents() { buttonGroup = new javax.swing.ButtonGroup(); - anyCentralRepoCaseRadio = new javax.swing.JRadioButton(); - specificCentralRepoCaseRadio = new javax.swing.JRadioButton(); caseComboBox = new javax.swing.JComboBox<>(); - comboBoxLabel = new javax.swing.JLabel(); + correlationComboBoxLabel = new javax.swing.JLabel(); correlationTypeComboBox = new javax.swing.JComboBox<>(); - - buttonGroup.add(anyCentralRepoCaseRadio); - anyCentralRepoCaseRadio.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(anyCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.anyCentralRepoCaseRadio.text")); // NOI18N - anyCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - anyCentralRepoCaseRadioActionPerformed(evt); - } - }); - - buttonGroup.add(specificCentralRepoCaseRadio); - org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.specificCentralRepoCaseRadio.text")); // NOI18N - specificCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - specificCentralRepoCaseRadioActionPerformed(evt); - } - }); + categoriesLabel = new javax.swing.JLabel(); + allFileCategoriesRadioButton = new javax.swing.JRadioButton(); + selectedFileCategoriesButton = new javax.swing.JRadioButton(); + pictureVideoCheckbox = new javax.swing.JCheckBox(); + documentsCheckbox = new javax.swing.JCheckBox(); + specificCentralRepoCaseCheckbox = new javax.swing.JCheckBox(); caseComboBox.setModel(casesList); caseComboBox.setEnabled(false); - org.openide.awt.Mnemonics.setLocalizedText(comboBoxLabel, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.comboBoxLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(correlationComboBoxLabel, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.correlationComboBoxLabel.text")); // NOI18N correlationTypeComboBox.setSelectedItem(null); correlationTypeComboBox.setToolTipText(org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.correlationTypeComboBox.toolTipText")); // NOI18N + correlationTypeComboBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + correlationTypeComboBoxActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(categoriesLabel, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.categoriesLabel.text")); // NOI18N + categoriesLabel.setEnabled(false); + categoriesLabel.setName(""); // NOI18N + + buttonGroup.add(allFileCategoriesRadioButton); + allFileCategoriesRadioButton.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(allFileCategoriesRadioButton, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.allFileCategoriesRadioButton.text")); // NOI18N + allFileCategoriesRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.allFileCategoriesRadioButton.toolTipText")); // NOI18N + allFileCategoriesRadioButton.setEnabled(false); + allFileCategoriesRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + allFileCategoriesRadioButtonActionPerformed(evt); + } + }); + + buttonGroup.add(selectedFileCategoriesButton); + org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.selectedFileCategoriesButton.text")); // NOI18N + selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.selectedFileCategoriesButton.toolTipText")); // NOI18N + selectedFileCategoriesButton.setEnabled(false); + selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + selectedFileCategoriesButtonActionPerformed(evt); + } + }); + + pictureVideoCheckbox.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(pictureVideoCheckbox, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.pictureVideoCheckbox.text")); // NOI18N + pictureVideoCheckbox.setEnabled(false); + pictureVideoCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + pictureVideoCheckboxActionPerformed(evt); + } + }); + + documentsCheckbox.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(documentsCheckbox, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.documentsCheckbox.text")); // NOI18N + documentsCheckbox.setEnabled(false); + documentsCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + documentsCheckboxActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseCheckbox, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.specificCentralRepoCaseCheckbox.text")); // NOI18N + specificCentralRepoCaseCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + specificCentralRepoCaseCheckboxActionPerformed(evt); + } + }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(specificCentralRepoCaseCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(anyCentralRepoCaseRadio) - .addComponent(specificCentralRepoCaseRadio) + .addComponent(correlationComboBoxLabel) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(categoriesLabel) + .addGroup(layout.createSequentialGroup() + .addGap(19, 19, 19) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(allFileCategoriesRadioButton) + .addComponent(selectedFileCategoriesButton) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(documentsCheckbox) + .addComponent(pictureVideoCheckbox)))))) + .addGap(0, 0, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() .addGap(21, 21, 21) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(comboBoxLabel) - .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE))))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(caseComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(correlationTypeComboBox, 0, 353, Short.MAX_VALUE)))) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(anyCentralRepoCaseRadio) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(specificCentralRepoCaseRadio) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addContainerGap() + .addComponent(specificCentralRepoCaseCheckbox) + .addGap(6, 6, 6) .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(comboBoxLabel) + .addComponent(correlationComboBoxLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(categoriesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(allFileCategoriesRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(selectedFileCategoriesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pictureVideoCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(documentsCheckbox) + .addContainerGap()) ); }// //GEN-END:initComponents - private void specificCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseRadioActionPerformed - this.caseComboBox.setEnabled(true); - if(this.caseComboBox.isEnabled() && this.caseComboBox.getSelectedItem() == null){ - this.caseComboBox.setSelectedIndex(0); - } - this.anyCase = false; - }//GEN-LAST:event_specificCentralRepoCaseRadioActionPerformed + private void allFileCategoriesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allFileCategoriesRadioButtonActionPerformed + pictureVideoCheckbox.setEnabled(false); + documentsCheckbox.setEnabled(false); + fileTypeFilterObservable.notifyObservers(); + }//GEN-LAST:event_allFileCategoriesRadioButtonActionPerformed - private void anyCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_anyCentralRepoCaseRadioActionPerformed - this.caseComboBox.setEnabled(false); - this.anyCase = true; - }//GEN-LAST:event_anyCentralRepoCaseRadioActionPerformed + private void selectedFileCategoriesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectedFileCategoriesButtonActionPerformed + pictureVideoCheckbox.setEnabled(true); + documentsCheckbox.setEnabled(true); + fileTypeFilterObservable.notifyObservers(); + }//GEN-LAST:event_selectedFileCategoriesButtonActionPerformed + + private void specificCentralRepoCaseCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseCheckboxActionPerformed + this.specificCaseSelected(specificCentralRepoCaseCheckbox.isSelected()); + }//GEN-LAST:event_specificCentralRepoCaseCheckboxActionPerformed + + private void correlationTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_correlationTypeComboBoxActionPerformed + boolean enableFileTypesFilter = this.correlationTypeComboBox.getSelectedItem().equals("Files"); + categoriesLabel.setEnabled(enableFileTypesFilter); + allFileCategoriesRadioButton.setEnabled(enableFileTypesFilter); + selectedFileCategoriesButton.setEnabled(enableFileTypesFilter); + boolean enableIndividualFilters = (enableFileTypesFilter && selectedFileCategoriesButton.isSelected()); + pictureVideoCheckbox.setEnabled(enableIndividualFilters); + documentsCheckbox.setEnabled(enableIndividualFilters); + }//GEN-LAST:event_correlationTypeComboBoxActionPerformed + + private void pictureVideoCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pictureVideoCheckboxActionPerformed + fileTypeFilterObservable.notifyObservers(); + }//GEN-LAST:event_pictureVideoCheckboxActionPerformed + + private void documentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsCheckboxActionPerformed + + fileTypeFilterObservable.notifyObservers(); + }//GEN-LAST:event_documentsCheckboxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JRadioButton anyCentralRepoCaseRadio; + private javax.swing.JRadioButton allFileCategoriesRadioButton; private javax.swing.ButtonGroup buttonGroup; private javax.swing.JComboBox caseComboBox; - private javax.swing.JLabel comboBoxLabel; + private javax.swing.JLabel categoriesLabel; + private javax.swing.JLabel correlationComboBoxLabel; private javax.swing.JComboBox correlationTypeComboBox; - private javax.swing.JRadioButton specificCentralRepoCaseRadio; + private javax.swing.JCheckBox documentsCheckbox; + private javax.swing.JCheckBox pictureVideoCheckbox; + private javax.swing.JRadioButton selectedFileCategoriesButton; + private javax.swing.JCheckBox specificCentralRepoCaseCheckbox; // End of variables declaration//GEN-END:variables Map getCaseMap() { @@ -194,16 +302,6 @@ public class InterCasePanel extends javax.swing.JPanel { this.caseComboBox.setModel(dataSourceComboBoxModel); } - void rigForMultipleCases(boolean multipleCases) { - this.anyCentralRepoCaseRadio.setEnabled(multipleCases); - this.anyCentralRepoCaseRadio.setEnabled(multipleCases); - - if(!multipleCases){ - this.specificCentralRepoCaseRadio.setSelected(true); - this.specificCaseSelected(true); - } - } - void setCaseMap(Map caseMap) { this.caseMap.clear(); this.caseMap.putAll(caseMap); @@ -212,23 +310,27 @@ public class InterCasePanel extends javax.swing.JPanel { boolean centralRepoHasMultipleCases() { return this.caseMap.size() >= 2; } - - Integer getSelectedCaseId(){ - if(this.anyCase){ - return InterCasePanel.NO_CASE_SELECTED; - } - - for(Entry entry : this.caseMap.entrySet()){ - if(entry.getValue().equals(this.caseComboBox.getSelectedItem())){ - return entry.getKey(); + + /** + * Get the ID for the selected case + * + * @return + */ + Integer getSelectedCaseId() { + if (specificCentralRepoCaseCheckbox.isSelected()) { + for (Entry entry : this.caseMap.entrySet()) { + if (entry.getValue().equals(this.caseComboBox.getSelectedItem())) { + return entry.getKey(); + } } } - return InterCasePanel.NO_CASE_SELECTED; } - + /** - * Returns the selected Correlation Type by getting the Type from the stored HashMap. + * Returns the selected Correlation Type by getting the Type from the stored + * HashMap. + * * @return Type the selected Correlation Type to query for. */ CorrelationAttributeInstance.Type getSelectedCorrelationType() { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form index 7038ca5926..f193a6e73d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form @@ -23,62 +23,58 @@ - - - - - + + - - - + + + + + + + + + + + + + + + + + + + - + + - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -86,12 +82,84 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index babbbd4096..097f609ebb 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -1,16 +1,16 @@ /* - * + * * Autopsy Forensic Browser - * + * * Copyright 2018 Basis Technology Corp. * Contact: carrier sleuthkit 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. @@ -23,18 +23,21 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Observable; +import java.util.Observer; import javax.swing.ComboBoxModel; + /** * UI controls for Common Files Search scenario where the user intends to find - * common files between datasources. It is an inner panel which provides the ability - * to select all datasources or a single datasource from a dropdown list of - * sources in the current case. + * common files between datasources. It is an inner panel which provides the + * ability to select all datasources or a single datasource from a dropdown list + * of sources in the current case. */ -public class IntraCasePanel extends javax.swing.JPanel { - +public final class IntraCasePanel extends javax.swing.JPanel { + private static final long serialVersionUID = 1L; static final long NO_DATA_SOURCE_SELECTED = -1; - + private final Observable fileTypeFilterObservable; private boolean singleDataSource; private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); private final Map dataSourceMap; @@ -46,25 +49,51 @@ public class IntraCasePanel extends javax.swing.JPanel { initComponents(); this.dataSourceMap = new HashMap<>(); this.singleDataSource = true; + this.onlySpecificDataSourceCheckbox.setEnabled(true); + fileTypeFilterObservable = new Observable() { + @Override + public void notifyObservers(){ + //set changed before notify observers + //we want this observerable to always cause the observer to update when notified + this.setChanged(); + super.notifyObservers(); + } + }; } - - public Map getDataSourceMap(){ + + void addObserver(Observer observer) { + fileTypeFilterObservable.addObserver(observer); + } + + Map getDataSourceMap() { return Collections.unmodifiableMap(this.dataSourceMap); } - - Long getSelectedDataSourceId(){ - if(!this.singleDataSource){ + + Long getSelectedDataSourceId() { + if (!this.singleDataSource) { return IntraCasePanel.NO_DATA_SOURCE_SELECTED; } - - for(Entry entry : this.dataSourceMap.entrySet()){ - if(entry.getValue().equals(this.selectDataSourceComboBox.getSelectedItem())){ + + for (Entry entry : this.dataSourceMap.entrySet()) { + if (entry.getValue().equals(this.selectDataSourceComboBox.getSelectedItem())) { return entry.getKey(); } } - + return IntraCasePanel.NO_DATA_SOURCE_SELECTED; - } + } + + boolean fileCategoriesButtonIsSelected() { + return selectedFileCategoriesButton.isSelected(); + } + + boolean pictureVideoCheckboxIsSelected() { + return pictureVideoCheckbox.isEnabled() && pictureVideoCheckbox.isSelected(); + } + + boolean documentsCheckboxIsSelected() { + return documentsCheckbox.isEnabled() && documentsCheckbox.isSelected(); + } /** * This method is called from within the constructor to initialize the form. @@ -76,32 +105,64 @@ public class IntraCasePanel extends javax.swing.JPanel { private void initComponents() { buttonGroup = new javax.swing.ButtonGroup(); - allDataSourcesRadioButton = new javax.swing.JRadioButton(); - withinDataSourceRadioButton = new javax.swing.JRadioButton(); selectDataSourceComboBox = new javax.swing.JComboBox<>(); - - buttonGroup.add(allDataSourcesRadioButton); - org.openide.awt.Mnemonics.setLocalizedText(allDataSourcesRadioButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.allDataSourcesRadioButton.text")); // NOI18N - allDataSourcesRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - allDataSourcesRadioButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - allDataSourcesRadioButtonActionPerformed(evt); - } - }); - - buttonGroup.add(withinDataSourceRadioButton); - org.openide.awt.Mnemonics.setLocalizedText(withinDataSourceRadioButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.withinDataSourceRadioButton.text")); // NOI18N - withinDataSourceRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - withinDataSourceRadioButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - withinDataSourceRadioButtonActionPerformed(evt); - } - }); + categoriesLabel = new javax.swing.JLabel(); + selectedFileCategoriesButton = new javax.swing.JRadioButton(); + pictureVideoCheckbox = new javax.swing.JCheckBox(); + documentsCheckbox = new javax.swing.JCheckBox(); + allFileCategoriesRadioButton = new javax.swing.JRadioButton(); + onlySpecificDataSourceCheckbox = new javax.swing.JCheckBox(); selectDataSourceComboBox.setModel(dataSourcesList); - selectDataSourceComboBox.setActionCommand(org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.selectDataSourceComboBox.actionCommand")); // NOI18N selectDataSourceComboBox.setEnabled(false); + org.openide.awt.Mnemonics.setLocalizedText(categoriesLabel, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.categoriesLabel.text")); // NOI18N + categoriesLabel.setName(""); // NOI18N + + buttonGroup.add(selectedFileCategoriesButton); + org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.selectedFileCategoriesButton.text")); // NOI18N + selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.selectedFileCategoriesButton.toolTipText")); // NOI18N + selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + selectedFileCategoriesButtonActionPerformed(evt); + } + }); + + pictureVideoCheckbox.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(pictureVideoCheckbox, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.pictureVideoCheckbox.text")); // NOI18N + pictureVideoCheckbox.setEnabled(false); + pictureVideoCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + pictureVideoCheckboxActionPerformed(evt); + } + }); + + documentsCheckbox.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(documentsCheckbox, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.documentsCheckbox.text")); // NOI18N + documentsCheckbox.setEnabled(false); + documentsCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + documentsCheckboxActionPerformed(evt); + } + }); + + buttonGroup.add(allFileCategoriesRadioButton); + allFileCategoriesRadioButton.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(allFileCategoriesRadioButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.allFileCategoriesRadioButton.text")); // NOI18N + allFileCategoriesRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.allFileCategoriesRadioButton.toolTipText")); // NOI18N + allFileCategoriesRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + allFileCategoriesRadioButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(onlySpecificDataSourceCheckbox, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.onlySpecificDataSourceCheckbox.text")); // NOI18N + onlySpecificDataSourceCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onlySpecificDataSourceCheckboxActionPerformed(evt); + } + }); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -109,34 +170,69 @@ public class IntraCasePanel extends javax.swing.JPanel { .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(allDataSourcesRadioButton) - .addComponent(withinDataSourceRadioButton))) + .addGap(21, 21, 21) + .addComponent(selectDataSourceComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() - .addGap(27, 27, 27) - .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(categoriesLabel) + .addGroup(layout.createSequentialGroup() + .addGap(19, 19, 19) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(allFileCategoriesRadioButton) + .addComponent(selectedFileCategoriesButton) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(documentsCheckbox) + .addComponent(pictureVideoCheckbox)))))) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) + .addComponent(onlySpecificDataSourceCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(allDataSourcesRadioButton) + .addContainerGap() + .addComponent(onlySpecificDataSourceCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(withinDataSourceRadioButton) + .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(categoriesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(allFileCategoriesRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(selectedFileCategoriesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pictureVideoCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(documentsCheckbox) + .addContainerGap()) ); }// //GEN-END:initComponents - private void allDataSourcesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allDataSourcesRadioButtonActionPerformed - selectDataSourceComboBox.setEnabled(!allDataSourcesRadioButton.isSelected()); - singleDataSource = false; - }//GEN-LAST:event_allDataSourcesRadioButtonActionPerformed + private void selectedFileCategoriesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectedFileCategoriesButtonActionPerformed + pictureVideoCheckbox.setEnabled(true); + documentsCheckbox.setEnabled(true); + fileTypeFilterObservable.notifyObservers(); + }//GEN-LAST:event_selectedFileCategoriesButtonActionPerformed - private void withinDataSourceRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_withinDataSourceRadioButtonActionPerformed - withinDataSourceSelected(withinDataSourceRadioButton.isSelected()); - }//GEN-LAST:event_withinDataSourceRadioButtonActionPerformed + private void allFileCategoriesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allFileCategoriesRadioButtonActionPerformed + pictureVideoCheckbox.setEnabled(false); + documentsCheckbox.setEnabled(false); + fileTypeFilterObservable.notifyObservers(); + }//GEN-LAST:event_allFileCategoriesRadioButtonActionPerformed + + private void onlySpecificDataSourceCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_onlySpecificDataSourceCheckboxActionPerformed + this.withinDataSourceSelected(onlySpecificDataSourceCheckbox.isSelected()); + }//GEN-LAST:event_onlySpecificDataSourceCheckboxActionPerformed + + private void pictureVideoCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pictureVideoCheckboxActionPerformed + fileTypeFilterObservable.notifyObservers(); + }//GEN-LAST:event_pictureVideoCheckboxActionPerformed + + private void documentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsCheckboxActionPerformed + fileTypeFilterObservable.notifyObservers(); + }//GEN-LAST:event_documentsCheckboxActionPerformed private void withinDataSourceSelected(boolean selected) { selectDataSourceComboBox.setEnabled(selected); @@ -147,10 +243,14 @@ public class IntraCasePanel extends javax.swing.JPanel { } // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JRadioButton allDataSourcesRadioButton; + private javax.swing.JRadioButton allFileCategoriesRadioButton; private javax.swing.ButtonGroup buttonGroup; + private javax.swing.JLabel categoriesLabel; + private javax.swing.JCheckBox documentsCheckbox; + private javax.swing.JCheckBox onlySpecificDataSourceCheckbox; + private javax.swing.JCheckBox pictureVideoCheckbox; private javax.swing.JComboBox selectDataSourceComboBox; - private javax.swing.JRadioButton withinDataSourceRadioButton; + private javax.swing.JRadioButton selectedFileCategoriesButton; // End of variables declaration//GEN-END:variables void setDataModel(DataSourceComboBoxModel dataSourceComboBoxModel) { @@ -158,16 +258,8 @@ public class IntraCasePanel extends javax.swing.JPanel { this.selectDataSourceComboBox.setModel(dataSourcesList); } - void rigForMultipleDataSources(boolean multipleDataSources) { - this.withinDataSourceRadioButton.setEnabled(multipleDataSources); - this.allDataSourcesRadioButton.setSelected(!multipleDataSources); - this.withinDataSourceRadioButton.setSelected(multipleDataSources); - this.withinDataSourceSelected(multipleDataSources); - - } - void setDataSourceMap(Map dataSourceMap) { this.dataSourceMap.clear(); this.dataSourceMap.putAll(dataSourceMap); } -} \ No newline at end of file +} From b577b761a653db6f68490a802794cb38f2ab6364 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 12 Sep 2018 23:24:56 -0400 Subject: [PATCH 024/273] Implementation as a JPopupMenu. --- .../autopsy/casemodule/CasePreferences.java | 38 +- .../corecomponents/ViewPreferencesPanel.form | 613 ++++++++++-------- .../corecomponents/ViewPreferencesPanel.java | 210 +++++- .../ViewPreferencesPanelController.java | 2 +- .../datamodel/AutopsyTreeChildFactory.java | 16 +- .../autopsy/datamodel/DeletedContent.java | 4 +- .../autopsy/datamodel/EmailExtracted.java | 4 +- .../autopsy/datamodel/ExtractedContent.java | 19 +- .../sleuthkit/autopsy/datamodel/FileSize.java | 4 +- .../datamodel/FileTypesByExtension.java | 4 +- .../datamodel/FileTypesByMimeType.java | 4 +- .../autopsy/datamodel/HashsetHits.java | 4 +- .../autopsy/datamodel/InterestingHits.java | 4 +- .../autopsy/datamodel/KeywordHits.java | 4 +- .../org/sleuthkit/autopsy/datamodel/Tags.java | 22 +- .../autopsy/datamodel/accounts/Accounts.java | 10 +- .../DirectoryTreeTopComponent.form | 8 + .../DirectoryTreeTopComponent.java | 69 +- .../directorytree/ViewContextAction.java | 3 +- 19 files changed, 650 insertions(+), 392 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java index 8d40b23538..8be8a44882 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java @@ -18,15 +18,18 @@ */ package org.sleuthkit.autopsy.casemodule; +import java.beans.PropertyChangeEvent; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.EnumSet; import java.util.Properties; import java.util.logging.Level; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; /** * Read and update case preference file values. @@ -38,25 +41,40 @@ public final class CasePreferences { private static final Logger logger = Logger.getLogger(CasePreferences.class.getName()); - private Boolean groupItemsInTreeByDataSource = null; + private static Boolean groupItemsInTreeByDataSource = null; - //DLG: - public CasePreferences(Case currentCase) { - loadFromStorage(currentCase); + private CasePreferences() { } - public Boolean getGroupItemsInTreeByDataSource() { + static { + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { + if (evt.getNewValue() != null) { + loadFromStorage((Case) evt.getNewValue()); + } else { + saveToStorage((Case) evt.getOldValue()); + clear(); + } + }); + try { + loadFromStorage(Case.getCurrentCaseThrows()); + } catch (NoCurrentCaseException ex) { + logger.log(Level.SEVERE, "No current case open.", ex); + } + } + + public static Boolean getGroupItemsInTreeByDataSource() { return groupItemsInTreeByDataSource; } - public void setGroupItemsInTreeByDataSource(boolean value) { + public static void setGroupItemsInTreeByDataSource(boolean value) { groupItemsInTreeByDataSource = value; + DirectoryTreeTopComponent.getDefault().refreshContentTreeSafe(); } /** * Load case preferences from the settings file. */ - private void loadFromStorage(Case currentCase) { + private static void loadFromStorage(Case currentCase) { Path settingsFile = Paths.get(currentCase.getConfigDirectory(), SETTINGS_FILE); //NON-NLS if (settingsFile.toFile().exists()) { // Read the settings @@ -73,11 +91,15 @@ public final class CasePreferences { } } } + + private static void clear() { + groupItemsInTreeByDataSource = null; + } /** * Store case preferences in the settings file. */ - public void saveToStorage(Case currentCase) { + private static void saveToStorage(Case currentCase) { Path settingsFile = Paths.get(currentCase.getConfigDirectory(), SETTINGS_FILE); //NON-NLS Properties props = new Properties(); if (groupItemsInTreeByDataSource != null) { diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form index 1fcbee8b23..e2313f0ce5 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form @@ -16,319 +16,368 @@ - - - - - - - - - + - - - - - - - - + - + - - - - - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + - - + + + + - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index 1e9b1fcbbd..51dc4d4f5d 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -28,11 +28,13 @@ import java.util.Objects; import java.util.Properties; import java.util.logging.Level; import javax.swing.JPanel; +import org.netbeans.spi.options.OptionsPanelController; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; /** * Panel for configuring view preferences. @@ -41,18 +43,30 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { private static final Logger logger = Logger.getLogger(ViewPreferencesPanel.class.getName()); - private Case currentCase = null; - private CasePreferences casePreferences = null; + private boolean immediateUpdates; /** * Creates new form ViewPreferencesPanel + * + * //DLG: Might not need this constructor anymore. */ public ViewPreferencesPanel() { initComponents(); } + /** + * Creates new form ViewPreferencesPanel + * + * //DLG: + */ + public ViewPreferencesPanel(boolean immediateUpdates) { + initComponents(); + this.immediateUpdates = immediateUpdates; + } + @Override public void load() { + // Global Settings boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer(); keepCurrentViewerRadioButton.setSelected(keepPreferredViewer); useBestViewerRadioButton.setSelected(!keepPreferredViewer); @@ -67,16 +81,17 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { dataSourcesHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree()); viewsHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInViewsTree()); - hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags() == false); - - try { - currentCase = Case.getCurrentCaseThrows(); - casePreferences = new CasePreferences(currentCase); + // Current Case Settings + boolean caseIsOpen = Case.isCaseOpen(); + currentCaseSettingsPanel.setEnabled(caseIsOpen); + hideOtherUsersTagsCheckbox.setEnabled(caseIsOpen); + groupByDataSourceCheckbox.setEnabled(caseIsOpen); - groupByDataSourceCheckbox.setSelected(Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true)); - } catch (NoCurrentCaseException ex) { - // No open case. - } + hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags() == false); + groupByDataSourceCheckbox.setSelected(Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)); + + // Current Session Settings + hideRejectedResultsCheckbox.setSelected(DirectoryTreeTopComponent.getDefault().getShowRejectedResults() == false); } @Override @@ -87,22 +102,23 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { UserPreferences.setHideKnownFilesInViewsTree(viewsHideKnownCheckbox.isSelected()); UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCheckbox.isSelected()); UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected()); + UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected() == false); - UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected()); + storeGroupItemsInTreeByDataSource(); - if (currentCase != null) { + DirectoryTreeTopComponent.getDefault().setShowRejectedResults(hideRejectedResultsCheckbox.isSelected() == false); + } + + private void storeGroupItemsInTreeByDataSource() { + if (Case.isCaseOpen()) { /* * Only write the value if it has already been previously stored, or * if the checkbox is selected. This allows GroupDataSourcesDialog * to work. */ - if (casePreferences.getGroupItemsInTreeByDataSource() != null || groupByDataSourceCheckbox.isSelected()) { - firePropertyChange( - CasePreferences.GROUP_ITEMS_IN_TREE_BY_DATASOURCE, - casePreferences.getGroupItemsInTreeByDataSource(), Boolean.valueOf(groupByDataSourceCheckbox.isSelected())); - casePreferences.setGroupItemsInTreeByDataSource(groupByDataSourceCheckbox.isSelected()); + if (CasePreferences.getGroupItemsInTreeByDataSource() != null || groupByDataSourceCheckbox.isSelected()) { + CasePreferences.setGroupItemsInTreeByDataSource(groupByDataSourceCheckbox.isSelected()); } - casePreferences.saveToStorage(currentCase); } } @@ -115,6 +131,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { // //GEN-BEGIN:initComponents private void initComponents() { + viewPreferencesScrollPane = new javax.swing.JScrollPane(); + viewPreferencesPanel = new javax.swing.JPanel(); globalSettingsPanel = new javax.swing.JPanel(); selectFileLabel = new javax.swing.JLabel(); useBestViewerRadioButton = new javax.swing.JRadioButton(); @@ -134,6 +152,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { currentSessionSettingsPanel = new javax.swing.JPanel(); hideRejectedResultsCheckbox = new javax.swing.JCheckBox(); + viewPreferencesScrollPane.setBorder(null); + globalSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.globalSettingsPanel.border.title"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(selectFileLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.selectFileLabel.text")); // NOI18N @@ -157,14 +177,34 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { org.openide.awt.Mnemonics.setLocalizedText(hideKnownFilesLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideKnownFilesLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideKnownCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.dataSourcesHideKnownCheckbox.text")); // NOI18N + dataSourcesHideKnownCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dataSourcesHideKnownCheckboxActionPerformed(evt); + } + }); org.openide.awt.Mnemonics.setLocalizedText(viewsHideKnownCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.viewsHideKnownCheckbox.text")); // NOI18N + viewsHideKnownCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + viewsHideKnownCheckboxActionPerformed(evt); + } + }); org.openide.awt.Mnemonics.setLocalizedText(hideSlackFilesLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideSlackFilesLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideSlackCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text")); // NOI18N + dataSourcesHideSlackCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dataSourcesHideSlackCheckboxActionPerformed(evt); + } + }); org.openide.awt.Mnemonics.setLocalizedText(viewsHideSlackCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.viewsHideSlackCheckbox.text")); // NOI18N + viewsHideSlackCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + viewsHideSlackCheckboxActionPerformed(evt); + } + }); org.openide.awt.Mnemonics.setLocalizedText(displayTimeLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.displayTimeLabel.text")); // NOI18N @@ -186,7 +226,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { globalSettingsPanel.setLayout(globalSettingsPanelLayout); globalSettingsPanelLayout.setHorizontalGroup( globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, globalSettingsPanelLayout.createSequentialGroup() + .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(displayTimeLabel) @@ -250,8 +290,18 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { currentCaseSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentCaseSettingsPanel.border.title"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(hideOtherUsersTagsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text")); // NOI18N + hideOtherUsersTagsCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + hideOtherUsersTagsCheckboxActionPerformed(evt); + } + }); org.openide.awt.Mnemonics.setLocalizedText(groupByDataSourceCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.groupByDataSourceCheckbox.text")); // NOI18N + groupByDataSourceCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + groupByDataSourceCheckboxActionPerformed(evt); + } + }); javax.swing.GroupLayout currentCaseSettingsPanelLayout = new javax.swing.GroupLayout(currentCaseSettingsPanel); currentCaseSettingsPanel.setLayout(currentCaseSettingsPanelLayout); @@ -277,6 +327,11 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { currentSessionSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentSessionSettingsPanel.border.title"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(hideRejectedResultsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideRejectedResultsCheckbox.text")); // NOI18N + hideRejectedResultsCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + hideRejectedResultsCheckboxActionPerformed(evt); + } + }); javax.swing.GroupLayout currentSessionSettingsPanelLayout = new javax.swing.GroupLayout(currentSessionSettingsPanel); currentSessionSettingsPanel.setLayout(currentSessionSettingsPanelLayout); @@ -294,50 +349,139 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addComponent(hideRejectedResultsCheckbox)) ); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + javax.swing.GroupLayout viewPreferencesPanelLayout = new javax.swing.GroupLayout(viewPreferencesPanel); + viewPreferencesPanel.setLayout(viewPreferencesPanelLayout); + viewPreferencesPanelLayout.setHorizontalGroup( + viewPreferencesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, viewPreferencesPanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(viewPreferencesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(currentSessionSettingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(globalSettingsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(globalSettingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() + viewPreferencesPanelLayout.setVerticalGroup( + viewPreferencesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(viewPreferencesPanelLayout.createSequentialGroup() .addComponent(globalSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGap(11, 11, 11) .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(currentSessionSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); + + viewPreferencesScrollPane.setViewportView(viewPreferencesPanel); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(viewPreferencesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 562, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(viewPreferencesScrollPane) + ); }// //GEN-END:initComponents private void useBestViewerRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useBestViewerRadioButtonActionPerformed useBestViewerRadioButton.setSelected(true); keepCurrentViewerRadioButton.setSelected(false); + if (immediateUpdates) { + UserPreferences.setKeepPreferredContentViewer(false); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } }//GEN-LAST:event_useBestViewerRadioButtonActionPerformed private void keepCurrentViewerRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keepCurrentViewerRadioButtonActionPerformed useBestViewerRadioButton.setSelected(false); keepCurrentViewerRadioButton.setSelected(true); + if (immediateUpdates) { + UserPreferences.setKeepPreferredContentViewer(true); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } }//GEN-LAST:event_keepCurrentViewerRadioButtonActionPerformed private void useLocalTimeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useLocalTimeRadioButtonActionPerformed useLocalTimeRadioButton.setSelected(true); useGMTTimeRadioButton.setSelected(false); + if (immediateUpdates) { + UserPreferences.setDisplayTimesInLocalTime(true); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } }//GEN-LAST:event_useLocalTimeRadioButtonActionPerformed private void useGMTTimeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useGMTTimeRadioButtonActionPerformed useLocalTimeRadioButton.setSelected(false); useGMTTimeRadioButton.setSelected(true); + if (immediateUpdates) { + UserPreferences.setDisplayTimesInLocalTime(false); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } }//GEN-LAST:event_useGMTTimeRadioButtonActionPerformed + private void dataSourcesHideKnownCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideKnownCheckboxActionPerformed + if (immediateUpdates) { + UserPreferences.setHideKnownFilesInDataSourcesTree(dataSourcesHideKnownCheckbox.isSelected()); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + }//GEN-LAST:event_dataSourcesHideKnownCheckboxActionPerformed + + private void viewsHideKnownCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideKnownCheckboxActionPerformed + if (immediateUpdates) { + UserPreferences.setHideKnownFilesInViewsTree(viewsHideKnownCheckbox.isSelected()); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + }//GEN-LAST:event_viewsHideKnownCheckboxActionPerformed + + private void dataSourcesHideSlackCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideSlackCheckboxActionPerformed + if (immediateUpdates) { + UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCheckbox.isSelected()); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + }//GEN-LAST:event_dataSourcesHideSlackCheckboxActionPerformed + + private void viewsHideSlackCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideSlackCheckboxActionPerformed + if (immediateUpdates) { + UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected()); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + }//GEN-LAST:event_viewsHideSlackCheckboxActionPerformed + + private void hideOtherUsersTagsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideOtherUsersTagsCheckboxActionPerformed + if (immediateUpdates) { + UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected() == false); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + }//GEN-LAST:event_hideOtherUsersTagsCheckboxActionPerformed + + private void groupByDataSourceCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_groupByDataSourceCheckboxActionPerformed + if (immediateUpdates) { + storeGroupItemsInTreeByDataSource(); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + }//GEN-LAST:event_groupByDataSourceCheckboxActionPerformed + + private void hideRejectedResultsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideRejectedResultsCheckboxActionPerformed + if (immediateUpdates) { + DirectoryTreeTopComponent.getDefault().setShowRejectedResults(hideRejectedResultsCheckbox.isSelected() == false); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + }//GEN-LAST:event_hideRejectedResultsCheckboxActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel currentCaseSettingsPanel; @@ -356,6 +500,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { private javax.swing.JRadioButton useBestViewerRadioButton; private javax.swing.JRadioButton useGMTTimeRadioButton; private javax.swing.JRadioButton useLocalTimeRadioButton; + private javax.swing.JPanel viewPreferencesPanel; + private javax.swing.JScrollPane viewPreferencesScrollPane; private javax.swing.JCheckBox viewsHideKnownCheckbox; private javax.swing.JCheckBox viewsHideSlackCheckbox; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanelController.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanelController.java index 40efcd0149..75a6bb4c42 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanelController.java @@ -106,7 +106,7 @@ public final class ViewPreferencesPanelController extends OptionsPanelController */ private ViewPreferencesPanel getPanel() { if (panel == null) { - panel = new ViewPreferencesPanel(); + panel = new ViewPreferencesPanel(false); panel.addPropertyChangeListener((PropertyChangeEvent evt) -> { if (evt.getPropertyName().equals(OptionsPanelController.PROP_CHANGED)) { changed(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java index 6fd17f6c4c..5af1d5c085 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java @@ -54,15 +54,9 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable list) { try { - Case currentCase = Case.getCurrentCaseThrows(); - CasePreferences casePreferences = new CasePreferences(currentCase); SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - if (Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true)) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { List dataSources = tskCase.getDataSources(); List keys = new ArrayList<>(); dataSources.forEach((datasource) -> { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java index 370cc5cec7..57bd68911c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.Set; @@ -39,6 +40,7 @@ import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @@ -460,7 +462,7 @@ public class DeletedContent implements AutopsyVisitableItem { + " OR known IS NULL)"; //NON-NLS } - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { query += " AND data_source_obj_id = " + filteringDSObjId; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java index d9df849d86..ff268f2de2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.Set; @@ -39,6 +40,7 @@ import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @@ -161,7 +163,7 @@ public class EmailExtracted implements AutopsyVisitableItem { + "attribute_type_id=" + pathAttrId //NON-NLS + " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS + " AND blackboard_artifacts.artifact_type_id=" + artId; //NON-NLS - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { query += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java index dc19f0ecb1..3ab5f6cb90 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java @@ -292,9 +292,7 @@ public class ExtractedContent implements AutopsyVisitableItem { protected boolean createKeys(List list) { if (skCase != null) { try { - Case currentCase = Case.getCurrentCaseThrows(); - CasePreferences casePreferences = new CasePreferences(currentCase); - List types = Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true) ? + List types = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? blackboard.getArtifactTypesInUse(datasourceObjId) : skCase.getArtifactTypesInUse() ; @@ -316,8 +314,6 @@ public class ExtractedContent implements AutopsyVisitableItem { node.updateDisplayName(); } } - } catch (NoCurrentCaseException ex) { - Logger.getLogger(TypeFactory.class.getName()).log(Level.SEVERE, "No current case open: " + ex.getLocalizedMessage()); //NON-NLS } catch (TskCoreException ex) { Logger.getLogger(TypeFactory.class.getName()).log(Level.SEVERE, "Error getting list of artifacts in use: " + ex.getLocalizedMessage()); //NON-NLS } @@ -361,14 +357,9 @@ public class ExtractedContent implements AutopsyVisitableItem { // a performance increase might be had by adding a // "getBlackboardArtifactCount()" method to skCase try { - Case currentCase = Case.getCurrentCaseThrows(); - CasePreferences casePreferences = new CasePreferences(currentCase); - this.childCount = Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true) ? + this.childCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? blackboard.getArtifactsCount(type.getTypeID(), datasourceObjId) : skCase.getBlackboardArtifactsTypeCount(type.getTypeID()); - } catch (NoCurrentCaseException ex) { - Logger.getLogger(TypeNode.class.getName()) - .log(Level.WARNING, "No current case open.", ex); //NON-NLS } catch (TskException ex) { Logger.getLogger(TypeNode.class.getName()) .log(Level.WARNING, "Error getting child count", ex); //NON-NLS @@ -490,15 +481,11 @@ public class ExtractedContent implements AutopsyVisitableItem { protected boolean createKeys(List list) { if (skCase != null) { try { - Case currentCase = Case.getCurrentCaseThrows(); - CasePreferences casePreferences = new CasePreferences(currentCase); List arts = - Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true) ? + Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? blackboard.getArtifacts(type.getTypeID(), datasourceObjId) : skCase.getBlackboardArtifacts(type.getTypeID()); list.addAll(arts); - } catch (NoCurrentCaseException ex) { - Logger.getLogger(ArtifactFactory.class.getName()).log(Level.SEVERE, "No current case open.", ex); //NON-NLS } catch (TskException ex) { Logger.getLogger(ArtifactFactory.class.getName()).log(Level.SEVERE, "Couldn't get blackboard artifacts from database", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java index 51ece423da..8ce1aa75c8 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.Set; @@ -36,6 +37,7 @@ import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @@ -446,7 +448,7 @@ public class FileSize implements AutopsyVisitableItem { } // filter by datasource if indicated in user preferences - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { query += " AND data_source_obj_id = " + filteringDSObjId; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtension.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtension.java index 1d24f081ab..5f1f33607d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtension.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtension.java @@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener; import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.Set; @@ -37,6 +38,7 @@ import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @@ -363,7 +365,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem { + (UserPreferences.hideKnownFilesInViewsTree() ? " AND (known IS NULL OR known != " + TskData.FileKnown.KNOWN.getFileKnownValue() + ")" : " ") - + (UserPreferences.groupItemsInTreeByDatasource() + + (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? " AND data_source_obj_id = " + filteringDataSourceObjId() : " ") + " AND (extension IN (" + filter.getFilter().stream() diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java index 90cb90ae77..ad4ea9de99 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java @@ -28,6 +28,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.Set; @@ -41,6 +42,7 @@ import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import static org.sleuthkit.autopsy.core.UserPreferences.hideKnownFilesInViewsTree; @@ -101,7 +103,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi + TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.ordinal() + (hideSlackFilesInViewsTree() ? "" : ("," + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.ordinal())) + "))" - + ( UserPreferences.groupItemsInTreeByDatasource() ? " AND data_source_obj_id = " + this.filteringDataSourceObjId() : " ") + + ( Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? " AND data_source_obj_id = " + this.filteringDataSourceObjId() : " ") + (hideKnownFilesInViewsTree() ? (" AND (known IS NULL OR known != " + TskData.FileKnown.KNOWN.getFileKnownValue() + ")") : ""); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java index 24bae3d368..8ff6645562 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java @@ -30,6 +30,7 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.Set; @@ -41,6 +42,7 @@ import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @@ -141,7 +143,7 @@ public class HashsetHits implements AutopsyVisitableItem { + "attribute_type_id=" + setNameId //NON-NLS + " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS + " AND blackboard_artifacts.artifact_type_id=" + artId; //NON-NLS - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { query += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java index 67622d180c..6e3c138fcd 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java @@ -30,6 +30,7 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.Set; @@ -41,6 +42,7 @@ import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @@ -132,7 +134,7 @@ public class InterestingHits implements AutopsyVisitableItem { + "attribute_type_id=" + setNameId //NON-NLS + " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS + " AND blackboard_artifacts.artifact_type_id=" + artId; //NON-NLS - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { query += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index 51367297b8..9e60fba7f8 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -29,6 +29,7 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.Set; @@ -43,6 +44,7 @@ import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @@ -321,7 +323,7 @@ public class KeywordHits implements AutopsyVisitableItem { } String queryStr = KEYWORD_HIT_ATTRIBUTES_QUERY; - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { queryStr += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java index b5f8ecff39..abf77350d2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java @@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener; import java.util.Collections; import java.util.EnumSet; import java.util.List; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.Set; @@ -34,6 +35,7 @@ import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.services.TagsManager; import org.sleuthkit.autopsy.core.UserPreferences; @@ -244,11 +246,11 @@ public class Tags implements AutopsyVisitableItem { List tagNamesInUse; if (UserPreferences.showOnlyCurrentUserTags()) { String userName = System.getProperty(USER_NAME_PROPERTY); - tagNamesInUse = UserPreferences.groupItemsInTreeByDatasource() + tagNamesInUse = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUseForUser(datasourceObjId, userName) : Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUseForUser(userName); } else { - tagNamesInUse = UserPreferences.groupItemsInTreeByDatasource() + tagNamesInUse = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse(datasourceObjId) : Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse(); } @@ -301,7 +303,7 @@ public class Tags implements AutopsyVisitableItem { TagsManager tm = Case.getCurrentCaseThrows().getServices().getTagsManager(); if (UserPreferences.showOnlyCurrentUserTags()) { String userName = System.getProperty(USER_NAME_PROPERTY); - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { tagsCount = tm.getContentTagsCountByTagNameForUser(tagName, datasourceObjId, userName); tagsCount += tm.getBlackboardArtifactTagsCountByTagNameForUser(tagName, datasourceObjId, userName); } else { @@ -309,7 +311,7 @@ public class Tags implements AutopsyVisitableItem { tagsCount += tm.getBlackboardArtifactTagsCountByTagNameForUser(tagName, userName); } } else { - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { tagsCount = tm.getContentTagsCountByTagName(tagName, datasourceObjId); tagsCount += tm.getBlackboardArtifactTagsCountByTagName(tagName, datasourceObjId); } else { @@ -422,11 +424,11 @@ public class Tags implements AutopsyVisitableItem { if (UserPreferences.showOnlyCurrentUserTags()) { String userName = System.getProperty(USER_NAME_PROPERTY); - tagsCount = UserPreferences.groupItemsInTreeByDatasource() + tagsCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagNameForUser(tagName, datasourceObjId, userName) : Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagNameForUser(tagName, userName); } else { - tagsCount = UserPreferences.groupItemsInTreeByDatasource() + tagsCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagName(tagName, datasourceObjId) : Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagName(tagName); } @@ -484,7 +486,7 @@ public class Tags implements AutopsyVisitableItem { protected boolean createKeys(List keys) { // Use the content tags bearing the specified tag name as the keys. try { - List contentTags = UserPreferences.groupItemsInTreeByDatasource() + List contentTags = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByTagName(tagName, datasourceObjId) : Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByTagName(tagName); if (UserPreferences.showOnlyCurrentUserTags()) { @@ -542,11 +544,11 @@ public class Tags implements AutopsyVisitableItem { try { if (UserPreferences.showOnlyCurrentUserTags()) { String userName = System.getProperty(USER_NAME_PROPERTY); - tagsCount = UserPreferences.groupItemsInTreeByDatasource() + tagsCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagNameForUser(tagName, datasourceObjId, userName) : Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagNameForUser(tagName, userName); } else { - tagsCount = UserPreferences.groupItemsInTreeByDatasource() + tagsCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagName(tagName, datasourceObjId) : Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagName(tagName); } @@ -604,7 +606,7 @@ public class Tags implements AutopsyVisitableItem { protected boolean createKeys(List keys) { try { // Use the blackboard artifact tags bearing the specified tag name as the keys. - List artifactTags = UserPreferences.groupItemsInTreeByDatasource() + List artifactTags = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByTagName(tagName, datasourceObjId) : Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByTagName(tagName); if (UserPreferences.showOnlyCurrentUserTags()) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index ff34985bc7..af4dd6c35e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -153,14 +153,8 @@ final public class Accounts implements AutopsyVisitableItem { * based on the UserPreferences groupItemsInTreeByDatasource setting */ private String getFilterByDataSourceClause() { - try { - Case currentCase = Case.getCurrentCaseThrows(); - CasePreferences casePreferences = new CasePreferences(currentCase); - if (Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true)) { - return " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId + " "; - } - } catch (NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, "No current case open.", ex); //DLG: Review this change. How should we return out of this??? + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { + return " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId + " "; } return " "; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form index bacd1d8903..ccdd7650ea 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form @@ -1,6 +1,14 @@
+ + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 880ebce710..db4f4d66d0 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -42,8 +42,11 @@ import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; import java.util.Properties; import javax.swing.Action; +import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; import javax.swing.tree.TreeSelectionModel; import org.apache.commons.lang3.StringUtils; import org.openide.explorer.ExplorerManager; @@ -69,6 +72,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl; import org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer; import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; +import org.sleuthkit.autopsy.corecomponents.ViewPreferencesPanel; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.datamodel.ArtifactNodeSelectionInfo; @@ -107,6 +111,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat private final transient ExplorerManager em = new ExplorerManager(); private static DirectoryTreeTopComponent instance; private final DataResultTopComponent dataResult = new DataResultTopComponent(Bundle.DirectoryTreeTopComponent_resultsView_title()); + private final ViewPreferencesPanel viewPreferencesPanel = new ViewPreferencesPanel(true); private final LinkedList backList; private final LinkedList forwardList; private static final String PREFERRED_ID = "DirectoryTreeTopComponent"; //NON-NLS @@ -114,6 +119,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat private AutopsyTreeChildFactory autopsyTreeChildFactory; private Children autopsyTreeChildren; private Accounts accounts; + private boolean showRejectedResults; private static final long DEFAULT_DATASOURCE_GROUPING_THRESHOLD = 5; // Threshold for prompting the user about grouping by data source private static final String GROUPING_THRESHOLD_NAME = "GroupDataSourceThreshold"; private static final String SETTINGS_FILE = "CasePreferences.properties"; //NON-NLS @@ -140,8 +146,27 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat backButton.setEnabled(false); forwardButton.setEnabled(false); - groupByDatasourceCheckBox.setSelected(UserPreferences.groupItemsInTreeByDatasource()); + groupByDatasourceCheckBox.setSelected(Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)); showOnlyCurrentUserTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags()); + + viewPreferencesPopupMenu.add(viewPreferencesPanel); + viewPreferencesPopupMenu.setSize(viewPreferencesPanel.getPreferredSize().width + 6, viewPreferencesPanel.getPreferredSize().height + 6); + viewPreferencesPopupMenu.addPopupMenuListener(new PopupMenuListener() { + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + openViewPreferencesButton.setSelected(true); + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + openViewPreferencesButton.setSelected(false); + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + openViewPreferencesButton.setSelected(false); + } + }); } /** @@ -185,6 +210,17 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat public DataResultTopComponent getDirectoryListing() { return this.dataResult; } + + public boolean getShowRejectedResults() { + return showRejectedResults; + } + + public void setShowRejectedResults(boolean showRejectedResults) { + this.showRejectedResults = showRejectedResults; + if (accounts != null) { + accounts.setShowRejected(showRejectedResults); + } + } /** * This method is called from within the constructor to initialize the form. @@ -194,6 +230,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat // //GEN-BEGIN:initComponents private void initComponents() { + viewPreferencesPopupMenu = new javax.swing.JPopupMenu(); treeView = new BeanTreeView(); backButton = new javax.swing.JButton(); forwardButton = new javax.swing.JButton(); @@ -369,8 +406,18 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat }//GEN-LAST:event_showRejectedCheckBoxActionPerformed private void openViewPreferencesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openViewPreferencesButtonActionPerformed - ViewPreferencesDialog dialog = new ViewPreferencesDialog(); - dialog.display(); + //DLG: ViewPreferencesDialog dialog = new ViewPreferencesDialog(); + //DLG: dialog.display(); + + /*ViewPreferencesPanel panel = new ViewPreferencesPanel(); + panel.load(); + + JPopupMenu menu = new JPopupMenu(); + menu.add(panel); + menu.show(openViewPreferencesButton, panel.getWidth(), panel.getHeight());*/ + + viewPreferencesPanel.load(); + viewPreferencesPopupMenu.show(openViewPreferencesButton, 0, openViewPreferencesButton.getHeight() - 1); }//GEN-LAST:event_openViewPreferencesButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables @@ -381,6 +428,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat private javax.swing.JCheckBox showOnlyCurrentUserTagsCheckbox; private javax.swing.JCheckBox showRejectedCheckBox; private javax.swing.JScrollPane treeView; + private javax.swing.JPopupMenu viewPreferencesPopupMenu; // End of variables declaration//GEN-END:variables /** @@ -440,20 +488,15 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat * @param dataSourceCount */ private void promptForDataSourceGrouping(Case currentCase, int dataSourceCount) { - CasePreferences casePreferences = new CasePreferences(currentCase); - - if (casePreferences.getGroupItemsInTreeByDataSource() == null) { + if (CasePreferences.getGroupItemsInTreeByDataSource() == null) { GroupDataSourcesDialog dialog = new GroupDataSourcesDialog(dataSourceCount); dialog.display(); if (dialog.groupByDataSourceSelected()) { - casePreferences.setGroupItemsInTreeByDataSource(true); + CasePreferences.setGroupItemsInTreeByDataSource(true); refreshContentTreeSafe(); //DLG: Consider an event. } else { - casePreferences.setGroupItemsInTreeByDataSource(false); + CasePreferences.setGroupItemsInTreeByDataSource(false); } - - // Save the response - casePreferences.saveToStorage(currentCase); } } @@ -498,7 +541,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat try { int dataSourceCount = currentCase.getDataSources().size(); - if (!UserPreferences.groupItemsInTreeByDatasource() + if (!Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) && dataSourceCount > threshold) { promptForDataSourceGrouping(currentCase, dataSourceCount); } @@ -928,7 +971,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat private void refreshTagsTree() { SwingUtilities.invokeLater(() -> { // if no open case or has no data then there is no tree to rebuild - if (UserPreferences.groupItemsInTreeByDatasource()) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { for (Node dataSource : autopsyTreeChildren.getNodes()) { Node tagsNode = dataSource.getChildren().findChild(Tags.getTagsDisplayName()); if (tagsNode != null) { diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index 585241c4f8..96fccea7ea 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -149,8 +149,7 @@ public class ViewContextAction extends AbstractAction { } Node parentTreeViewNode; - CasePreferences casePreferences = new CasePreferences(currentCase); - if (Objects.equals(casePreferences.getGroupItemsInTreeByDataSource(), true)) { // 'Group by Data Source' view + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { // 'Group by Data Source' view SleuthkitCase skCase; String dsname; From 3a1cc602f62c143da48dd9d0365e00aebeb47892 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 13 Sep 2018 00:18:10 -0400 Subject: [PATCH 025/273] Fixed button anchor on directory tree. --- .../DirectoryTreeTopComponent.form | 38 +++++++++---------- .../DirectoryTreeTopComponent.java | 32 ++++++++-------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form index ccdd7650ea..c36a2ca273 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form @@ -24,26 +24,26 @@ - - - + + - - - - - - - - + + + + + + + + + - + @@ -56,14 +56,14 @@ - - - - - - + + - + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index db4f4d66d0..22320f9d1f 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -310,21 +310,20 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(treeView) .addGroup(layout.createSequentialGroup() - .addGap(1, 1, 1) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(showOnlyCurrentUserTagsCheckbox) - .addGap(18, 18, 18) - .addComponent(showRejectedCheckBox) - .addGap(18, 18, 18) - .addComponent(groupByDatasourceCheckBox)) .addGroup(layout.createSequentialGroup() .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(254, 254, 254) - .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(showOnlyCurrentUserTagsCheckbox) + .addComponent(showRejectedCheckBox) + .addComponent(groupByDatasourceCheckBox)) + .addGap(0, 247, Short.MAX_VALUE))) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -334,13 +333,14 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(9, 9, 9) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(showOnlyCurrentUserTagsCheckbox) - .addComponent(showRejectedCheckBox) - .addComponent(groupByDatasourceCheckBox)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(showOnlyCurrentUserTagsCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(treeView, javax.swing.GroupLayout.DEFAULT_SIZE, 870, Short.MAX_VALUE)) + .addComponent(showRejectedCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(groupByDatasourceCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(treeView, javax.swing.GroupLayout.DEFAULT_SIZE, 828, Short.MAX_VALUE)) ); }// //GEN-END:initComponents From a3547b0e8c32ce2e133fdd8cc7e69c04ae91473e Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 13 Sep 2018 01:27:57 -0400 Subject: [PATCH 026/273] Cleanup. --- .../autopsy/casemodule/Bundle.properties | 2 - .../autopsy/core/UserPreferences.java | 6 +- .../corecomponents/AutopsyOptionsPanel.form | 242 +----------------- .../corecomponents/AutopsyOptionsPanel.java | 232 +---------------- .../autopsy/corecomponents/Bundle.properties | 17 -- .../corecomponents/Bundle_ja.properties | 11 - .../corecomponents/ViewPreferencesDialog.form | 78 ------ .../corecomponents/ViewPreferencesDialog.java | 133 ---------- .../corecomponents/ViewPreferencesPanel.java | 77 +++--- .../autopsy/datamodel/accounts/Accounts.java | 4 +- .../autopsy/directorytree/Bundle.properties | 3 - .../DirectoryTreeTopComponent.form | 60 +---- .../DirectoryTreeTopComponent.java | 86 +------ 13 files changed, 69 insertions(+), 882 deletions(-) delete mode 100755 Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.form delete mode 100755 Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index a89ea845dd..4154a913b9 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -233,5 +233,3 @@ LocalDiskSelectionDialog.okButton.text=OK LocalDiskPanel.localDiskLabel.text=Local Disk: LocalDiskPanel.imageWriterErrorLabel.text=Error Label LocalDiskSelectionDialog.title=Select Local Disk -ViewPreferencesDialog.okButton.text=OK -ViewPreferencesDialog.cancelButton.text=Cancel diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 3b92e24481..48ce2c5731 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -189,11 +189,13 @@ public final class UserPreferences { preferences.putInt(NUMBER_OF_FILE_INGEST_THREADS, value); } - public static boolean groupItemsInTreeByDatasource() { //DLG: Replace use of this with the equivallent method in CasePreferences + @Deprecated + public static boolean groupItemsInTreeByDatasource() { return preferences.getBoolean(GROUP_ITEMS_IN_TREE_BY_DATASOURCE, false); } - public static void setGroupItemsInTreeByDatasource(boolean value) { //DLG: Replace use of this with the equivallent method in CasePreferences + @Deprecated + public static void setGroupItemsInTreeByDatasource(boolean value) { preferences.putBoolean(GROUP_ITEMS_IN_TREE_BY_DATASOURCE, value); } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form index b63f0c6f8b..94a225dfe0 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form @@ -35,7 +35,7 @@ - + @@ -64,15 +64,11 @@ - - - - - - - - - + + + + + @@ -81,14 +77,11 @@ - - - - - + + - + @@ -128,7 +121,7 @@ - + @@ -232,219 +225,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -471,7 +251,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java index 2bdf9dd7ea..b2558400ed 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java @@ -285,16 +285,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { * Load the saved user preferences. */ void load() { - boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer(); - oldKeepCurrentViewerRB.setSelected(keepPreferredViewer); - oldUseBestViewerRB.setSelected(!keepPreferredViewer); - oldDataSourcesHideKnownCB.setSelected(UserPreferences.hideKnownFilesInDataSourcesTree()); - oldViewsHideKnownCB.setSelected(UserPreferences.hideKnownFilesInViewsTree()); - oldDataSourcesHideSlackCB.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree()); - oldViewsHideSlackCB.setSelected(UserPreferences.hideSlackFilesInViewsTree()); - boolean useLocalTime = UserPreferences.displayTimesInLocalTime(); - oldUseLocalTimeRB.setSelected(useLocalTime); - oldUseGMTTimeRB.setSelected(!useLocalTime); String path = ModuleSettings.getConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP); boolean useDefault = (path == null || path.isEmpty()); defaultLogoRB.setSelected(useDefault); @@ -350,12 +340,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { * Store the current user preferences. */ void store() { - UserPreferences.setKeepPreferredContentViewer(oldKeepCurrentViewerRB.isSelected()); - UserPreferences.setHideKnownFilesInDataSourcesTree(oldDataSourcesHideKnownCB.isSelected()); - UserPreferences.setHideKnownFilesInViewsTree(oldViewsHideKnownCB.isSelected()); - UserPreferences.setHideSlackFilesInDataSourcesTree(oldDataSourcesHideSlackCB.isSelected()); - UserPreferences.setHideSlackFilesInViewsTree(oldViewsHideSlackCB.isSelected()); - UserPreferences.setDisplayTimesInLocalTime(oldUseLocalTimeRB.isSelected()); UserPreferences.setLogFileCount(Integer.parseInt(logFileCount.getText())); if (!agencyLogoPathField.getText().isEmpty()) { File file = new File(agencyLogoPathField.getText()); @@ -535,19 +519,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { defaultLogoRB = new javax.swing.JRadioButton(); specifyLogoRB = new javax.swing.JRadioButton(); agencyLogoPathFieldValidationLabel = new javax.swing.JLabel(); - oldViewPanel = new javax.swing.JPanel(); - jLabelSelectFile = new javax.swing.JLabel(); - oldUseBestViewerRB = new javax.swing.JRadioButton(); - oldKeepCurrentViewerRB = new javax.swing.JRadioButton(); - jLabelHideKnownFiles = new javax.swing.JLabel(); - oldDataSourcesHideKnownCB = new javax.swing.JCheckBox(); - oldViewsHideKnownCB = new javax.swing.JCheckBox(); - jLabelHideSlackFiles = new javax.swing.JLabel(); - oldDataSourcesHideSlackCB = new javax.swing.JCheckBox(); - oldViewsHideSlackCB = new javax.swing.JCheckBox(); - jLabelTimeDisplay = new javax.swing.JLabel(); - oldUseLocalTimeRB = new javax.swing.JRadioButton(); - oldUseGMTTimeRB = new javax.swing.JRadioButton(); runtimePanel = new javax.swing.JPanel(); maxMemoryLabel = new javax.swing.JLabel(); maxMemoryUnitsLabel = new javax.swing.JLabel(); @@ -624,7 +595,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addComponent(agencyLogoPathFieldValidationLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(agencyLogoPreview, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(479, Short.MAX_VALUE)) ); logoPanelLayout.setVerticalGroup( logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -643,139 +614,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGap(0, 0, Short.MAX_VALUE)) ); - oldViewPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldViewPanel.border.title"))); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(jLabelSelectFile, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelSelectFile.text")); // NOI18N - - fileSelectionButtonGroup.add(oldUseBestViewerRB); - org.openide.awt.Mnemonics.setLocalizedText(oldUseBestViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldUseBestViewerRB.text")); // NOI18N - oldUseBestViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldUseBestViewerRB.toolTipText")); // NOI18N - oldUseBestViewerRB.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - oldUseBestViewerRBActionPerformed(evt); - } - }); - - fileSelectionButtonGroup.add(oldKeepCurrentViewerRB); - org.openide.awt.Mnemonics.setLocalizedText(oldKeepCurrentViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldKeepCurrentViewerRB.text")); // NOI18N - oldKeepCurrentViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldKeepCurrentViewerRB.toolTipText")); // NOI18N - oldKeepCurrentViewerRB.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - oldKeepCurrentViewerRBActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(jLabelHideKnownFiles, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelHideKnownFiles.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(oldDataSourcesHideKnownCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldDataSourcesHideKnownCB.text")); // NOI18N - oldDataSourcesHideKnownCB.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - oldDataSourcesHideKnownCBActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(oldViewsHideKnownCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldViewsHideKnownCB.text")); // NOI18N - oldViewsHideKnownCB.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - oldViewsHideKnownCBActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(jLabelHideSlackFiles, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelHideSlackFiles.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(oldDataSourcesHideSlackCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldDataSourcesHideSlackCB.text")); // NOI18N - oldDataSourcesHideSlackCB.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - oldDataSourcesHideSlackCBActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(oldViewsHideSlackCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldViewsHideSlackCB.text")); // NOI18N - oldViewsHideSlackCB.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - oldViewsHideSlackCBActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(jLabelTimeDisplay, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelTimeDisplay.text")); // NOI18N - - displayTimesButtonGroup.add(oldUseLocalTimeRB); - org.openide.awt.Mnemonics.setLocalizedText(oldUseLocalTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldUseLocalTimeRB.text")); // NOI18N - oldUseLocalTimeRB.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - oldUseLocalTimeRBActionPerformed(evt); - } - }); - - displayTimesButtonGroup.add(oldUseGMTTimeRB); - org.openide.awt.Mnemonics.setLocalizedText(oldUseGMTTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.oldUseGMTTimeRB.text")); // NOI18N - oldUseGMTTimeRB.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - oldUseGMTTimeRBActionPerformed(evt); - } - }); - - javax.swing.GroupLayout oldViewPanelLayout = new javax.swing.GroupLayout(oldViewPanel); - oldViewPanel.setLayout(oldViewPanelLayout); - oldViewPanelLayout.setHorizontalGroup( - oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, oldViewPanelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(oldViewPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(oldViewPanelLayout.createSequentialGroup() - .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(oldUseGMTTimeRB) - .addComponent(oldKeepCurrentViewerRB) - .addComponent(oldUseBestViewerRB) - .addComponent(oldDataSourcesHideKnownCB) - .addComponent(oldViewsHideKnownCB)) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(oldViewPanelLayout.createSequentialGroup() - .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(oldDataSourcesHideSlackCB) - .addComponent(oldViewsHideSlackCB) - .addComponent(oldUseLocalTimeRB)) - .addContainerGap(158, Short.MAX_VALUE)))) - .addGroup(oldViewPanelLayout.createSequentialGroup() - .addGroup(oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabelHideSlackFiles) - .addComponent(jLabelTimeDisplay) - .addComponent(jLabelHideKnownFiles) - .addComponent(jLabelSelectFile)) - .addGap(30, 30, 30)))) - ); - oldViewPanelLayout.setVerticalGroup( - oldViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, oldViewPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabelSelectFile) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(oldUseBestViewerRB) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(oldKeepCurrentViewerRB) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabelHideKnownFiles) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(oldDataSourcesHideKnownCB) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(oldViewsHideKnownCB) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabelHideSlackFiles) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(oldDataSourcesHideSlackCB) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(oldViewsHideSlackCB) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabelTimeDisplay) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(oldUseLocalTimeRB) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(oldUseGMTTimeRB)) - ); - runtimePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.runtimePanel.border.title"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(maxMemoryLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.maxMemoryLabel.text")); // NOI18N @@ -831,7 +669,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGroup(runtimePanelLayout.createSequentialGroup() .addComponent(maxMemoryUnitsLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, 783, Short.MAX_VALUE)) .addGroup(runtimePanelLayout.createSequentialGroup() .addComponent(maxMemoryUnitsLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -884,26 +722,21 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1010, Short.MAX_VALUE) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(oldViewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1002, Short.MAX_VALUE)) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(0, 0, 0) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(oldViewPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap() + .addComponent(runtimePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + .addContainerGap(185, Short.MAX_VALUE)) ); jScrollPane1.setViewportView(jPanel1); @@ -917,7 +750,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(0, 0, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -940,38 +773,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_memFieldKeyReleased - private void oldUseGMTTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldUseGMTTimeRBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_oldUseGMTTimeRBActionPerformed - - private void oldUseLocalTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldUseLocalTimeRBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_oldUseLocalTimeRBActionPerformed - - private void oldViewsHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldViewsHideSlackCBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_oldViewsHideSlackCBActionPerformed - - private void oldDataSourcesHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldDataSourcesHideSlackCBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_oldDataSourcesHideSlackCBActionPerformed - - private void oldViewsHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldViewsHideKnownCBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_oldViewsHideKnownCBActionPerformed - - private void oldDataSourcesHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldDataSourcesHideKnownCBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_oldDataSourcesHideKnownCBActionPerformed - - private void oldKeepCurrentViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldKeepCurrentViewerRBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_oldKeepCurrentViewerRBActionPerformed - - private void oldUseBestViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oldUseBestViewerRBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_oldUseBestViewerRBActionPerformed - private void specifyLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyLogoRBActionPerformed agencyLogoPathField.setEnabled(true); browseLogosButton.setEnabled(true); @@ -1031,10 +832,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JRadioButton defaultLogoRB; private javax.swing.ButtonGroup displayTimesButtonGroup; private javax.swing.ButtonGroup fileSelectionButtonGroup; - private javax.swing.JLabel jLabelHideKnownFiles; - private javax.swing.JLabel jLabelHideSlackFiles; - private javax.swing.JLabel jLabelSelectFile; - private javax.swing.JLabel jLabelTimeDisplay; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextField logFileCount; @@ -1047,15 +844,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JLabel maxMemoryUnitsLabel1; private javax.swing.JTextField memField; private javax.swing.JLabel memFieldValidationLabel; - private javax.swing.JCheckBox oldDataSourcesHideKnownCB; - private javax.swing.JCheckBox oldDataSourcesHideSlackCB; - private javax.swing.JRadioButton oldKeepCurrentViewerRB; - private javax.swing.JRadioButton oldUseBestViewerRB; - private javax.swing.JRadioButton oldUseGMTTimeRB; - private javax.swing.JRadioButton oldUseLocalTimeRB; - private javax.swing.JPanel oldViewPanel; - private javax.swing.JCheckBox oldViewsHideKnownCB; - private javax.swing.JCheckBox oldViewsHideSlackCB; private javax.swing.JLabel restartNecessaryWarning; private javax.swing.JPanel runtimePanel; private javax.swing.JRadioButton specifyLogoRB; diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index 1a83101f5e..6191af9990 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -96,9 +96,6 @@ DataResultViewerThumbnail.comboBox.mediumThumbnails=Medium Thumbnails DataResultViewerThumbnail.comboBox.largeThumbnails=Large Thumbnails DataResultViewerThumbnail.switchPage.done.errMsg=Error making thumbnails\: {0} AboutWindowPanel.actVerboseLogging.text=Activate verbose logging -AutopsyOptionsPanel.jLabelSelectFile.text=When selecting a file: -AutopsyOptionsPanel.jLabelHideKnownFiles.text=Hide known files (i.e. those in the NIST NSRL) in the: -AutopsyOptionsPanel.jLabelTimeDisplay.text=When displaying times: OptionsCategory_Name_Multi_User_Settings=Multi-User OptionsCategory_Keywords_Multi_User_Options=Multi-User Settings MultiUserSettingsPanel.lbSolrSettings.text=Solr Settings @@ -145,7 +142,6 @@ MultiUserSettingsPanel.lbTestSolrWarning.text= MultiUserSettingsPanel.lbTestDbWarning.text= MultiUserSettingsPanel.KeywordSearchNull=Cannot find keyword search service MultiUserSettingsPanel.InvalidPortNumber=Invalid port number -AutopsyOptionsPanel.jLabelHideSlackFiles.text=Hide slack files in the: AutopsyOptionsPanel.agencyLogoImageLabel.toolTipText= AutopsyOptionsPanel.agencyLogoPathField.text= SortChooserDialog.label=remove @@ -180,19 +176,6 @@ ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=Hide other user's tags ViewPreferencesPanel.currentCaseSettingsPanel.border.title=Current Case Settings OptionsCategory_Name_View=View OptionsCategory_Keywords_View=View -ViewPreferencesDialog.okButton.text=OK -ViewPreferencesDialog.cancelButton.text=Cancel -AutopsyOptionsPanel.oldViewPanel.border.title=View -AutopsyOptionsPanel.oldUseBestViewerRB.toolTipText=For example, change from Hex to Media when a JPEG is selected. -AutopsyOptionsPanel.oldUseBestViewerRB.text=Change to the most specific file viewer -AutopsyOptionsPanel.oldKeepCurrentViewerRB.toolTipText=For example, stay in Hex view when a JPEG is selected. -AutopsyOptionsPanel.oldKeepCurrentViewerRB.text=Stay on the same file viewer -AutopsyOptionsPanel.oldDataSourcesHideKnownCB.text=Data Sources area (the directory hierarchy) -AutopsyOptionsPanel.oldViewsHideKnownCB.text=Views area -AutopsyOptionsPanel.oldDataSourcesHideSlackCB.text=Data Sources area (the directory hierarchy) -AutopsyOptionsPanel.oldViewsHideSlackCB.text=Views area -AutopsyOptionsPanel.oldUseLocalTimeRB.text=Use local time zone -AutopsyOptionsPanel.oldUseGMTTimeRB.text=Use GMT ViewPreferencesPanel.useBestViewerRadioButton.toolTipText=For example, change from Hex to Media when a JPEG is selected. ViewPreferencesPanel.useBestViewerRadioButton.text=Change to the most specific file viewer ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText=For example, stay in Hex view when a JPEG is selected. diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties index 0eadc6458b..0085a9f773 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties @@ -79,9 +79,6 @@ DataResultViewerThumbnail.comboBox.mediumThumbnails=\u30b5\u30e0\u30cd\u30a4\u30 DataResultViewerThumbnail.comboBox.largeThumbnails=\u30b5\u30e0\u30cd\u30a4\u30eb\uff08\u5927\uff09 DataResultViewerThumbnail.switchPage.done.errMsg=\u30b5\u30e0\u30cd\u30a4\u30eb\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a {0} AboutWindowPanel.actVerboseLogging.text=Verbose\u30ed\u30b0\u3092\u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8 -AutopsyOptionsPanel.jLabelSelectFile.text=\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3059\u308b\u5834\u5408\uff1a -AutopsyOptionsPanel.jLabelHideKnownFiles.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\uff08NIST NSRL\u5185\u306e\uff09\u3092\u6b21\u306b\u96a0\u3059\uff1a -AutopsyOptionsPanel.jLabelTimeDisplay.text=\u6642\u9593\u3092\u8868\u793a\u3059\u308b\u5834\u5408\uff1a OptionsCategory_Name_Multi_User_Settings=\u8907\u6570\u306e\u30e6\u30fc\u30b6\u30fc OptionsCategory_Keywords_Multi_User_Options=\u8907\u6570\u306e\u30e6\u30fc\u30b6\u30fc\u30aa\u30d7\u30b7\u30e7\u30f3 MultiUserSettingsPanel.lbSolrSettings.text=Solr\u8a2d\u5b9a @@ -126,14 +123,6 @@ DataResultPanel.descriptionLabel.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30d1 ViewPreferencesPanel.selectFileLabel.text=\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3059\u308b\u5834\u5408\uff1a ViewPreferencesPanel.displayTimeLabel.text=\u6642\u9593\u3092\u8868\u793a\u3059\u308b\u5834\u5408\uff1a ViewPreferencesPanel.hideKnownFilesLabel.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\uff08NIST NSRL\u5185\u306e\uff09\u3092\u6b21\u306b\u96a0\u3059\uff1a -AutopsyOptionsPanel.oldUseBestViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u306fHEX\u304b\u3089\u30e1\u30c7\u30a3\u30a2\u306b\u5909\u66f4\u3059\u308b\u3002 -AutopsyOptionsPanel.oldUseBestViewerRB.text=\u6700\u3082\u5c02\u9580\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u306b\u5909\u66f4 -AutopsyOptionsPanel.oldKeepCurrentViewerRB.text=\u305d\u306e\u307e\u307e\u540c\u3058\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u3092\u4f7f\u7528 -AutopsyOptionsPanel.oldKeepCurrentViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u305d\u306e\u307e\u307eHEX\u30d3\u30e5\u30fc\u3092\u4f7f\u7528\u3002 -AutopsyOptionsPanel.oldDataSourcesHideKnownCB.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a8\u30ea\u30a2\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u968e\u5c64\uff09 -AutopsyOptionsPanel.oldViewsHideKnownCB.text=\u30d3\u30e5\u30fc\u30a8\u30ea\u30a2 -AutopsyOptionsPanel.oldUseLocalTimeRB.text=\u30ed\u30fc\u30ab\u30eb\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u4f7f\u7528 -AutopsyOptionsPanel.oldUseGMTTimeRB.text=GMT\u3092\u4f7f\u7528 ViewPreferencesPanel.useBestViewerRadioButton.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u306fHEX\u304b\u3089\u30e1\u30c7\u30a3\u30a2\u306b\u5909\u66f4\u3059\u308b\u3002 ViewPreferencesPanel.useBestViewerRadioButton.text=\u6700\u3082\u5c02\u9580\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u306b\u5909\u66f4 ViewPreferencesPanel.keepCurrentViewerRadioButton.text=\u305d\u306e\u307e\u307e\u540c\u3058\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u3092\u4f7f\u7528 diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.form deleted file mode 100755 index d57d767a1e..0000000000 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.form +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.java deleted file mode 100755 index bab69e596b..0000000000 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesDialog.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit 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.corecomponents; - -import java.awt.Dialog; -import org.openide.util.NbBundle; -import org.openide.windows.WindowManager; - -/** - * Popup dialog for hosting the ViewPreferencesPanel. This is intended to be - * used from the DirectoryTreeTopComponent. - */ -final public class ViewPreferencesDialog extends javax.swing.JDialog { - - /** - * Creates new form ViewPreferencesDialog - */ - @NbBundle.Messages({ - "ViewPreferencesDialog.title.text=View Preferences" - }) - public ViewPreferencesDialog() { - super(WindowManager.getDefault().getMainWindow(), - Bundle.ViewPreferencesDialog_title_text(), - Dialog.ModalityType.APPLICATION_MODAL); - initComponents(); - viewPreferencesPanel.load(); - } - - /** - * Show the dialog. - */ - public void display() { - setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - setVisible(true); - } - - /** - * Close the dialog. - */ - private void close() { - setVisible(false); - dispose(); - } - - /** - * 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") - // //GEN-BEGIN:initComponents - private void initComponents() { - - okButton = new javax.swing.JButton(); - cancelButton = new javax.swing.JButton(); - viewPreferencesPanel = new org.sleuthkit.autopsy.corecomponents.ViewPreferencesPanel(); - - setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - - org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(ViewPreferencesDialog.class, "ViewPreferencesDialog.okButton.text")); // NOI18N - okButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - okButtonActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(ViewPreferencesDialog.class, "ViewPreferencesDialog.cancelButton.text")); // NOI18N - cancelButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - cancelButtonActionPerformed(evt); - } - }); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(viewPreferencesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(viewPreferencesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(okButton) - .addComponent(cancelButton)) - .addContainerGap()) - ); - - pack(); - }// //GEN-END:initComponents - - private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed - viewPreferencesPanel.store(); - close(); - }//GEN-LAST:event_okButtonActionPerformed - - private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed - close(); - }//GEN-LAST:event_cancelButtonActionPerformed - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton cancelButton; - private javax.swing.JButton okButton; - private org.sleuthkit.autopsy.corecomponents.ViewPreferencesPanel viewPreferencesPanel; - // End of variables declaration//GEN-END:variables -} diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index 51dc4d4f5d..4b944744ac 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -18,82 +18,62 @@ */ package org.sleuthkit.autopsy.corecomponents; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Objects; -import java.util.Properties; -import java.util.logging.Level; import javax.swing.JPanel; import org.netbeans.spi.options.OptionsPanelController; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.CasePreferences; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.core.UserPreferences; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; /** * Panel for configuring view preferences. */ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { - - private static final Logger logger = Logger.getLogger(ViewPreferencesPanel.class.getName()); - - private boolean immediateUpdates; - + + private final boolean immediateUpdates; + /** * Creates new form ViewPreferencesPanel - * - * //DLG: Might not need this constructor anymore. - */ - public ViewPreferencesPanel() { - initComponents(); - } - - /** - * Creates new form ViewPreferencesPanel - * - * //DLG: + * + * @param immediateUpdates If true, value changes will be persisted at the + * moment they occur. */ public ViewPreferencesPanel(boolean immediateUpdates) { initComponents(); this.immediateUpdates = immediateUpdates; } - + @Override public void load() { // Global Settings boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer(); keepCurrentViewerRadioButton.setSelected(keepPreferredViewer); useBestViewerRadioButton.setSelected(!keepPreferredViewer); - + boolean useLocalTime = UserPreferences.displayTimesInLocalTime(); useLocalTimeRadioButton.setSelected(useLocalTime); useGMTTimeRadioButton.setSelected(!useLocalTime); - + dataSourcesHideKnownCheckbox.setSelected(UserPreferences.hideKnownFilesInDataSourcesTree()); viewsHideKnownCheckbox.setSelected(UserPreferences.hideKnownFilesInViewsTree()); - + dataSourcesHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree()); viewsHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInViewsTree()); - + // Current Case Settings boolean caseIsOpen = Case.isCaseOpen(); currentCaseSettingsPanel.setEnabled(caseIsOpen); hideOtherUsersTagsCheckbox.setEnabled(caseIsOpen); groupByDataSourceCheckbox.setEnabled(caseIsOpen); - - hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags() == false); + + hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags()); groupByDataSourceCheckbox.setSelected(Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)); - + // Current Session Settings hideRejectedResultsCheckbox.setSelected(DirectoryTreeTopComponent.getDefault().getShowRejectedResults() == false); } - + @Override public void store() { UserPreferences.setKeepPreferredContentViewer(keepCurrentViewerRadioButton.isSelected()); @@ -102,23 +82,24 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { UserPreferences.setHideKnownFilesInViewsTree(viewsHideKnownCheckbox.isSelected()); UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCheckbox.isSelected()); UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected()); - UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected() == false); - + UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected()); + storeGroupItemsInTreeByDataSource(); - + DirectoryTreeTopComponent.getDefault().setShowRejectedResults(hideRejectedResultsCheckbox.isSelected() == false); } - + + /** + * Store the 'groupByDataSourceCheckbox' value. + * + * Note: The value will not be stored if the value hasn't previously been + * stored and the checkbox isn't selected. This is so GroupDataSourcesDialog + * can prompt the user for this in the event the value hasn't been + * initialized. + */ private void storeGroupItemsInTreeByDataSource() { - if (Case.isCaseOpen()) { - /* - * Only write the value if it has already been previously stored, or - * if the checkbox is selected. This allows GroupDataSourcesDialog - * to work. - */ - if (CasePreferences.getGroupItemsInTreeByDataSource() != null || groupByDataSourceCheckbox.isSelected()) { - CasePreferences.setGroupItemsInTreeByDataSource(groupByDataSourceCheckbox.isSelected()); - } + if (Case.isCaseOpen() && (CasePreferences.getGroupItemsInTreeByDataSource() != null || groupByDataSourceCheckbox.isSelected())) { + CasePreferences.setGroupItemsInTreeByDataSource(groupByDataSourceCheckbox.isSelected()); } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index af4dd6c35e..d8fbd410ff 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -167,7 +167,7 @@ final public class Accounts implements AutopsyVisitableItem { * @return An Action that will toggle whether rejected artifacts are shown * in the tree rooted by this Accounts instance. */ - //DLG: Remove this! + @Deprecated public Action newToggleShowRejectedAction() { return new ToggleShowRejected(); } @@ -1690,7 +1690,7 @@ final public class Accounts implements AutopsyVisitableItem { } - //DLG: Remove this! + @Deprecated private final class ToggleShowRejected extends AbstractAction { @NbBundle.Messages("ToggleShowRejected.name=Show Rejected Results") diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties index 10bd0622cb..26c970b2b3 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties @@ -59,7 +59,6 @@ DirectoryTreeFilterNode.action.collapseAll.text=Collapse All DirectoryTreeFilterNode.action.openFileSrcByAttr.text=Open File Search by Attributes DirectoryTreeFilterNode.action.runIngestMods.text=Run Ingest Modules DirectoryTreeTopComponent.action.viewArtContent.text=View Artifact Content -DirectoryTreeTopComponent.showRejectedCheckBox.text=Show Rejected ExplorerNodeActionVisitor.action.imgDetails.title=Image Details ExplorerNodeActionVisitor.action.extUnallocToSingleFiles=Extract Unallocated Space to Single Files ExplorerNodeActionVisitor.action.fileSystemDetails.title=File System Details @@ -119,11 +118,9 @@ AddExternalViewerRulePanel.browseButton.text=Browse AddExternalViewerRulePanel.exePathTextField.text= AddExternalViewerRulePanel.exePathLabel.text=Path of the program to use for files with this type or extension AddExternalViewerRulePanel.extRadioButton.text=Extension -DirectoryTreeTopComponent.groupByDatasourceCheckBox.text=Group Data Source GroupDataSourcesDialog.dataSourceCountLabel.text=jLabel1 GroupDataSourcesDialog.queryLabel.text=Would you like to group by data source for faster loading? GroupDataSourcesDialog.yesButton.text=Yes GroupDataSourcesDialog.noButton.text=No GroupDataSourcesDialog.title=Group by Data Source? -DirectoryTreeTopComponent.showOnlyCurrentUserTagsCheckbox.text=Hide Other Tags DirectoryTreeTopComponent.openViewPreferencesButton.text= diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form index c36a2ca273..ac5b8e9c5a 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form @@ -26,23 +26,11 @@ - - - - - - - - - - - - - - - - - + + + + + @@ -56,14 +44,8 @@ - - - - - - - + @@ -168,35 +150,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 22320f9d1f..73d7017149 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -65,7 +65,6 @@ import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.corecomponents.ViewPreferencesDialog; import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl; @@ -145,9 +144,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat this.forwardList = new LinkedList<>(); backButton.setEnabled(false); forwardButton.setEnabled(false); - - groupByDatasourceCheckBox.setSelected(Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)); - showOnlyCurrentUserTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags()); viewPreferencesPopupMenu.add(viewPreferencesPanel); viewPreferencesPopupMenu.setSize(viewPreferencesPanel.getPreferredSize().width + 6, viewPreferencesPanel.getPreferredSize().height + 6); @@ -179,7 +175,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat switch (evt.getKey()) { case UserPreferences.HIDE_KNOWN_FILES_IN_DATA_SRCS_TREE: case UserPreferences.HIDE_SLACK_FILES_IN_DATA_SRCS_TREE: - //DLG: case UserPreferences.GROUP_ITEMS_IN_TREE_BY_DATASOURCE: refreshContentTreeSafe(); break; case UserPreferences.SHOW_ONLY_CURRENT_USER_TAGS: @@ -235,9 +230,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat backButton = new javax.swing.JButton(); forwardButton = new javax.swing.JButton(); openViewPreferencesButton = new javax.swing.JButton(); - showRejectedCheckBox = new javax.swing.JCheckBox(); - groupByDatasourceCheckBox = new javax.swing.JCheckBox(); - showOnlyCurrentUserTagsCheckbox = new javax.swing.JCheckBox(); treeView.setBorder(null); @@ -283,46 +275,17 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat } }); - org.openide.awt.Mnemonics.setLocalizedText(showRejectedCheckBox, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.showRejectedCheckBox.text")); // NOI18N - showRejectedCheckBox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - showRejectedCheckBoxActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(groupByDatasourceCheckBox, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.groupByDatasourceCheckBox.text")); // NOI18N - groupByDatasourceCheckBox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - groupByDatasourceCheckBoxActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(showOnlyCurrentUserTagsCheckbox, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.showOnlyCurrentUserTagsCheckbox.text")); // NOI18N - showOnlyCurrentUserTagsCheckbox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - showOnlyCurrentUserTagsCheckboxActionPerformed(evt); - } - }); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(treeView) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(showOnlyCurrentUserTagsCheckbox) - .addComponent(showRejectedCheckBox) - .addComponent(groupByDatasourceCheckBox)) - .addGap(0, 247, Short.MAX_VALUE))) + .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 264, Short.MAX_VALUE) + .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); layout.setVerticalGroup( @@ -333,14 +296,8 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(showOnlyCurrentUserTagsCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(showRejectedCheckBox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(groupByDatasourceCheckBox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(treeView, javax.swing.GroupLayout.DEFAULT_SIZE, 828, Short.MAX_VALUE)) + .addComponent(treeView, javax.swing.GroupLayout.DEFAULT_SIZE, 900, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -393,29 +350,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat this.setCursor(null); }//GEN-LAST:event_forwardButtonActionPerformed - private void groupByDatasourceCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_groupByDatasourceCheckBoxActionPerformed - UserPreferences.setGroupItemsInTreeByDatasource(this.groupByDatasourceCheckBox.isSelected()); //DLG: Remove this checkbox - }//GEN-LAST:event_groupByDatasourceCheckBoxActionPerformed - - private void showOnlyCurrentUserTagsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showOnlyCurrentUserTagsCheckboxActionPerformed - UserPreferences.setShowOnlyCurrentUserTags(this.showOnlyCurrentUserTagsCheckbox.isSelected()); //DLG: Remove this checkbox - }//GEN-LAST:event_showOnlyCurrentUserTagsCheckboxActionPerformed - - private void showRejectedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showRejectedCheckBoxActionPerformed - //DLG: Remove this checkbox - }//GEN-LAST:event_showRejectedCheckBoxActionPerformed - private void openViewPreferencesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openViewPreferencesButtonActionPerformed - //DLG: ViewPreferencesDialog dialog = new ViewPreferencesDialog(); - //DLG: dialog.display(); - - /*ViewPreferencesPanel panel = new ViewPreferencesPanel(); - panel.load(); - - JPopupMenu menu = new JPopupMenu(); - menu.add(panel); - menu.show(openViewPreferencesButton, panel.getWidth(), panel.getHeight());*/ - viewPreferencesPanel.load(); viewPreferencesPopupMenu.show(openViewPreferencesButton, 0, openViewPreferencesButton.getHeight() - 1); }//GEN-LAST:event_openViewPreferencesButtonActionPerformed @@ -423,10 +358,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton backButton; private javax.swing.JButton forwardButton; - private javax.swing.JCheckBox groupByDatasourceCheckBox; private javax.swing.JButton openViewPreferencesButton; - private javax.swing.JCheckBox showOnlyCurrentUserTagsCheckbox; - private javax.swing.JCheckBox showRejectedCheckBox; private javax.swing.JScrollPane treeView; private javax.swing.JPopupMenu viewPreferencesPopupMenu; // End of variables declaration//GEN-END:variables @@ -493,7 +425,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat dialog.display(); if (dialog.groupByDataSourceSelected()) { CasePreferences.setGroupItemsInTreeByDataSource(true); - refreshContentTreeSafe(); //DLG: Consider an event. + refreshContentTreeSafe(); } else { CasePreferences.setGroupItemsInTreeByDataSource(false); } @@ -599,10 +531,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat Arrays.stream(resultsChildren.getNodes()).forEach(tree::expandNode); accounts = resultsChildren.findChild(Accounts.NAME).getLookup().lookup(Accounts.class); - if (!Objects.isNull(accounts)) { - showRejectedCheckBox.setAction(accounts.newToggleShowRejectedAction()); - showRejectedCheckBox.setSelected(false); - } } Node views = rootChildren.findChild(ViewsNode.NAME); From 9c5e612ffe4493736e4523da5629de8e66ad5f69 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 13 Sep 2018 02:28:19 -0400 Subject: [PATCH 027/273] Fixed bug with button; bug with tags refresh. --- .../autopsy/corecomponents/ViewPreferencesPanel.java | 2 +- .../directorytree/DirectoryTreeTopComponent.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index 4b944744ac..a4ab51bb1f 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -441,7 +441,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { private void hideOtherUsersTagsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideOtherUsersTagsCheckboxActionPerformed if (immediateUpdates) { - UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected() == false); + UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected()); } else { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 73d7017149..0123a8af8d 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -897,6 +897,17 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat * Refresh only the tags subtree(s) of the tree view. */ private void refreshTagsTree() { + // if no open case or has no data then there is no tree to rebuild + Case currentCase; + try { + currentCase = Case.getCurrentCaseThrows(); + } catch (NoCurrentCaseException ex) { + return; + } + if (null == currentCase || currentCase.hasData() == false) { + return; + } + SwingUtilities.invokeLater(() -> { // if no open case or has no data then there is no tree to rebuild if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { From 7e71970049c79b77ce0d151afdf8a5f220df9dcf Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 13 Sep 2018 03:07:56 -0400 Subject: [PATCH 028/273] Added documentation; removed unnecessary code. --- .../autopsy/casemodule/CasePreferences.java | 18 +++++++++++++++++- .../sleuthkit/autopsy/datamodel/FileSize.java | 2 +- .../autopsy/datamodel/accounts/Accounts.java | 2 +- .../DirectoryTreeTopComponent.java | 11 +++++++++++ .../directorytree/ViewContextAction.java | 13 ++----------- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java index 8be8a44882..4b53331e8f 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java @@ -37,12 +37,14 @@ import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; public final class CasePreferences { private static final String SETTINGS_FILE = "CasePreferences.properties"; //NON-NLS - public static final String GROUP_ITEMS_IN_TREE_BY_DATASOURCE = "GroupItemsInTreeByDataSource"; //NON-NLS private static final Logger logger = Logger.getLogger(CasePreferences.class.getName()); private static Boolean groupItemsInTreeByDataSource = null; + /** + * Prevent instantiation. + */ private CasePreferences() { } @@ -62,10 +64,21 @@ public final class CasePreferences { } } + /** + * Get the 'groupItemsInTreeByDataSource' value. This can be true, false, or + * null. + * + * @return The value. + */ public static Boolean getGroupItemsInTreeByDataSource() { return groupItemsInTreeByDataSource; } + /** + * Set the 'groupItemsInTreeByDataSource' value to true or false. + * + * @param value The value to use for the value change. + */ public static void setGroupItemsInTreeByDataSource(boolean value) { groupItemsInTreeByDataSource = value; DirectoryTreeTopComponent.getDefault().refreshContentTreeSafe(); @@ -92,6 +105,9 @@ public final class CasePreferences { } } + /** + * Reset all values to their default states. + */ private static void clear() { groupItemsInTreeByDataSource = null; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java index 8ce1aa75c8..53628326a2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java @@ -447,7 +447,7 @@ public class FileSize implements AutopsyVisitableItem { query += " AND (type != " + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType() + ")"; //NON-NLS } - // filter by datasource if indicated in user preferences + // filter by datasource if indicated in case preferences if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { query += " AND data_source_obj_id = " + filteringDSObjId; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index d8fbd410ff..d8e40d8a3e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -150,7 +150,7 @@ final public class Accounts implements AutopsyVisitableItem { * Returns the clause to filter artifacts by data source. * * @return A clause that will or will not filter artifacts by datasource - * based on the UserPreferences groupItemsInTreeByDatasource setting + * based on the CasePreferences groupItemsInTreeByDataSource setting */ private String getFilterByDataSourceClause() { if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 0123a8af8d..90d8f7540c 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -206,10 +206,21 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat return this.dataResult; } + /** + * Show rejected results? + * + * @return True if showing rejected results; otherwise false. + */ public boolean getShowRejectedResults() { return showRejectedResults; } + /** + * Setter to determine if rejected results should be shown or not. + * + * @param showRejectedResults True if showing rejected results; otherwise + * false. + */ public void setShowRejectedResults(boolean showRejectedResults) { this.showRejectedResults = showRejectedResults; if (accounts != null) { diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index 96fccea7ea..cfdd2039ce 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -139,15 +139,6 @@ public class ViewContextAction extends AbstractAction { */ DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance(); ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager(); - Case currentCase; - try { - currentCase = Case.getCurrentCaseThrows(); - } catch (NoCurrentCaseException ex) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); - logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS - return; - } - Node parentTreeViewNode; if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { // 'Group by Data Source' view @@ -155,7 +146,7 @@ public class ViewContextAction extends AbstractAction { String dsname; try { // get the objid/name of the datasource of the selected content. - skCase = currentCase.getSleuthkitCase(); + skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); long contentDSObjid = content.getDataSource().getId(); DataSource datasource = skCase.getDataSource(contentDSObjid); dsname = datasource.getName(); @@ -171,7 +162,7 @@ public class ViewContextAction extends AbstractAction { logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS return; } - } catch (TskDataException | TskCoreException ex) { + } catch (NoCurrentCaseException | TskDataException | TskCoreException ex) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS return; From d9b45b0f01632ee8b39aa4f8c06bdf8fd5a65714 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 13 Sep 2018 03:45:05 -0400 Subject: [PATCH 029/273] Improved tag data check. --- .../DirectoryTreeTopComponent.java | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 90d8f7540c..c11844fc2e 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -908,19 +908,12 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat * Refresh only the tags subtree(s) of the tree view. */ private void refreshTagsTree() { - // if no open case or has no data then there is no tree to rebuild - Case currentCase; - try { - currentCase = Case.getCurrentCaseThrows(); - } catch (NoCurrentCaseException ex) { - return; - } - if (null == currentCase || currentCase.hasData() == false) { - return; - } - SwingUtilities.invokeLater(() -> { - // if no open case or has no data then there is no tree to rebuild + // Ensure the component children have been created first. + if (autopsyTreeChildren == null) { + return; + } + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { for (Node dataSource : autopsyTreeChildren.getNodes()) { Node tagsNode = dataSource.getChildren().findChild(Tags.getTagsDisplayName()); From 773203f5c032ed29de1ed067b480e15e26ca08d6 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 13 Sep 2018 10:19:36 -0400 Subject: [PATCH 030/273] Fixed a minor bug with the properties file. --- .../autopsy/casemodule/CasePreferences.java | 20 ++++++++++++++----- .../DirectoryTreeTopComponent.java | 7 +++---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java index 4b53331e8f..1c853c7951 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java @@ -37,6 +37,9 @@ import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; public final class CasePreferences { private static final String SETTINGS_FILE = "CasePreferences.properties"; //NON-NLS + private static final String KEY_GROUP_BY_DATA_SOURCE = "groupByDataSource"; //NON-NLS + private static final String VALUE_TRUE = "true"; //NON-NLS + private static final String VALUE_FALSE = "false"; //NON-NLS private static final Logger logger = Logger.getLogger(CasePreferences.class.getName()); @@ -94,10 +97,17 @@ public final class CasePreferences { try (InputStream inputStream = Files.newInputStream(settingsFile)) { Properties props = new Properties(); props.load(inputStream); - if (props.getProperty("groupByDataSource", "false").equals("true")) { - groupItemsInTreeByDataSource = true; - } else { - groupItemsInTreeByDataSource = false; + String groupByDataSourceValue = props.getProperty(KEY_GROUP_BY_DATA_SOURCE); + switch (groupByDataSourceValue) { + case VALUE_TRUE: + groupItemsInTreeByDataSource = true; + break; + case VALUE_FALSE: + groupItemsInTreeByDataSource = false; + break; + default: + groupItemsInTreeByDataSource = null; + break; } } catch (IOException ex) { logger.log(Level.SEVERE, "Error reading settings file", ex); @@ -119,7 +129,7 @@ public final class CasePreferences { Path settingsFile = Paths.get(currentCase.getConfigDirectory(), SETTINGS_FILE); //NON-NLS Properties props = new Properties(); if (groupItemsInTreeByDataSource != null) { - props.setProperty("groupByDataSource", (groupItemsInTreeByDataSource ? "true" : "false")); + props.setProperty(KEY_GROUP_BY_DATA_SOURCE, (groupItemsInTreeByDataSource ? VALUE_TRUE : VALUE_FALSE)); } try (OutputStream fos = Files.newOutputStream(settingsFile)) { diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index c11844fc2e..9c577cba59 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -427,10 +427,9 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat * Ask the user if they want to group by data source when opening a large * case. * - * @param currentCase - * @param dataSourceCount + * @param dataSourceCount The number of data sources in the case. */ - private void promptForDataSourceGrouping(Case currentCase, int dataSourceCount) { + private void promptForDataSourceGrouping(int dataSourceCount) { if (CasePreferences.getGroupItemsInTreeByDataSource() == null) { GroupDataSourcesDialog dialog = new GroupDataSourcesDialog(dataSourceCount); dialog.display(); @@ -486,7 +485,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat int dataSourceCount = currentCase.getDataSources().size(); if (!Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) && dataSourceCount > threshold) { - promptForDataSourceGrouping(currentCase, dataSourceCount); + promptForDataSourceGrouping(dataSourceCount); } } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error loading data sources", ex); From 6a20eef257591d980e5953dc6a9d7c65fc425ab8 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 13 Sep 2018 11:26:18 -0400 Subject: [PATCH 031/273] 4167 clean up IntraCasePanel and InterCasePanel classes and add comments --- .../CommonAttributePanel.java | 4 +- .../commonfilesearch/InterCasePanel.java | 77 +++++++++++++--- .../commonfilesearch/IntraCasePanel.java | 92 ++++++++++++++----- 3 files changed, 138 insertions(+), 35 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index fc4ce620ba..56d5168664 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -325,7 +325,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer //only enable all this stuff if we actually have datasources if (dataSourcesNames.length > 0) { dataSourcesNames = dataSourceMap.values().toArray(dataSourcesNames); - CommonAttributePanel.this.intraCasePanel.setDataModel(new DataSourceComboBoxModel(dataSourcesNames)); + CommonAttributePanel.this.intraCasePanel.setDatasourceComboboxModel(new DataSourceComboBoxModel(dataSourcesNames)); if (!this.caseHasMultipleSources()) { //disable intra case search when only 1 data source in current case intraCaseRadio.setEnabled(false); @@ -394,7 +394,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer if (caseNames.length > 0) { caseNames = caseMap.values().toArray(caseNames); - CommonAttributePanel.this.interCasePanel.setCaseList(new DataSourceComboBoxModel(caseNames)); + CommonAttributePanel.this.interCasePanel.setCaseComboboxModel(new DataSourceComboBoxModel(caseNames)); } else { CommonAttributePanel.this.disableIntercaseSearch(); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 76eb3c6b97..42775117a2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -64,25 +64,45 @@ public final class InterCasePanel extends javax.swing.JPanel { }; } + /** + * Add an Observer to the Observable portion of this panel so that it can be + * notified of changes to this panel. + * + * @param observer the object which is observing this panel + */ void addObserver(Observer observer) { fileTypeFilterObservable.addObserver(observer); } - void specificCaseSelected(boolean selected) { - this.caseComboBox.setEnabled(selected); - if (selected) { - this.caseComboBox.setSelectedIndex(0); - } - } - + /** + * If the user has selected to show only results of specific file types. + * + * @return if the selected file categories button is enabled AND selected, + * true for enabled AND selected false for not selected OR not + * enabled + */ boolean fileCategoriesButtonIsSelected() { return selectedFileCategoriesButton.isEnabled() && selectedFileCategoriesButton.isSelected(); } + /** + * If the user has selected selected to show Picture and Video files as part + * of the filtered results. + * + * @return if the pictures and video checkbox is enabled AND selected, true + * for enabled AND selected false for not selected OR not enabled + */ boolean pictureVideoCheckboxIsSelected() { return pictureVideoCheckbox.isEnabled() && pictureVideoCheckbox.isSelected(); } + /** + * If the user has selected selected to show Document files as part of the + * filtered results. + * + * @return if the documents checkbox is enabled AND selected, true for + * enabled AND selected false for not selected OR not enabled + */ boolean documentsCheckboxIsSelected() { return documentsCheckbox.isEnabled() && documentsCheckbox.isSelected(); } @@ -245,21 +265,31 @@ public final class InterCasePanel extends javax.swing.JPanel { }// //GEN-END:initComponents private void allFileCategoriesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allFileCategoriesRadioButtonActionPerformed + //When the allFileCategoriesRadioButton is selected disable the options + //related to selected file categories and notify observers that the panel has changed + //incase the current settings are invalid pictureVideoCheckbox.setEnabled(false); documentsCheckbox.setEnabled(false); fileTypeFilterObservable.notifyObservers(); }//GEN-LAST:event_allFileCategoriesRadioButtonActionPerformed private void selectedFileCategoriesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectedFileCategoriesButtonActionPerformed + //When the selectedFileCategoriesButton is selected enable its related options + //and notify observers that the panel has changed incase the current settings are invalid pictureVideoCheckbox.setEnabled(true); documentsCheckbox.setEnabled(true); fileTypeFilterObservable.notifyObservers(); }//GEN-LAST:event_selectedFileCategoriesButtonActionPerformed private void specificCentralRepoCaseCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseCheckboxActionPerformed - this.specificCaseSelected(specificCentralRepoCaseCheckbox.isSelected()); + //When the specificCentralRepoCaseCheckbox is clicked update its related options + this.caseComboBox.setEnabled(specificCentralRepoCaseCheckbox.isSelected()); + if (specificCentralRepoCaseCheckbox.isSelected()) { + this.caseComboBox.setSelectedIndex(0); + } }//GEN-LAST:event_specificCentralRepoCaseCheckboxActionPerformed + private void correlationTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_correlationTypeComboBoxActionPerformed boolean enableFileTypesFilter = this.correlationTypeComboBox.getSelectedItem().equals("Files"); categoriesLabel.setEnabled(enableFileTypesFilter); @@ -271,11 +301,12 @@ public final class InterCasePanel extends javax.swing.JPanel { }//GEN-LAST:event_correlationTypeComboBoxActionPerformed private void pictureVideoCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pictureVideoCheckboxActionPerformed + //notify observers that the panel has changed incase the current settings are invalid fileTypeFilterObservable.notifyObservers(); }//GEN-LAST:event_pictureVideoCheckboxActionPerformed private void documentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsCheckboxActionPerformed - + //notify observers that the panel has changed incase the current settings are invalid fileTypeFilterObservable.notifyObservers(); }//GEN-LAST:event_documentsCheckboxActionPerformed @@ -293,20 +324,43 @@ public final class InterCasePanel extends javax.swing.JPanel { private javax.swing.JCheckBox specificCentralRepoCaseCheckbox; // End of variables declaration//GEN-END:variables + /** + * Get the map of cases which was used to populate the combo box on + * this panel. + * + * @return an unmodifiable copy of the map of cases + */ Map getCaseMap() { return Collections.unmodifiableMap(this.caseMap); } - void setCaseList(DataSourceComboBoxModel dataSourceComboBoxModel) { + /** + * Set the datamodel for the combo box which displays the cases in + * the central repository + * + * @param dataSourceComboBoxModel the DataSourceComboBoxModel to use + */ + void setCaseComboboxModel(DataSourceComboBoxModel dataSourceComboBoxModel) { this.casesList = dataSourceComboBoxModel; this.caseComboBox.setModel(dataSourceComboBoxModel); } + /** + * Update the map of cases that this panel allows the user to select from + * + * @param caseMap A map of cases + */ void setCaseMap(Map caseMap) { this.caseMap.clear(); this.caseMap.putAll(caseMap); } + /** + * Whether or not the central repository has multiple cases in it. + * + * @return true when the central repository has 2 or more case, false if it + * has 0 or 1 case in it. + */ boolean centralRepoHasMultipleCases() { return this.caseMap.size() >= 2; } @@ -314,7 +368,8 @@ public final class InterCasePanel extends javax.swing.JPanel { /** * Get the ID for the selected case * - * @return + * @return the ID of the selected case or InterCasePanel.NO_CASE_SELECTED + * when none selected */ Integer getSelectedCaseId() { if (specificCentralRepoCaseCheckbox.isSelected()) { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index 097f609ebb..d9711fe71a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -38,7 +38,6 @@ public final class IntraCasePanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; static final long NO_DATA_SOURCE_SELECTED = -1; private final Observable fileTypeFilterObservable; - private boolean singleDataSource; private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); private final Map dataSourceMap; @@ -48,11 +47,10 @@ public final class IntraCasePanel extends javax.swing.JPanel { public IntraCasePanel() { initComponents(); this.dataSourceMap = new HashMap<>(); - this.singleDataSource = true; this.onlySpecificDataSourceCheckbox.setEnabled(true); fileTypeFilterObservable = new Observable() { - @Override - public void notifyObservers(){ + @Override + public void notifyObservers() { //set changed before notify observers //we want this observerable to always cause the observer to update when notified this.setChanged(); @@ -61,36 +59,71 @@ public final class IntraCasePanel extends javax.swing.JPanel { }; } + /** + * Add an Observer to the Observable portion of this panel so that it can be + * notified of changes to this panel. + * + * @param observer the object which is observing this panel + */ void addObserver(Observer observer) { fileTypeFilterObservable.addObserver(observer); } + /** + * Get the map of datasources which was used to populate the combo box on + * this panel. + * + * @return an unmodifiable copy of the map of datasources + */ Map getDataSourceMap() { return Collections.unmodifiableMap(this.dataSourceMap); } + /** + * Get the ID for the datasource selected in the combo box. + * + * @return the selected datasource ID or + * IntraCasePanel.NO_DATA_SOURCE_SELECTED if none is selected + */ Long getSelectedDataSourceId() { - if (!this.singleDataSource) { - return IntraCasePanel.NO_DATA_SOURCE_SELECTED; - } - - for (Entry entry : this.dataSourceMap.entrySet()) { - if (entry.getValue().equals(this.selectDataSourceComboBox.getSelectedItem())) { - return entry.getKey(); + if (onlySpecificDataSourceCheckbox.isSelected()) { + for (Entry entry : this.dataSourceMap.entrySet()) { + if (entry.getValue().equals(this.selectDataSourceComboBox.getSelectedItem())) { + return entry.getKey(); + } } } - return IntraCasePanel.NO_DATA_SOURCE_SELECTED; } + /** + * If the user has selected to show only results of specific file types. + * + * @return if the selected file categories button is selected, true for + * selected false for not selected + */ boolean fileCategoriesButtonIsSelected() { return selectedFileCategoriesButton.isSelected(); } + /** + * If the user has selected selected to show Picture and Video files as part + * of the filtered results. + * + * @return if the pictures and video checkbox is enabled AND selected, true + * for enabled AND selected false for not selected OR not enabled + */ boolean pictureVideoCheckboxIsSelected() { return pictureVideoCheckbox.isEnabled() && pictureVideoCheckbox.isSelected(); } + /** + * If the user has selected selected to show Document files as part of the + * filtered results. + * + * @return if the documents checkbox is enabled AND selected, true for + * enabled AND selected false for not selected OR not enabled + */ boolean documentsCheckboxIsSelected() { return documentsCheckbox.isEnabled() && documentsCheckbox.isSelected(); } @@ -211,37 +244,40 @@ public final class IntraCasePanel extends javax.swing.JPanel { }// //GEN-END:initComponents private void selectedFileCategoriesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectedFileCategoriesButtonActionPerformed + //When the selectedFileCategoriesButton is selected enable its related options + //and notify observers that the panel has changed incase the current settings are invalid pictureVideoCheckbox.setEnabled(true); documentsCheckbox.setEnabled(true); fileTypeFilterObservable.notifyObservers(); }//GEN-LAST:event_selectedFileCategoriesButtonActionPerformed private void allFileCategoriesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allFileCategoriesRadioButtonActionPerformed + //When the allFileCategoriesRadioButton is selected disable the options + //related to selected file categories and notify observers that the panel has changed + //incase the current settings are invalid pictureVideoCheckbox.setEnabled(false); documentsCheckbox.setEnabled(false); fileTypeFilterObservable.notifyObservers(); }//GEN-LAST:event_allFileCategoriesRadioButtonActionPerformed private void onlySpecificDataSourceCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_onlySpecificDataSourceCheckboxActionPerformed - this.withinDataSourceSelected(onlySpecificDataSourceCheckbox.isSelected()); + //When the onlySpecificDataSourceCheckbox is clicked update its related options + selectDataSourceComboBox.setEnabled(onlySpecificDataSourceCheckbox.isSelected()); + if (selectDataSourceComboBox.isEnabled()) { + selectDataSourceComboBox.setSelectedIndex(0); + } }//GEN-LAST:event_onlySpecificDataSourceCheckboxActionPerformed private void pictureVideoCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pictureVideoCheckboxActionPerformed + //notify observers that the panel has changed incase the current settings are invalid fileTypeFilterObservable.notifyObservers(); }//GEN-LAST:event_pictureVideoCheckboxActionPerformed private void documentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsCheckboxActionPerformed + //notify observers that the panel has changed incase the current settings are invalid fileTypeFilterObservable.notifyObservers(); }//GEN-LAST:event_documentsCheckboxActionPerformed - private void withinDataSourceSelected(boolean selected) { - selectDataSourceComboBox.setEnabled(selected); - if (selectDataSourceComboBox.isEnabled()) { - selectDataSourceComboBox.setSelectedIndex(0); - singleDataSource = true; - } - } - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton allFileCategoriesRadioButton; private javax.swing.ButtonGroup buttonGroup; @@ -253,11 +289,23 @@ public final class IntraCasePanel extends javax.swing.JPanel { private javax.swing.JRadioButton selectedFileCategoriesButton; // End of variables declaration//GEN-END:variables - void setDataModel(DataSourceComboBoxModel dataSourceComboBoxModel) { + /** + * Set the datamodel for the combo box which displays the data sources in + * the current case + * + * @param dataSourceComboBoxModel the DataSourceComboBoxModel to use + */ + void setDatasourceComboboxModel(DataSourceComboBoxModel dataSourceComboBoxModel) { this.dataSourcesList = dataSourceComboBoxModel; this.selectDataSourceComboBox.setModel(dataSourcesList); } + /** + * Update the map of datasources that this panel allows the user to select + * from + * + * @param dataSourceMap A map of datasources + */ void setDataSourceMap(Map dataSourceMap) { this.dataSourceMap.clear(); this.dataSourceMap.putAll(dataSourceMap); From ad3a196d12c20ca7b61d116cf52a296df2361e84 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 13 Sep 2018 12:17:56 -0400 Subject: [PATCH 032/273] 4167 clean up and add comments to CommonAttributePanel --- .../commonfilesearch/Bundle.properties | 2 +- .../CommonAttributePanel.form | 8 +- .../CommonAttributePanel.java | 171 +++++++++++++----- .../CommonAttributeSearchAction.java | 31 +++- 4 files changed, 152 insertions(+), 60 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index 035e165ae4..0915cc2769 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -21,7 +21,6 @@ IntraCasePanel.documentsCheckbox.text=Documents IntraCasePanel.pictureVideoCheckbox.text=Pictures and Videos IntraCasePanel.selectedFileCategoriesButton.toolTipText=Select from the options below... CommonAttributePanel.percentageThresholdTextTwo.text_1=% of data sources in central repository. -CommonAttributePanel.percentageThresholdTextOne.text=20 CommonAttributePanel.percentageThresholdCheck.text_1_1=Hide files found in over CommonAttributePanel.intraCaseRadio.text=Between data sources in current case CommonAttributePanel.errorText.text=In order to search, you must select a file category. @@ -40,3 +39,4 @@ CommonAttributePanel.intraCasePanel.border.title=Current Case Options CommonAttributePanel.commonItemSearchDescription.text=Find items that exist in multipel data sources or cases CommonAttributePanel.scopeLabel.text=Scope of Search InterCasePanel.correlationComboBoxLabel.text=Select correlation type to search: +CommonAttributePanel.percentageThresholdInputBox.text=20 diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form index 834b42a763..0f81ccb799 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form @@ -66,7 +66,7 @@ - + @@ -115,7 +115,7 @@ - + @@ -205,11 +205,11 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index 56d5168664..aac27c914b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -97,12 +97,12 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer this.errorManager = new UserInputErrorManager(); - this.percentageThresholdTextOne.getDocument().addDocumentListener(new DocumentListener() { + this.percentageThresholdInputBox.getDocument().addDocumentListener(new DocumentListener() { - private Dimension preferredSize = CommonAttributePanel.this.percentageThresholdTextOne.getPreferredSize(); + private Dimension preferredSize = CommonAttributePanel.this.percentageThresholdInputBox.getPreferredSize(); private void maintainSize() { - CommonAttributePanel.this.percentageThresholdTextOne.setSize(preferredSize); + CommonAttributePanel.this.percentageThresholdInputBox.setSize(preferredSize); } @Override @@ -125,6 +125,13 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer }); } + /** + * Get whether or not the central repository will be enabled as a search + * option. + * + * @return true if the central repository exists and has at least 2 cases in + * and includes the current case, false otherwise. + */ static boolean isEamDbAvailableForIntercaseSearch() { try { return EamDb.isEnabled() @@ -144,7 +151,14 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer checkFileTypeCheckBoxState(); } - static boolean isEamDbAvailableForPercentageFrequencyCalculations() { + /** + * Get whether or not the central repository will be available for filtering + * results. + * + * @return true if the central repository exists and has at least 1 case in + * it, false otherwise. + */ + private static boolean isEamDbAvailableForPercentageFrequencyCalculations() { try { return EamDb.isEnabled() && EamDb.getInstance() != null @@ -155,11 +169,18 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer return false; } + /** + * Disable the option to search for common attributes in the central + * repository. + */ private void disableIntercaseSearch() { this.intraCaseRadio.setSelected(true); this.interCaseRadio.setEnabled(false); } + /** + * Perform the common attribute search. + */ @NbBundle.Messages({ "CommonAttributePanel.search.results.titleAll=Common Attributes (All Data Sources)", "CommonAttributePanel.search.results.titleSingle=Common Attributes (Match Within Data Source: %s)", @@ -179,10 +200,21 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer private String tabTitle; private ProgressHandle progress; + /** + * Set the title of the search results for searches using all data + * sources. + */ private void setTitleForAllDataSources() { this.tabTitle = Bundle.CommonAttributePanel_search_results_titleAll(); } + /** + * Set the title of the search results for searches using a single + * source. + * + * @param dataSourceId the datasource ID of the the source being + * used + */ private void setTitleForSingleSource(Long dataSourceId) { final String CommonAttributePanel_search_results_titleSingle = Bundle.CommonAttributePanel_search_results_titleSingle(); final Object[] dataSourceName = new Object[]{intraCasePanel.getDataSourceMap().get(dataSourceId)}; @@ -316,6 +348,10 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer new SwingWorker, Void>() { + /** + * Update the user interface of the panel to reflect the datasources + * available. + */ private void updateUi() { final Map dataSourceMap = CommonAttributePanel.this.intraCasePanel.getDataSourceMap(); @@ -333,12 +369,18 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer intraCasePanel.setVisible(false); interCasePanel.setVisible(true); } - CommonAttributePanel.this.updateErrorTextAndSearchBox(); + CommonAttributePanel.this.updateErrorTextAndSearchButton(); } } + /** + * Check if the case has multiple data sources + * + * @return true if the case has multiple data sources, false + * otherwise + */ private boolean caseHasMultipleSources() { - return CommonAttributePanel.this.intraCasePanel.getDataSourceMap().size() > 2; + return CommonAttributePanel.this.intraCasePanel.getDataSourceMap().size() > 2; //WJS-TODO should be > than 1? } @Override @@ -386,6 +428,10 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer new SwingWorker, Void>() { + /** + * Update the user interface of the panel to reflect the cases + * available. + */ private void updateUi() { final Map caseMap = CommonAttributePanel.this.interCasePanel.getCaseMap(); @@ -400,7 +446,16 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer } } - private Map mapDataSources(List cases) throws EamDbException { + /** + * Create a map of cases from a list of cases. + * + * @param cases + * + * @return a map of Cases + * + * @throws EamDbException + */ + private Map mapCases(List cases) throws EamDbException { Map casemap = new HashMap<>(); CorrelationCase currentCorCase = EamDb.getInstance().getCase(Case.getCurrentCase()); for (CorrelationCase correlationCase : cases) { @@ -408,7 +463,6 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer casemap.put(correlationCase.getID(), correlationCase.getDisplayName()); } } - return casemap; } @@ -416,7 +470,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer protected Map doInBackground() throws EamDbException { List dataSources = EamDb.getInstance().getCases(); - Map caseMap = mapDataSources(dataSources); + Map caseMap = mapCases(dataSources); return caseMap; } @@ -457,7 +511,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer intraCaseRadio = new javax.swing.JRadioButton(); interCaseRadio = new javax.swing.JRadioButton(); percentageThresholdCheck = new javax.swing.JCheckBox(); - percentageThresholdTextOne = new javax.swing.JTextField(); + percentageThresholdInputBox = new javax.swing.JTextField(); percentageThresholdTextTwo = new javax.swing.JLabel(); intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); @@ -518,11 +572,11 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer } }); - percentageThresholdTextOne.setHorizontalAlignment(javax.swing.JTextField.TRAILING); - percentageThresholdTextOne.setText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdTextOne.text")); // NOI18N - percentageThresholdTextOne.setMaximumSize(new java.awt.Dimension(40, 24)); - percentageThresholdTextOne.setMinimumSize(new java.awt.Dimension(40, 24)); - percentageThresholdTextOne.setPreferredSize(new java.awt.Dimension(40, 24)); + percentageThresholdInputBox.setHorizontalAlignment(javax.swing.JTextField.TRAILING); + percentageThresholdInputBox.setText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdInputBox.text")); // NOI18N + percentageThresholdInputBox.setMaximumSize(new java.awt.Dimension(40, 24)); + percentageThresholdInputBox.setMinimumSize(new java.awt.Dimension(40, 24)); + percentageThresholdInputBox.setPreferredSize(new java.awt.Dimension(40, 24)); org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdTextTwo, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdTextTwo.text_1")); // NOI18N @@ -541,37 +595,33 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(0, 0, 0) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addComponent(errorText, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) - .addGap(65, 65, 65) - .addComponent(searchButton) - .addContainerGap()) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() - .addGap(20, 20, 20) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(intraCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(interCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE)))) - .addGap(0, 0, Short.MAX_VALUE)))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(errorText, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addGap(65, 65, 65) + .addComponent(searchButton) + .addContainerGap()) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(percentageThresholdCheck) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(percentageThresholdTextOne, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(scopeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(37, 37, 37)) .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(interCasePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(intraCasePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGap(0, 0, 0)))) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() + .addGap(20, 20, 20) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(intraCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(interCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE)))) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(interCasePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(intraCasePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGap(0, 0, Short.MAX_VALUE)))) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -591,7 +641,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(percentageThresholdCheck) - .addComponent(percentageThresholdTextOne, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(percentageThresholdTextTwo)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 50, Short.MAX_VALUE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) @@ -609,9 +659,9 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer private void percentageThresholdCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_percentageThresholdCheckActionPerformed if (this.percentageThresholdCheck.isSelected()) { - this.percentageThresholdTextOne.setEnabled(true); + this.percentageThresholdInputBox.setEnabled(true); } else { - this.percentageThresholdTextOne.setEnabled(false); + this.percentageThresholdInputBox.setEnabled(false); } this.handleFrequencyPercentageState(); @@ -632,8 +682,12 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer SwingUtilities.windowForComponent(this).dispose(); }//GEN-LAST:event_searchButtonActionPerformed + /** + * Convert the text in the percentage threshold input box into an integer, + * -1 is used when the string can not be converted to an integer. + */ private void percentageThresholdChanged() { - String percentageString = this.percentageThresholdTextOne.getText(); + String percentageString = this.percentageThresholdInputBox.getText(); try { this.percentageThresholdValue = Integer.parseInt(percentageString); @@ -645,7 +699,11 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer this.handleFrequencyPercentageState(); } - private void updateErrorTextAndSearchBox() { + /** + * Update the error text and the enabled status of the search button to + * reflect the current validity of the search settings. + */ + private void updateErrorTextAndSearchButton() { if (this.errorManager.anyErrors()) { this.searchButton.setEnabled(false); //grab the first error error and show it @@ -657,20 +715,32 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer } } + /** + * Set the enabled status of the percentage threshold options + * + * @param enabled true to enable percentage threshold options, false to + * disable them + */ private void enablePercentageOptions(boolean enabled) { - this.percentageThresholdTextOne.setEnabled(enabled); + this.percentageThresholdInputBox.setEnabled(enabled); this.percentageThresholdCheck.setEnabled(enabled); this.percentageThresholdCheck.setSelected(enabled); this.percentageThresholdTextTwo.setEnabled(enabled); } + /** + * Check that the integer value of what is entered in the percentage + * threshold text box is a valid percentage and update the errorManager to + * reflect the validity. + */ private void handleFrequencyPercentageState() { if (this.percentageThresholdValue > 0 && this.percentageThresholdValue <= 100) { this.errorManager.setError(UserInputErrorManager.FREQUENCY_PERCENTAGE_OUT_OF_RANGE_KEY, false); } else { + this.errorManager.setError(UserInputErrorManager.FREQUENCY_PERCENTAGE_OUT_OF_RANGE_KEY, true); } - this.updateErrorTextAndSearchBox(); + this.updateErrorTextAndSearchButton(); } // Variables declaration - do not modify//GEN-BEGIN:variables @@ -683,17 +753,26 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer private javax.swing.JRadioButton intraCaseRadio; private javax.swing.JPanel jPanel1; private javax.swing.JCheckBox percentageThresholdCheck; - private javax.swing.JTextField percentageThresholdTextOne; + private javax.swing.JTextField percentageThresholdInputBox; private javax.swing.JLabel percentageThresholdTextTwo; private javax.swing.JLabel scopeLabel; private javax.swing.JButton searchButton; // End of variables declaration//GEN-END:variables + /** + * Add this panel as an observer of it's sub panels so that errors can be + * indicated accurately. + */ void observeSubPanels() { intraCasePanel.addObserver(this); interCasePanel.addObserver(this); } + /** + * Check that the sub panels have valid options selected regarding their + * file type filtering options, and update the errorManager with the + * validity. + */ private void checkFileTypeCheckBoxState() { boolean validCheckBoxState = true; if (CommonAttributePanel.this.interCaseRadio.isSelected()) { @@ -710,7 +789,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer } else { this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, true); } - this.updateErrorTextAndSearchBox(); + this.updateErrorTextAndSearchButton(); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java index d5a7c9df80..0d5db72bc4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java @@ -37,7 +37,23 @@ final public class CommonAttributeSearchAction extends CallableSystemAction { private static CommonAttributeSearchAction instance = null; private static final long serialVersionUID = 1L; - CommonAttributeSearchAction() { + /** + * Get the default CommonAttributeSearchAction. + * + * @return the default instance of this action + */ + public static synchronized CommonAttributeSearchAction getDefault() { + if (instance == null) { + instance = new CommonAttributeSearchAction(); + } + return instance; + } + + /** + * Create a CommonAttributeSearchAction for opening the common attribute + * search dialog + */ + private CommonAttributeSearchAction() { super(); this.setEnabled(false); } @@ -54,15 +70,8 @@ final public class CommonAttributeSearchAction extends CallableSystemAction { } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error getting data sources for action enabled check", ex); - } - return super.isEnabled() && shouldBeEnabled; - } - - public static synchronized CommonAttributeSearchAction getDefault() { - if (instance == null) { - instance = new CommonAttributeSearchAction(); } - return instance; + return super.isEnabled() && shouldBeEnabled; } @Override @@ -75,8 +84,12 @@ final public class CommonAttributeSearchAction extends CallableSystemAction { createAndShowPanel(); } + /** + * Create the commonAttributePanel and diplay it. + */ private void createAndShowPanel() { CommonAttributePanel commonAttributePanel = new CommonAttributePanel(); + //In order to update errors the CommonAttributePanel needs to observe its sub panels commonAttributePanel.observeSubPanels(); commonAttributePanel.setVisible(true); } From a6c3607ea1421ca58fbad5d87ca58403d266e56a Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 13 Sep 2018 14:58:06 -0400 Subject: [PATCH 033/273] Reduced the number of calls to count unique data sources in intercase correlation to one, this will have merge conflicts with brians branch --- .../commonfilesearch/CommonAttributeSearchResults.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java index 036b97a92a..e561d0bc55 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java @@ -125,6 +125,7 @@ final public class CommonAttributeSearchResults { EamDb eamDb = EamDb.getInstance(); Map> itemsToRemove = new HashMap<>(); + Double uniqueCaseDataSourceTuples = eamDb.getCountUniqueDataSources().doubleValue(); for(Entry listOfValues : Collections.unmodifiableMap(this.instanceCountToAttributeValues).entrySet()){ @@ -134,7 +135,11 @@ final public class CommonAttributeSearchResults { for(CommonAttributeValue value : values.getDelayedMetadataList()){ // Need the real metadata try { - int frequencyPercentage = eamDb.getFrequencyPercentage(new CorrelationAttributeInstance(fileAttributeType, value.getValue())); + CorrelationAttributeInstance corAttr = new CorrelationAttributeInstance(fileAttributeType, value.getValue()); + Double uniqueTypeValueTuples = eamDb.getCountUniqueCaseDataSourceTuplesHavingTypeValue( + corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue(); + Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100; + int frequencyPercentage = commonalityPercentage.intValue(); if(frequencyPercentage > maximumPercentageThreshold){ if(itemsToRemove.containsKey(key)){ @@ -184,4 +189,4 @@ final public class CommonAttributeSearchResults { } return count; } -} +} \ No newline at end of file From c426b2c7efdfd1dc1eb155d53ed1dc53e6d7b5a6 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 13 Sep 2018 15:09:25 -0400 Subject: [PATCH 034/273] Added one comment --- .../autopsy/commonfilesearch/CommonAttributeSearchResults.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java index e561d0bc55..c577c573b0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java @@ -125,6 +125,8 @@ final public class CommonAttributeSearchResults { EamDb eamDb = EamDb.getInstance(); Map> itemsToRemove = new HashMap<>(); + //Call countUniqueDataSources once to reduce the number of DB queries needed to get + //the frequencyPercentage Double uniqueCaseDataSourceTuples = eamDb.getCountUniqueDataSources().doubleValue(); for(Entry listOfValues : Collections.unmodifiableMap(this.instanceCountToAttributeValues).entrySet()){ From 9fb24ff6ff73dae4a8bbef914452fd2886f969da Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 13 Sep 2018 16:16:29 -0400 Subject: [PATCH 035/273] Removed instance creation in the loop and passed the attributes themselves directly --- .../autopsy/commonfilesearch/CommonAttributeSearchResults.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java index c577c573b0..76c6f5c151 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java @@ -137,9 +137,8 @@ final public class CommonAttributeSearchResults { for(CommonAttributeValue value : values.getDelayedMetadataList()){ // Need the real metadata try { - CorrelationAttributeInstance corAttr = new CorrelationAttributeInstance(fileAttributeType, value.getValue()); Double uniqueTypeValueTuples = eamDb.getCountUniqueCaseDataSourceTuplesHavingTypeValue( - corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue(); + fileAttributeType, value.getValue()).doubleValue(); Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100; int frequencyPercentage = commonalityPercentage.intValue(); From 0e8c25b3fa44617df3cc6ae9082d2f562f1f59de Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 13 Sep 2018 16:17:53 -0400 Subject: [PATCH 036/273] Changed fileAttributeType name to just attributeType --- .../commonfilesearch/CommonAttributeSearchResults.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java index 76c6f5c151..d7761b47c3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java @@ -116,7 +116,7 @@ final public class CommonAttributeSearchResults { return Collections.unmodifiableMap(this.instanceCountToAttributeValues); } - CorrelationAttributeInstance.Type fileAttributeType = CorrelationAttributeInstance + CorrelationAttributeInstance.Type attributeType = CorrelationAttributeInstance .getDefaultCorrelationTypes() .stream() .filter(filterType -> filterType.getId() == this.resultTypeId) @@ -138,7 +138,7 @@ final public class CommonAttributeSearchResults { try { Double uniqueTypeValueTuples = eamDb.getCountUniqueCaseDataSourceTuplesHavingTypeValue( - fileAttributeType, value.getValue()).doubleValue(); + attributeType, value.getValue()).doubleValue(); Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100; int frequencyPercentage = commonalityPercentage.intValue(); From 3d71afde77d70f84fa15e5b19715adec84867dc4 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 13 Sep 2018 22:17:29 -0400 Subject: [PATCH 037/273] Fixed positioning of controls on panel. --- .../corecomponents/ViewPreferencesPanel.form | 48 +++++++++---------- .../corecomponents/ViewPreferencesPanel.java | 46 +++++++++--------- 2 files changed, 45 insertions(+), 49 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form index e2313f0ce5..0665023009 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form @@ -16,7 +16,7 @@ - + @@ -54,9 +54,9 @@ - - - + + + @@ -80,7 +80,7 @@ - + @@ -96,6 +96,7 @@ + @@ -117,14 +118,14 @@ - + - - + + @@ -153,6 +154,9 @@ + + + @@ -272,6 +276,16 @@ + + + + + + + + + + @@ -290,10 +304,7 @@ - - - - + @@ -302,25 +313,12 @@ - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index a4ab51bb1f..2864d62474 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -64,7 +64,6 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { // Current Case Settings boolean caseIsOpen = Case.isCaseOpen(); currentCaseSettingsPanel.setEnabled(caseIsOpen); - hideOtherUsersTagsCheckbox.setEnabled(caseIsOpen); groupByDataSourceCheckbox.setEnabled(caseIsOpen); hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags()); @@ -127,8 +126,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { displayTimeLabel = new javax.swing.JLabel(); useLocalTimeRadioButton = new javax.swing.JRadioButton(); useGMTTimeRadioButton = new javax.swing.JRadioButton(); - currentCaseSettingsPanel = new javax.swing.JPanel(); hideOtherUsersTagsCheckbox = new javax.swing.JCheckBox(); + currentCaseSettingsPanel = new javax.swing.JPanel(); groupByDataSourceCheckbox = new javax.swing.JCheckBox(); currentSessionSettingsPanel = new javax.swing.JPanel(); hideRejectedResultsCheckbox = new javax.swing.JCheckBox(); @@ -203,6 +202,13 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { } }); + org.openide.awt.Mnemonics.setLocalizedText(hideOtherUsersTagsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text")); // NOI18N + hideOtherUsersTagsCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + hideOtherUsersTagsCheckboxActionPerformed(evt); + } + }); + javax.swing.GroupLayout globalSettingsPanelLayout = new javax.swing.GroupLayout(globalSettingsPanel); globalSettingsPanel.setLayout(globalSettingsPanelLayout); globalSettingsPanelLayout.setHorizontalGroup( @@ -221,6 +227,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addComponent(selectFileLabel)) .addGap(18, 18, 18) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(hideOtherUsersTagsCheckbox) .addComponent(hideKnownFilesLabel) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -235,12 +242,12 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(dataSourcesHideKnownCheckbox) .addComponent(viewsHideKnownCheckbox))))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(29, Short.MAX_VALUE)) ); globalSettingsPanelLayout.setVerticalGroup( globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, globalSettingsPanelLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addContainerGap() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addComponent(hideKnownFilesLabel) @@ -265,18 +272,14 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(useLocalTimeRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(useGMTTimeRadioButton)))) + .addComponent(useGMTTimeRadioButton))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(hideOtherUsersTagsCheckbox) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); currentCaseSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentCaseSettingsPanel.border.title"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(hideOtherUsersTagsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text")); // NOI18N - hideOtherUsersTagsCheckbox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - hideOtherUsersTagsCheckboxActionPerformed(evt); - } - }); - org.openide.awt.Mnemonics.setLocalizedText(groupByDataSourceCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.groupByDataSourceCheckbox.text")); // NOI18N groupByDataSourceCheckbox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -290,19 +293,14 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(currentCaseSettingsPanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(hideOtherUsersTagsCheckbox) - .addComponent(groupByDataSourceCheckbox)) + .addComponent(groupByDataSourceCheckbox) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); currentCaseSettingsPanelLayout.setVerticalGroup( currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(currentCaseSettingsPanelLayout.createSequentialGroup() .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(hideOtherUsersTagsCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(groupByDataSourceCheckbox) - .addGap(20, 20, 20)) + .addComponent(groupByDataSourceCheckbox)) ); currentSessionSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentSessionSettingsPanel.border.title"))); // NOI18N @@ -345,9 +343,9 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { viewPreferencesPanelLayout.setVerticalGroup( viewPreferencesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(viewPreferencesPanelLayout.createSequentialGroup() - .addComponent(globalSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(11, 11, 11) - .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(globalSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 197, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(currentSessionSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) @@ -359,7 +357,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(viewPreferencesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 562, Short.MAX_VALUE) + .addComponent(viewPreferencesScrollPane) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) From 0117d4ae1b4600700c379b473efe6611197b3eb9 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 14 Sep 2018 10:12:05 -0400 Subject: [PATCH 038/273] Removed columns with performance impacts. --- .../CaseDBCommonAttributeInstanceNode.java | 1 - .../autopsy/communications/RelationshipNode.java | 1 - .../autopsy/contentviewers/MessageContentViewer.java | 1 - .../autopsy/datamodel/AbstractAbstractFileNode.java | 8 ++++---- .../autopsy/datamodel/AbstractFsContentNode.java | 3 --- .../autopsy/datamodel/BlackboardArtifactNode.java | 6 ++++-- .../org/sleuthkit/autopsy/datamodel/LayoutFileNode.java | 5 +---- .../sleuthkit/autopsy/datamodel/LocalDirectoryNode.java | 1 - .../org/sleuthkit/autopsy/datamodel/LocalFileNode.java | 3 --- .../sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java | 1 - 10 files changed, 9 insertions(+), 21 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java index 45ba05735e..83cbed96ee 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java @@ -92,7 +92,6 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode { sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, getHashSetHitsCsvList(this.getContent()))); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource())); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, StringUtils.defaultString(this.getContent().getMIMEType()))); - this.addTagProperty(sheetSet, tags); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, caseName)); return sheet; diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java index 0b92830002..23aef3dfe8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java @@ -120,7 +120,6 @@ final class RelationshipNode extends BlackboardArtifactNode { break; } } - addTagProperty(sheetSet, tags); return sheet; } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index b109b12da0..dd82e1d645 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -737,7 +737,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont sheetSet.put(new NodeProperty<>("Mime Type", "Mime Type", "Mime Type", StringUtils.defaultString(file.getMIMEType()))); sheetSet.put(new NodeProperty<>("Known", "Known", "Known", file.getKnown().getName())); - addTagProperty(sheetSet, tags); return sheet; } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 5173ef6c63..ab7ad3f881 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -30,6 +30,7 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Children; import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.WeakListeners; import org.sleuthkit.autopsy.casemodule.Case; @@ -38,6 +39,7 @@ import org.sleuthkit.autopsy.casemodule.events.CommentChangedEvent; import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent; import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; @@ -194,7 +196,6 @@ public abstract class AbstractAbstractFileNode extends A "AbstractAbstractFileNode.typeDirColLbl=Type(Dir)", "AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)", "AbstractAbstractFileNode.knownColLbl=Known", - "AbstractAbstractFileNode.inHashsetsColLbl=In Hashsets", "AbstractAbstractFileNode.md5HashColLbl=MD5 Hash", "AbstractAbstractFileNode.objectId=Object ID", "AbstractAbstractFileNode.mimeType=MIME Type", @@ -218,7 +219,6 @@ public abstract class AbstractAbstractFileNode extends A TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()), TYPE_META(AbstractAbstractFileNode_typeMetaColLbl()), KNOWN(AbstractAbstractFileNode_knownColLbl()), - HASHSETS(AbstractAbstractFileNode_inHashsetsColLbl()), MD5HASH(AbstractAbstractFileNode_md5HashColLbl()), ObjectID(AbstractAbstractFileNode_objectId()), MIMETYPE(AbstractAbstractFileNode_mimeType()), @@ -261,7 +261,6 @@ public abstract class AbstractAbstractFileNode extends A map.put(TYPE_DIR.toString(), content.getDirType().getLabel()); map.put(TYPE_META.toString(), content.getMetaType().toString()); map.put(KNOWN.toString(), content.getKnown().getName()); - map.put(HASHSETS.toString(), getHashSetHitsCsvList(content)); map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash())); map.put(ObjectID.toString(), content.getId()); map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType())); @@ -385,7 +384,7 @@ public abstract class AbstractAbstractFileNode extends A } else if (attribute != null) { description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description(); } - } catch (EamDbException ex) { + } catch (CorrelationAttributeNormalizationException | EamDbException ex) { logger.log(Level.WARNING, "Error getting count of datasources with correlation attribute", ex); } sheetSet.put( @@ -422,6 +421,7 @@ public abstract class AbstractAbstractFileNode extends A * Sheet.get(Sheet.PROPERTIES) * @param tags the list of tags associated with the file */ + @Deprecated protected final void addTagProperty(Sheet.Set sheetSet, List tags) { sheetSet.put(new NodeProperty<>("Tags", AbstractAbstractFileNode_tagsProperty_displayName(), NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index 02dd3c1d28..364fbab991 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -96,9 +96,6 @@ public abstract class AbstractFsContentNode extends Abst sheetSet.put(new NodeProperty<>(HIDE_PARENT, HIDE_PARENT, HIDE_PARENT, HIDE_PARENT)); } - // add tags property to the sheet - addTagProperty(sheetSet, tags); - return sheet; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 7310d8ff1d..fb5dc71c5d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -38,6 +38,7 @@ import java.util.stream.Collectors; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.WeakListeners; @@ -50,6 +51,7 @@ import org.sleuthkit.autopsy.casemodule.events.CommentChangedEvent; import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent; import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; @@ -500,7 +502,6 @@ public class BlackboardArtifactNode extends AbstractContentNode tags) { sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); @@ -667,7 +669,7 @@ public class BlackboardArtifactNode extends AbstractContentNode { + @Deprecated public static enum LayoutContentPropertyType { PARTS { @@ -99,9 +100,6 @@ public class LayoutFileNode extends AbstractAbstractFileNode { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } - // add tags property to the sheet - addTagProperty(sheetSet, tags); - return sheet; } @@ -145,7 +143,6 @@ public class LayoutFileNode extends AbstractAbstractFileNode { void fillPropertyMap(Map map) { AbstractAbstractFileNode.fillPropertyMap(map, getContent()); - map.put(LayoutContentPropertyType.PARTS.toString(), content.getNumParts()); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java index f6f3de7680..a0e4410225 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java @@ -76,7 +76,6 @@ public class LocalDirectoryNode extends SpecialDirectoryNode { for (Map.Entry entry : map.entrySet()) { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } - addTagProperty(sheetSet, tags); return sheet; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index a9c09ee1d7..eede4dcfa8 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -91,9 +91,6 @@ public class LocalFileNode extends AbstractAbstractFileNode { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } - // add tags property to the sheet - addTagProperty(sheetSet, tags); - return sheet; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java index 02f382e6ad..ce87bf6da6 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java @@ -101,7 +101,6 @@ public class VirtualDirectoryNode extends SpecialDirectoryNode { for (Map.Entry entry : map.entrySet()) { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } - addTagProperty(sheetSet, tags); } else { sheetSet.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_type_name(), Bundle.VirtualDirectoryNode_createSheet_type_displayName(), From c4bcbb92ec2a95fbad21e08f60f3377dc1608e0a Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 14 Sep 2018 10:14:01 -0400 Subject: [PATCH 039/273] Removed unused imports. --- .../sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java | 1 - .../org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 1 - 2 files changed, 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index ab7ad3f881..4a186b0f29 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -30,7 +30,6 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Children; import org.openide.nodes.Sheet; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.WeakListeners; import org.sleuthkit.autopsy.casemodule.Case; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index fb5dc71c5d..1739415437 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -38,7 +38,6 @@ import java.util.stream.Collectors; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; -import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.WeakListeners; From e6b034e46e2b4054266f27b2e623631b2bc34d2a Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 14 Sep 2018 11:55:34 -0400 Subject: [PATCH 040/273] Fixed merge conflict. --- .../sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java | 2 +- .../org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index f85143a003..a2c80ef159 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -383,7 +383,7 @@ public abstract class AbstractAbstractFileNode extends A } else if (attribute != null) { description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description(); } - } catch (CorrelationAttributeNormalizationException | EamDbException ex) { + } catch (EamDbException ex) { logger.log(Level.WARNING, "Error getting count of datasources with correlation attribute", ex); } catch (CorrelationAttributeNormalizationException ex) { logger.log(Level.WARNING, "Unable to normalize data to get count of datasources with correlation attribute", ex); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index b622a77fd3..abdf31ecb5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -668,7 +668,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Fri, 14 Sep 2018 14:01:27 -0400 Subject: [PATCH 041/273] 4167 fix typos and message text in Common Property Search --- .../autopsy/commonfilesearch/Bundle.properties | 12 ++++++------ .../commonfilesearch/CommonAttributePanel.java | 7 ++++--- .../autopsy/commonfilesearch/InterCasePanel.java | 3 ++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index 0915cc2769..1e6302d3d7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -20,8 +20,8 @@ IntraCasePanel.allFileCategoriesRadioButton.text=All file types IntraCasePanel.documentsCheckbox.text=Documents IntraCasePanel.pictureVideoCheckbox.text=Pictures and Videos IntraCasePanel.selectedFileCategoriesButton.toolTipText=Select from the options below... -CommonAttributePanel.percentageThresholdTextTwo.text_1=% of data sources in central repository. -CommonAttributePanel.percentageThresholdCheck.text_1_1=Hide files found in over +CommonAttributePanel.percentageThresholdTextTwo.text_1=% of data sources in Central Repository. +CommonAttributePanel.percentageThresholdCheck.text_1_1=Hide items found in over CommonAttributePanel.intraCaseRadio.text=Between data sources in current case CommonAttributePanel.errorText.text=In order to search, you must select a file category. CommonAttributePanel.searchButton.text=Search @@ -32,11 +32,11 @@ InterCasePanel.selectedFileCategoriesButton.toolTipText=Select from the options InterCasePanel.selectedFileCategoriesButton.text=Only the selected file types: InterCasePanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results... InterCasePanel.allFileCategoriesRadioButton.text=All file types -InterCasePanel.specificCentralRepoCaseCheckbox.text=Only specific case in Central Repository -IntraCasePanel.onlySpecificDataSourceCheckbox.text=Only specific data source in current case +InterCasePanel.specificCentralRepoCaseCheckbox.text=Common items need to exist in a specific case +IntraCasePanel.onlySpecificDataSourceCheckbox.text=Common items need to exist in a specific data source CommonAttributePanel.interCasePanel.border.title=Central Repository Options CommonAttributePanel.intraCasePanel.border.title=Current Case Options -CommonAttributePanel.commonItemSearchDescription.text=Find items that exist in multipel data sources or cases +CommonAttributePanel.commonItemSearchDescription.text=Find items that exist in multiple data sources or cases CommonAttributePanel.scopeLabel.text=Scope of Search -InterCasePanel.correlationComboBoxLabel.text=Select correlation type to search: +InterCasePanel.correlationComboBoxLabel.text=Property Type To Match CommonAttributePanel.percentageThresholdInputBox.text=20 diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index aac27c914b..739985db31 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Observable; import java.util.Observer; import java.util.concurrent.ExecutionException; @@ -99,7 +100,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer this.percentageThresholdInputBox.getDocument().addDocumentListener(new DocumentListener() { - private Dimension preferredSize = CommonAttributePanel.this.percentageThresholdInputBox.getPreferredSize(); + private final Dimension preferredSize = CommonAttributePanel.this.percentageThresholdInputBox.getPreferredSize(); private void maintainSize() { CommonAttributePanel.this.percentageThresholdInputBox.setSize(preferredSize); @@ -265,7 +266,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer filterByMedia = intraCasePanel.pictureVideoCheckboxIsSelected(); filterByDocuments = intraCasePanel.documentsCheckboxIsSelected(); } - if (dataSourceId == CommonAttributePanel.NO_DATA_SOURCE_SELECTED) { + if (Objects.equals(dataSourceId, CommonAttributePanel.NO_DATA_SOURCE_SELECTED)) { builder = new AllIntraCaseCommonAttributeSearcher(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold); setTitleForAllDataSources(); @@ -380,7 +381,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer * otherwise */ private boolean caseHasMultipleSources() { - return CommonAttributePanel.this.intraCasePanel.getDataSourceMap().size() > 2; //WJS-TODO should be > than 1? + return CommonAttributePanel.this.intraCasePanel.getDataSourceMap().size() > 1; } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 42775117a2..55219f0e51 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -291,7 +291,8 @@ public final class InterCasePanel extends javax.swing.JPanel { private void correlationTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_correlationTypeComboBoxActionPerformed - boolean enableFileTypesFilter = this.correlationTypeComboBox.getSelectedItem().equals("Files"); + //we do not currenlty have mime type in the central repository so this section will always be disabled + boolean enableFileTypesFilter = false; //this.correlationTypeComboBox.getSelectedItem().equals("Files"); categoriesLabel.setEnabled(enableFileTypesFilter); allFileCategoriesRadioButton.setEnabled(enableFileTypesFilter); selectedFileCategoriesButton.setEnabled(enableFileTypesFilter); From 02d888274bb6ae9c151497780e9f9cd9a0fee3b5 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 14 Sep 2018 14:08:39 -0400 Subject: [PATCH 042/273] 4167 rename action text and messages as Common Property Search --- .../CommonAttributePanel.java | 22 +++++++++---------- .../CommonAttributeSearchAction.java | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index 739985db31..c159053f7e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -74,10 +74,10 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer * Creates new form CommonFilesPanel */ @NbBundle.Messages({ - "CommonAttributePanel.title=Common Attribute Panel", + "CommonAttributePanel.title=Common Property Panel", "CommonAttributePanel.exception=Unexpected Exception loading DataSources.", - "CommonAttributePanel.frame.title=Find Common Attributes", - "CommonAttributePanel.frame.msg=Find Common Attributes", + "CommonAttributePanel.frame.title=Find Common Properties", + "CommonAttributePanel.frame.msg=Find Common Properties", "CommonAttributePanel.intraCasePanel.title=Curren Case Options"}) CommonAttributePanel() { super(new JFrame(Bundle.CommonAttributePanel_frame_title()), @@ -183,16 +183,16 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer * Perform the common attribute search. */ @NbBundle.Messages({ - "CommonAttributePanel.search.results.titleAll=Common Attributes (All Data Sources)", - "CommonAttributePanel.search.results.titleSingle=Common Attributes (Match Within Data Source: %s)", - "CommonAttributePanel.search.results.pathText=Common Attribute Search Results", - "CommonAttributePanel.search.done.searchProgressGathering=Gathering Common Attribute Search Results.", - "CommonAttributePanel.search.done.searchProgressDisplay=Displaying Common Attribute Search Results.", + "CommonAttributePanel.search.results.titleAll=Common Properties (All Data Sources)", + "CommonAttributePanel.search.results.titleSingle=Common Properties (Match Within Data Source: %s)", + "CommonAttributePanel.search.results.pathText=Common Property Search Results", + "CommonAttributePanel.search.done.searchProgressGathering=Gathering Common Property Search Results.", + "CommonAttributePanel.search.done.searchProgressDisplay=Displaying Common Property Search Results.", "CommonAttributePanel.search.done.tskCoreException=Unable to run query against DB.", "CommonAttributePanel.search.done.noCurrentCaseException=Unable to open case file.", - "CommonAttributePanel.search.done.exception=Unexpected exception running Common Attribute Search.", - "CommonAttributePanel.search.done.interupted=Something went wrong finding common attributes.", - "CommonAttributePanel.search.done.sqlException=Unable to query db for attributes or data sources."}) + "CommonAttributePanel.search.done.exception=Unexpected exception running Common Property Search.", + "CommonAttributePanel.search.done.interupted=Something went wrong finding common properties.", + "CommonAttributePanel.search.done.sqlException=Unable to query db for properties or data sources."}) private void search() { String pathText = Bundle.CommonAttributePanel_search_results_pathText(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java index 0d5db72bc4..66a3170c4a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchAction.java @@ -95,7 +95,7 @@ final public class CommonAttributeSearchAction extends CallableSystemAction { } @NbBundle.Messages({ - "CommonAttributeSearchAction.getName.text=Common Attribute Search"}) + "CommonAttributeSearchAction.getName.text=Common Property Search"}) @Override public String getName() { return Bundle.CommonAttributeSearchAction_getName_text(); From d74f496a09c652f167cbe121e0239581d887694b Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 14 Sep 2018 15:34:48 -0400 Subject: [PATCH 043/273] Hiding columns when checkbox is selected. --- .../CaseDBCommonAttributeInstanceNode.java | 9 +- .../communications/RelationshipNode.java | 9 +- .../contentviewers/MessageContentViewer.java | 9 +- .../autopsy/core/UserPreferences.java | 16 ++++ .../autopsy/corecomponents/Bundle.properties | 1 + .../corecomponents/ViewPreferencesPanel.form | 90 ++++++++++++------- .../corecomponents/ViewPreferencesPanel.java | 81 +++++++++++------ .../datamodel/AbstractFsContentNode.java | 13 +-- .../datamodel/BlackboardArtifactNode.java | 9 +- .../autopsy/datamodel/LayoutFileNode.java | 9 +- .../autopsy/datamodel/LocalDirectoryNode.java | 9 +- .../autopsy/datamodel/LocalFileNode.java | 9 +- .../datamodel/VirtualDirectoryNode.java | 9 +- .../DirectoryTreeTopComponent.java | 1 + 14 files changed, 185 insertions(+), 89 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java index 45ba05735e..ee5135b28a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java @@ -22,6 +22,7 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -84,10 +85,12 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode { final String NO_DESCR = Bundle.CommonFilesSearchResultsViewerTable_noDescText(); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), NO_DESCR, this.getContent().getName())); - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); this.addScoreProperty(sheetSet, tags); - this.addCommentProperty(sheetSet, tags, correlationAttribute); - this.addCountProperty(sheetSet, correlationAttribute); + if (UserPreferences.hideExaminerNotifications() == false) { + CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); + this.addCommentProperty(sheetSet, tags, correlationAttribute); + this.addCountProperty(sheetSet, correlationAttribute); + } sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), NO_DESCR, this.getContent().getParentPath())); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, getHashSetHitsCsvList(this.getContent()))); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource())); diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java index 0b92830002..c6a470264d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java @@ -24,6 +24,7 @@ import java.util.logging.Level; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -68,10 +69,12 @@ final class RelationshipNode extends BlackboardArtifactNode { } sheetSet.put(new NodeProperty<>("Type", "Type", "Type", getDisplayName())); - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); addScoreProperty(sheetSet, tags); - addCommentProperty(sheetSet, tags, correlationAttribute); - addCountProperty(sheetSet, correlationAttribute); + if (UserPreferences.hideExaminerNotifications() == false) { + CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); + addCommentProperty(sheetSet, tags, correlationAttribute); + addCountProperty(sheetSet, correlationAttribute); + } final BlackboardArtifact artifact = getArtifact(); BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(getArtifact().getArtifactTypeID()); if (null != fromID) { diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index b109b12da0..1a8eb073de 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -37,6 +37,7 @@ import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; @@ -729,10 +730,12 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont AbstractFile file = getContent(); sheetSet.put(new NodeProperty<>("Name", "Name", "Name", file.getName())); - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); addScoreProperty(sheetSet, tags); - addCommentProperty(sheetSet, tags, correlationAttribute); - addCountProperty(sheetSet, correlationAttribute); + if (UserPreferences.hideExaminerNotifications() == false) { + CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); + addCommentProperty(sheetSet, tags, correlationAttribute); + addCountProperty(sheetSet, correlationAttribute); + } sheetSet.put(new NodeProperty<>("Size", "Size", "Size", file.getSize())); sheetSet.put(new NodeProperty<>("Mime Type", "Mime Type", "Mime Type", StringUtils.defaultString(file.getMIMEType()))); sheetSet.put(new NodeProperty<>("Known", "Known", "Known", file.getKnown().getName())); diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 48ce2c5731..69ec5e009e 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -71,6 +71,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_EXAMINER_NOTIFICATIONS = "HideExaminerNotifications"; // Prevent instantiation. private UserPreferences() { @@ -220,6 +221,21 @@ public final class UserPreferences { preferences.putBoolean(SHOW_ONLY_CURRENT_USER_TAGS, value); } + /** + * //DLG: + */ + public static boolean hideExaminerNotifications() { + return preferences.getBoolean(HIDE_EXAMINER_NOTIFICATIONS, false); + } + + + /** + * //DLG: + */ + public static void setHideExaminerNotifications(boolean value) { + preferences.putBoolean(HIDE_EXAMINER_NOTIFICATIONS, value); + } + /** * Reads persisted case database connection info. * diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index 6191af9990..3623530baa 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -188,3 +188,4 @@ ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text=Data Sources area (the di ViewPreferencesPanel.viewsHideSlackCheckbox.text=Views area ViewPreferencesPanel.currentSessionSettingsPanel.border.title=Current Session Settings ViewPreferencesPanel.hideRejectedResultsCheckbox.text=Hide rejected results +ViewPreferencesPanel.hideExaminerNotificationsCheckbox.text=Hide examiner notifications diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form index 0665023009..d0dd3c6e7c 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form @@ -54,12 +54,12 @@ - + - + @@ -82,52 +82,63 @@ - - - - - - - - + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + - - + - + @@ -140,7 +151,7 @@ - + @@ -156,7 +167,8 @@ - + + @@ -286,6 +298,16 @@ + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index 2864d62474..04d9e7d7f3 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -60,13 +60,16 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { dataSourcesHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree()); viewsHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInViewsTree()); + + hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags()); + hideExaminerNotificationsCheckbox.setSelected(UserPreferences.hideExaminerNotifications()); + // Current Case Settings boolean caseIsOpen = Case.isCaseOpen(); currentCaseSettingsPanel.setEnabled(caseIsOpen); groupByDataSourceCheckbox.setEnabled(caseIsOpen); - hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags()); groupByDataSourceCheckbox.setSelected(Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)); // Current Session Settings @@ -82,6 +85,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCheckbox.isSelected()); UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected()); UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected()); + UserPreferences.setHideExaminerNotifications(hideExaminerNotificationsCheckbox.isSelected()); storeGroupItemsInTreeByDataSource(); @@ -127,6 +131,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { useLocalTimeRadioButton = new javax.swing.JRadioButton(); useGMTTimeRadioButton = new javax.swing.JRadioButton(); hideOtherUsersTagsCheckbox = new javax.swing.JCheckBox(); + hideExaminerNotificationsCheckbox = new javax.swing.JCheckBox(); currentCaseSettingsPanel = new javax.swing.JPanel(); groupByDataSourceCheckbox = new javax.swing.JCheckBox(); currentSessionSettingsPanel = new javax.swing.JPanel(); @@ -209,6 +214,13 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { } }); + org.openide.awt.Mnemonics.setLocalizedText(hideExaminerNotificationsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideExaminerNotificationsCheckbox.text")); // NOI18N + hideExaminerNotificationsCheckbox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + hideExaminerNotificationsCheckboxActionPerformed(evt); + } + }); + javax.swing.GroupLayout globalSettingsPanelLayout = new javax.swing.GroupLayout(globalSettingsPanel); globalSettingsPanel.setLayout(globalSettingsPanelLayout); globalSettingsPanelLayout.setHorizontalGroup( @@ -216,38 +228,45 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(displayTimeLabel) .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) + .addComponent(hideExaminerNotificationsCheckbox) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addComponent(hideOtherUsersTagsCheckbox) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(keepCurrentViewerRadioButton) - .addComponent(useBestViewerRadioButton) - .addComponent(useGMTTimeRadioButton) - .addComponent(useLocalTimeRadioButton))) - .addComponent(selectFileLabel)) - .addGap(18, 18, 18) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(hideOtherUsersTagsCheckbox) - .addComponent(hideKnownFilesLabel) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(hideKnownFilesLabel) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideSlackCheckbox) + .addComponent(viewsHideSlackCheckbox))) + .addComponent(hideSlackFilesLabel)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideKnownCheckbox) + .addComponent(viewsHideKnownCheckbox))))) + .addGap(27, 27, 27) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(displayTimeLabel) + .addComponent(selectFileLabel) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGap(10, 10, 10) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideSlackCheckbox) - .addComponent(viewsHideSlackCheckbox))) - .addComponent(hideSlackFilesLabel)) - .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideKnownCheckbox) - .addComponent(viewsHideKnownCheckbox))))) - .addContainerGap(29, Short.MAX_VALUE)) + .addComponent(keepCurrentViewerRadioButton) + .addComponent(useBestViewerRadioButton) + .addComponent(useGMTTimeRadioButton) + .addComponent(useLocalTimeRadioButton)))) + .addGap(20, 20, 20)))) ); globalSettingsPanelLayout.setVerticalGroup( globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addContainerGap() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addComponent(hideKnownFilesLabel) @@ -275,7 +294,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addComponent(useGMTTimeRadioButton))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(hideOtherUsersTagsCheckbox) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(hideExaminerNotificationsCheckbox)) ); currentCaseSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentCaseSettingsPanel.border.title"))); // NOI18N @@ -343,12 +363,12 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { viewPreferencesPanelLayout.setVerticalGroup( viewPreferencesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(viewPreferencesPanelLayout.createSequentialGroup() - .addComponent(globalSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 197, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(globalSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(currentSessionSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(13, Short.MAX_VALUE)) ); viewPreferencesScrollPane.setViewportView(viewPreferencesPanel); @@ -461,6 +481,14 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { } }//GEN-LAST:event_hideRejectedResultsCheckboxActionPerformed + private void hideExaminerNotificationsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideExaminerNotificationsCheckboxActionPerformed + if (immediateUpdates) { + UserPreferences.setHideExaminerNotifications(hideExaminerNotificationsCheckbox.isSelected()); + } else { + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + }//GEN-LAST:event_hideExaminerNotificationsCheckboxActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel currentCaseSettingsPanel; @@ -470,6 +498,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { private javax.swing.JLabel displayTimeLabel; private javax.swing.JPanel globalSettingsPanel; private javax.swing.JCheckBox groupByDataSourceCheckbox; + private javax.swing.JCheckBox hideExaminerNotificationsCheckbox; private javax.swing.JLabel hideKnownFilesLabel; private javax.swing.JCheckBox hideOtherUsersTagsCheckbox; private javax.swing.JCheckBox hideRejectedResultsCheckbox; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index 02dd3c1d28..bc42c4e80c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -24,6 +24,7 @@ import java.util.Map; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.ContentTag; @@ -82,12 +83,14 @@ public abstract class AbstractFsContentNode extends Abst AbstractFilePropertyType.NAME.toString(), NO_DESCR, getName())); - //add the cr status property before the propertyMap to ensure it is early in column order + //add the status property before the propertyMap to ensure it is early in column order addScoreProperty(sheetSet, tags); - //add the comment property before the propertyMap to ensure it is early in column order - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); - addCommentProperty(sheetSet, tags, correlationAttribute); - addCountProperty(sheetSet, correlationAttribute); + if (UserPreferences.hideExaminerNotifications() == false) { + //add the comment property before the propertyMap to ensure it is early in column order + CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); + addCommentProperty(sheetSet, tags, correlationAttribute); + addCountProperty(sheetSet, correlationAttribute); + } for (AbstractFilePropertyType propType : AbstractFilePropertyType.values()) { final String propString = propType.toString(); sheetSet.put(new NodeProperty<>(propString, propString, NO_DESCR, map.get(propString))); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 4178d2fafe..b816d7670a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -55,6 +55,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.Score; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; @@ -350,10 +351,12 @@ public class BlackboardArtifactNode extends AbstractContentNode { NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.name.displayName"), NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.name.desc"), getName())); - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); addScoreProperty(sheetSet, tags); - addCommentProperty(sheetSet, tags, correlationAttribute); - addCountProperty(sheetSet, correlationAttribute); + if (UserPreferences.hideExaminerNotifications() == false) { + CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); + addCommentProperty(sheetSet, tags, correlationAttribute); + addCountProperty(sheetSet, correlationAttribute); + } final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.noDescr.text"); for (Map.Entry entry : map.entrySet()) { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java index f6f3de7680..9488202b92 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java @@ -24,6 +24,7 @@ import java.util.Map; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.LocalDirectory; @@ -63,10 +64,12 @@ public class LocalDirectoryNode extends SpecialDirectoryNode { Bundle.LocalDirectoryNode_createSheet_name_displayName(), Bundle.LocalDirectoryNode_createSheet_name_desc(), getName())); - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); addScoreProperty(sheetSet, tags); - addCommentProperty(sheetSet, tags, correlationAttribute); - addCountProperty(sheetSet, correlationAttribute); + if (UserPreferences.hideExaminerNotifications() == false) { + CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); + addCommentProperty(sheetSet, tags, correlationAttribute); + addCountProperty(sheetSet, correlationAttribute); + } // At present, a LocalDirectory will never be a datasource - the top level of a logical // file set is a VirtualDirectory Map map = new LinkedHashMap<>(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index a9c09ee1d7..90fe295825 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -33,6 +33,7 @@ import org.openide.util.Utilities; import org.sleuthkit.autopsy.actions.AddContentTagAction; import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; @@ -82,10 +83,12 @@ public class LocalFileNode extends AbstractAbstractFileNode { NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.name.displayName"), NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.name.desc"), getName())); - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); addScoreProperty(sheetSet, tags); - addCommentProperty(sheetSet, tags, correlationAttribute); - addCountProperty(sheetSet, correlationAttribute); + if (UserPreferences.hideExaminerNotifications() == false) { + CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); + addCommentProperty(sheetSet, tags, correlationAttribute); + addCountProperty(sheetSet, correlationAttribute); + } final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.noDescr.text"); for (Map.Entry entry : map.entrySet()) { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java index 02f382e6ad..2244ccd90d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java @@ -29,6 +29,7 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.SleuthkitCase; @@ -90,10 +91,12 @@ public class VirtualDirectoryNode extends SpecialDirectoryNode { NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.name.desc"), getName())); if (!this.content.isDataSource()) { - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); addScoreProperty(sheetSet, tags); - addCommentProperty(sheetSet, tags, correlationAttribute); - addCountProperty(sheetSet, correlationAttribute); + if (UserPreferences.hideExaminerNotifications() == false) { + CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); + addCommentProperty(sheetSet, tags, correlationAttribute); + addCountProperty(sheetSet, correlationAttribute); + } Map map = new LinkedHashMap<>(); fillPropertyMap(map, getContent()); diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 9c577cba59..fe453eea9d 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -175,6 +175,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat switch (evt.getKey()) { case UserPreferences.HIDE_KNOWN_FILES_IN_DATA_SRCS_TREE: case UserPreferences.HIDE_SLACK_FILES_IN_DATA_SRCS_TREE: + case UserPreferences.HIDE_EXAMINER_NOTIFICATIONS: refreshContentTreeSafe(); break; case UserPreferences.SHOW_ONLY_CURRENT_USER_TAGS: From 4dff05f58a668e9c562cdc82a90846751097e5a0 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 17 Sep 2018 09:29:02 -0400 Subject: [PATCH 044/273] Small little name change --- .../autopsy/keywordsearch/SqliteTextExtractor.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java index 9ced18fea6..f33b52bb9d 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SqliteTextExtractor.java @@ -116,9 +116,9 @@ public class SqliteTextExtractor extends ContentTextExtractor { private CharSequence getDatabaseContents(Content source, AbstractReader reader) { try { Map tables = reader.getTableSchemas(); - LinkedList databaseStorage = new LinkedList<>(); + Collection databaseStorage = new LinkedList<>(); - Integer charactersCopied = loadDatabaseIntoList(databaseStorage, + Integer charactersCopied = loadDatabaseIntoCollection(databaseStorage, tables, reader, source); return toCharSequence(databaseStorage, charactersCopied); @@ -138,12 +138,12 @@ public class SqliteTextExtractor extends ContentTextExtractor { * rows from the table. The table string will be added to the list of * contents. * - * @param databaseStorage List containing all of the database content + * @param databaseStorage Collection containing all of the database content * @param tables A map of table names to table schemas * @param reader SqliteReader for interfacing with the database * @param source Source database file for logging */ - private int loadDatabaseIntoList(LinkedList databaseStorage, + private int loadDatabaseIntoCollection(Collection databaseStorage, Map tables, AbstractReader reader, Content source) { int charactersCopied = 0; @@ -178,7 +178,7 @@ public class SqliteTextExtractor extends ContentTextExtractor { * * @return A character seqeunces of the database contents */ - private CharSequence toCharSequence(LinkedList databaseStorage, + private CharSequence toCharSequence(Collection databaseStorage, int characterCount) { final char[] databaseCharArray = new char[characterCount]; From 6bd8b6fe4867f21e6ec7bd4301d058c91a547536 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Mon, 17 Sep 2018 10:14:28 -0400 Subject: [PATCH 045/273] Modified logic to take checkboxes into account. --- .../CaseDBCommonAttributeInstanceNode.java | 17 ++-- .../communications/RelationshipNode.java | 13 ++- .../contentviewers/MessageContentViewer.java | 13 ++- .../autopsy/core/UserPreferences.java | 10 +-- .../autopsy/corecomponents/Bundle.properties | 2 +- .../corecomponents/ViewPreferencesPanel.form | 79 ++++++++++--------- .../corecomponents/ViewPreferencesPanel.java | 77 +++++++++--------- .../datamodel/AbstractFsContentNode.java | 17 ++-- .../datamodel/BlackboardArtifactNode.java | 12 ++- .../autopsy/datamodel/LayoutFileNode.java | 13 ++- .../autopsy/datamodel/LocalDirectoryNode.java | 13 ++- .../autopsy/datamodel/LocalFileNode.java | 13 ++- .../datamodel/VirtualDirectoryNode.java | 12 ++- .../DirectoryTreeTopComponent.java | 2 +- 14 files changed, 178 insertions(+), 115 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java index ee5135b28a..e925c570b9 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java @@ -22,6 +22,7 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.FileNode; @@ -85,11 +86,17 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode { final String NO_DESCR = Bundle.CommonFilesSearchResultsViewerTable_noDescText(); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), NO_DESCR, this.getContent().getName())); - this.addScoreProperty(sheetSet, tags); - if (UserPreferences.hideExaminerNotifications() == false) { - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); - this.addCommentProperty(sheetSet, tags, correlationAttribute); - this.addCountProperty(sheetSet, correlationAttribute); + + addScoreProperty(sheetSet, tags); + + CorrelationAttributeInstance correlationAttribute = null; + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { + correlationAttribute = getCorrelationAttributeInstance(); + } + addCommentProperty(sheetSet, tags, correlationAttribute); + + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { + addCountProperty(sheetSet, correlationAttribute); } sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), NO_DESCR, this.getContent().getParentPath())); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, getHashSetHitsCsvList(this.getContent()))); diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java index c6a470264d..1e21b7d269 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationshipNode.java @@ -24,6 +24,7 @@ import java.util.logging.Level; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; @@ -69,10 +70,16 @@ final class RelationshipNode extends BlackboardArtifactNode { } sheetSet.put(new NodeProperty<>("Type", "Type", "Type", getDisplayName())); + addScoreProperty(sheetSet, tags); - if (UserPreferences.hideExaminerNotifications() == false) { - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); - addCommentProperty(sheetSet, tags, correlationAttribute); + + CorrelationAttributeInstance correlationAttribute = null; + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { + correlationAttribute = getCorrelationAttributeInstance(); + } + addCommentProperty(sheetSet, tags, correlationAttribute); + + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { addCountProperty(sheetSet, correlationAttribute); } final BlackboardArtifact artifact = getArtifact(); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 1a8eb073de..9c2b91d783 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -37,6 +37,7 @@ import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; @@ -730,10 +731,16 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont AbstractFile file = getContent(); sheetSet.put(new NodeProperty<>("Name", "Name", "Name", file.getName())); + addScoreProperty(sheetSet, tags); - if (UserPreferences.hideExaminerNotifications() == false) { - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); - addCommentProperty(sheetSet, tags, correlationAttribute); + + CorrelationAttributeInstance correlationAttribute = null; + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { + correlationAttribute = getCorrelationAttributeInstance(); + } + addCommentProperty(sheetSet, tags, correlationAttribute); + + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { addCountProperty(sheetSet, correlationAttribute); } sheetSet.put(new NodeProperty<>("Size", "Size", "Size", file.getSize())); diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 69ec5e009e..88cde61470 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -71,7 +71,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_EXAMINER_NOTIFICATIONS = "HideExaminerNotifications"; + public static final String HIDE_CENTRAL_REPO_NOTIFICATIONS = "HideCentralRepoNotifications"; // Prevent instantiation. private UserPreferences() { @@ -224,16 +224,16 @@ public final class UserPreferences { /** * //DLG: */ - public static boolean hideExaminerNotifications() { - return preferences.getBoolean(HIDE_EXAMINER_NOTIFICATIONS, false); + public static boolean hideCentralRepoNotifications() { + return preferences.getBoolean(HIDE_CENTRAL_REPO_NOTIFICATIONS, false); } /** * //DLG: */ - public static void setHideExaminerNotifications(boolean value) { - preferences.putBoolean(HIDE_EXAMINER_NOTIFICATIONS, value); + public static void setHideCentralRepoNotifications(boolean value) { + preferences.putBoolean(HIDE_CENTRAL_REPO_NOTIFICATIONS, value); } /** diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index 3623530baa..6ae4b8aead 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -188,4 +188,4 @@ ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text=Data Sources area (the di ViewPreferencesPanel.viewsHideSlackCheckbox.text=Views area ViewPreferencesPanel.currentSessionSettingsPanel.border.title=Current Session Settings ViewPreferencesPanel.hideRejectedResultsCheckbox.text=Hide rejected results -ViewPreferencesPanel.hideExaminerNotificationsCheckbox.text=Hide examiner notifications +ViewPreferencesPanel.doNotUseCentralRepoCheckbox.text=Do not use Central Repository for C(omments) and O(ccurences) columns to reduce loading times diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form index d0dd3c6e7c..5281b02584 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form @@ -83,51 +83,52 @@ - + - - - - - + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - + @@ -168,7 +169,7 @@ - + @@ -298,14 +299,14 @@ - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index 04d9e7d7f3..2a4ad2a599 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -23,6 +23,7 @@ import javax.swing.JPanel; import org.netbeans.spi.options.OptionsPanelController; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.CasePreferences; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; @@ -62,14 +63,14 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { viewsHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInViewsTree()); hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags()); - hideExaminerNotificationsCheckbox.setSelected(UserPreferences.hideExaminerNotifications()); + doNotUseCentralRepoCheckbox.setEnabled(EamDbUtil.useCentralRepo()); + doNotUseCentralRepoCheckbox.setSelected(UserPreferences.hideCentralRepoNotifications()); // Current Case Settings boolean caseIsOpen = Case.isCaseOpen(); currentCaseSettingsPanel.setEnabled(caseIsOpen); groupByDataSourceCheckbox.setEnabled(caseIsOpen); - groupByDataSourceCheckbox.setSelected(Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)); // Current Session Settings @@ -85,7 +86,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCheckbox.isSelected()); UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected()); UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected()); - UserPreferences.setHideExaminerNotifications(hideExaminerNotificationsCheckbox.isSelected()); + UserPreferences.setHideCentralRepoNotifications(doNotUseCentralRepoCheckbox.isSelected()); storeGroupItemsInTreeByDataSource(); @@ -131,7 +132,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { useLocalTimeRadioButton = new javax.swing.JRadioButton(); useGMTTimeRadioButton = new javax.swing.JRadioButton(); hideOtherUsersTagsCheckbox = new javax.swing.JCheckBox(); - hideExaminerNotificationsCheckbox = new javax.swing.JCheckBox(); + doNotUseCentralRepoCheckbox = new javax.swing.JCheckBox(); currentCaseSettingsPanel = new javax.swing.JPanel(); groupByDataSourceCheckbox = new javax.swing.JCheckBox(); currentSessionSettingsPanel = new javax.swing.JPanel(); @@ -214,10 +215,10 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { } }); - org.openide.awt.Mnemonics.setLocalizedText(hideExaminerNotificationsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideExaminerNotificationsCheckbox.text")); // NOI18N - hideExaminerNotificationsCheckbox.addActionListener(new java.awt.event.ActionListener() { + org.openide.awt.Mnemonics.setLocalizedText(doNotUseCentralRepoCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.doNotUseCentralRepoCheckbox.text")); // NOI18N + doNotUseCentralRepoCheckbox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - hideExaminerNotificationsCheckboxActionPerformed(evt); + doNotUseCentralRepoCheckboxActionPerformed(evt); } }); @@ -229,39 +230,39 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addContainerGap() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addComponent(hideExaminerNotificationsCheckbox) + .addComponent(doNotUseCentralRepoCheckbox) .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addComponent(hideOtherUsersTagsCheckbox) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(hideKnownFilesLabel) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(hideOtherUsersTagsCheckbox) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(hideKnownFilesLabel) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideSlackCheckbox) + .addComponent(viewsHideSlackCheckbox))) + .addComponent(hideSlackFilesLabel)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideKnownCheckbox) + .addComponent(viewsHideKnownCheckbox))))) + .addGap(27, 27, 27) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(displayTimeLabel) + .addComponent(selectFileLabel) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGap(10, 10, 10) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideSlackCheckbox) - .addComponent(viewsHideSlackCheckbox))) - .addComponent(hideSlackFilesLabel)) - .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideKnownCheckbox) - .addComponent(viewsHideKnownCheckbox))))) - .addGap(27, 27, 27) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(displayTimeLabel) - .addComponent(selectFileLabel) - .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(keepCurrentViewerRadioButton) - .addComponent(useBestViewerRadioButton) - .addComponent(useGMTTimeRadioButton) - .addComponent(useLocalTimeRadioButton)))) - .addGap(20, 20, 20)))) + .addComponent(keepCurrentViewerRadioButton) + .addComponent(useBestViewerRadioButton) + .addComponent(useGMTTimeRadioButton) + .addComponent(useLocalTimeRadioButton)))))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) ); globalSettingsPanelLayout.setVerticalGroup( globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -295,7 +296,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(hideOtherUsersTagsCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(hideExaminerNotificationsCheckbox)) + .addComponent(doNotUseCentralRepoCheckbox)) ); currentCaseSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentCaseSettingsPanel.border.title"))); // NOI18N @@ -481,13 +482,13 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { } }//GEN-LAST:event_hideRejectedResultsCheckboxActionPerformed - private void hideExaminerNotificationsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideExaminerNotificationsCheckboxActionPerformed + private void doNotUseCentralRepoCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_doNotUseCentralRepoCheckboxActionPerformed if (immediateUpdates) { - UserPreferences.setHideExaminerNotifications(hideExaminerNotificationsCheckbox.isSelected()); + UserPreferences.setHideCentralRepoNotifications(doNotUseCentralRepoCheckbox.isSelected()); } else { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } - }//GEN-LAST:event_hideExaminerNotificationsCheckboxActionPerformed + }//GEN-LAST:event_doNotUseCentralRepoCheckboxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables @@ -496,9 +497,9 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { private javax.swing.JCheckBox dataSourcesHideKnownCheckbox; private javax.swing.JCheckBox dataSourcesHideSlackCheckbox; private javax.swing.JLabel displayTimeLabel; + private javax.swing.JCheckBox doNotUseCentralRepoCheckbox; private javax.swing.JPanel globalSettingsPanel; private javax.swing.JCheckBox groupByDataSourceCheckbox; - private javax.swing.JCheckBox hideExaminerNotificationsCheckbox; private javax.swing.JLabel hideKnownFilesLabel; private javax.swing.JCheckBox hideOtherUsersTagsCheckbox; private javax.swing.JCheckBox hideRejectedResultsCheckbox; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index bc42c4e80c..4b8798af68 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -24,6 +24,7 @@ import java.util.Map; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; @@ -83,14 +84,20 @@ public abstract class AbstractFsContentNode extends Abst AbstractFilePropertyType.NAME.toString(), NO_DESCR, getName())); - //add the status property before the propertyMap to ensure it is early in column order + addScoreProperty(sheetSet, tags); - if (UserPreferences.hideExaminerNotifications() == false) { - //add the comment property before the propertyMap to ensure it is early in column order - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); - addCommentProperty(sheetSet, tags, correlationAttribute); + + //add the comment property before the propertyMap to ensure it is early in column order + CorrelationAttributeInstance correlationAttribute = null; + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { + correlationAttribute = getCorrelationAttributeInstance(); + } + addCommentProperty(sheetSet, tags, correlationAttribute); + + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { addCountProperty(sheetSet, correlationAttribute); } + for (AbstractFilePropertyType propType : AbstractFilePropertyType.values()) { final String propString = propType.toString(); sheetSet.put(new NodeProperty<>(propString, propString, NO_DESCR, map.get(propString))); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index b816d7670a..69d2a73afc 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -351,10 +351,16 @@ public class BlackboardArtifactNode extends AbstractContentNode { NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.name.displayName"), NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.name.desc"), getName())); + addScoreProperty(sheetSet, tags); - if (UserPreferences.hideExaminerNotifications() == false) { - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); - addCommentProperty(sheetSet, tags, correlationAttribute); + + CorrelationAttributeInstance correlationAttribute = null; + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { + correlationAttribute = getCorrelationAttributeInstance(); + } + addCommentProperty(sheetSet, tags, correlationAttribute); + + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { addCountProperty(sheetSet, correlationAttribute); } final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.noDescr.text"); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java index 9488202b92..72d1a537db 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java @@ -24,6 +24,7 @@ import java.util.Map; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.LocalDirectory; @@ -64,10 +65,16 @@ public class LocalDirectoryNode extends SpecialDirectoryNode { Bundle.LocalDirectoryNode_createSheet_name_displayName(), Bundle.LocalDirectoryNode_createSheet_name_desc(), getName())); + addScoreProperty(sheetSet, tags); - if (UserPreferences.hideExaminerNotifications() == false) { - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); - addCommentProperty(sheetSet, tags, correlationAttribute); + + CorrelationAttributeInstance correlationAttribute = null; + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { + correlationAttribute = getCorrelationAttributeInstance(); + } + addCommentProperty(sheetSet, tags, correlationAttribute); + + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { addCountProperty(sheetSet, correlationAttribute); } // At present, a LocalDirectory will never be a datasource - the top level of a logical diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index 90fe295825..1200e1553d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -33,6 +33,7 @@ import org.openide.util.Utilities; import org.sleuthkit.autopsy.actions.AddContentTagAction; import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.coreutils.Logger; @@ -83,10 +84,16 @@ public class LocalFileNode extends AbstractAbstractFileNode { NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.name.displayName"), NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.name.desc"), getName())); + addScoreProperty(sheetSet, tags); - if (UserPreferences.hideExaminerNotifications() == false) { - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); - addCommentProperty(sheetSet, tags, correlationAttribute); + + CorrelationAttributeInstance correlationAttribute = null; + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { + correlationAttribute = getCorrelationAttributeInstance(); + } + addCommentProperty(sheetSet, tags, correlationAttribute); + + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { addCountProperty(sheetSet, correlationAttribute); } final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.noDescr.text"); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java index 2244ccd90d..8992698eb4 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java @@ -29,6 +29,7 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.ContentTag; @@ -92,9 +93,14 @@ public class VirtualDirectoryNode extends SpecialDirectoryNode { getName())); if (!this.content.isDataSource()) { addScoreProperty(sheetSet, tags); - if (UserPreferences.hideExaminerNotifications() == false) { - CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance(); - addCommentProperty(sheetSet, tags, correlationAttribute); + + CorrelationAttributeInstance correlationAttribute = null; + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { + correlationAttribute = getCorrelationAttributeInstance(); + } + addCommentProperty(sheetSet, tags, correlationAttribute); + + if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoNotifications() == false) { addCountProperty(sheetSet, correlationAttribute); } Map map = new LinkedHashMap<>(); diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index fe453eea9d..5df4a16e2c 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -175,7 +175,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat switch (evt.getKey()) { case UserPreferences.HIDE_KNOWN_FILES_IN_DATA_SRCS_TREE: case UserPreferences.HIDE_SLACK_FILES_IN_DATA_SRCS_TREE: - case UserPreferences.HIDE_EXAMINER_NOTIFICATIONS: + case UserPreferences.HIDE_CENTRAL_REPO_NOTIFICATIONS: refreshContentTreeSafe(); break; case UserPreferences.SHOW_ONLY_CURRENT_USER_TAGS: From 3357c7fc020c1b4fb6d46393b661d7aece0d5296 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Sep 2018 10:30:14 -0400 Subject: [PATCH 046/273] 4167 adjust title of common property search to include percent --- .../AbstractCommonAttributeSearcher.java | 106 ++++++++-------- .../AllInterCaseCommonAttributeSearcher.java | 27 +++-- .../AllIntraCaseCommonAttributeSearcher.java | 34 +++--- .../CommonAttributePanel.form | 48 +++++--- .../CommonAttributePanel.java | 113 ++++++++---------- .../commonfilesearch/InterCasePanel.form | 6 +- .../commonfilesearch/InterCasePanel.java | 6 +- .../commonfilesearch/IntraCasePanel.form | 11 +- .../commonfilesearch/IntraCasePanel.java | 7 +- ...ingleInterCaseCommonAttributeSearcher.java | 27 +++-- ...ingleIntraCaseCommonAttributeSearcher.java | 38 +++--- 11 files changed, 240 insertions(+), 183 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java index 9804d06ca9..f79737c116 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java @@ -1,16 +1,16 @@ /* - * + * * Autopsy Forensic Browser - * + * * Copyright 2018 Basis Technology Corp. * Contact: carrier sleuthkit 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. @@ -33,62 +33,58 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.datamodel.TskCoreException; - /** - * Prototype for an object which finds files with common attributes. - * Subclass this and implement findMatches in order + * Prototype for an object which finds files with common attributes. Subclass + * this and implement findMatches in order */ public abstract class AbstractCommonAttributeSearcher { - + private final Map dataSourceIdToNameMap; private boolean filterByMedia; private boolean filterByDoc; final int frequencyPercentageThreshold; - - AbstractCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMedia, boolean filterByDoc, int percentageThreshold){ + + AbstractCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMedia, boolean filterByDoc, int percentageThreshold) { this.filterByDoc = filterByDoc; this.filterByMedia = filterByMedia; this.dataSourceIdToNameMap = dataSourceIdMap; this.frequencyPercentageThreshold = percentageThreshold; } - - Map getDataSourceIdToNameMap(){ + + Map getDataSourceIdToNameMap() { return Collections.unmodifiableMap(this.dataSourceIdToNameMap); } - + /** - * Implement this to search for files with common attributes. Creates an - * object (CommonAttributeSearchResults) which contains all of the information - * required to display a tree view in the UI. The view will contain 3 layers: - * a top level node, indicating the number matches each of it's children possess, - * a mid level node indicating the matched attribute, + * Implement this to search for files with common attributes. Creates an + * object (CommonAttributeSearchResults) which contains all of the + * information required to display a tree view in the UI. The view will + * contain 3 layers: a top level node, indicating the number matches each of + * it's children possess, a mid level node indicating the matched attribute, + * * @return + * * @throws TskCoreException * @throws NoCurrentCaseException * @throws SQLException - * @throws EamDbException + * @throws EamDbException */ public abstract CommonAttributeSearchResults findMatches() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException; - + /** - * Implement this to create a descriptive string for the tab which will display - * this data. + * Implement this to create a descriptive string for the tab which will + * display this data. + * * @return an informative string */ - @NbBundle.Messages({ - "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraAll=Common Attributes (All Data Sources, %s)", - "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraSingle=Common Attributes (Data Source: %s, %s)", - "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterAll=Common Attributes (All Central Repository Cases, %s)", - "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterSingle=Common Attributes (Central Repository Case: %s, %s)", - }) - abstract String buildTabTitle(); - + abstract String getTabTitle(); + @NbBundle.Messages({ "AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.doc=Documents", "AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.media=Media", "AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories" }) - + String buildCategorySelectionString() { if (!this.isFilterByDoc() && !this.isFilterByMedia()) { return Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_all(); @@ -103,15 +99,33 @@ public abstract class AbstractCommonAttributeSearcher { return String.join(", ", filters); } } - + + /** + * Get the portion of the title that will display the frequency percentage + * threshold. Items that existed in over this percent of data sources were + * ommited from the results. + * + * @return A string providing the frequency percentage threshold, or an empty string if no threshold was set + */ + @NbBundle.Messages({ + "# {0} - threshold percent", + "AbstractCommonFilesMetadataBuilder.getPercentFilter.thresholdPercent=, Threshold {0}%"}) + String getPercentThresholdString() { + if (frequencyPercentageThreshold == 0) { + return ""; + } else { + return Bundle.AbstractCommonFilesMetadataBuilder_getPercentFilter_thresholdPercent(frequencyPercentageThreshold); + } + } + static Map collateMatchesByNumberOfInstances(Map commonFiles) { //collate matches by number of matching instances - doing this in sql doesnt seem efficient Map instanceCollatedCommonFiles = new TreeMap<>(); - - for(CommonAttributeValue md5Metadata : commonFiles.values()){ + + for (CommonAttributeValue md5Metadata : commonFiles.values()) { Integer size = md5Metadata.getInstanceCount(); - - if(instanceCollatedCommonFiles.containsKey(size)){ + + if (instanceCollatedCommonFiles.containsKey(size)) { instanceCollatedCommonFiles.get(size).addMetadataToList(md5Metadata); } else { CommonAttributeValueList value = new CommonAttributeValueList(); @@ -121,13 +135,13 @@ public abstract class AbstractCommonAttributeSearcher { } return instanceCollatedCommonFiles; } - + /* * The set of the MIME types that will be checked for extension mismatches - * when checkType is ONLY_MEDIA. - * ".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff", ".bmp", ".tec" - * ".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v", //NON-NLS - * ".m4v", ".mp4", ".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm", ".wmv", ".mpv", ".flv", ".swf" + * when checkType is ONLY_MEDIA. ".jpg", ".jpeg", ".png", ".psd", ".nef", + * ".tiff", ".bmp", ".tec" ".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v", + * //NON-NLS ".m4v", ".mp4", ".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm", + * ".wmv", ".mpv", ".flv", ".swf" */ static final Set MEDIA_PICS_VIDEO_MIME_TYPES = Stream.of( "image/bmp", //NON-NLS @@ -157,11 +171,9 @@ public abstract class AbstractCommonAttributeSearcher { /* * The set of the MIME types that will be checked for extension mismatches - * when checkType is ONLY_TEXT_FILES. - * ".doc", ".docx", ".odt", ".xls", ".xlsx", ".ppt", ".pptx" - * ".txt", ".rtf", ".log", ".text", ".xml" - * ".html", ".htm", ".css", ".js", ".php", ".aspx" - * ".pdf" + * when checkType is ONLY_TEXT_FILES. ".doc", ".docx", ".odt", ".xls", + * ".xlsx", ".ppt", ".pptx" ".txt", ".rtf", ".log", ".text", ".xml" ".html", + * ".htm", ".css", ".js", ".php", ".aspx" ".pdf" */ static final Set TEXT_FILES_MIME_TYPES = Stream.of( "text/plain", //NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index d8a7f27b44..3fbf41af2c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -1,16 +1,16 @@ /* - * + * * Autopsy Forensic Browser - * + * * Copyright 2018 Basis Technology Corp. * Contact: carrier sleuthkit 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. @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.SQLException; import java.util.Map; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; @@ -36,9 +37,10 @@ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttribut /** * * @param filterByMediaMimeType match only on files whose mime types can be - * broadly categorized as media types - * @param filterByDocMimeType match only on files whose mime types can be - * broadly categorized as document types + * broadly categorized as media types + * @param filterByDocMimeType match only on files whose mime types can be + * broadly categorized as document types + * * @throws EamDbException */ public AllInterCaseCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, Type corAttrType, int percentageThreshold) throws EamDbException { @@ -52,9 +54,12 @@ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttribut return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold, this.corAttrType); } + @NbBundle.Messages({ + "# {0} - attr type", + "# {1} - threshold string", + "AllInterCaseCommonAttributeSearcher.buildTabTitle.titleInterAll=Common Attributes (All Central Repository Cases, {0}{1})"}) @Override - String buildTabTitle() { - final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterAll(); - return String.format(titleTemplate, new Object[]{this.corAttrType.getDisplayName()}); + String getTabTitle() { + return Bundle.AllInterCaseCommonAttributeSearcher_buildTabTitle_titleInterAll(this.corAttrType.getDisplayName(), this.getPercentThresholdString()); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java index 35a5c70452..310799d94c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java @@ -1,16 +1,16 @@ /* - * + * * Autopsy Forensic Browser - * + * * Copyright 2018 Basis Technology Corp. * Contact: carrier sleuthkit 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. @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Map; +import org.openide.util.NbBundle; import org.sleuthkit.datamodel.TskData.FileKnown; /** @@ -27,15 +28,17 @@ import org.sleuthkit.datamodel.TskData.FileKnown; */ final public class AllIntraCaseCommonAttributeSearcher extends IntraCaseCommonAttributeSearcher { - private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL)%s GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS + private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != " + FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL)%s GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS /** * Implements the algorithm for getting common files across all data * sources. * - * @param dataSourceIdMap a map of obj_id to datasource name - * @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types - * @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types + * @param dataSourceIdMap a map of obj_id to datasource name + * @param filterByMediaMimeType match only on files whose mime types can be + * broadly categorized as media types + * @param filterByDocMimeType match only on files whose mime types can be + * broadly categorized as document types */ public AllIntraCaseCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, int percentageThreshold) { super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, percentageThreshold); @@ -44,14 +47,17 @@ final public class AllIntraCaseCommonAttributeSearcher extends IntraCaseCommonAt @Override protected String buildSqlSelectStatement() { - Object[] args = new String[] {SELECT_PREFIX, determineMimeTypeFilter()}; + Object[] args = new String[]{SELECT_PREFIX, determineMimeTypeFilter()}; return String.format(WHERE_CLAUSE, args); } + @NbBundle.Messages({ + "# {0} - build category", + "# {1} - threshold string", + "AllIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraAll=Common Attributes (All Data Sources, {0}{1})" + }) @Override - String buildTabTitle() { - final String buildCategorySelectionString = this.buildCategorySelectionString(); - final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleIntraAll(); - return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); + String getTabTitle() { + return Bundle.AllIntraCaseCommonAttributeSearcher_buildTabTitle_titleIntraAll(this.buildCategorySelectionString(), this.getPercentThresholdString()); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form index 0f81ccb799..5f0beb57e0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form @@ -7,7 +7,7 @@ - + @@ -27,7 +27,7 @@ - +
@@ -35,13 +35,13 @@ - + - + - + @@ -63,6 +63,10 @@ + + + + @@ -70,10 +74,6 @@ - - - - @@ -93,6 +93,11 @@ + + + + + @@ -109,16 +114,18 @@ - + - + - + + + @@ -238,12 +245,16 @@ + + + - + - + + @@ -255,14 +266,19 @@ + + + - + - + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index c159053f7e..c4aa8019f2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -94,7 +94,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer this.disableIntercaseSearch(); } - this.enablePercentageOptions(CommonAttributePanel.isEamDbAvailableForPercentageFrequencyCalculations()); + this.updatePercentageOptions(CommonAttributePanel.getNumberOfDataSourcesAvailable()); this.errorManager = new UserInputErrorManager(); @@ -153,21 +153,22 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer } /** - * Get whether or not the central repository will be available for filtering - * results. + * Get the number of data sources in the central repository if it is + * enabled, zero if it is not enabled. * - * @return true if the central repository exists and has at least 1 case in - * it, false otherwise. + * @return the number of data sources in the current central repo, or 0 if + * it is disabled */ - private static boolean isEamDbAvailableForPercentageFrequencyCalculations() { + private static Long getNumberOfDataSourcesAvailable() { try { - return EamDb.isEnabled() - && EamDb.getInstance() != null - && EamDb.getInstance().getCases().size() > 0; + if (EamDb.isEnabled() + && EamDb.getInstance() != null) { + return EamDb.getInstance().getCountUniqueDataSources(); + } } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Unexpected exception while checking for EamDB enabled.", ex); } - return false; + return 0L; } /** @@ -183,8 +184,6 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer * Perform the common attribute search. */ @NbBundle.Messages({ - "CommonAttributePanel.search.results.titleAll=Common Properties (All Data Sources)", - "CommonAttributePanel.search.results.titleSingle=Common Properties (Match Within Data Source: %s)", "CommonAttributePanel.search.results.pathText=Common Property Search Results", "CommonAttributePanel.search.done.searchProgressGathering=Gathering Common Property Search Results.", "CommonAttributePanel.search.done.searchProgressDisplay=Displaying Common Property Search Results.", @@ -194,35 +193,12 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer "CommonAttributePanel.search.done.interupted=Something went wrong finding common properties.", "CommonAttributePanel.search.done.sqlException=Unable to query db for properties or data sources."}) private void search() { - String pathText = Bundle.CommonAttributePanel_search_results_pathText(); new SwingWorker() { private String tabTitle; private ProgressHandle progress; - /** - * Set the title of the search results for searches using all data - * sources. - */ - private void setTitleForAllDataSources() { - this.tabTitle = Bundle.CommonAttributePanel_search_results_titleAll(); - } - - /** - * Set the title of the search results for searches using a single - * source. - * - * @param dataSourceId the datasource ID of the the source being - * used - */ - private void setTitleForSingleSource(Long dataSourceId) { - final String CommonAttributePanel_search_results_titleSingle = Bundle.CommonAttributePanel_search_results_titleSingle(); - final Object[] dataSourceName = new Object[]{intraCasePanel.getDataSourceMap().get(dataSourceId)}; - - this.tabTitle = String.format(CommonAttributePanel_search_results_titleSingle, dataSourceName); - } - @Override protected CommonAttributeSearchResults doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { progress = ProgressHandle.createHandle(Bundle.CommonAttributePanel_search_done_searchProgressGathering()); @@ -268,17 +244,13 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer } if (Objects.equals(dataSourceId, CommonAttributePanel.NO_DATA_SOURCE_SELECTED)) { builder = new AllIntraCaseCommonAttributeSearcher(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold); - - setTitleForAllDataSources(); } else { builder = new SingleIntraCaseCommonAttributeSearcher(dataSourceId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold); - - setTitleForSingleSource(dataSourceId); } } metadata = builder.findMatches(); - this.tabTitle = builder.buildTabTitle(); + this.tabTitle = builder.getTabTitle(); return metadata; } @@ -303,7 +275,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer viewers.add(table); progress.setDisplayName(Bundle.CommonAttributePanel_search_done_searchProgressDisplay()); - DataResultTopComponent.createInstance(tabTitle, pathText, tableFilterWithDescendantsNode, metadata.size(), viewers); + DataResultTopComponent.createInstance(tabTitle, Bundle.CommonAttributePanel_search_results_pathText(), tableFilterWithDescendantsNode, metadata.size(), viewers); progress.finish(); } catch (InterruptedException ex) { @@ -381,7 +353,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer * otherwise */ private boolean caseHasMultipleSources() { - return CommonAttributePanel.this.intraCasePanel.getDataSourceMap().size() > 1; + return CommonAttributePanel.this.intraCasePanel.getDataSourceMap().size() > 1; } @Override @@ -516,8 +488,9 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer percentageThresholdTextTwo = new javax.swing.JLabel(); intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); + dataSourcesLabel = new javax.swing.JLabel(); - setMinimumSize(new java.awt.Dimension(450, 440)); + setMinimumSize(new java.awt.Dimension(450, 460)); setResizable(false); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosed(java.awt.event.WindowEvent evt) { @@ -525,9 +498,9 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer } }); - jPanel1.setMaximumSize(new java.awt.Dimension(450, 400)); - jPanel1.setMinimumSize(new java.awt.Dimension(450, 400)); - jPanel1.setPreferredSize(new java.awt.Dimension(450, 400)); + jPanel1.setMaximumSize(new java.awt.Dimension(450, 460)); + jPanel1.setMinimumSize(new java.awt.Dimension(450, 460)); + jPanel1.setPreferredSize(new java.awt.Dimension(450, 460)); jPanel1.setRequestFocusEnabled(false); org.openide.awt.Mnemonics.setLocalizedText(scopeLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.scopeLabel.text")); // NOI18N @@ -582,12 +555,15 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdTextTwo, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdTextTwo.text_1")); // NOI18N intraCasePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.intraCasePanel.border.title"))); // NOI18N - intraCasePanel.setMinimumSize(new java.awt.Dimension(204, 204)); - intraCasePanel.setPreferredSize(new java.awt.Dimension(430, 204)); + intraCasePanel.setMaximumSize(new java.awt.Dimension(32779, 192)); + intraCasePanel.setMinimumSize(new java.awt.Dimension(204, 192)); + intraCasePanel.setPreferredSize(new java.awt.Dimension(430, 192)); + intraCasePanel.setVerifyInputWhenFocusTarget(false); interCasePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.interCasePanel.border.title"))); // NOI18N - interCasePanel.setMinimumSize(new java.awt.Dimension(430, 249)); - interCasePanel.setPreferredSize(new java.awt.Dimension(430, 249)); + interCasePanel.setMaximumSize(new java.awt.Dimension(32779, 230)); + interCasePanel.setMinimumSize(new java.awt.Dimension(430, 230)); + interCasePanel.setPreferredSize(new java.awt.Dimension(430, 230)); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); @@ -601,15 +577,15 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer .addGap(65, 65, 65) .addComponent(searchButton) .addContainerGap()) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(scopeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(37, 37, 37)) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(percentageThresholdCheck) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(scopeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(37, 37, 37)) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) @@ -622,7 +598,11 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(interCasePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(intraCasePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addGap(0, 0, Short.MAX_VALUE)))) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(21, 21, 21) + .addComponent(dataSourcesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()))) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -636,15 +616,17 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(interCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(interCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(interCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) - .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 197, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(intraCasePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(percentageThresholdCheck) .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(percentageThresholdTextTwo)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 50, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dataSourcesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, Short.MAX_VALUE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(searchButton) .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -717,16 +699,24 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer } /** - * Set the enabled status of the percentage threshold options + * Update the percentage options to reflect the number of data sources + * available. * - * @param enabled true to enable percentage threshold options, false to - * disable them + * @param numberOfDataSources the number of data sources available in the + * central repository */ - private void enablePercentageOptions(boolean enabled) { + @NbBundle.Messages({ + "# {0} - number of datasources", + "CommonAttributePanel.dataSourcesLabel.text=The current Central Repository contains {0} data source(s)."}) + private void updatePercentageOptions(Long numberOfDataSources) { + boolean enabled = numberOfDataSources > 0L; + String numberOfDataSourcesText = enabled ? Bundle.CommonAttributePanel_dataSourcesLabel_text(numberOfDataSources) : ""; + this.dataSourcesLabel.setText(numberOfDataSourcesText); this.percentageThresholdInputBox.setEnabled(enabled); this.percentageThresholdCheck.setEnabled(enabled); this.percentageThresholdCheck.setSelected(enabled); this.percentageThresholdTextTwo.setEnabled(enabled); + } /** @@ -746,6 +736,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel commonItemSearchDescription; + private javax.swing.JLabel dataSourcesLabel; private javax.swing.JLabel errorText; private org.sleuthkit.autopsy.commonfilesearch.InterCasePanel interCasePanel; private javax.swing.JRadioButton interCaseRadio; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form index d38bea0c01..167e9acd48 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form @@ -63,8 +63,8 @@ - - + + @@ -80,7 +80,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 55219f0e51..70c38af896 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -243,8 +243,8 @@ public final class InterCasePanel extends javax.swing.JPanel { layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(specificCentralRepoCaseCheckbox) - .addGap(6, 6, 6) + .addComponent(specificCentralRepoCaseCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(correlationComboBoxLabel) @@ -260,7 +260,7 @@ public final class InterCasePanel extends javax.swing.JPanel { .addComponent(pictureVideoCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(documentsCheckbox) - .addContainerGap()) + .addGap(0, 0, 0)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form index f193a6e73d..be311f3e46 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form @@ -49,7 +49,7 @@ - + @@ -156,6 +156,15 @@ + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index d9711fe71a..4841d39e84 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -190,6 +190,9 @@ public final class IntraCasePanel extends javax.swing.JPanel { }); org.openide.awt.Mnemonics.setLocalizedText(onlySpecificDataSourceCheckbox, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.onlySpecificDataSourceCheckbox.text")); // NOI18N + onlySpecificDataSourceCheckbox.setMaximumSize(new java.awt.Dimension(243, 23)); + onlySpecificDataSourceCheckbox.setMinimumSize(new java.awt.Dimension(243, 23)); + onlySpecificDataSourceCheckbox.setPreferredSize(new java.awt.Dimension(243, 23)); onlySpecificDataSourceCheckbox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { onlySpecificDataSourceCheckboxActionPerformed(evt); @@ -220,13 +223,13 @@ public final class IntraCasePanel extends javax.swing.JPanel { .addComponent(pictureVideoCheckbox)))))) .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) - .addComponent(onlySpecificDataSourceCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE) + .addComponent(onlySpecificDataSourceCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, 384, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(onlySpecificDataSourceCheckbox) + .addComponent(onlySpecificDataSourceCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index 8091e96fbb..12fa6f47ad 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java @@ -1,16 +1,16 @@ /* - * + * * Autopsy Forensic Browser - * + * * Copyright 2018 Basis Technology Corp. * Contact: carrier sleuthkit 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. @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.SQLException; import java.util.Map; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; @@ -42,6 +43,7 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri * @param correlationCaseId * @param filterByMediaMimeType * @param filterByDocMimeType + * * @throws EamDbException */ public SingleInterCaseCommonAttributeSearcher(int correlationCaseId, Map dataSourceIdMap, boolean filterByMediaMimeType, @@ -57,8 +59,10 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri * occur in the case with the given ID. * * @param correlationCaseId id of case where matches must occur (no other - * matches will be shown) + * matches will be shown) + * * @return business object needed to populate tree table with results + * * @throws TskCoreException * @throws NoCurrentCaseException * @throws SQLException @@ -79,9 +83,14 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold, this.corAttrType); } + @NbBundle.Messages({ + "# {0} - case name", + "# {1} - attr type", + "# {2} - threshold string", + "SingleInterCaseCommonAttributeSearcher.buildTabTitle.titleInterSingle=Common Attributes (Central Repository Case: {0}, {1}{2})"}) + @Override - String buildTabTitle() { - final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterSingle(); - return String.format(titleTemplate, new Object[]{this.correlationCaseName, this.corAttrType.getDisplayName()}); + String getTabTitle() { + return Bundle.SingleInterCaseCommonAttributeSearcher_buildTabTitle_titleInterSingle(this.correlationCaseName, this.corAttrType.getDisplayName(), this.getPercentThresholdString()); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java index f28f0d0bf0..70846fa407 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java @@ -1,16 +1,16 @@ /* - * + * * Autopsy Forensic Browser - * + * * Copyright 2018 Basis Technology Corp. * Contact: carrier sleuthkit 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. @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Map; +import org.openide.util.NbBundle; import org.sleuthkit.datamodel.TskData.FileKnown; /** @@ -27,19 +28,21 @@ import org.sleuthkit.datamodel.TskData.FileKnown; */ final public class SingleIntraCaseCommonAttributeSearcher extends IntraCaseCommonAttributeSearcher { - private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL) and data_source_obj_id=%s%s) GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS + private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where md5 in (select md5 from tsk_files where (known != " + FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL) and data_source_obj_id=%s%s) GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS private final Long selectedDataSourceId; private final String dataSourceName; /** * Implements the algorithm for getting common files that appear at least * once in the given data source - * @param dataSourceId data source id for which common files must appear at least once - * @param dataSourceIdMap a map of obj_id to datasource name + * + * @param dataSourceId data source id for which common files must + * appear at least once + * @param dataSourceIdMap a map of obj_id to datasource name * @param filterByMediaMimeType match only on files whose mime types can be - * broadly categorized as media types - * @param filterByDocMimeType match only on files whose mime types can be - * broadly categorized as document types + * broadly categorized as media types + * @param filterByDocMimeType match only on files whose mime types can be + * broadly categorized as document types */ public SingleIntraCaseCommonAttributeSearcher(Long dataSourceId, Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, int percentageThreshold) { super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, percentageThreshold); @@ -53,10 +56,13 @@ final public class SingleIntraCaseCommonAttributeSearcher extends IntraCaseCommo return String.format(SingleIntraCaseCommonAttributeSearcher.WHERE_CLAUSE, args); } + @NbBundle.Messages({ + "# {0} - data source name", + "# {1} - build category", + "# {2} - threshold string", + "SingleIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraSingle=Common Attributes (Data Source: {0}, {1}{2})"}) @Override - public String buildTabTitle() { - final String buildCategorySelectionString = this.buildCategorySelectionString(); - final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleIntraSingle(); - return String.format(titleTemplate, new Object[]{this.dataSourceName, buildCategorySelectionString}); + String getTabTitle() { + return Bundle.SingleIntraCaseCommonAttributeSearcher_buildTabTitle_titleIntraSingle(this.dataSourceName, this.buildCategorySelectionString(), this.getPercentThresholdString()); } -} \ No newline at end of file +} From a320e80c33c0ae785b6c7235614b9d33f1d6e973 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Sep 2018 11:47:11 -0400 Subject: [PATCH 047/273] 4167 rename title of search results to properties --- .../commonfilesearch/AllInterCaseCommonAttributeSearcher.java | 2 +- .../commonfilesearch/AllIntraCaseCommonAttributeSearcher.java | 2 +- .../SingleInterCaseCommonAttributeSearcher.java | 2 +- .../SingleIntraCaseCommonAttributeSearcher.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index 3fbf41af2c..f28d636be0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -57,7 +57,7 @@ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttribut @NbBundle.Messages({ "# {0} - attr type", "# {1} - threshold string", - "AllInterCaseCommonAttributeSearcher.buildTabTitle.titleInterAll=Common Attributes (All Central Repository Cases, {0}{1})"}) + "AllInterCaseCommonAttributeSearcher.buildTabTitle.titleInterAll=Common Properties (All Central Repository Cases, {0}{1})"}) @Override String getTabTitle() { return Bundle.AllInterCaseCommonAttributeSearcher_buildTabTitle_titleInterAll(this.corAttrType.getDisplayName(), this.getPercentThresholdString()); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java index 310799d94c..a02e16cfd8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java @@ -54,7 +54,7 @@ final public class AllIntraCaseCommonAttributeSearcher extends IntraCaseCommonAt @NbBundle.Messages({ "# {0} - build category", "# {1} - threshold string", - "AllIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraAll=Common Attributes (All Data Sources, {0}{1})" + "AllIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraAll=Common Properties (All Data Sources, {0}{1})" }) @Override String getTabTitle() { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index 12fa6f47ad..3d2abda13c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java @@ -87,7 +87,7 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri "# {0} - case name", "# {1} - attr type", "# {2} - threshold string", - "SingleInterCaseCommonAttributeSearcher.buildTabTitle.titleInterSingle=Common Attributes (Central Repository Case: {0}, {1}{2})"}) + "SingleInterCaseCommonAttributeSearcher.buildTabTitle.titleInterSingle=Common Properties (Central Repository Case: {0}, {1}{2})"}) @Override String getTabTitle() { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java index 70846fa407..cfbdf10c59 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java @@ -60,7 +60,7 @@ final public class SingleIntraCaseCommonAttributeSearcher extends IntraCaseCommo "# {0} - data source name", "# {1} - build category", "# {2} - threshold string", - "SingleIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraSingle=Common Attributes (Data Source: {0}, {1}{2})"}) + "SingleIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraSingle=Common Properties (Data Source: {0}, {1}{2})"}) @Override String getTabTitle() { return Bundle.SingleIntraCaseCommonAttributeSearcher_buildTabTitle_titleIntraSingle(this.dataSourceName, this.buildCategorySelectionString(), this.getPercentThresholdString()); From b298407da756c0d95e25b377235c9953367a2c8e Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Sep 2018 16:12:34 -0400 Subject: [PATCH 048/273] 4215 remove highlighting of tagged files and artifacts --- .../corecomponents/DataResultViewerTable.java | 57 +------------------ 1 file changed, 3 insertions(+), 54 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 0752b67075..4b93eba8cc 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -96,7 +96,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { private static final ImageIcon NOTABLE_ICON_SCORE = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false)); @NbBundle.Messages("DataResultViewerTable.firstColLbl=Name") static private final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl(); - static private final Color TAGGED_ROW_COLOR = new Color(255, 255, 195); private final String title; private final Map columnMap; private final Map> propertiesMap; @@ -160,7 +159,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); outline.setRootVisible(false); outline.setDragEnabled(false); - outline.setDefaultRenderer(Object.class, new ColorTagCustomRenderer()); /* * Add a table listener to the child OutlineView (explorer view) to @@ -842,54 +840,11 @@ public class DataResultViewerTable extends AbstractDataResultViewer { } } - /** - * This custom renderer extends the renderer that was already being used by - * the outline table. This renderer colors a row if the tags property of the - * node is not empty. - */ - private class ColorTagCustomRenderer extends DefaultOutlineCellRenderer { - - private static final long serialVersionUID = 1L; - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { - - Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); - // only override the color if a node is not selected - if (rootNode != null && !isSelected) { - Node node = rootNode.getChildren().getNodeAt(table.convertRowIndexToModel(row)); - boolean tagFound = false; - if (node != null) { - Node.PropertySet[] propSets = node.getPropertySets(); - if (propSets.length != 0) { - // currently, a node has only one property set, named Sheet.PROPERTIES ("properties") - Node.Property[] props = propSets[0].getProperties(); - for (Property prop : props) { - if ("Tags".equals(prop.getName())) {//NON-NLS - try { - tagFound = !prop.getValue().equals(""); - } catch (IllegalAccessException | InvocationTargetException ignore) { - //if unable to get the tags property value, treat it like it not having a comment - } - break; - } - } - } - } - //if the node does have associated tags, set its background color - if (tagFound) { - component.setBackground(TAGGED_ROW_COLOR); - } - } - return component; - } - } - /* * A renderer which based on the contents of the cell will display an icon * to indicate the presence of a comment related to the content. */ - private final class HasCommentCellRenderer extends ColorTagCustomRenderer { + private final class HasCommentCellRenderer extends DefaultOutlineCellRenderer { private static final long serialVersionUID = 1L; @@ -899,8 +854,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { "DataResultViewerTable.commentRenderer.noComment.toolTip=No comments found"}) @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - setBackground(component.getBackground()); //inherit highlighting setHorizontalAlignment(CENTER); Object switchValue = null; if ((value instanceof NodeProperty)) { @@ -949,14 +902,12 @@ public class DataResultViewerTable extends AbstractDataResultViewer { * A renderer which based on the contents of the cell will display an icon * to indicate the score associated with the item. */ - private final class ScoreCellRenderer extends ColorTagCustomRenderer { + private final class ScoreCellRenderer extends DefaultOutlineCellRenderer { private static final long serialVersionUID = 1L; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - setBackground(component.getBackground()); //inherit highlighting setHorizontalAlignment(CENTER); Object switchValue = null; if ((value instanceof NodeProperty)) { @@ -998,14 +949,12 @@ public class DataResultViewerTable extends AbstractDataResultViewer { * A renderer which based on the contents of the cell will display an empty * cell if no count was available. */ - private final class CountCellRenderer extends ColorTagCustomRenderer { + private final class CountCellRenderer extends DefaultOutlineCellRenderer { private static final long serialVersionUID = 1L; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - setBackground(component.getBackground()); //inherit highlighting setHorizontalAlignment(LEFT); Object countValue = null; if ((value instanceof NodeProperty)) { From d0bbbdd0f564671999b9c4b76f8e289541780022 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 17 Sep 2018 16:51:45 -0400 Subject: [PATCH 049/273] Add deprecation to comment. --- .../sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index a2c80ef159..34b5344211 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -399,6 +399,7 @@ public abstract class AbstractAbstractFileNode extends A * * @param sheetSet the modifiable Sheet.Set returned by * Sheet.get(Sheet.PROPERTIES) + * @deprecated */ @NbBundle.Messages("AbstractAbstractFileNode.tagsProperty.displayName=Tags") @Deprecated From 439c841e2816d85dfeddf7cacf0e1def63da1330 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 17 Sep 2018 16:52:44 -0400 Subject: [PATCH 050/273] Add deprecated to comment --- .../sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 34b5344211..c833ca0443 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -423,6 +423,7 @@ public abstract class AbstractAbstractFileNode extends A * @param sheetSet the modifiable Sheet.Set returned by * Sheet.get(Sheet.PROPERTIES) * @param tags the list of tags associated with the file + * @deprecated */ @Deprecated protected final void addTagProperty(Sheet.Set sheetSet, List tags) { From e3395af37979c216ec9f9c184f386ecb80ef5a39 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Mon, 17 Sep 2018 17:07:08 -0400 Subject: [PATCH 051/273] Revised UI. --- .../autopsy/corecomponents/Bundle.properties | 3 +- .../corecomponents/ViewPreferencesPanel.form | 76 +++++++++++-------- .../corecomponents/ViewPreferencesPanel.java | 58 ++++++++------ .../ImageGalleryOptionsPanelController.java | 2 +- 4 files changed, 83 insertions(+), 56 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index 6191af9990..7b82cf0ed1 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -172,7 +172,7 @@ ViewPreferencesPanel.displayTimeLabel.text=When displaying times: ViewPreferencesPanel.hideSlackFilesLabel.text=Hide slack files in the: ViewPreferencesPanel.groupByDataSourceCheckbox.text=Group by data source ViewPreferencesPanel.hideKnownFilesLabel.text=Hide known files (i.e. those in the NIST NSRL) in the: -ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=Hide other user's tags +ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=Tags area in the tree ViewPreferencesPanel.currentCaseSettingsPanel.border.title=Current Case Settings OptionsCategory_Name_View=View OptionsCategory_Keywords_View=View @@ -188,3 +188,4 @@ ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text=Data Sources area (the di ViewPreferencesPanel.viewsHideSlackCheckbox.text=Views area ViewPreferencesPanel.currentSessionSettingsPanel.border.title=Current Session Settings ViewPreferencesPanel.hideRejectedResultsCheckbox.text=Hide rejected results +ViewPreferencesPanel.hideOtherUsersTagsLabel.text=Hide other user's tags in the: diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form index 0665023009..e0706af676 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form @@ -54,7 +54,7 @@ - + @@ -82,50 +82,58 @@ - - - - - - - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + - + - + @@ -155,8 +163,9 @@ + + - @@ -286,6 +295,13 @@ + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index 2864d62474..d50ca7a6c1 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -127,6 +127,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { useLocalTimeRadioButton = new javax.swing.JRadioButton(); useGMTTimeRadioButton = new javax.swing.JRadioButton(); hideOtherUsersTagsCheckbox = new javax.swing.JCheckBox(); + hideOtherUsersTagsLabel = new javax.swing.JLabel(); currentCaseSettingsPanel = new javax.swing.JPanel(); groupByDataSourceCheckbox = new javax.swing.JCheckBox(); currentSessionSettingsPanel = new javax.swing.JPanel(); @@ -209,6 +210,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { } }); + org.openide.awt.Mnemonics.setLocalizedText(hideOtherUsersTagsLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideOtherUsersTagsLabel.text")); // NOI18N + javax.swing.GroupLayout globalSettingsPanelLayout = new javax.swing.GroupLayout(globalSettingsPanel); globalSettingsPanel.setLayout(globalSettingsPanelLayout); globalSettingsPanelLayout.setHorizontalGroup( @@ -216,38 +219,43 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(displayTimeLabel) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGap(10, 10, 10) + .addComponent(hideOtherUsersTagsCheckbox)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(keepCurrentViewerRadioButton) - .addComponent(useBestViewerRadioButton) - .addComponent(useGMTTimeRadioButton) - .addComponent(useLocalTimeRadioButton))) - .addComponent(selectFileLabel)) - .addGap(18, 18, 18) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(hideOtherUsersTagsCheckbox) - .addComponent(hideKnownFilesLabel) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(hideKnownFilesLabel) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideSlackCheckbox) + .addComponent(viewsHideSlackCheckbox))) + .addComponent(hideSlackFilesLabel)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideKnownCheckbox) + .addComponent(viewsHideKnownCheckbox))))) + .addGap(18, 18, 18) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(displayTimeLabel) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGap(10, 10, 10) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideSlackCheckbox) - .addComponent(viewsHideSlackCheckbox))) - .addComponent(hideSlackFilesLabel)) - .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideKnownCheckbox) - .addComponent(viewsHideKnownCheckbox))))) - .addContainerGap(29, Short.MAX_VALUE)) + .addComponent(keepCurrentViewerRadioButton) + .addComponent(useBestViewerRadioButton) + .addComponent(useGMTTimeRadioButton) + .addComponent(useLocalTimeRadioButton))) + .addComponent(selectFileLabel))) + .addComponent(hideOtherUsersTagsLabel)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); globalSettingsPanelLayout.setVerticalGroup( globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addContainerGap() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addComponent(hideKnownFilesLabel) @@ -274,8 +282,9 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(useGMTTimeRadioButton))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(hideOtherUsersTagsCheckbox) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(hideOtherUsersTagsLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(hideOtherUsersTagsCheckbox)) ); currentCaseSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentCaseSettingsPanel.border.title"))); // NOI18N @@ -343,7 +352,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { viewPreferencesPanelLayout.setVerticalGroup( viewPreferencesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(viewPreferencesPanelLayout.createSequentialGroup() - .addComponent(globalSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 197, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(globalSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -472,6 +481,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { private javax.swing.JCheckBox groupByDataSourceCheckbox; private javax.swing.JLabel hideKnownFilesLabel; private javax.swing.JCheckBox hideOtherUsersTagsCheckbox; + private javax.swing.JLabel hideOtherUsersTagsLabel; private javax.swing.JCheckBox hideRejectedResultsCheckbox; private javax.swing.JLabel hideSlackFilesLabel; private javax.swing.JRadioButton keepCurrentViewerRadioButton; diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java index af91181287..11a557a7d4 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java @@ -34,7 +34,7 @@ import org.openide.util.Lookup; iconBase = "org/sleuthkit/autopsy/imagegallery/images/btn_icon_image_gallery_32.png", keywords = "#OptionsCategory_Keywords_Options", keywordsCategory = "Options", - position = 15 + position = 16 ) @org.openide.util.NbBundle.Messages({"OptionsCategory_Name_Options=Image / Video Gallery", "OptionsCategory_Keywords_Options=image video gallery category "}) public final class ImageGalleryOptionsPanelController extends OptionsPanelController { From 36d2b382f555970ab2a161bb3154046fdd1b57c7 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 18 Sep 2018 12:15:18 +0200 Subject: [PATCH 052/273] make center pane have smaller minimum width (by allowing lower 'toolbar' to shrink), allowing to side panes to have more room. --- .../gui/drawableviews/GroupPane.fxml | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/GroupPane.fxml b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/GroupPane.fxml index 0e788327c4..79134d0e4d 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/GroupPane.fxml +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/GroupPane.fxml @@ -15,6 +15,7 @@ + @@ -27,11 +28,18 @@ - - + + + + + + + + + - - - - - - - - - - - - - - + + + -