Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 6434-non-public-artifactviewers

This commit is contained in:
Raman Arora 2020-06-25 11:43:30 -04:00
commit a8ed98d037
31 changed files with 1344 additions and 733 deletions

View File

@ -53,7 +53,7 @@ public interface CentralRepository {
case SQLITE: case SQLITE:
return SqliteCentralRepo.getInstance(); return SqliteCentralRepo.getInstance();
default: default:
throw new CentralRepoException("Failed to get CentralRepository instance, Central Repositiory is not enabled."); return null;
} }
} }

View File

@ -127,12 +127,16 @@ public class PersonaAccount {
* @param confidence Confidence level. * @param confidence Confidence level.
* *
* @return PersonaAccount * @return PersonaAccount
*
* @throws CentralRepoException If there is an error in creating the * @throws CentralRepoException If there is an error in creating the
* account. * account.
*/ */
static PersonaAccount addPersonaAccount(Persona persona, CentralRepoAccount account, String justification, Persona.Confidence confidence) throws CentralRepoException { static PersonaAccount addPersonaAccount(Persona persona, CentralRepoAccount account, String justification, Persona.Confidence confidence) throws CentralRepoException {
CentralRepository cr = CentralRepository.getInstance(); CentralRepository cr = CentralRepository.getInstance();
if(cr == null) {
throw new CentralRepoException("Failed to add Persona, Central Repository is not enable");
}
CentralRepoExaminer currentExaminer = cr.getOrInsertExaminer(System.getProperty("user.name")); CentralRepoExaminer currentExaminer = cr.getOrInsertExaminer(System.getProperty("user.name"));
Instant instant = Instant.now(); Instant instant = Instant.now();
@ -147,7 +151,7 @@ public class PersonaAccount {
+ currentExaminer.getId() + currentExaminer.getId()
+ ")"; + ")";
cr.executeInsertSQL(insertClause); CentralRepository.getInstance().executeInsertSQL(insertClause);
String queryClause = PERSONA_ACCOUNTS_QUERY_CLAUSE String queryClause = PERSONA_ACCOUNTS_QUERY_CLAUSE
+ "WHERE persona_id = " + persona.getId() + "WHERE persona_id = " + persona.getId()
@ -245,15 +249,21 @@ public class PersonaAccount {
* persona_account. * persona_account.
*/ */
static Collection<PersonaAccount> getPersonaAccountsForPersona(long personaId) throws CentralRepoException { static Collection<PersonaAccount> getPersonaAccountsForPersona(long personaId) throws CentralRepoException {
CentralRepository cr = CentralRepository.getInstance();
if (cr != null) {
String queryClause = PERSONA_ACCOUNTS_QUERY_CLAUSE String queryClause = PERSONA_ACCOUNTS_QUERY_CLAUSE
+ " WHERE persona_accounts.persona_id = " + personaId; + " WHERE persona_accounts.persona_id = " + personaId;
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback(); PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback); cr.executeSelectSQL(queryClause, queryCallback);
return queryCallback.getPersonaAccountsList(); return queryCallback.getPersonaAccountsList();
} }
return new ArrayList<>();
}
/** /**
* Gets all the Persona for the specified Account. * Gets all the Persona for the specified Account.
* *
@ -269,12 +279,18 @@ public class PersonaAccount {
+ " WHERE persona_accounts.account_id = " + accountId + " WHERE persona_accounts.account_id = " + accountId
+ " AND personas.status_id != " + Persona.PersonaStatus.DELETED.getStatusId(); + " AND personas.status_id != " + Persona.PersonaStatus.DELETED.getStatusId();
CentralRepository cr = CentralRepository.getInstance();
if (cr != null) {
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback(); PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback); cr.executeSelectSQL(queryClause, queryCallback);
return queryCallback.getPersonaAccountsList(); return queryCallback.getPersonaAccountsList();
} }
return new ArrayList<>();
}
/** /**
* Gets all the Persona associated with all the accounts matching the given * Gets all the Persona associated with all the accounts matching the given
* account identifier substring. * account identifier substring.
@ -292,12 +308,17 @@ public class PersonaAccount {
+ " WHERE LOWER(accounts.account_unique_identifier) LIKE LOWER('%" + accountIdentifierSubstring + "%')" + " WHERE LOWER(accounts.account_unique_identifier) LIKE LOWER('%" + accountIdentifierSubstring + "%')"
+ " AND personas.status_id != " + Persona.PersonaStatus.DELETED.getStatusId(); + " AND personas.status_id != " + Persona.PersonaStatus.DELETED.getStatusId();
CentralRepository cr = CentralRepository.getInstance();
if (cr != null) {
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback(); PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback); cr.executeSelectSQL(queryClause, queryCallback);
return queryCallback.getPersonaAccountsList(); return queryCallback.getPersonaAccountsList();
} }
return new ArrayList<>();
}
/** /**
* Gets all the Persona associated with the given account. * Gets all the Persona associated with the given account.
* *
@ -314,10 +335,14 @@ public class PersonaAccount {
+ " AND type_name = '" + account.getAccountType().getTypeName() + "' " + " AND type_name = '" + account.getAccountType().getTypeName() + "' "
+ " AND personas.status_id != " + Persona.PersonaStatus.DELETED.getStatusId(); + " AND personas.status_id != " + Persona.PersonaStatus.DELETED.getStatusId();
CentralRepository cr = CentralRepository.getInstance();
if (cr != null) {
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback(); PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback); cr.executeSelectSQL(queryClause, queryCallback);
return queryCallback.getPersonaAccountsList(); return queryCallback.getPersonaAccountsList();
}
return new ArrayList<>();
} }
/** /**
@ -329,8 +354,14 @@ public class PersonaAccount {
* account. * account.
*/ */
static void removePersonaAccount(long id) throws CentralRepoException { static void removePersonaAccount(long id) throws CentralRepoException {
CentralRepository cr = CentralRepository.getInstance();
if(cr == null) {
throw new CentralRepoException("Failed to remove persona account, Central Repo is not enabled");
}
String deleteClause = " DELETE FROM persona_accounts WHERE id = " + id; String deleteClause = " DELETE FROM persona_accounts WHERE id = " + id;
CentralRepository.getInstance().executeDeleteSQL(deleteClause); cr.executeDeleteSQL(deleteClause);
} }
/** /**
@ -342,8 +373,14 @@ public class PersonaAccount {
* account. * account.
*/ */
static void modifyPersonaAccount(long id, Persona.Confidence confidence, String justification) throws CentralRepoException { static void modifyPersonaAccount(long id, Persona.Confidence confidence, String justification) throws CentralRepoException {
CentralRepository cr = CentralRepository.getInstance();
if (cr == null) {
throw new CentralRepoException("Failed to modify persona account, Central Repo is not enabled");
}
String updateClause = "UPDATE persona_accounts SET confidence_id = " + confidence.getLevelId() + ", justification = \"" + justification + "\" WHERE id = " + id; String updateClause = "UPDATE persona_accounts SET confidence_id = " + confidence.getLevelId() + ", justification = \"" + justification + "\" WHERE id = " + id;
CentralRepository.getInstance().executeUpdateSQL(updateClause); cr.executeUpdateSQL(updateClause);
} }
/** /**
@ -382,12 +419,13 @@ public class PersonaAccount {
* *
* @return Collection of all accounts associated with the given persona, may * @return Collection of all accounts associated with the given persona, may
* be empty. * be empty.
*
* @throws CentralRepoException If there is an error in getting the * @throws CentralRepoException If there is an error in getting the
* accounts. * accounts.
*/ */
static Collection<CentralRepoAccount> getAccountsForPersona(long personaId) throws CentralRepoException { static Collection<CentralRepoAccount> getAccountsForPersona(long personaId) throws CentralRepoException {
CentralRepository cr = CentralRepository.getInstance();
if (cr != null) {
String queryClause = "SELECT account_id, " String queryClause = "SELECT account_id, "
+ " accounts.account_type_id as account_type_id, accounts.account_unique_identifier as account_unique_identifier," + " accounts.account_type_id as account_type_id, accounts.account_unique_identifier as account_unique_identifier,"
+ " account_types.type_name as type_name " + " account_types.type_name as type_name "
@ -397,9 +435,11 @@ public class PersonaAccount {
+ " WHERE persona_accounts.persona_id = " + personaId; + " WHERE persona_accounts.persona_id = " + personaId;
AccountsForPersonaQueryCallback queryCallback = new AccountsForPersonaQueryCallback(); AccountsForPersonaQueryCallback queryCallback = new AccountsForPersonaQueryCallback();
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback); cr.executeSelectSQL(queryClause, queryCallback);
return queryCallback.getAccountsList(); return queryCallback.getAccountsList();
}
return new ArrayList<>();
} }
} }

View File

@ -63,7 +63,6 @@ import org.sleuthkit.datamodel.TskCoreException;
public class ExtractedContent implements AutopsyVisitableItem { public class ExtractedContent implements AutopsyVisitableItem {
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED); private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED);
private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED);
public static final String NAME = NbBundle.getMessage(RootNode.class, "ExtractedContentNode.name.text"); public static final String NAME = NbBundle.getMessage(RootNode.class, "ExtractedContentNode.name.text");
private final long filteringDSObjId; // 0 if not filtering/grouping by data source private final long filteringDSObjId; // 0 if not filtering/grouping by data source
private SleuthkitCase skCase; // set to null after case has been closed private SleuthkitCase skCase; // set to null after case has been closed
@ -145,12 +144,19 @@ public class ExtractedContent implements AutopsyVisitableItem {
* This area has all of the blackboard artifacts that are not displayed in a * This area has all of the blackboard artifacts that are not displayed in a
* more specific form elsewhere in the tree. * more specific form elsewhere in the tree.
*/ */
private class TypeFactory extends ChildFactory.Detachable<BlackboardArtifact.Type> { private class TypeFactory extends ChildFactory.Detachable<BlackboardArtifact.Type> implements RefreshThrottler.Refresher {
private final ArrayList<BlackboardArtifact.Type> doNotShow = new ArrayList<>(); private final ArrayList<BlackboardArtifact.Type> doNotShow = new ArrayList<>();
// maps the artifact type to its child node // maps the artifact type to its child node
private final HashMap<BlackboardArtifact.Type, TypeNode> typeNodeList = new HashMap<>(); private final HashMap<BlackboardArtifact.Type, TypeNode> typeNodeList = new HashMap<>();
/**
* RefreshThrottler is used to limit the number of refreshes performed
* when CONTENT_CHANGED and DATA_ADDED ingest module events are
* received.
*/
private final RefreshThrottler refreshThrottler = new RefreshThrottler(this);
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
TypeFactory() { TypeFactory() {
super(); super();
@ -173,27 +179,11 @@ public class ExtractedContent implements AutopsyVisitableItem {
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
String eventType = evt.getPropertyName(); String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) { if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
/** // case was closed. Remove listeners so that we don't get called with a stale case handle
* This is a stop gap measure until a different way of handling if (evt.getNewValue() == null) {
* the closing of cases is worked out. Currently, remote events removeNotify();
* may be received for a case that is already closed. skCase = null;
*/
try {
Case.getCurrentCaseThrows();
/**
* Due to some unresolved issues with how cases are closed,
* it is possible for the event to have a null oldValue if
* the event is a remote event.
*/
final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
if (null != event && !(this.doNotShow.contains(event.getBlackboardArtifactType()))) {
refresh(true);
}
} catch (NoCurrentCaseException notUsed) {
/**
* Case is closed, do nothing.
*/
} }
} else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
|| eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) { || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
@ -204,32 +194,26 @@ public class ExtractedContent implements AutopsyVisitableItem {
*/ */
try { try {
Case.getCurrentCaseThrows(); Case.getCurrentCaseThrows();
refresh(true); refresh(false);
} catch (NoCurrentCaseException notUsed) { } catch (NoCurrentCaseException notUsed) {
/** /**
* Case is closed, do nothing. * Case is closed, do nothing.
*/ */
} }
} else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
// case was closed. Remove listeners so that we don't get called with a stale case handle
if (evt.getNewValue() == null) {
removeNotify();
skCase = null;
}
} }
}; };
@Override @Override
protected void addNotify() { protected void addNotify() {
refreshThrottler.registerForIngestModuleEvents();
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
} }
@Override @Override
protected void removeNotify() { protected void removeNotify() {
refreshThrottler.unregisterEventListener();
IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(pcl);
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
typeNodeList.clear(); typeNodeList.clear();
} }
@ -273,6 +257,40 @@ public class ExtractedContent implements AutopsyVisitableItem {
typeNodeList.put(key, node); typeNodeList.put(key, node);
return node; return node;
} }
@Override
public void refresh() {
refresh(false);
}
@Override
public boolean isRefreshRequired(PropertyChangeEvent evt) {
String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
/**
* This is a stop gap measure until a different way of handling
* the closing of cases is worked out. Currently, remote events
* may be received for a case that is already closed.
*/
try {
Case.getCurrentCaseThrows();
/**
* Due to some unresolved issues with how cases are closed,
* it is possible for the event to have a null oldValue if
* the event is a remote event.
*/
final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
if (null != event && !(this.doNotShow.contains(event.getBlackboardArtifactType()))) {
return true;
}
} catch (NoCurrentCaseException notUsed) {
/**
* Case is closed, do nothing.
*/
}
}
return false;
}
} }
/** /**
@ -355,73 +373,53 @@ public class ExtractedContent implements AutopsyVisitableItem {
/** /**
* Creates children for a given artifact type * Creates children for a given artifact type
*/ */
private class ArtifactFactory extends BaseChildFactory<BlackboardArtifact> { private class ArtifactFactory extends BaseChildFactory<BlackboardArtifact> implements RefreshThrottler.Refresher {
private BlackboardArtifact.Type type; private final BlackboardArtifact.Type type;
/**
* RefreshThrottler is used to limit the number of refreshes performed
* when CONTENT_CHANGED and DATA_ADDED ingest module events are
* received.
*/
private final RefreshThrottler refreshThrottler = new RefreshThrottler(this);
ArtifactFactory(BlackboardArtifact.Type type) { ArtifactFactory(BlackboardArtifact.Type type) {
super(type.getTypeName()); super(type.getTypeName());
this.type = type; this.type = type;
} }
private final PropertyChangeListener pcl = new PropertyChangeListener() { private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String eventType = evt.getPropertyName(); String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) { if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
/**
* Checking for a current case is a stop gap measure until a
* different way of handling the closing of cases is worked
* out. Currently, remote events may be received for a case
* that is already closed.
*/
try {
Case.getCurrentCaseThrows();
/**
* Even with the check above, it is still possible that
* the case will be closed in a different thread before
* this code executes. If that happens, it is possible
* for the event to have a null oldValue.
*/
final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
if (null != event && event.getBlackboardArtifactType().equals(type)) {
refresh(true);
}
} catch (NoCurrentCaseException notUsed) {
/**
* Case is closed, do nothing.
*/
}
} else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
|| eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) { || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
/** /**
* Checking for a current case is a stop gap measure until a * Checking for a current case is a stop gap measure until a
* different way of handling the closing of cases is worked * different way of handling the closing of cases is worked out.
* out. Currently, remote events may be received for a case * Currently, remote events may be received for a case that is
* that is already closed. * already closed.
*/ */
try { try {
Case.getCurrentCaseThrows(); Case.getCurrentCaseThrows();
refresh(true); refresh(false);
} catch (NoCurrentCaseException notUsed) { } catch (NoCurrentCaseException notUsed) {
/** /**
* Case is closed, do nothing. * Case is closed, do nothing.
*/ */
} }
} }
}
}; };
@Override @Override
protected void onAdd() { protected void onAdd() {
refreshThrottler.registerForIngestModuleEvents();
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl);
} }
@Override @Override
protected void onRemove() { protected void onRemove() {
refreshThrottler.unregisterEventListener();
IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(pcl);
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
} }
@Override @Override
@ -451,5 +449,43 @@ public class ExtractedContent implements AutopsyVisitableItem {
} }
return Collections.emptyList(); return Collections.emptyList();
} }
@Override
public void refresh() {
refresh(false);
}
@Override
public boolean isRefreshRequired(PropertyChangeEvent evt) {
String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
/**
* Checking for a current case is a stop gap measure until a
* different way of handling the closing of cases is worked out.
* Currently, remote events may be received for a case that is
* already closed.
*/
try {
Case.getCurrentCaseThrows();
/**
* Even with the check above, it is still possible that the
* case will be closed in a different thread before this
* code executes. If that happens, it is possible for the
* event to have a null oldValue.
*/
final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
if (null != event && event.getBlackboardArtifactType().equals(type)) {
return true;
}
} catch (NoCurrentCaseException notUsed) {
/**
* Case is closed, do nothing.
*/
}
}
return false;
}
} }
} }

View File

@ -82,39 +82,26 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
* Listens for case and ingest invest. Updates observers when events are * Listens for case and ingest invest. Updates observers when events are
* fired. FileType and FileTypes nodes are all listening to this. * fired. FileType and FileTypes nodes are all listening to this.
*/ */
private class FileTypesByExtObservable extends Observable { private class FileTypesByExtObservable extends Observable implements RefreshThrottler.Refresher {
private final PropertyChangeListener pcl; private final PropertyChangeListener pcl;
private final Set<Case.Events> CASE_EVENTS_OF_INTEREST; private final Set<Case.Events> CASE_EVENTS_OF_INTEREST;
/**
* RefreshThrottler is used to limit the number of refreshes performed
* when CONTENT_CHANGED and DATA_ADDED ingest module events are
* received.
*/
private final RefreshThrottler refreshThrottler = new RefreshThrottler(this);
private FileTypesByExtObservable() { private FileTypesByExtObservable() {
super(); super();
this.CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.CURRENT_CASE); this.CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.CURRENT_CASE);
this.pcl = (PropertyChangeEvent evt) -> { this.pcl = (PropertyChangeEvent evt) -> {
String eventType = evt.getPropertyName(); String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString()) if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
|| eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
|| eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString()) || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())
|| eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) { || eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
/**
* If a new file has been added but does not have an extension
* there is nothing to do.
*/
if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
if ((evt.getOldValue() instanceof ModuleContentEvent) == false) {
return;
}
ModuleContentEvent moduleContentEvent = (ModuleContentEvent) evt.getOldValue();
if ((moduleContentEvent.getSource() instanceof AbstractFile) == false) {
return;
}
AbstractFile abstractFile = (AbstractFile) moduleContentEvent.getSource();
if (abstractFile.getNameExtension().isEmpty()) {
return;
}
}
/** /**
* Checking for a current case is a stop gap measure until a * Checking for a current case is a stop gap measure until a
* different way of handling the closing of cases is worked * different way of handling the closing of cases is worked
@ -139,14 +126,14 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
}; };
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); refreshThrottler.registerForIngestModuleEvents();
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
} }
private void removeListeners() { private void removeListeners() {
deleteObservers(); deleteObservers();
IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(pcl);
IngestManager.getInstance().removeIngestModuleEventListener(pcl); refreshThrottler.unregisterEventListener();
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
} }
@ -154,7 +141,52 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
setChanged(); setChanged();
notifyObservers(); notifyObservers();
} }
@Override
public void refresh() {
typesRoot.updateShowCounts();
update();
} }
@Override
public boolean isRefreshRequired(PropertyChangeEvent evt) {
String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
/**
* Checking for a current case is a stop gap measure until a
* different way of handling the closing of cases is worked out.
* Currently, remote events may be received for a case that is
* already closed.
*/
try {
Case.getCurrentCaseThrows();
/**
* If a new file has been added but does not have an
* extension there is nothing to do.
*/
if ((evt.getOldValue() instanceof ModuleContentEvent) == false) {
return false;
}
ModuleContentEvent moduleContentEvent = (ModuleContentEvent) evt.getOldValue();
if ((moduleContentEvent.getSource() instanceof AbstractFile) == false) {
return false;
}
AbstractFile abstractFile = (AbstractFile) moduleContentEvent.getSource();
if (!abstractFile.getNameExtension().isEmpty()) {
return true;
}
} catch (NoCurrentCaseException ex) {
/**
* Case is closed, no refresh needed.
*/
return false;
}
}
return false;
}
}
private static final String FNAME = NbBundle.getMessage(FileTypesByExtNode.class, "FileTypesByExtNode.fname.text"); private static final String FNAME = NbBundle.getMessage(FileTypesByExtNode.class, "FileTypesByExtNode.fname.text");
/** /**

View File

@ -0,0 +1,125 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.datamodel;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
* Utility class that can be used by UI nodes to reduce the number of
* potentially expensive UI refresh events when DATA_ADDED and CONTENT_CHANGED
* ingest manager events are received.
*/
class RefreshThrottler {
/**
* The Refresher interface needs to be implemented by ChildFactory instances
* that wish to take advantage of throttled refresh functionality.
*/
interface Refresher {
/**
* The RefreshThrottler calls this method when the RefreshTask runs.
*
*/
void refresh();
/**
* Determine whether the given event should result in a refresh.
*
* @param evt
*
* @return true if event should trigger a refresh, otherwise false.
*/
boolean isRefreshRequired(PropertyChangeEvent evt);
}
static ScheduledThreadPoolExecutor refreshExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder().setNameFormat("Node Refresh Thread").build());
// Keep a thread safe reference to the current refresh task (if any)
private final AtomicReference<RefreshTask> refreshTaskRef;
// The factory instance that will be called when a refresh is due.
private final Refresher refresher;
private static final long MIN_SECONDS_BETWEEN_REFRESH = 5;
private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED, IngestManager.IngestModuleEvent.CONTENT_CHANGED);
/**
* A RefreshTask is scheduled to run when an event arrives and there isn't
* one already scheduled.
*/
private final class RefreshTask implements Runnable {
@Override
public void run() {
// Call refresh on the factory
refresher.refresh();
// Clear the refresh task reference
refreshTaskRef.set(null);
}
}
/**
* PropertyChangeListener that reacts to DATA_ADDED and CONTENT_CHANGED
* events and schedules a refresh task if one is not already scheduled.
*/
private final PropertyChangeListener pcl;
RefreshThrottler(Refresher r) {
this.refreshTaskRef = new AtomicReference<>(null);
refresher = r;
pcl = (PropertyChangeEvent evt) -> {
String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())
|| eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
if (!refresher.isRefreshRequired(evt)) {
return;
}
RefreshTask task = new RefreshTask();
if (refreshTaskRef.compareAndSet(null, task)) {
refreshExecutor.schedule(task, MIN_SECONDS_BETWEEN_REFRESH, TimeUnit.SECONDS);
}
}
};
}
/**
* Set up listener for ingest module events of interest.
*/
void registerForIngestModuleEvents() {
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl);
}
/**
* Remove ingest module event listener.
*/
void unregisterEventListener() {
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
}
}

View File

@ -101,7 +101,7 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li
constraints.weightx = LABEL_WEIGHT; constraints.weightx = LABEL_WEIGHT;
constraints.weighty = LABEL_WEIGHT; constraints.weighty = LABEL_WEIGHT;
constraints.gridwidth = LABEL_WIDTH; constraints.gridwidth = LABEL_WIDTH;
addToGridBagLayout(filterPanel.getCheckbox(), null, column); addToGridBagLayout(filterPanel.getCheckbox(), filterPanel.getAdditionalLabel(), column);
if (filterPanel.hasPanel()) { if (filterPanel.hasPanel()) {
constraints.gridx += constraints.gridwidth; constraints.gridx += constraints.gridwidth;
constraints.fill = GridBagConstraints.BOTH; constraints.fill = GridBagConstraints.BOTH;

View File

@ -101,3 +101,6 @@ DocumentFilterPanel.documentsFiltersSplitPane.border.title=Step 2: Filter which
ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show
VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show
DiscoveryDialog.step1Label.text=Step 1: Choose result type DiscoveryDialog.step1Label.text=Step 1: Choose result type
ResultsSplitPaneDivider.hideButton.text=
ResultsSplitPaneDivider.showButton.text=
ResultsSplitPaneDivider.detailsLabel.text=Details Area

View File

@ -11,7 +11,7 @@ DiscoveryTopComponent.name=\ Discovery
DiscoveryTopComponent.newSearch.text=New Search DiscoveryTopComponent.newSearch.text=New Search
DiscoveryTopComponent.searchCancelled.text=Search has been cancelled. DiscoveryTopComponent.searchCancelled.text=Search has been cancelled.
# {0} - search # {0} - search
DiscoveryTopComponent.searchComplete.text=Results for {0} DiscoveryTopComponent.searchComplete.text=Results with {0}
# {0} - searchType # {0} - searchType
DiscoveryTopComponent.searchInProgress.text=Performing search for results of type {0}. Please wait. DiscoveryTopComponent.searchInProgress.text=Performing search for results of type {0}. Please wait.
DiscoveryUiUtility.bytes.text=bytes DiscoveryUiUtility.bytes.text=bytes
@ -57,18 +57,24 @@ FileSearch.InterestingItemGroupKey.noSets=None
FileSearch.KeywordListGroupKey.noKeywords=None FileSearch.KeywordListGroupKey.noKeywords=None
FileSearch.NoGroupingGroupKey.allFiles=All Files FileSearch.NoGroupingGroupKey.allFiles=All Files
FileSearch.ObjectDetectedGroupKey.noSets=None FileSearch.ObjectDetectedGroupKey.noSets=None
FileSearchData.FileSize.LARGE_IMAGE.displayName=Large: 1-50MB FileSearchData.FileSize.100kbto1mb=: 100KB-1MB
FileSearchData.FileSize.LARGE_VIDEO.displayName=Large: 1-5GB FileSearchData.FileSize.100mbto1gb=: 100MB-1GB
FileSearchData.FileSize.MEDIUM_IMAGE.displayName=Medium: 100KB-1MB FileSearchData.FileSize.10PlusGb=: 10GB+
FileSearchData.FileSize.MEDIUM_VIDEO.displayName=Medium: 100MB-1GB FileSearchData.FileSize.16kbto100kb=: 16-100KB
FileSearchData.FileSize.SMALL_IMAGE.displayName=Small: 16-100KB FileSearchData.FileSize.1gbto5gb=: 1-5GB
FileSearchData.FileSize.SMALL_VIDEO.displayName=Small: 500KB-100MB FileSearchData.FileSize.1mbto50mb=: 1-50MB
FileSearchData.FileSize.XLARGE_IMAGE.displayName=XLarge: 50-200MB FileSearchData.FileSize.200PlusMb=: 200MB+
FileSearchData.FileSize.XLARGE_VIDEO.displayName=XLarge: 5-10GB FileSearchData.FileSize.500kbto100mb=: 500KB-100MB
FileSearchData.FileSize.XSMALL_IMAGE.displayName=XSmall: 0-16KB FileSearchData.FileSize.50mbto200mb=: 50-200MB
FileSearchData.FileSize.XSMALL_VIDEO.displayName=XSmall: 0-500KB FileSearchData.FileSize.5gbto10gb=: 5-10GB
FileSearchData.FileSize.XXLARGE_IMAGE.displayName=XXLarge: 200MB+ FileSearchData.FileSize.LARGE.displayName=Large
FileSearchData.FileSize.XXLARGE_VIDEO.displayName=XXLarge: 10GB+ FileSearchData.FileSize.MEDIUM.displayName=Medium
FileSearchData.FileSize.SMALL.displayName=Small
FileSearchData.FileSize.upTo16kb=: 0-16KB
FileSearchData.FileSize.upTo500kb=: 0-500KB
FileSearchData.FileSize.XLARGE.displayName=XLarge
FileSearchData.FileSize.XSMALL.displayName=XSmall
FileSearchData.FileSize.XXLARGE.displayName=XXLarge
FileSearchData.FileType.Audio.displayName=Audio FileSearchData.FileType.Audio.displayName=Audio
FileSearchData.FileType.Documents.displayName=Documents FileSearchData.FileType.Documents.displayName=Documents
FileSearchData.FileType.Executables.displayName=Executables FileSearchData.FileType.Executables.displayName=Executables
@ -106,45 +112,44 @@ FileSearchFiltering.concatenateSetNamesForDisplay.comma=,
# {1} - Data source ID # {1} - Data source ID
FileSearchFiltering.DataSourceFilter.datasource={0}({1}) FileSearchFiltering.DataSourceFilter.datasource={0}({1})
# {0} - filters # {0} - filters
FileSearchFiltering.DataSourceFilter.desc=Files in data source(s): {0} FileSearchFiltering.DataSourceFilter.desc=Data source(s): {0}
FileSearchFiltering.DataSourceFilter.or=\ or FileSearchFiltering.DataSourceFilter.or=,
# {0} - filters # {0} - filters
FileSearchFiltering.FileTypeFilter.desc=Files with type: {0} FileSearchFiltering.FileTypeFilter.desc=Type: {0}
FileSearchFiltering.FileTypeFilter.or=\ or FileSearchFiltering.FileTypeFilter.or=,
# {0} - filters # {0} - filters
FileSearchFiltering.FrequencyFilter.desc=Files with frequency: {0} FileSearchFiltering.FrequencyFilter.desc=Past occurrences: {0}
FileSearchFiltering.FrequencyFilter.or=\ or FileSearchFiltering.FrequencyFilter.or=,
# {0} - filters # {0} - filters
FileSearchFiltering.HashSetFilter.desc=Files with hash set hits in set(s): {0} FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}
# {0} - filters # {0} - filters
FileSearchFiltering.InterestingItemSetFilter.desc=Files with interesting item hits in set(s): {0} FileSearchFiltering.InterestingItemSetFilter.desc=Interesting item hits in set(s): {0}
# {0} - filters # {0} - filters
FileSearchFiltering.KeywordListFilter.desc=Files with keywords in list(s): {0} FileSearchFiltering.KeywordListFilter.desc=Keywords in list(s): {0}
FileSearchFiltering.KnownFilter.desc=Files which are not known FileSearchFiltering.KnownFilter.desc=which are not known
# {0} - filters # {0} - filters
FileSearchFiltering.ObjectDetectionFilter.desc=Files with objects detected in set(s): {0} FileSearchFiltering.ObjectDetectionFilter.desc=Objects detected in set(s): {0}
# {0} - filters # {0} - filters
FileSearchFiltering.ParentFilter.desc=Files with paths matching: {0} FileSearchFiltering.ParentFilter.desc=Paths matching: {0}
FileSearchFiltering.ParentFilter.exact=(exact match) FileSearchFiltering.ParentFilter.exact=(exact match)
FileSearchFiltering.ParentFilter.or=\ or FileSearchFiltering.ParentFilter.excluded=(excluded)
FileSearchFiltering.ParentFilter.included=(included)
FileSearchFiltering.ParentFilter.or=,
FileSearchFiltering.ParentFilter.substring=(substring) FileSearchFiltering.ParentFilter.substring=(substring)
FileSearchFiltering.ParentSearchTerm.excludeString=\ (exclude) FileSearchFiltering.ParentSearchTerm.excludeString=\ (exclude)
FileSearchFiltering.ParentSearchTerm.fullString=\ (exact) FileSearchFiltering.ParentSearchTerm.fullString=\ (exact)
FileSearchFiltering.ParentSearchTerm.includeString=\ (include) FileSearchFiltering.ParentSearchTerm.includeString=\ (include)
FileSearchFiltering.ParentSearchTerm.subString=\ (substring) FileSearchFiltering.ParentSearchTerm.subString=\ (substring)
FileSearchFiltering.PreviouslyNotableFilter.desc=Files that were previously marked as notable FileSearchFiltering.PreviouslyNotableFilter.desc=that were previously marked as notable
# {0} - filters # {0} - filters
FileSearchFiltering.ScoreFilter.desc=Files with score(s) of : {0} FileSearchFiltering.ScoreFilter.desc=Score(s) of : {0}
# {0} - filters # {0} - filters
FileSearchFiltering.SizeFilter.desc=Files with size in range(s): {0} FileSearchFiltering.SizeFilter.desc=Size(s): {0}
FileSearchFiltering.SizeFilter.or=\ or FileSearchFiltering.SizeFilter.or=,
# {0} - Minimum bytes
# {1} - Maximum bytes
FileSearchFiltering.SizeFilter.range=({0} to {1})
# {0} - tag names # {0} - tag names
FileSearchFiltering.TagsFilter.desc=Files that have been tagged {0} FileSearchFiltering.TagsFilter.desc=Tagged {0}
FileSearchFiltering.TagsFilter.or=\ or FileSearchFiltering.TagsFilter.or=,
FileSearchFiltering.UserCreatedFilter.desc=Files that contain EXIF data FileSearchFiltering.UserCreatedFilter.desc=that contain EXIF data
FileSearchPanel.sortingPanel.border.title=Grouping FileSearchPanel.sortingPanel.border.title=Grouping
FileSearchPanel.addButton.text=Add FileSearchPanel.addButton.text=Add
FileSearchPanel.substringRadioButton.text=Substring FileSearchPanel.substringRadioButton.text=Substring
@ -259,6 +264,9 @@ DocumentFilterPanel.documentsFiltersSplitPane.border.title=Step 2: Filter which
ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show
VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show
DiscoveryDialog.step1Label.text=Step 1: Choose result type DiscoveryDialog.step1Label.text=Step 1: Choose result type
ResultsSplitPaneDivider.hideButton.text=
ResultsSplitPaneDivider.showButton.text=
ResultsSplitPaneDivider.detailsLabel.text=Details Area
VideoThumbnailPanel.bytes.text=bytes VideoThumbnailPanel.bytes.text=bytes
VideoThumbnailPanel.deleted.text=All instances of file are deleted. VideoThumbnailPanel.deleted.text=All instances of file are deleted.
VideoThumbnailPanel.gigaBytes.text=GB VideoThumbnailPanel.gigaBytes.text=GB

View File

@ -43,23 +43,25 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace pref="196" max="32767" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="filler1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="step1Label" min="-2" pref="243" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0">
</Group>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
<Component id="imagesButton" min="-2" pref="110" max="-2" attributes="0"/> <Component id="imagesButton" min="-2" pref="110" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="videosButton" min="-2" pref="110" max="-2" attributes="0"/> <Component id="videosButton" min="-2" pref="110" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="documentsButton" min="-2" max="-2" attributes="0"/> <Component id="documentsButton" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="370" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="step1Label" min="-2" pref="243" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="filler1" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="391" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace pref="196" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>

View File

@ -275,19 +275,21 @@ final class DiscoveryDialog extends javax.swing.JDialog {
toolBarPanelLayout.setHorizontalGroup( toolBarPanelLayout.setHorizontalGroup(
toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(toolBarPanelLayout.createSequentialGroup() .addGroup(toolBarPanelLayout.createSequentialGroup()
.addContainerGap(196, Short.MAX_VALUE) .addContainerGap()
.addGroup(toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, toolBarPanelLayout.createSequentialGroup()
.addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(step1Label, javax.swing.GroupLayout.PREFERRED_SIZE, 243, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(toolBarPanelLayout.createSequentialGroup() .addGroup(toolBarPanelLayout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(imagesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(imagesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(videosButton, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(videosButton, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(documentsButton))) .addComponent(documentsButton)
.addContainerGap(196, Short.MAX_VALUE)) .addContainerGap(370, Short.MAX_VALUE))
.addGroup(toolBarPanelLayout.createSequentialGroup()
.addComponent(step1Label, javax.swing.GroupLayout.PREFERRED_SIZE, 243, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(391, Short.MAX_VALUE))))
); );
toolBarPanelLayout.setVerticalGroup( toolBarPanelLayout.setVerticalGroup(
toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) toolBarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

View File

@ -41,7 +41,7 @@
<SubComponents> <SubComponents>
<Container class="javax.swing.JSplitPane" name="rightSplitPane"> <Container class="javax.swing.JSplitPane" name="rightSplitPane">
<Properties> <Properties>
<Property name="dividerSize" type="int" value="15"/> <Property name="dividerSize" type="int" value="35"/>
<Property name="orientation" type="int" value="0"/> <Property name="orientation" type="int" value="0"/>
<Property name="resizeWeight" type="double" value="1.0"/> <Property name="resizeWeight" type="double" value="1.0"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">

View File

@ -19,11 +19,14 @@
package org.sleuthkit.autopsy.discovery; package org.sleuthkit.autopsy.discovery;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics; import java.awt.Graphics;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.swing.JSplitPane; import javax.swing.JSplitPane;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.windows.Mode; import org.openide.windows.Mode;
@ -67,6 +70,34 @@ public final class DiscoveryTopComponent extends TopComponent {
mainSplitPane.setLeftComponent(groupListPanel); mainSplitPane.setLeftComponent(groupListPanel);
rightSplitPane.setTopComponent(resultsPanel); rightSplitPane.setTopComponent(resultsPanel);
rightSplitPane.setBottomComponent(detailsPanel); rightSplitPane.setBottomComponent(detailsPanel);
//set color of divider
rightSplitPane.setUI(new BasicSplitPaneUI() {
@Override
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDividerImpl(this);
}
});
}
/**
* Private class for replacing the divider for the results split pane.
*/
private final class BasicSplitPaneDividerImpl extends BasicSplitPaneDivider {
/**
* Construct a new BasicSplitPaneDividerImpl.
*
* @param ui The component which contains the split pane this divider is
* in.
*/
BasicSplitPaneDividerImpl(BasicSplitPaneUI ui) {
super(ui);
this.setLayout(new BorderLayout());
this.add(new ResultsSplitPaneDivider());
}
private static final long serialVersionUID = 1L;
} }
/** /**
@ -129,7 +160,7 @@ public final class DiscoveryTopComponent extends TopComponent {
mainSplitPane.setDividerLocation(250); mainSplitPane.setDividerLocation(250);
mainSplitPane.setPreferredSize(new java.awt.Dimension(1100, 700)); mainSplitPane.setPreferredSize(new java.awt.Dimension(1100, 700));
rightSplitPane.setDividerSize(15); rightSplitPane.setDividerSize(35);
rightSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); rightSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
rightSplitPane.setResizeWeight(1.0); rightSplitPane.setResizeWeight(1.0);
rightSplitPane.setPreferredSize(new java.awt.Dimension(800, 700)); rightSplitPane.setPreferredSize(new java.awt.Dimension(800, 700));
@ -249,11 +280,11 @@ public final class DiscoveryTopComponent extends TopComponent {
@Subscribe @Subscribe
@Messages({"DiscoveryTopComponent.newSearch.text=New Search", @Messages({"DiscoveryTopComponent.newSearch.text=New Search",
"# {0} - search", "# {0} - search",
"DiscoveryTopComponent.searchComplete.text=Results for {0}"}) "DiscoveryTopComponent.searchComplete.text=Results with {0}"})
void handleSearchCompleteEvent(DiscoveryEventUtils.SearchCompleteEvent searchCompleteEvent) { void handleSearchCompleteEvent(DiscoveryEventUtils.SearchCompleteEvent searchCompleteEvent) {
newSearchButton.setText(Bundle.DiscoveryTopComponent_newSearch_text()); newSearchButton.setText(Bundle.DiscoveryTopComponent_newSearch_text());
progressMessageTextArea.setForeground(Color.black); progressMessageTextArea.setForeground(Color.black);
progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchComplete_text(searchCompleteEvent.getFilters().stream().map(FileFilter::getDesc).collect(Collectors.joining(", ")))); progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchComplete_text(searchCompleteEvent.getFilters().stream().map(FileFilter::getDesc).collect(Collectors.joining("; "))));
progressMessageTextArea.setCaretPosition(0); progressMessageTextArea.setCaretPosition(0);
} }
@ -269,6 +300,7 @@ public final class DiscoveryTopComponent extends TopComponent {
newSearchButton.setText(Bundle.DiscoveryTopComponent_newSearch_text()); newSearchButton.setText(Bundle.DiscoveryTopComponent_newSearch_text());
progressMessageTextArea.setForeground(Color.red); progressMessageTextArea.setForeground(Color.red);
progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchCancelled_text()); progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchCancelled_text());
} }
/** /**

View File

@ -45,7 +45,6 @@ final class DocumentFilterPanel extends AbstractFiltersPanel {
addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0); addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0);
addFilter(new HashSetFilterPanel(), false, null, 1); addFilter(new HashSetFilterPanel(), false, null, 1);
addFilter(new InterestingItemsFilterPanel(), false, null, 1); addFilter(new InterestingItemsFilterPanel(), false, null, 1);
addFilter(new ObjectDetectedFilterPanel(), false, null, 1);
addFilter(new ParentFolderFilterPanel(), false, null, 1); addFilter(new ParentFolderFilterPanel(), false, null, 1);
addPanelsToScrollPane(documentsFiltersSplitPane); addPanelsToScrollPane(documentsFiltersSplitPane);
} }

View File

@ -126,39 +126,46 @@ final class FileSearchData {
* Enum representing the file size * Enum representing the file size
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"FileSearchData.FileSize.XXLARGE_IMAGE.displayName=XXLarge: 200MB+", "FileSearchData.FileSize.XXLARGE.displayName=XXLarge",
"FileSearchData.FileSize.XLARGE_IMAGE.displayName=XLarge: 50-200MB", "FileSearchData.FileSize.XLARGE.displayName=XLarge",
"FileSearchData.FileSize.LARGE_IMAGE.displayName=Large: 1-50MB", "FileSearchData.FileSize.LARGE.displayName=Large",
"FileSearchData.FileSize.MEDIUM_IMAGE.displayName=Medium: 100KB-1MB", "FileSearchData.FileSize.MEDIUM.displayName=Medium",
"FileSearchData.FileSize.SMALL_IMAGE.displayName=Small: 16-100KB", "FileSearchData.FileSize.SMALL.displayName=Small",
"FileSearchData.FileSize.XSMALL_IMAGE.displayName=XSmall: 0-16KB", "FileSearchData.FileSize.XSMALL.displayName=XSmall",
"FileSearchData.FileSize.XXLARGE_VIDEO.displayName=XXLarge: 10GB+", "FileSearchData.FileSize.10PlusGb=: 10GB+",
"FileSearchData.FileSize.XLARGE_VIDEO.displayName=XLarge: 5-10GB", "FileSearchData.FileSize.5gbto10gb=: 5-10GB",
"FileSearchData.FileSize.LARGE_VIDEO.displayName=Large: 1-5GB", "FileSearchData.FileSize.1gbto5gb=: 1-5GB",
"FileSearchData.FileSize.MEDIUM_VIDEO.displayName=Medium: 100MB-1GB", "FileSearchData.FileSize.100mbto1gb=: 100MB-1GB",
"FileSearchData.FileSize.SMALL_VIDEO.displayName=Small: 500KB-100MB", "FileSearchData.FileSize.200PlusMb=: 200MB+",
"FileSearchData.FileSize.XSMALL_VIDEO.displayName=XSmall: 0-500KB",}) "FileSearchData.FileSize.50mbto200mb=: 50-200MB",
"FileSearchData.FileSize.500kbto100mb=: 500KB-100MB",
"FileSearchData.FileSize.1mbto50mb=: 1-50MB",
"FileSearchData.FileSize.100kbto1mb=: 100KB-1MB",
"FileSearchData.FileSize.16kbto100kb=: 16-100KB",
"FileSearchData.FileSize.upTo500kb=: 0-500KB",
"FileSearchData.FileSize.upTo16kb=: 0-16KB",})
enum FileSize { enum FileSize {
XXLARGE_VIDEO(0, 10000 * BYTES_PER_MB, -1, Bundle.FileSearchData_FileSize_XXLARGE_VIDEO_displayName()), XXLARGE_VIDEO(0, 10000 * BYTES_PER_MB, -1, Bundle.FileSearchData_FileSize_XXLARGE_displayName(), Bundle.FileSearchData_FileSize_10PlusGb()),
XLARGE_VIDEO(1, 5000 * BYTES_PER_MB, 10000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_XLARGE_VIDEO_displayName()), XLARGE_VIDEO(1, 5000 * BYTES_PER_MB, 10000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_XLARGE_displayName(), Bundle.FileSearchData_FileSize_5gbto10gb()),
LARGE_VIDEO(2, 1000 * BYTES_PER_MB, 5000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_LARGE_VIDEO_displayName()), LARGE_VIDEO(2, 1000 * BYTES_PER_MB, 5000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_LARGE_displayName(), Bundle.FileSearchData_FileSize_1gbto5gb()),
MEDIUM_VIDEO(3, 100 * BYTES_PER_MB, 1000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_MEDIUM_VIDEO_displayName()), MEDIUM_VIDEO(3, 100 * BYTES_PER_MB, 1000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_MEDIUM_displayName(), Bundle.FileSearchData_FileSize_100mbto1gb()),
SMALL_VIDEO(4, 500000, 100 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_SMALL_VIDEO_displayName()), SMALL_VIDEO(4, 500000, 100 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_SMALL_displayName(), Bundle.FileSearchData_FileSize_500kbto100mb()),
XSMALL_VIDEO(5, 0, 500000, Bundle.FileSearchData_FileSize_XSMALL_VIDEO_displayName()), XSMALL_VIDEO(5, 0, 500000, Bundle.FileSearchData_FileSize_XSMALL_displayName(), Bundle.FileSearchData_FileSize_upTo500kb()),
XXLARGE_IMAGE(6, 200 * BYTES_PER_MB, -1, Bundle.FileSearchData_FileSize_XXLARGE_IMAGE_displayName()), XXLARGE_IMAGE(6, 200 * BYTES_PER_MB, -1, Bundle.FileSearchData_FileSize_XXLARGE_displayName(), Bundle.FileSearchData_FileSize_200PlusMb()),
XLARGE_IMAGE(7, 50 * BYTES_PER_MB, 200 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_XLARGE_IMAGE_displayName()), XLARGE_IMAGE(7, 50 * BYTES_PER_MB, 200 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_XLARGE_displayName(), Bundle.FileSearchData_FileSize_50mbto200mb()),
LARGE_IMAGE(8, 1 * BYTES_PER_MB, 50 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_LARGE_IMAGE_displayName()), LARGE_IMAGE(8, 1 * BYTES_PER_MB, 50 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_LARGE_displayName(), Bundle.FileSearchData_FileSize_1mbto50mb()),
MEDIUM_IMAGE(9, 100000, 1 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_MEDIUM_IMAGE_displayName()), MEDIUM_IMAGE(9, 100000, 1 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_MEDIUM_displayName(), Bundle.FileSearchData_FileSize_100kbto1mb()),
SMALL_IMAGE(10, 16000, 100000, Bundle.FileSearchData_FileSize_SMALL_IMAGE_displayName()), SMALL_IMAGE(10, 16000, 100000, Bundle.FileSearchData_FileSize_SMALL_displayName(), Bundle.FileSearchData_FileSize_16kbto100kb()),
XSMALL_IMAGE(11, 0, 16000, Bundle.FileSearchData_FileSize_XSMALL_IMAGE_displayName()); XSMALL_IMAGE(11, 0, 16000, Bundle.FileSearchData_FileSize_XSMALL_displayName(), Bundle.FileSearchData_FileSize_upTo16kb());
private final int ranking; // Must be unique for each value private final int ranking; // Must be unique for each value
private final long minBytes; // Note that the size must be strictly greater than this to match private final long minBytes; // Note that the size must be strictly greater than this to match
private final long maxBytes; private final long maxBytes;
private final String displayName; private final String sizeGroup;
private final String displaySize;
final static long NO_MAXIMUM = -1; final static long NO_MAXIMUM = -1;
FileSize(int ranking, long minB, long maxB, String displayName) { FileSize(int ranking, long minB, long maxB, String displayName, String displaySize) {
this.ranking = ranking; this.ranking = ranking;
this.minBytes = minB; this.minBytes = minB;
if (maxB >= 0) { if (maxB >= 0) {
@ -166,7 +173,8 @@ final class FileSearchData {
} else { } else {
this.maxBytes = NO_MAXIMUM; this.maxBytes = NO_MAXIMUM;
} }
this.displayName = displayName; this.sizeGroup = displayName;
this.displaySize = displaySize;
} }
/** /**
@ -246,7 +254,11 @@ final class FileSearchData {
@Override @Override
public String toString() { public String toString() {
return displayName; return sizeGroup + displaySize;
}
String getSizeGroup(){
return sizeGroup;
} }
/** /**

View File

@ -207,11 +207,8 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.SizeFilter.desc=Files with size in range(s): {0}", "FileSearchFiltering.SizeFilter.desc=Size(s): {0}",
"FileSearchFiltering.SizeFilter.or= or ", "FileSearchFiltering.SizeFilter.or=, "})
"# {0} - Minimum bytes",
"# {1} - Maximum bytes",
"FileSearchFiltering.SizeFilter.range=({0} to {1})",})
@Override @Override
String getDesc() { String getDesc() {
String desc = ""; // NON-NLS String desc = ""; // NON-NLS
@ -219,7 +216,7 @@ class FileSearchFiltering {
if (!desc.isEmpty()) { if (!desc.isEmpty()) {
desc += Bundle.FileSearchFiltering_SizeFilter_or(); desc += Bundle.FileSearchFiltering_SizeFilter_or();
} }
desc += Bundle.FileSearchFiltering_SizeFilter_range(size.getMinBytes(), size.getMaxBytes()); desc += size.getSizeGroup();
} }
desc = Bundle.FileSearchFiltering_SizeFilter_desc(desc); desc = Bundle.FileSearchFiltering_SizeFilter_desc(desc);
return desc; return desc;
@ -364,10 +361,12 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.ParentFilter.desc=Files with paths matching: {0}", "FileSearchFiltering.ParentFilter.desc=Paths matching: {0}",
"FileSearchFiltering.ParentFilter.or= or ", "FileSearchFiltering.ParentFilter.or=, ",
"FileSearchFiltering.ParentFilter.exact=(exact match)", "FileSearchFiltering.ParentFilter.exact=(exact match)",
"FileSearchFiltering.ParentFilter.substring=(substring)",}) "FileSearchFiltering.ParentFilter.substring=(substring)",
"FileSearchFiltering.ParentFilter.included=(included)",
"FileSearchFiltering.ParentFilter.excluded=(excluded)"})
@Override @Override
String getDesc() { String getDesc() {
String desc = ""; // NON-NLS String desc = ""; // NON-NLS
@ -380,6 +379,11 @@ class FileSearchFiltering {
} else { } else {
desc += searchTerm.getSearchStr() + Bundle.FileSearchFiltering_ParentFilter_substring(); desc += searchTerm.getSearchStr() + Bundle.FileSearchFiltering_ParentFilter_substring();
} }
if (searchTerm.isIncluded()) {
desc += Bundle.FileSearchFiltering_ParentFilter_included();
} else {
desc += Bundle.FileSearchFiltering_ParentFilter_excluded();
}
} }
desc = Bundle.FileSearchFiltering_ParentFilter_desc(desc); desc = Bundle.FileSearchFiltering_ParentFilter_desc(desc);
return desc; return desc;
@ -417,8 +421,8 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.DataSourceFilter.desc=Files in data source(s): {0}", "FileSearchFiltering.DataSourceFilter.desc=Data source(s): {0}",
"FileSearchFiltering.DataSourceFilter.or= or ", "FileSearchFiltering.DataSourceFilter.or=, ",
"# {0} - Data source name", "# {0} - Data source name",
"# {1} - Data source ID", "# {1} - Data source ID",
"FileSearchFiltering.DataSourceFilter.datasource={0}({1})",}) "FileSearchFiltering.DataSourceFilter.datasource={0}({1})",})
@ -466,7 +470,7 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.KeywordListFilter.desc=Files with keywords in list(s): {0}",}) "FileSearchFiltering.KeywordListFilter.desc=Keywords in list(s): {0}",})
@Override @Override
String getDesc() { String getDesc() {
return Bundle.FileSearchFiltering_KeywordListFilter_desc(concatenateSetNamesForDisplay(listNames)); return Bundle.FileSearchFiltering_KeywordListFilter_desc(concatenateSetNamesForDisplay(listNames));
@ -516,8 +520,8 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.FileTypeFilter.desc=Files with type: {0}", "FileSearchFiltering.FileTypeFilter.desc=Type: {0}",
"FileSearchFiltering.FileTypeFilter.or= or ",}) "FileSearchFiltering.FileTypeFilter.or=, ",})
@Override @Override
String getDesc() { String getDesc() {
String desc = ""; String desc = "";
@ -586,8 +590,8 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.FrequencyFilter.desc=Files with frequency: {0}", "FileSearchFiltering.FrequencyFilter.desc=Past occurrences: {0}",
"FileSearchFiltering.FrequencyFilter.or= or ",}) "FileSearchFiltering.FrequencyFilter.or=, ",})
@Override @Override
String getDesc() { String getDesc() {
String desc = ""; // NON-NLS String desc = ""; // NON-NLS
@ -595,7 +599,7 @@ class FileSearchFiltering {
if (!desc.isEmpty()) { if (!desc.isEmpty()) {
desc += Bundle.FileSearchFiltering_FrequencyFilter_or(); desc += Bundle.FileSearchFiltering_FrequencyFilter_or();
} }
desc += freq.name(); desc += freq.toString();
} }
return Bundle.FileSearchFiltering_FrequencyFilter_desc(desc); return Bundle.FileSearchFiltering_FrequencyFilter_desc(desc);
} }
@ -632,7 +636,7 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.HashSetFilter.desc=Files with hash set hits in set(s): {0}",}) "FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}",})
@Override @Override
String getDesc() { String getDesc() {
return Bundle.FileSearchFiltering_HashSetFilter_desc(concatenateSetNamesForDisplay(setNames)); return Bundle.FileSearchFiltering_HashSetFilter_desc(concatenateSetNamesForDisplay(setNames));
@ -670,7 +674,7 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.InterestingItemSetFilter.desc=Files with interesting item hits in set(s): {0}",}) "FileSearchFiltering.InterestingItemSetFilter.desc=Interesting item hits in set(s): {0}",})
@Override @Override
String getDesc() { String getDesc() {
return Bundle.FileSearchFiltering_InterestingItemSetFilter_desc(concatenateSetNamesForDisplay(setNames)); return Bundle.FileSearchFiltering_InterestingItemSetFilter_desc(concatenateSetNamesForDisplay(setNames));
@ -708,7 +712,7 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.ObjectDetectionFilter.desc=Files with objects detected in set(s): {0}",}) "FileSearchFiltering.ObjectDetectionFilter.desc=Objects detected in set(s): {0}",})
@Override @Override
String getDesc() { String getDesc() {
return Bundle.FileSearchFiltering_ObjectDetectionFilter_desc(concatenateSetNamesForDisplay(typeNames)); return Bundle.FileSearchFiltering_ObjectDetectionFilter_desc(concatenateSetNamesForDisplay(typeNames));
@ -784,7 +788,7 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - filters", "# {0} - filters",
"FileSearchFiltering.ScoreFilter.desc=Files with score(s) of : {0}",}) "FileSearchFiltering.ScoreFilter.desc=Score(s) of : {0}",})
@Override @Override
String getDesc() { String getDesc() {
return Bundle.FileSearchFiltering_ScoreFilter_desc( return Bundle.FileSearchFiltering_ScoreFilter_desc(
@ -826,8 +830,8 @@ class FileSearchFiltering {
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - tag names", "# {0} - tag names",
"FileSearchFiltering.TagsFilter.desc=Files that have been tagged {0}", "FileSearchFiltering.TagsFilter.desc=Tagged {0}",
"FileSearchFiltering.TagsFilter.or= or ",}) "FileSearchFiltering.TagsFilter.or=, ",})
@Override @Override
String getDesc() { String getDesc() {
String desc = ""; // NON-NLS String desc = ""; // NON-NLS
@ -862,7 +866,7 @@ class FileSearchFiltering {
} }
@NbBundle.Messages({ @NbBundle.Messages({
"FileSearchFiltering.UserCreatedFilter.desc=Files that contain EXIF data",}) "FileSearchFiltering.UserCreatedFilter.desc=that contain EXIF data",})
@Override @Override
String getDesc() { String getDesc() {
return Bundle.FileSearchFiltering_UserCreatedFilter_desc(); return Bundle.FileSearchFiltering_UserCreatedFilter_desc();
@ -931,7 +935,7 @@ class FileSearchFiltering {
} }
@NbBundle.Messages({ @NbBundle.Messages({
"FileSearchFiltering.PreviouslyNotableFilter.desc=Files that were previously marked as notable",}) "FileSearchFiltering.PreviouslyNotableFilter.desc=that were previously marked as notable",})
@Override @Override
String getDesc() { String getDesc() {
return Bundle.FileSearchFiltering_PreviouslyNotableFilter_desc(); return Bundle.FileSearchFiltering_PreviouslyNotableFilter_desc();
@ -949,7 +953,7 @@ class FileSearchFiltering {
} }
@NbBundle.Messages({ @NbBundle.Messages({
"FileSearchFiltering.KnownFilter.desc=Files which are not known"}) "FileSearchFiltering.KnownFilter.desc=which are not known"})
@Override @Override
String getDesc() { String getDesc() {
return Bundle.FileSearchFiltering_KnownFilter_desc(); return Bundle.FileSearchFiltering_KnownFilter_desc();

View File

@ -37,6 +37,18 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.ButtonGroup" name="includeButtonGroup">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.ButtonGroup" name="pathTypeButtonGroup">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
</NonVisualComponents> </NonVisualComponents>
<Properties> <Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
@ -143,6 +155,9 @@
</Container> </Container>
<Component class="javax.swing.JRadioButton" name="fullRadioButton"> <Component class="javax.swing.JRadioButton" name="fullRadioButton">
<Properties> <Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="pathTypeButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/> <Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.fullRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.fullRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
@ -152,6 +167,9 @@
</Component> </Component>
<Component class="javax.swing.JRadioButton" name="includeRadioButton"> <Component class="javax.swing.JRadioButton" name="includeRadioButton">
<Properties> <Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="includeButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/> <Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.includeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.includeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
@ -161,6 +179,9 @@
</Component> </Component>
<Component class="javax.swing.JRadioButton" name="substringRadioButton"> <Component class="javax.swing.JRadioButton" name="substringRadioButton">
<Properties> <Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="pathTypeButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.substringRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.substringRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
@ -169,6 +190,9 @@
</Component> </Component>
<Component class="javax.swing.JRadioButton" name="excludeRadioButton"> <Component class="javax.swing.JRadioButton" name="excludeRadioButton">
<Properties> <Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="includeButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.excludeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.excludeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>

View File

@ -66,6 +66,8 @@ final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel {
parentCheckbox = new javax.swing.JCheckBox(); parentCheckbox = new javax.swing.JCheckBox();
parentLabel = new javax.swing.JLabel(); parentLabel = new javax.swing.JLabel();
javax.swing.ButtonGroup includeButtonGroup = new javax.swing.ButtonGroup();
javax.swing.ButtonGroup pathTypeButtonGroup = new javax.swing.ButtonGroup();
parentScrollPane = new javax.swing.JScrollPane(); parentScrollPane = new javax.swing.JScrollPane();
parentList = new javax.swing.JList<>(); parentList = new javax.swing.JList<>();
fullRadioButton = new javax.swing.JRadioButton(); fullRadioButton = new javax.swing.JRadioButton();
@ -106,17 +108,21 @@ final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel {
}); });
parentScrollPane.setViewportView(parentList); parentScrollPane.setViewportView(parentList);
pathTypeButtonGroup.add(fullRadioButton);
fullRadioButton.setSelected(true); fullRadioButton.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(fullRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.fullRadioButton.text_1")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(fullRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.fullRadioButton.text_1")); // NOI18N
fullRadioButton.setEnabled(false); fullRadioButton.setEnabled(false);
includeButtonGroup.add(includeRadioButton);
includeRadioButton.setSelected(true); includeRadioButton.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(includeRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.includeRadioButton.text_1")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(includeRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.includeRadioButton.text_1")); // NOI18N
includeRadioButton.setEnabled(false); includeRadioButton.setEnabled(false);
pathTypeButtonGroup.add(substringRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(substringRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.substringRadioButton.text_1")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(substringRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.substringRadioButton.text_1")); // NOI18N
substringRadioButton.setEnabled(false); substringRadioButton.setEnabled(false);
includeButtonGroup.add(excludeRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(excludeRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.excludeRadioButton.text_1")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(excludeRadioButton, org.openide.util.NbBundle.getMessage(ParentFolderFilterPanel.class, "ParentFolderFilterPanel.excludeRadioButton.text_1")); // NOI18N
excludeRadioButton.setEnabled(false); excludeRadioButton.setEnabled(false);
@ -188,7 +194,7 @@ final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel {
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void parentCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_parentCheckboxActionPerformed private void parentCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_parentCheckboxActionPerformed
// parentFilterSettings(true, true, parentCheckbox.isSelected(), null); configurePanel(parentCheckbox.isSelected(), null);
}//GEN-LAST:event_parentCheckboxActionPerformed }//GEN-LAST:event_parentCheckboxActionPerformed
private void parentListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_parentListValueChanged private void parentListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_parentListValueChanged
@ -235,6 +241,7 @@ final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel {
parentCheckbox.setSelected(selected); parentCheckbox.setSelected(selected);
if (parentCheckbox.isEnabled() && parentCheckbox.isSelected()) { if (parentCheckbox.isEnabled() && parentCheckbox.isSelected()) {
parentScrollPane.setEnabled(true); parentScrollPane.setEnabled(true);
parentLabel.setEnabled(true);
includeRadioButton.setEnabled(true); includeRadioButton.setEnabled(true);
excludeRadioButton.setEnabled(true); excludeRadioButton.setEnabled(true);
fullRadioButton.setEnabled(true); fullRadioButton.setEnabled(true);
@ -248,6 +255,7 @@ final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel {
} }
} else { } else {
parentScrollPane.setEnabled(false); parentScrollPane.setEnabled(false);
parentLabel.setEnabled(false);
parentList.setEnabled(false); parentList.setEnabled(false);
includeRadioButton.setEnabled(false); includeRadioButton.setEnabled(false);
excludeRadioButton.setEnabled(false); excludeRadioButton.setEnabled(false);

View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="aa" green="aa" red="aa" type="rgb"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="detailsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="251" max="32767" attributes="0"/>
<Component id="showButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="hideButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Component id="filler2" alignment="1" max="32767" attributes="0"/>
<Component id="filler1" alignment="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="filler2" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="hideButton" max="32767" attributes="0"/>
<Component id="showButton" max="32767" attributes="0"/>
<Component id="detailsLabel" alignment="0" min="-2" pref="25" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="filler1" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="detailsLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsSplitPaneDivider.detailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="hideButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/discovery/arrow-down.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsSplitPaneDivider.hideButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[0, 0, 0, 0]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hideButtonActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="hideButton.setCursor(Cursor.getDefaultCursor());"/>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="showButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/discovery/arrow-up.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsSplitPaneDivider.showButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[0, 0, 0, 0]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showButtonActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="showButton.setCursor(Cursor.getDefaultCursor());"/>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.Box$Filler" name="filler1">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 32767]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
</AuxValues>
</Component>
<Component class="javax.swing.Box$Filler" name="filler2">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 32767]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
</AuxValues>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,121 @@
/*
* Autopsy
*
* Copyright 2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.discovery;
import java.awt.Cursor;
/**
* Panel for separating the results list from the details area.
*/
final class ResultsSplitPaneDivider extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
/**
* Creates new form LabeledSplitPaneDivider.
*/
ResultsSplitPaneDivider() {
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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
javax.swing.JLabel detailsLabel = new javax.swing.JLabel();
javax.swing.JButton hideButton = new javax.swing.JButton();
javax.swing.JButton showButton = new javax.swing.JButton();
javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
setBackground(new java.awt.Color(170, 170, 170));
org.openide.awt.Mnemonics.setLocalizedText(detailsLabel, org.openide.util.NbBundle.getMessage(ResultsSplitPaneDivider.class, "ResultsSplitPaneDivider.detailsLabel.text")); // NOI18N
detailsLabel.setFocusable(false);
hideButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/discovery/arrow-down.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(hideButton, org.openide.util.NbBundle.getMessage(ResultsSplitPaneDivider.class, "ResultsSplitPaneDivider.hideButton.text")); // NOI18N
hideButton.setBorder(null);
hideButton.setFocusable(false);
hideButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
hideButton.setCursor(Cursor.getDefaultCursor());
hideButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
hideButtonActionPerformed(evt);
}
});
showButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/discovery/arrow-up.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(showButton, org.openide.util.NbBundle.getMessage(ResultsSplitPaneDivider.class, "ResultsSplitPaneDivider.showButton.text")); // NOI18N
showButton.setBorder(null);
showButton.setFocusable(false);
showButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
showButton.setCursor(Cursor.getDefaultCursor());
showButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
showButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(detailsLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 251, Short.MAX_VALUE)
.addComponent(showButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(hideButton)
.addContainerGap())
.addComponent(filler2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(filler1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(filler2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(hideButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(showButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(detailsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(0, 0, 0)
.addComponent(filler1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void showButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showButtonActionPerformed
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(true));
}//GEN-LAST:event_showButtonActionPerformed
private void hideButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideButtonActionPerformed
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(false));
}//GEN-LAST:event_hideButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}

View File

@ -11,12 +11,17 @@
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,73,0,0,1,24"/> <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,102,0,0,1,56"/>
</AuxValues> </AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents> <SubComponents>
<Container class="javax.swing.JScrollPane" name="videoFiltersScrollPane"> <Container class="javax.swing.JScrollPane" name="videoFiltersScrollPane">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[312, 102]"/>
</Property>
</Properties>
<AuxValues> <AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/> <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
@ -32,7 +37,7 @@
<Container class="javax.swing.JPanel" name="videoFiltersPanel"> <Container class="javax.swing.JPanel" name="videoFiltersPanel">
<Properties> <Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[223, 66]"/> <Dimension value="[310, 100]"/>
</Property> </Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
@ -45,7 +50,7 @@
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Component id="videoFiltersSplitPane" max="32767" attributes="0"/> <Component id="videoFiltersSplitPane" pref="294" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
@ -54,7 +59,7 @@
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Component id="videoFiltersSplitPane" max="32767" attributes="0"/> <Component id="videoFiltersSplitPane" pref="84" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>

View File

@ -66,7 +66,9 @@ final class VideoFilterPanel extends AbstractFiltersPanel {
setLayout(new java.awt.BorderLayout()); setLayout(new java.awt.BorderLayout());
videoFiltersPanel.setPreferredSize(new java.awt.Dimension(223, 66)); videoFiltersScrollPane.setPreferredSize(new java.awt.Dimension(312, 102));
videoFiltersPanel.setPreferredSize(new java.awt.Dimension(310, 100));
videoFiltersSplitPane.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(VideoFilterPanel.class, "VideoFilterPanel.videoFiltersSplitPane.border.title"))); // NOI18N videoFiltersSplitPane.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(VideoFilterPanel.class, "VideoFilterPanel.videoFiltersSplitPane.border.title"))); // NOI18N
videoFiltersSplitPane.setResizeWeight(0.5); videoFiltersSplitPane.setResizeWeight(0.5);
@ -77,14 +79,14 @@ final class VideoFilterPanel extends AbstractFiltersPanel {
videoFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) videoFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(videoFiltersPanelLayout.createSequentialGroup() .addGroup(videoFiltersPanelLayout.createSequentialGroup()
.addGap(8, 8, 8) .addGap(8, 8, 8)
.addComponent(videoFiltersSplitPane) .addComponent(videoFiltersSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 294, Short.MAX_VALUE)
.addGap(8, 8, 8)) .addGap(8, 8, 8))
); );
videoFiltersPanelLayout.setVerticalGroup( videoFiltersPanelLayout.setVerticalGroup(
videoFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) videoFiltersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(videoFiltersPanelLayout.createSequentialGroup() .addGroup(videoFiltersPanelLayout.createSequentialGroup()
.addGap(8, 8, 8) .addGap(8, 8, 8)
.addComponent(videoFiltersSplitPane) .addComponent(videoFiltersSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 84, Short.MAX_VALUE)
.addGap(8, 8, 8)) .addGap(8, 8, 8))
); );

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -1388,7 +1388,8 @@ class ExtractRegistry extends Extract {
line = reader.readLine(); line = reader.readLine();
// Columns are // Columns are
// FileX -> <file> // FileX -> <file>
while (!line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains("Applets")) { while (!line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains("Applets")
&& !line.contains(("Recent File List"))) {
// Split line on "> " which is the record delimiter between position and file // Split line on "> " which is the record delimiter between position and file
String tokens[] = line.split("> "); String tokens[] = line.split("> ");
String fileName = tokens[1]; String fileName = tokens[1];

View File

@ -36,6 +36,7 @@ sub pluginmain {
my $class = shift; my $class = shift;
my $ntuser = shift; my $ntuser = shift;
#::logMsg("autospyrunmru"); #::logMsg("autospyrunmru");
if (defined(Parse::Win32Registry->new($ntuser))) {
my $reg = Parse::Win32Registry->new($ntuser); my $reg = Parse::Win32Registry->new($ntuser);
my $root_key = $reg->get_root_key; my $root_key = $reg->get_root_key;
@ -72,7 +73,7 @@ sub pluginmain {
#::rptMsg($key_path." not found."); #::rptMsg($key_path." not found.");
#::logMsg($key_path." not found."); #::logMsg($key_path." not found.");
} }
}
} }
1; 1;

View File

@ -35,6 +35,7 @@ sub pluginmain {
my $class = shift; my $class = shift;
my $ntuser = shift; my $ntuser = shift;
#::logMsg("||logonusername||"); #::logMsg("||logonusername||");
if (defined(Parse::Win32Registry->new($ntuser))) {
my $reg = Parse::Win32Registry->new($ntuser); my $reg = Parse::Win32Registry->new($ntuser);
my $root_key = $reg->get_root_key; my $root_key = $reg->get_root_key;
@ -65,6 +66,7 @@ sub pluginmain {
#::rptMsg($key_path." not found."); #::rptMsg($key_path." not found.");
#::logMsg($key_path." not found."); #::logMsg($key_path." not found.");
} }
}
} }
1; 1;

View File

@ -31,6 +31,8 @@ sub pluginmain {
#::logMsg("Launching ntusernetwork v.".$VERSION); #::logMsg("Launching ntusernetwork v.".$VERSION);
#::rptMsg("ntusernetwork v.".$VERSION); # banner #::rptMsg("ntusernetwork v.".$VERSION); # banner
#::rptMsg("(".$config{hive}.") ".getShortDescr()."\n"); # banner #::rptMsg("(".$config{hive}.") ".getShortDescr()."\n"); # banner
if (defined(Parse::Win32Registry->new($ntuser))) {
my $reg = Parse::Win32Registry->new($ntuser); my $reg = Parse::Win32Registry->new($ntuser);
my $root_key = $reg->get_root_key; my $root_key = $reg->get_root_key;
@ -89,5 +91,6 @@ sub pluginmain {
#::rptMsg($key_path." key not found."); #::rptMsg($key_path." key not found.");
} }
::rptMsg("</artifacts></NtuserNetwork>"); ::rptMsg("</artifacts></NtuserNetwork>");
}
} }
1; 1;

View File

@ -41,6 +41,7 @@ sub pluginmain {
my $class = shift; my $class = shift;
my $ntuser = shift; my $ntuser = shift;
#::logMsg("||recentdocs||"); #::logMsg("||recentdocs||");
if (defined(Parse::Win32Registry->new($ntuser))) {
my $reg = Parse::Win32Registry->new($ntuser); my $reg = Parse::Win32Registry->new($ntuser);
my $root_key = $reg->get_root_key; my $root_key = $reg->get_root_key;
my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs"; my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs";
@ -50,7 +51,7 @@ sub pluginmain {
#::rptMsg("**All values printed in MRUList\\MRUListEx order."); #::rptMsg("**All values printed in MRUList\\MRUListEx order.");
#::rptMsg($key_path); #::rptMsg($key_path);
::rptMsg("<recentdocs><mtime>".gmtime($key->get_timestamp())."</mtime><artifacts>"); ::rptMsg("<recentdocs><mtime>".gmtime($key->get_timestamp())."</mtime><artifacts>");
# Get RecentDocs values # Get RecentDocs values
my %rdvals = getRDValues($key); my %rdvals = getRDValues($key);
if (%rdvals) { if (%rdvals) {
my $tag; my $tag;
@ -75,7 +76,7 @@ sub pluginmain {
#::logMsg("Error: ".$key_path." has no values."); #::logMsg("Error: ".$key_path." has no values.");
} }
::rptMsg("</artifacts></recentdocs>"); ::rptMsg("</artifacts></recentdocs>");
# Get RecentDocs subkeys' values # Get RecentDocs subkeys' values
my @subkeys = $key->get_list_of_subkeys(); my @subkeys = $key->get_list_of_subkeys();
if (scalar(@subkeys) > 0) { if (scalar(@subkeys) > 0) {
foreach my $s (@subkeys) { foreach my $s (@subkeys) {
@ -115,6 +116,7 @@ sub pluginmain {
else { else {
#::rptMsg($key_path." not found."); #::rptMsg($key_path." not found.");
} }
}
} }

View File

@ -41,7 +41,9 @@ sub pluginmain {
my $class = shift; my $class = shift;
my $hive = shift; my $hive = shift;
#::logMsg("Launching shellfolders v.".$VERSION); #::logMsg("Launching shellfolders v.".$VERSION);
if (defined(Parse::Win32Registry->new($hive))) {
my $reg = Parse::Win32Registry->new($hive); my $reg = Parse::Win32Registry->new($hive);
my $root_key = $reg->get_root_key; my $root_key = $reg->get_root_key;
my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; my $key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
@ -68,5 +70,6 @@ sub pluginmain {
#::rptMsg($key_path." not found."); #::rptMsg($key_path." not found.");
#::logMsg($key_path." not found."); #::logMsg($key_path." not found.");
} }
}
} }
1; 1;

View File

@ -37,10 +37,11 @@ sub pluginmain {
# ::rptMsg("officedocs v.".$VERSION); # 20110830 [fpi] + banner # ::rptMsg("officedocs v.".$VERSION); # 20110830 [fpi] + banner
# ::rptMsg("(".getHive().") ".getShortDescr()."\n"); # 20110830 [fpi] + banner # ::rptMsg("(".getHive().") ".getShortDescr()."\n"); # 20110830 [fpi] + banner
::rptMsg("<office>"); ::rptMsg("<office>");
if (defined(Parse::Win32Registry->new($ntuser))) {
my $reg = Parse::Win32Registry->new($ntuser); my $reg = Parse::Win32Registry->new($ntuser);
my $root_key = $reg->get_root_key; my $root_key = $reg->get_root_key;
#::rptMsg("officedocs v.".$VERSION); #::rptMsg("officedocs v.".$VERSION);
# First, let's find out which version of Office is installed # First, let's find out which version of Office is installed
my $version; my $version;
my $tag = 0; my $tag = 0;
my @versions = ("7\.0","8\.0", "9\.0", "10\.0", "11\.0","12\.0"); my @versions = ("7\.0","8\.0", "9\.0", "10\.0", "11\.0","12\.0");
@ -59,7 +60,7 @@ sub pluginmain {
::rptMsg("<mtime> ".gmtime($of_key->get_timestamp())."</mtime>"); ::rptMsg("<mtime> ".gmtime($of_key->get_timestamp())."</mtime>");
::rptMsg("<artifacts>"); ::rptMsg("<artifacts>");
if ($of_key) { if ($of_key) {
# Attempt to retrieve Word docs # Attempt to retrieve Word docs
my @funcs = ("Open","Save As","File Save"); my @funcs = ("Open","Save As","File Save");
foreach my $func (@funcs) { foreach my $func (@funcs) {
my $word = "Common\\Open Find\\Microsoft Office Word\\Settings\\".$func."\\File Name MRU"; my $word = "Common\\Open Find\\Microsoft Office Word\\Settings\\".$func."\\File Name MRU";
@ -74,11 +75,11 @@ sub pluginmain {
#map{::rptMsg("$_");}@data; #map{::rptMsg("$_");}@data;
} }
else { else {
# ::rptMsg("Could not access ".$word); # ::rptMsg("Could not access ".$word);
} }
#::rptMsg(""); #::rptMsg("");
} }
# Attempt to retrieve Excel docs # Attempt to retrieve Excel docs
my $excel = 'Excel\\Recent Files'; my $excel = 'Excel\\Recent Files';
if (my $excel_key = $of_key->get_subkey($excel)) { if (my $excel_key = $of_key->get_subkey($excel)) {
#::rptMsg($key_path."\\".$excel); #::rptMsg($key_path."\\".$excel);
@ -86,14 +87,14 @@ sub pluginmain {
my @vals = $excel_key->get_list_of_values(); my @vals = $excel_key->get_list_of_values();
if (scalar(@vals) > 0) { if (scalar(@vals) > 0) {
my %files; my %files;
# Retrieve values and load into a hash for sorting # Retrieve values and load into a hash for sorting
foreach my $v (@vals) { foreach my $v (@vals) {
my $val = $v->get_name(); my $val = $v->get_name();
my $data = $v->get_data(); my $data = $v->get_data();
my $tag = (split(/File/,$val))[1]; my $tag = (split(/File/,$val))[1];
$files{$tag} = $val.":".$data; $files{$tag} = $val.":".$data;
} }
# Print sorted content to report file # Print sorted content to report file
foreach my $u (sort {$a <=> $b} keys %files) { foreach my $u (sort {$a <=> $b} keys %files) {
my ($val,$data) = split(/:/,$files{$u},2); my ($val,$data) = split(/:/,$files{$u},2);
::rptMsg("<Excel name=\"".$val."\">".$data . "</Excel>"); ::rptMsg("<Excel name=\"".$val."\">".$data . "</Excel>");
@ -107,7 +108,7 @@ sub pluginmain {
#::rptMsg($key_path.$excel." not found."); #::rptMsg($key_path.$excel." not found.");
} }
#::rptMsg(""); #::rptMsg("");
# Attempt to retrieve PowerPoint docs # Attempt to retrieve PowerPoint docs
my $ppt = 'PowerPoint\\Recent File List'; my $ppt = 'PowerPoint\\Recent File List';
if (my $ppt_key = $of_key->get_subkey($ppt)) { if (my $ppt_key = $of_key->get_subkey($ppt)) {
#::rptMsg($key_path."\\".$ppt); #::rptMsg($key_path."\\".$ppt);
@ -115,14 +116,14 @@ sub pluginmain {
my @vals = $ppt_key->get_list_of_values(); my @vals = $ppt_key->get_list_of_values();
if (scalar(@vals) > 0) { if (scalar(@vals) > 0) {
my %files; my %files;
# Retrieve values and load into a hash for sorting # Retrieve values and load into a hash for sorting
foreach my $v (@vals) { foreach my $v (@vals) {
my $val = $v->get_name(); my $val = $v->get_name();
my $data = $v->get_data(); my $data = $v->get_data();
my $tag = (split(/File/,$val))[1]; my $tag = (split(/File/,$val))[1];
$files{$tag} = $val.":".$data; $files{$tag} = $val.":".$data;
} }
# Print sorted content to report file # Print sorted content to report file
foreach my $u (sort {$a <=> $b} keys %files) { foreach my $u (sort {$a <=> $b} keys %files) {
my ($val,$data) = split(/:/,$files{$u},2); my ($val,$data) = split(/:/,$files{$u},2);
::rptMsg("<PowerPoint name=\"".$val."\">".$data . "</PowerPoint>"); ::rptMsg("<PowerPoint name=\"".$val."\">".$data . "</PowerPoint>");
@ -146,6 +147,7 @@ sub pluginmain {
#::logMsg("MSOffice version not found."); #::logMsg("MSOffice version not found.");
#::rptMsg("MSOffice version not found."); #::rptMsg("MSOffice version not found.");
} }
}
::rptMsg("</office>"); ::rptMsg("</office>");
} }

View File

@ -72,7 +72,7 @@ sub pluginmain {
#::logMsg("Launching officedocs2010 v.".$VERSION); #::logMsg("Launching officedocs2010 v.".$VERSION);
#::rptMsg("officedocs2010 v.".$VERSION); # 20110830 [fpi] + banner #::rptMsg("officedocs2010 v.".$VERSION); # 20110830 [fpi] + banner
#::rptMsg("(".getHive().") ".getShortDescr()."\n"); # 20110830 [fpi] + banner #::rptMsg("(".getHive().") ".getShortDescr()."\n"); # 20110830 [fpi] + banner
if (defined(Parse::Win32Registry->new($ntuser))) {
my $reg = Parse::Win32Registry->new($ntuser); my $reg = Parse::Win32Registry->new($ntuser);
my $root_key = $reg->get_root_key; my $root_key = $reg->get_root_key;
# ::rptMsg("officedocs v.".$VERSION); # 20110830 [fpi] - redundant # ::rptMsg("officedocs v.".$VERSION); # 20110830 [fpi] - redundant
@ -87,7 +87,7 @@ sub pluginmain {
my $key_path = "Software\\Microsoft\\Office\\14.0"; my $key_path = "Software\\Microsoft\\Office\\14.0";
my $of_key = $root_key->get_subkey($key_path); my $of_key = $root_key->get_subkey($key_path);
if ($of_key) { if ($of_key) {
# Attempt to retrieve Word docs # Attempt to retrieve Word docs
my $word = 'Word\\File MRU'; my $word = 'Word\\File MRU';
if (my $word_key = $of_key->get_subkey($word)) { if (my $word_key = $of_key->get_subkey($word)) {
#::rptMsg($key_path."\\".$word); #::rptMsg($key_path."\\".$word);
@ -95,7 +95,7 @@ sub pluginmain {
my @vals = $word_key->get_list_of_values(); my @vals = $word_key->get_list_of_values();
if (scalar(@vals) > 0) { if (scalar(@vals) > 0) {
my %files; my %files;
# Retrieve values and load into a hash for sorting # Retrieve values and load into a hash for sorting
foreach my $v (@vals) { foreach my $v (@vals) {
my $val = $v->get_name(); my $val = $v->get_name();
if ($val eq "Max Display") { next; } if ($val eq "Max Display") { next; }
@ -103,7 +103,7 @@ sub pluginmain {
my $tag = (split(/Item/,$val))[1]; my $tag = (split(/Item/,$val))[1];
$files{$tag} = $val.":".$data; $files{$tag} = $val.":".$data;
} }
# Print sorted content to report file # Print sorted content to report file
foreach my $u (sort {$a <=> $b} keys %files) { foreach my $u (sort {$a <=> $b} keys %files) {
my ($val,$data) = split(/:/,$files{$u},2); my ($val,$data) = split(/:/,$files{$u},2);
::rptMsg("<Word name=\"".$val."\">".$data . "</Word>"); ::rptMsg("<Word name=\"".$val."\">".$data . "</Word>");
@ -117,7 +117,7 @@ sub pluginmain {
#::rptMsg($key_path.$word." not found."); #::rptMsg($key_path.$word." not found.");
} }
#::rptMsg(""); #::rptMsg("");
# Attempt to retrieve Excel docs # Attempt to retrieve Excel docs
my $excel = 'Excel\\File MRU'; my $excel = 'Excel\\File MRU';
if (my $excel_key = $of_key->get_subkey($excel)) { if (my $excel_key = $of_key->get_subkey($excel)) {
#::rptMsg($key_path."\\".$excel); #::rptMsg($key_path."\\".$excel);
@ -125,7 +125,7 @@ sub pluginmain {
my @vals = $excel_key->get_list_of_values(); my @vals = $excel_key->get_list_of_values();
if (scalar(@vals) > 0) { if (scalar(@vals) > 0) {
my %files; my %files;
# Retrieve values and load into a hash for sorting # Retrieve values and load into a hash for sorting
foreach my $v (@vals) { foreach my $v (@vals) {
my $val = $v->get_name(); my $val = $v->get_name();
if ($val eq "Max Display") { next; } if ($val eq "Max Display") { next; }
@ -133,7 +133,7 @@ sub pluginmain {
my $tag = (split(/Item/,$val))[1]; my $tag = (split(/Item/,$val))[1];
$files{$tag} = $val.":".$data; $files{$tag} = $val.":".$data;
} }
# Print sorted content to report file # Print sorted content to report file
foreach my $u (sort {$a <=> $b} keys %files) { foreach my $u (sort {$a <=> $b} keys %files) {
my ($val,$data) = split(/:/,$files{$u},2); my ($val,$data) = split(/:/,$files{$u},2);
::rptMsg("<Excel name=\"".$val."\">".$data . "</Excel>"); ::rptMsg("<Excel name=\"".$val."\">".$data . "</Excel>");
@ -147,7 +147,7 @@ sub pluginmain {
#::rptMsg($key_path.$excel." not found."); #::rptMsg($key_path.$excel." not found.");
} }
#::rptMsg(""); #::rptMsg("");
# Attempt to retrieve Access docs # Attempt to retrieve Access docs
my $access = 'Access\\File MRU'; my $access = 'Access\\File MRU';
if (my $access_key = $of_key->get_subkey($access)) { if (my $access_key = $of_key->get_subkey($access)) {
#::rptMsg($key_path."\\".$access); #::rptMsg($key_path."\\".$access);
@ -155,7 +155,7 @@ sub pluginmain {
my @vals = $access_key->get_list_of_values(); my @vals = $access_key->get_list_of_values();
if (scalar(@vals) > 0) { if (scalar(@vals) > 0) {
my %files; my %files;
# Retrieve values and load into a hash for sorting # Retrieve values and load into a hash for sorting
foreach my $v (@vals) { foreach my $v (@vals) {
my $val = $v->get_name(); my $val = $v->get_name();
if ($val eq "Max Display") { next; } if ($val eq "Max Display") { next; }
@ -163,7 +163,7 @@ sub pluginmain {
my $tag = (split(/Item/,$val))[1]; my $tag = (split(/Item/,$val))[1];
$files{$tag} = $val.":".$data; $files{$tag} = $val.":".$data;
} }
# Print sorted content to report file # Print sorted content to report file
foreach my $u (sort {$a <=> $b} keys %files) { foreach my $u (sort {$a <=> $b} keys %files) {
my ($val,$data) = split(/:/,$files{$u},2); my ($val,$data) = split(/:/,$files{$u},2);
::rptMsg("<Access name=\"".$val."\">".$data . "</Access>"); ::rptMsg("<Access name=\"".$val."\">".$data . "</Access>");
@ -177,7 +177,7 @@ sub pluginmain {
# ::rptMsg($key_path.$access." not found."); # ::rptMsg($key_path.$access." not found.");
} }
#::rptMsg(""); #::rptMsg("");
# Attempt to retrieve PowerPoint docs # Attempt to retrieve PowerPoint docs
my $ppt = 'PowerPoint\\File MRU'; my $ppt = 'PowerPoint\\File MRU';
if (my $ppt_key = $of_key->get_subkey($ppt)) { if (my $ppt_key = $of_key->get_subkey($ppt)) {
#::rptMsg($key_path."\\".$ppt); #::rptMsg($key_path."\\".$ppt);
@ -185,7 +185,7 @@ sub pluginmain {
my @vals = $ppt_key->get_list_of_values(); my @vals = $ppt_key->get_list_of_values();
if (scalar(@vals) > 0) { if (scalar(@vals) > 0) {
my %files; my %files;
# Retrieve values and load into a hash for sorting # Retrieve values and load into a hash for sorting
foreach my $v (@vals) { foreach my $v (@vals) {
my $val = $v->get_name(); my $val = $v->get_name();
if ($val eq "Max Display") { next; } if ($val eq "Max Display") { next; }
@ -193,7 +193,7 @@ sub pluginmain {
my $tag = (split(/Item/,$val))[1]; my $tag = (split(/Item/,$val))[1];
$files{$tag} = $val.":".$data; $files{$tag} = $val.":".$data;
} }
# Print sorted content to report file # Print sorted content to report file
foreach my $u (sort {$a <=> $b} keys %files) { foreach my $u (sort {$a <=> $b} keys %files) {
my ($val,$data) = split(/:/,$files{$u},2); my ($val,$data) = split(/:/,$files{$u},2);
::rptMsg("<PowerPoint name=\"".$val."\">".$data . "</PowerPoint>"); ::rptMsg("<PowerPoint name=\"".$val."\">".$data . "</PowerPoint>");
@ -216,6 +216,7 @@ sub pluginmain {
# ::logMsg("MSOffice version not found."); # ::logMsg("MSOffice version not found.");
# ::rptMsg("MSOffice version not found."); # ::rptMsg("MSOffice version not found.");
} }
}
} }
1; 1;