From 6156016bf5798d04acab6e1dbbb95a7f226913b0 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 25 May 2021 08:52:22 -0400 Subject: [PATCH 01/70] annotations styling updates --- .../AnnotationsContentViewer.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java index 5d109438c3..304300cec4 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.contentviewers; +import java.awt.Color; import java.awt.Component; import java.util.concurrent.ExecutionException; import java.util.logging.Level; @@ -49,13 +50,15 @@ import org.jsoup.nodes.Document; }) public class AnnotationsContentViewer extends javax.swing.JPanel implements DataContentViewer { + private static final String DEFAULT_FONT_FAMILY = new JLabel().getFont().getFamily(); private static final int DEFAULT_FONT_SIZE = new JLabel().getFont().getSize(); + private static final Color DEFAULT_BACKGROUND = new JLabel().getBackground(); // how big the subheader should be - private static final int SUBHEADER_FONT_SIZE = DEFAULT_FONT_SIZE * 12 / 11; + private static final int SUBHEADER_FONT_SIZE = DEFAULT_FONT_SIZE + 1; // how big the header should be - private static final int HEADER_FONT_SIZE = DEFAULT_FONT_SIZE * 14 / 11; + private static final int HEADER_FONT_SIZE = DEFAULT_FONT_SIZE + 2; // the subsection indent private static final int DEFAULT_SUBSECTION_LEFT_PAD = DEFAULT_FONT_SIZE; @@ -67,12 +70,16 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data // additional styling for components private static final String STYLE_SHEET_RULE - = String.format(" .%s { font-size: %dpx;font-style:italic; margin: 0px; padding: 0px; } ", Annotations.MESSAGE_CLASSNAME, DEFAULT_FONT_SIZE) - + String.format(" .%s {font-size:%dpx;font-weight:bold; margin: 0px; margin-top: %dpx; padding: 0px; } ", - Annotations.SUBHEADER_CLASSNAME, SUBHEADER_FONT_SIZE, DEFAULT_SUBSECTION_SPACING) - + String.format(" .%s { font-size:%dpx;font-weight:bold; margin: 0px; padding: 0px; } ", Annotations.HEADER_CLASSNAME, HEADER_FONT_SIZE) - + String.format(" td { vertical-align: top; font-size:%dpx; text-align: left; margin: 0px; padding: 0px %dpx 0px 0px;} ", DEFAULT_FONT_SIZE, CELL_SPACING) - + String.format(" th { vertical-align: top; text-align: left; margin: 0px; padding: 0px %dpx 0px 0px} ", DEFAULT_FONT_SIZE, CELL_SPACING) + = String.format(" .%s { font-family: %s; font-size: %dpt; font-style:italic; margin: 0px; padding: 0px; } ", + Annotations.MESSAGE_CLASSNAME, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE) + + String.format(" .%s { font-family: %s; font-size:%dpt;font-weight:bold; margin: 0px; margin-top: %dpx; padding: 0px; } ", + Annotations.SUBHEADER_CLASSNAME, DEFAULT_FONT_FAMILY, SUBHEADER_FONT_SIZE, DEFAULT_SUBSECTION_SPACING) + + String.format(" .%s { font-family: %s; font-size:%dpt;font-weight:bold; margin: 0px; padding: 0px; } ", + Annotations.HEADER_CLASSNAME, DEFAULT_FONT_FAMILY, HEADER_FONT_SIZE) + + String.format(" td { vertical-align: top; font-family: %s; font-size:%dpt; text-align: left; margin: 0px; padding: 0px %dpx 0px 0px;} ", + DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, CELL_SPACING) + + String.format(" th { vertical-align: top; text-align: left; margin: 0px; padding: 0px %dpx 0px 0px} ", + DEFAULT_FONT_SIZE, CELL_SPACING) + String.format(" .%s { margin: %dpx 0px; padding-left: %dpx; } ", Annotations.SUBSECTION_CLASSNAME, DEFAULT_SUBSECTION_SPACING, DEFAULT_SUBSECTION_LEFT_PAD) + String.format(" .%s { margin-bottom: %dpx; } ", Annotations.SECTION_CLASSNAME, DEFAULT_SECTION_SPACING); @@ -87,6 +94,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data public AnnotationsContentViewer() { initComponents(); Utilities.configureTextPaneAsHtml(textPanel); + textPanel.setBackground(DEFAULT_BACKGROUND); // get html editor kit and apply additional style rules EditorKit editorKit = textPanel.getEditorKit(); if (editorKit instanceof HTMLEditorKit) { From a14da8b04bb79eab19d1ff513ecaac196ab3898a Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Wed, 26 May 2021 13:29:57 -0400 Subject: [PATCH 02/70] Make listeners in ChildFactory.Detachable weak --- .../autopsy/datamodel/Artifacts.java | 77 ++++++++------- .../datamodel/AutopsyTreeChildFactory.java | 19 ++-- .../autopsy/datamodel/BaseChildFactory.java | 5 +- .../datamodel/DataSourcesByTypeNode.java | 13 ++- .../autopsy/datamodel/EmailExtracted.java | 23 +++-- .../autopsy/datamodel/HashsetHits.java | 23 +++-- .../sleuthkit/autopsy/datamodel/HostNode.java | 33 ++++--- .../autopsy/datamodel/InterestingHits.java | 25 ++--- .../autopsy/datamodel/KeywordHits.java | 8 +- .../autopsy/datamodel/OsAccounts.java | 16 ++-- .../autopsy/datamodel/PersonGroupingNode.java | 13 ++- .../org/sleuthkit/autopsy/datamodel/Tags.java | 21 ++-- .../autopsy/datamodel/accounts/Accounts.java | 95 +++++++++---------- 13 files changed, 196 insertions(+), 175 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Artifacts.java b/Core/src/org/sleuthkit/autopsy/datamodel/Artifacts.java index d39bef3ee9..6e207b9458 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Artifacts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Artifacts.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2020 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.lang.ref.WeakReference; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -36,6 +37,7 @@ import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.Lookup; import org.openide.util.NbBundle; +import org.openide.util.WeakListeners; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -276,6 +278,8 @@ public class Artifacts { */ private final RefreshThrottler refreshThrottler = new RefreshThrottler(this); private final Category category; + + private final PropertyChangeListener weakPcl; /** * Main constructor. @@ -289,45 +293,46 @@ public class Artifacts { super(); this.filteringDSObjId = filteringDSObjId; this.category = category; - } - - private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { - String eventType = evt.getPropertyName(); - 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(); - } - } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) - || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.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(); - refresh(false); - } catch (NoCurrentCaseException notUsed) { + + PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { + String eventType = evt.getPropertyName(); + 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(); + } + } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) + || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) { /** - * Case is closed, do nothing. + * 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(); + refresh(false); + } catch (NoCurrentCaseException notUsed) { + /** + * Case is closed, do nothing. + */ + } } - } - }; + }; - @Override - protected void addNotify() { + weakPcl = WeakListeners.propertyChange(pcl, null); + refreshThrottler.registerForIngestModuleEvents(); - IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); - Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); } @Override - protected void removeNotify() { + protected void finalize() throws Throwable { + super.finalize(); refreshThrottler.unregisterEventListener(); - IngestManager.getInstance().removeIngestJobEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); typeNodeMap.clear(); } @@ -623,17 +628,21 @@ public class Artifacts { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); @Override protected void onAdd() { refreshThrottler.registerForIngestModuleEvents(); - IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); } @Override protected void onRemove() { - refreshThrottler.unregisterEventListener(); - IngestManager.getInstance().removeIngestJobEventListener(pcl); + if(refreshThrottler != null) { + refreshThrottler.unregisterEventListener(); + } + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java index 845591e261..5b9302d357 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2018 Basis Technology Corp. + * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,6 +31,7 @@ import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.openide.nodes.ChildFactory; import org.openide.nodes.Node; +import org.openide.util.WeakListeners; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -75,17 +76,17 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable extends ChildFactory.D isPageSizeChangeEvent = false; this.filter = filter; } - + @Override protected void addNotify() { onAdd(); } @Override - protected void removeNotify() { + protected void finalize() throws Throwable { + super.finalize(); onRemove(); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesByTypeNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesByTypeNode.java index 1fab7774c7..322a18428e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesByTypeNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesByTypeNode.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; +import org.openide.util.WeakListeners; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; @@ -71,15 +72,17 @@ public class DataSourcesByTypeNode extends DisplayableItemNode { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); - @Override - protected void addNotify() { - Case.addEventTypeSubscriber(UPDATE_EVTS, pcl); + public DataSourcesByTypeChildren() { + Case.addEventTypeSubscriber(UPDATE_EVTS, weakPcl); } @Override - protected void removeNotify() { - Case.removeEventTypeSubscriber(UPDATE_EVTS, pcl); + public void finalize() throws Throwable { + super.finalize(); + Case.removeEventTypeSubscriber(UPDATE_EVTS, weakPcl); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java index 357f6ec153..8a621bf245 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2012-2020 Basis Technology Corp. + * Copyright 2012-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,6 +37,7 @@ import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; +import org.openide.util.WeakListeners; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -312,21 +313,23 @@ public class EmailExtracted implements AutopsyVisitableItem { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); - @Override - protected void addNotify() { - 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); + AccountFactory() { + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); emailResults.update(); emailResults.addObserver(this); } @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); + protected void finalize() throws Throwable{ + super.finalize(); + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); emailResults.deleteObserver(this); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java index 5906b01a78..5aa6c0b570 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2020 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,6 +39,7 @@ import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; +import org.openide.util.WeakListeners; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -277,21 +278,23 @@ public class HashsetHits implements AutopsyVisitableItem { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); - @Override - protected void addNotify() { - 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); + HashsetNameFactory() { + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); hashsetResults.update(); hashsetResults.addObserver(this); } @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); + protected void finalize() throws Throwable { + super.finalize(); + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); hashsetResults.deleteObserver(this); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java index a98bdb61dd..323536df9e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java @@ -65,18 +65,7 @@ public class HostNode extends DisplayableItemNode { private final Host host; private final Function dataSourceToNode; - - /** - * Main constructor. - * - * @param dataSourceToItem Converts a data source to a node. - * @param host The host. - */ - HostGroupingChildren(Function dataSourceToNode, Host host) { - this.host = host; - this.dataSourceToNode = dataSourceToNode; - } - + /** * Listener for handling DATA_SOURCE_ADDED / HOST_DELETED events. * A host may have been deleted as part of a merge, which means its data sources could @@ -92,15 +81,25 @@ public class HostNode extends DisplayableItemNode { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(dataSourceAddedPcl, null); - @Override - protected void addNotify() { - Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), dataSourceAddedPcl); + /** + * Main constructor. + * + * @param dataSourceToItem Converts a data source to a node. + * @param host The host. + */ + HostGroupingChildren(Function dataSourceToNode, Host host) { + this.host = host; + this.dataSourceToNode = dataSourceToNode; + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), weakPcl); } @Override - protected void removeNotify() { - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), dataSourceAddedPcl); + protected void finalize() throws Throwable { + super.finalize(); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), weakPcl); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java index 22525854ca..41b90268a2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2020 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,6 +39,7 @@ import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; +import org.openide.util.WeakListeners; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -270,21 +271,23 @@ public class InterestingHits implements AutopsyVisitableItem { } } }; - - @Override - protected void addNotify() { - 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); + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); + + SetNameFactory() { + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); interestingResults.update(); interestingResults.addObserver(this); } @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); + protected void finalize() throws Throwable { + super.finalize(); + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); interestingResults.deleteObserver(this); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index eab8a07d3a..b55fc9353a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2020 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -429,13 +429,13 @@ public class KeywordHits implements AutopsyVisitableItem { private abstract class DetachableObserverChildFactory extends ChildFactory.Detachable implements Observer { - @Override - protected void addNotify() { + DetachableObserverChildFactory() { keywordResults.addObserver(this); } @Override - protected void removeNotify() { + protected void finalize() throws Throwable { + super.finalize(); keywordResults.deleteObserver(this); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/OsAccounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/OsAccounts.java index 170251bd13..950565a5f2 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/OsAccounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/OsAccounts.java @@ -136,17 +136,19 @@ public final class OsAccounts implements AutopsyVisitableItem { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(listener, null); - @Override - protected void addNotify() { - Case.addEventTypeSubscriber(EnumSet.of(Case.Events.OS_ACCOUNT_ADDED, Case.Events.OS_ACCOUNT_REMOVED), listener); - Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), listener); + OsAccountNodeFactory () { + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.OS_ACCOUNT_ADDED, Case.Events.OS_ACCOUNT_REMOVED), weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); } @Override - protected void removeNotify() { - Case.removeEventTypeSubscriber(Collections.singleton(Case.Events.OS_ACCOUNT_ADDED), listener); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), listener); + protected void finalize() throws Throwable { + super.finalize(); + Case.removeEventTypeSubscriber(Collections.singleton(Case.Events.OS_ACCOUNT_ADDED), weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/PersonGroupingNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/PersonGroupingNode.java index 4f12779ee8..0655383c40 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/PersonGroupingNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/PersonGroupingNode.java @@ -86,6 +86,7 @@ public class PersonGroupingNode extends DisplayableItemNode { */ PersonChildren(Person person) { this.person = person; + Case.addEventTypeSubscriber(CHILD_EVENTS, weakPcl); } /** @@ -100,15 +101,13 @@ public class PersonGroupingNode extends DisplayableItemNode { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(hostAddedDeletedPcl, null); @Override - protected void addNotify() { - Case.addEventTypeSubscriber(CHILD_EVENTS, hostAddedDeletedPcl); - } - - @Override - protected void removeNotify() { - Case.removeEventTypeSubscriber(CHILD_EVENTS, hostAddedDeletedPcl); + protected void finalize() throws Throwable { + super.finalize(); + Case.removeEventTypeSubscriber(CHILD_EVENTS, weakPcl); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java index 6fa6487b5e..2816b2b2b6 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -33,6 +33,7 @@ import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; +import org.openide.util.WeakListeners; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -213,6 +214,8 @@ public class Tags implements AutopsyVisitableItem { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); /** * Constructor @@ -221,21 +224,17 @@ public class Tags implements AutopsyVisitableItem { */ TagNameNodeFactory(long objId) { this.filteringDSObjId = objId; - - } - - @Override - protected void addNotify() { - IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); - Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, weakPcl); tagResults.update(); tagResults.addObserver(this); } @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); + protected void finalize() throws Throwable { + super.finalize(); + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, weakPcl); tagResults.deleteObserver(this); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 18136db99e..1f186aae2c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -57,6 +57,7 @@ import org.openide.nodes.NodeOp; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.Utilities; +import org.openide.util.WeakListeners; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -496,6 +497,9 @@ final public class Accounts implements AutopsyVisitableItem { private DefaultAccountFactory(Account.Type accountType) { this.accountType = accountType; + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); } private final PropertyChangeListener pcl = new PropertyChangeListener() { @@ -549,21 +553,15 @@ final public class Accounts implements AutopsyVisitableItem { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); @Override - protected void addNotify() { - 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); - super.addNotify(); - } - - @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); - super.removeNotify(); + protected void finalize() throws Throwable { + super.finalize(); + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); } @Override @@ -726,6 +724,14 @@ final public class Accounts implements AutopsyVisitableItem { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); + + ViewModeFactory() { + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); + } @Subscribe @Override @@ -740,18 +746,11 @@ final public class Accounts implements AutopsyVisitableItem { } @Override - protected void addNotify() { - 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); - super.addNotify(); - } - - @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); + protected void finalize() throws Throwable { + super.finalize(); + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); super.removeNotify(); } @@ -880,21 +879,21 @@ final public class Accounts implements AutopsyVisitableItem { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); - @Override - protected void addNotify() { - 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); - super.addNotify(); + FileWithCCNFactory() { + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); } @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); - super.removeNotify(); + protected void finalize() throws Throwable { + super.finalize(); + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); } @Subscribe @@ -1094,21 +1093,21 @@ final public class Accounts implements AutopsyVisitableItem { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); - @Override - protected void addNotify() { - 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); - super.addNotify(); + BINFactory() { + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); } @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); - super.removeNotify(); + protected void finalize() throws Throwable{ + super.finalize(); + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); } @Subscribe From 8d75a118135cb060a9043151714f2e64e29ce957 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 27 May 2021 15:05:18 -0400 Subject: [PATCH 03/70] First cut --- .../autoingest/AutoIngestAdminActions.java | 48 ++++++++++ .../autoingest/AutoIngestJobNodeData.java | 39 +++++++- .../autoingest/AutoIngestJobsNode.java | 3 + .../autoingest/AutoIngestManager.java | 31 +++++- .../autoingest/AutoIngestMonitor.java | 48 +++++++++- .../autoingest/AutoIngestOcrEnabledEvent.java | 95 +++++++++++++++++++ .../autoingest/PrioritizationAction.java | 2 +- 7 files changed, 260 insertions(+), 6 deletions(-) create mode 100755 Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java index a881a96fb2..994d2f91a0 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java @@ -157,6 +157,54 @@ final class AutoIngestAdminActions { } } } + + @NbBundle.Messages({"AutoIngestAdminActions.enableOCR.title=Enable OCR For This Case", + "AutoIngestAdminActions.enableOCR.error=Failed to enable OCR for case \"%s\"."}) + static final class EnableOCR extends AbstractAction { + + private static final long serialVersionUID = 1L; + private final AutoIngestJob job; + + EnableOCR(AutoIngestJob job) { + super(Bundle.AutoIngestAdminActions_enableOCR_title()); + this.job = job; + } + + @Override + public void actionPerformed(ActionEvent e) { + + if (job == null) { + return; + } + + final AutoIngestDashboardTopComponent tc = (AutoIngestDashboardTopComponent) WindowManager.getDefault().findTopComponent(AutoIngestDashboardTopComponent.PREFERRED_ID); + if (tc == null) { + return; + } + + AutoIngestDashboard dashboard = tc.getAutoIngestDashboard(); + if (dashboard != null) { + dashboard.getPendingJobsPanel().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + EventQueue.invokeLater(() -> { + try { + dashboard.getMonitor().enableOcrForCase(job.getManifest().getCaseName()); + dashboard.getPendingJobsPanel().refresh(new AutoIngestNodeRefreshEvents.RefreshCaseEvent(dashboard.getMonitor(), job.getManifest().getCaseName())); // ELTODO + } catch (AutoIngestMonitor.AutoIngestMonitorException ex) { + String errorMessage = String.format(Bundle.AutoIngestAdminActions_enableOCR_error(), job.getManifest().getCaseName()); + logger.log(Level.SEVERE, errorMessage, ex); + MessageNotifyUtil.Message.error(errorMessage); + } finally { + dashboard.getPendingJobsPanel().setCursor(Cursor.getDefaultCursor()); + } + }); + } + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); //To change body of generated methods, choose Tools | Templates. + } + } @NbBundle.Messages({"AutoIngestAdminActions.progressDialogAction.title=Ingest Progress"}) static final class ProgressDialogAction extends AbstractAction { diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java index f367fdf553..a70e341c79 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,7 +31,7 @@ import javax.lang.model.type.TypeKind; */ final class AutoIngestJobNodeData { - private static final int CURRENT_VERSION = 2; + private static final int CURRENT_VERSION = 3; private static final int DEFAULT_PRIORITY = 0; /* @@ -47,7 +47,7 @@ final class AutoIngestJobNodeData { * data. This avoids the need to continuously enlarge the buffer. Once the * buffer has all the necessary data, it will be resized as appropriate. */ - private static final int MAX_POSSIBLE_NODE_DATA_SIZE = 131637; + private static final int MAX_POSSIBLE_NODE_DATA_SIZE = 131641; /* * Version 0 fields. @@ -78,6 +78,11 @@ final class AutoIngestJobNodeData { * Version 2 fields. */ private long dataSourceSize; + + /* + * Version 3 fields. + */ + private boolean ocrEnabled; /** * Gets the current version of the auto ingest job coordination service node @@ -115,6 +120,7 @@ final class AutoIngestJobNodeData { setProcessingStageStartDate(job.getProcessingStageStartDate()); setProcessingStageDetails(job.getProcessingStageDetails()); setDataSourceSize(job.getDataSourceSize()); + setOcrEnabled(false); // ELTODO } /** @@ -150,6 +156,7 @@ final class AutoIngestJobNodeData { this.processingStageDetailsDescription = ""; this.processingStageDetailsStartDate = 0L; this.dataSourceSize = 0L; + this.ocrEnabled = false; /* * Get fields from node data. @@ -192,6 +199,14 @@ final class AutoIngestJobNodeData { */ this.dataSourceSize = buffer.getLong(); } + + if (buffer.hasRemaining()) { + /* + * Get version 3 fields. + */ + int ocrFlag = buffer.getInt(); + this.ocrEnabled = (1 == ocrFlag); + } } catch (BufferUnderflowException ex) { throw new InvalidDataException("Node data is incomplete", ex); @@ -234,6 +249,24 @@ final class AutoIngestJobNodeData { void setPriority(int priority) { this.priority = priority; } + + /** + * Gets the OCR flag for the job. + * + * @return Flag whether OCR is enabled/disabled. + */ + boolean getOcrEnabled() { + return this.ocrEnabled; + } + + /** + * Sets the OCR enabled/disabled flag for the job. + * + * @param enabled Flag whether OCR is enabled/disabled. + */ + void setOcrEnabled(boolean enabled) { + this.ocrEnabled = enabled; + } /** * Gets the number of times the job has crashed during processing. diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index ffe8e19f01..a81e0d2157 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -364,6 +364,9 @@ final class AutoIngestJobsNode extends AbstractNode { PrioritizationAction.DeprioritizeCaseAction deprioritizeCaseAction = new PrioritizationAction.DeprioritizeCaseAction(jobWrapper.getJob()); deprioritizeCaseAction.setEnabled(jobWrapper.getPriority() > 0); actions.add(deprioritizeCaseAction); + + // ELTODO enable/disable based on current state + actions.add(new AutoIngestAdminActions.EnableOCR(jobWrapper.getJob())); break; case RUNNING_JOB: actions.add(new AutoIngestAdminActions.ProgressDialogAction(jobWrapper.getJob())); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index e3cace62fc..beaaffffb0 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -470,6 +470,34 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen setChanged(); notifyObservers(Event.CASE_PRIORITIZED); } + + /** + * Processes a case OCR enabled/disabled event from another node. + * + * @param event OCR enabled/disabled event from another auto ingest node. + */ + private void handleRemoteOcrEvent(AutoIngestOcrEnabledEvent event) { + // ELTODO + switch (event.getEventType()) { + case OCR_ENABLED: + sysLogger.log(Level.INFO, "Received OCR enabled event for case {0} from user {1} on machine {2}", + new Object[]{event.getCaseName(), event.getUserName(), event.getNodeName()}); + break; + case OCR_DISABLED: + sysLogger.log(Level.INFO, "Received OCR disabled event for case {0} from user {1} on machine {2}", + new Object[]{event.getCaseName(), event.getUserName(), event.getNodeName()}); + break; + default: + sysLogger.log(Level.WARNING, "Received invalid OCR enabled/disabled event from user {0} on machine {1}", + new Object[]{event.getUserName(), event.getNodeName()}); + break; + } + + String hostName = event.getNodeName(); + hostNamesToLastMsgTime.put(hostName, Instant.now()); + setChanged(); + notifyObservers(Event.OCR_STATE_CHANGE); // ELTODO + } /** * Processes a case deletion event from another node by triggering an @@ -3150,7 +3178,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen REPORT_STATE, CANCEL_JOB, REPROCESS_JOB, - GENERATE_THREAD_DUMP_RESPONSE + GENERATE_THREAD_DUMP_RESPONSE, + OCR_STATE_CHANGE } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java index fbca3f50ee..23ac9b6b6f 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java @@ -84,7 +84,8 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen AutoIngestManager.Event.SHUTTING_DOWN.toString(), AutoIngestManager.Event.SHUTDOWN.toString(), AutoIngestManager.Event.RESUMED.toString(), - AutoIngestManager.Event.GENERATE_THREAD_DUMP_RESPONSE.toString()})); + AutoIngestManager.Event.GENERATE_THREAD_DUMP_RESPONSE.toString(), + AutoIngestManager.Event.OCR_STATE_CHANGE.toString()})); private final AutopsyEventPublisher eventPublisher; private CoordinationService coordinationService; private final ScheduledThreadPoolExecutor coordSvcQueryExecutor; @@ -427,6 +428,51 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen return new JobsSnapshot(); } } + + /** + * Enables OCR for all pending ingest jobs for a specified case. + * + * @param caseName The name of the case to enable OCR. + * + * @throws AutoIngestMonitorException If there is an error enabling OCR for the jobs for the case. + * + */ + void enableOcrForCase(final String caseName) throws AutoIngestMonitorException { + List jobsToPrioritize = new ArrayList<>(); + synchronized (jobsLock) { + for (AutoIngestJob pendingJob : getPendingJobs()) { + if (pendingJob.getManifest().getCaseName().equals(caseName)) { + jobsToPrioritize.add(pendingJob); + } + } + if (!jobsToPrioritize.isEmpty()) { + for (AutoIngestJob job : jobsToPrioritize) { + String manifestNodePath = job.getManifest().getFilePath().toString(); + try { + AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath)); + nodeData.setOcrEnabled(true); + coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath, nodeData.toArray()); + } catch (AutoIngestJobNodeData.InvalidDataException | CoordinationServiceException | InterruptedException ex) { + throw new AutoIngestMonitorException("Error enabling OCR for job " + job.toString(), ex); + } + job.enableOcr(true); // ELTODO + + /** + * Update job object in pending jobs queue + */ + jobsSnapshot.addOrReplacePendingJob(job); + } + + /* + * Publish the OCR enabled event. + */ + new Thread(() -> { + eventPublisher.publishRemotely(new AutoIngestOcrEnabledEvent(LOCAL_HOST_NAME, caseName, + AutoIngestManager.getSystemUserNameProperty(), AutoIngestOcrEnabledEvent.EventType.OCR_ENABLED)); + }).start(); + } + } + } /** * Removes the priority (set to zero) of all pending ingest jobs for a diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java new file mode 100755 index 0000000000..1489112ade --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java @@ -0,0 +1,95 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.experimental.autoingest; + +import java.io.Serializable; +import org.sleuthkit.autopsy.events.AutopsyEvent; + +/** + * Event published when an automated ingest manager enables or disables OCR on a case. + */ +public final class AutoIngestOcrEnabledEvent extends AutopsyEvent implements Serializable { + + /** + * Possible event types + */ + enum EventType { + OCR_ENABLED, + OCR_DISABLED + } + + private static final long serialVersionUID = 1L; + private final String caseName; + private final String nodeName; + private final String userName; + private final EventType eventType; + + /** + * Constructs an event published when an automated ingest manager + * enables or disables OCR on a case. + * + * @param caseName The name of the case. + * @param nodeName The host name of the node that enabled/disabled OCR. + * @param userName The logged in user + * @param eventType The type of OCR enabled/disabled event + */ + public AutoIngestOcrEnabledEvent(String nodeName, String caseName, String userName, EventType eventType) { + super(AutoIngestManager.Event.CASE_PRIORITIZED.toString(), null, null); + this.caseName = caseName; + this.nodeName = nodeName; + this.userName = userName; + this.eventType = eventType; + } + + /** + * Gets the name of the prioritized case. + * + * @return The case name. + */ + public String getCaseName() { + return caseName; + } + + /** + * Gets the host name of the node that prioritized the case. + * + * @return The host name of the node. + */ + public String getNodeName() { + return nodeName; + } + + /** + * Gets the user logged in to the node that prioritized the case. + * + * @return The user name + */ + String getUserName() { + return userName; + } + + /** + * Gets the type of prioritization + * + * @return The type + */ + EventType getEventType() { + return eventType; + } +} diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/PrioritizationAction.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/PrioritizationAction.java index 006dc3e580..97ad2cee63 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/PrioritizationAction.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/PrioritizationAction.java @@ -193,7 +193,7 @@ abstract class PrioritizationAction extends AbstractAction { * AutoIngestJob is a part of. */ @Messages({"PrioritizationAction.prioritizeCaseAction.title=Prioritize Case", - "PrioritizationAction.prioritizeCaseAction.error==Failed to prioritize case \"%s\"."}) + "PrioritizationAction.prioritizeCaseAction.error=Failed to prioritize case \"%s\"."}) static final class PrioritizeCaseAction extends PrioritizationAction { private static final long serialVersionUID = 1L; From f43d18a7b630d27b56b2f3bc3243f38491f02a5d Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 28 May 2021 15:00:35 -0400 Subject: [PATCH 04/70] Added some UI components --- .../autoingest/AutoIngestControlPanel.java | 26 +++++-- .../autoingest/AutoIngestJob.java | 32 ++++++++- .../autoingest/AutoIngestJobNodeData.java | 2 +- .../autoingest/AutoIngestJobsNode.java | 3 +- .../autoingest/AutoIngestJobsPanel.java | 3 +- .../autoingest/AutoIngestMonitor.java | 4 +- .../autoingest/AutoIngestOcrEnabledEvent.java | 2 +- .../autoingest/Bundle.properties-MERGED | 8 ++- .../autoingest/OcrIconCellRenderer.java | 72 +++++++++++++++++++ 9 files changed, 138 insertions(+), 14 deletions(-) create mode 100755 Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/OcrIconCellRenderer.java diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java index 0e25ca655f..bdc32a4d40 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2015-2018 Basis Technology Corp. + * Copyright 2015-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -179,7 +179,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { "AutoIngestControlPanel.JobsTableModel.ColumnHeader.Status=Status", "AutoIngestControlPanel.JobsTableModel.ColumnHeader.CaseFolder=Case Folder", "AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob= Local Job?", - "AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath= Manifest File Path" + "AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath= Manifest File Path", + "AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR=OCR Enabled" }) private enum JobsTableModelColumns { @@ -195,7 +196,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { CASE_DIRECTORY_PATH(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.CaseFolder")), IS_LOCAL_JOB(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob")), MANIFEST_FILE_PATH(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath")), - PRIORITY(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.Priority")); + PRIORITY(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.Priority")), + OCR(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR")); private final String header; private JobsTableModelColumns(String header) { @@ -219,7 +221,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { CASE_DIRECTORY_PATH.getColumnHeader(), IS_LOCAL_JOB.getColumnHeader(), MANIFEST_FILE_PATH.getColumnHeader(), - PRIORITY.getColumnHeader()}; + PRIORITY.getColumnHeader(), + OCR.getColumnHeader()}; } /** @@ -406,6 +409,13 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { column.setMaxWidth(PRIORITY_COLUMN_MAX_WIDTH); column.setPreferredWidth(PRIORITY_COLUMN_PREFERRED_WIDTH); column.setWidth(PRIORITY_COLUMN_PREFERRED_WIDTH); + + // ELTODO + column = pendingTable.getColumn(JobsTableModelColumns.OCR.getColumnHeader()); + column.setCellRenderer(new OcrIconCellRenderer()); + column.setMaxWidth(PRIORITY_COLUMN_MAX_WIDTH);// ELTODO + column.setPreferredWidth(PRIORITY_COLUMN_PREFERRED_WIDTH);// ELTODO + column.setWidth(PRIORITY_COLUMN_PREFERRED_WIDTH);// ELTODO /** * Allow sorting when a column header is clicked. @@ -457,6 +467,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.IS_LOCAL_JOB.getColumnHeader())); runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader())); runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.PRIORITY.getColumnHeader())); + runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.OCR.getColumnHeader())); + /* * Set up a column to display the cases associated with the jobs. */ @@ -553,6 +565,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.PRIORITY.getColumnHeader())); + completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.OCR.getColumnHeader())); // ELTODO ? + /* * Set up a column to display the cases associated with the jobs. */ @@ -882,6 +896,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { }); break; case CASE_PRIORITIZED: + case OCR_STATE_CHANGE: updateExecutor.submit(new UpdatePendingJobsTableTask()); break; case JOB_STATUS_UPDATED: @@ -1193,7 +1208,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH job.getProcessingHostName().equals(LOCAL_HOST_NAME), // IS_LOCAL_JOB job.getManifest().getFilePath(), // MANIFEST_FILE_PATH - job.getPriority()}); // PRIORITY + job.getPriority(), // PRIORITY + job.getOcrEnabled()}); // OCR FLAG } } catch (Exception ex) { sysLogger.log(Level.SEVERE, "Dashboard error refreshing table", ex); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJob.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJob.java index 68487d0fcb..a1ce23b917 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJob.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJob.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -46,7 +46,7 @@ import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotProvider; final class AutoIngestJob implements Comparable, IngestProgressSnapshotProvider, Serializable { private static final long serialVersionUID = 1L; - private static final int CURRENT_VERSION = 3; + private static final int CURRENT_VERSION = 4; private static final int DEFAULT_PRIORITY = 0; private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName(); @@ -100,6 +100,11 @@ final class AutoIngestJob implements Comparable, IngestProgressSn private List ingestThreadsSnapshot; private List ingestJobsSnapshot; private Map moduleRunTimesSnapshot; + + /* + * Version 4 fields. + */ + private boolean ocrEnabled; /** * Constructs a new automated ingest job. All job state not specified in the @@ -194,6 +199,11 @@ final class AutoIngestJob implements Comparable, IngestProgressSn this.ingestJobsSnapshot = Collections.emptyList(); this.moduleRunTimesSnapshot = Collections.emptyMap(); + /* + * Version 4 fields + */ + this.ocrEnabled = nodeData.getOcrEnabled(); + } catch (Exception ex) { throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex); } @@ -253,6 +263,24 @@ final class AutoIngestJob implements Comparable, IngestProgressSn synchronized Integer getPriority() { return this.priority; } + + /** + * Gets the OCR flag for the job. + * + * @return Flag whether OCR is enabled/disabled. + */ + synchronized boolean getOcrEnabled() { + return this.ocrEnabled; + } + + /** + * Sets the OCR enabled/disabled flag for the job. + * + * @param enabled Flag whether OCR is enabled/disabled. + */ + synchronized void setOcrEnabled(boolean enabled) { + this.ocrEnabled = enabled; + } /** * Sets the processing stage of the job. The start date/time for the stage diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java index a70e341c79..7078cda1d7 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java @@ -120,7 +120,7 @@ final class AutoIngestJobNodeData { setProcessingStageStartDate(job.getProcessingStageStartDate()); setProcessingStageDetails(job.getProcessingStageDetails()); setDataSourceSize(job.getDataSourceSize()); - setOcrEnabled(false); // ELTODO + setOcrEnabled(job.getOcrEnabled()); } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index a81e0d2157..5fd6eb2a6e 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -57,7 +57,8 @@ final class AutoIngestJobsNode extends AbstractNode { "AutoIngestJobsNode.jobCreated.text=Job Created", "AutoIngestJobsNode.jobCompleted.text=Job Completed", "AutoIngestJobsNode.priority.text=Prioritized", - "AutoIngestJobsNode.status.text=Status" + "AutoIngestJobsNode.status.text=Status", + "AutoIngestJobsNode.ocr.text=OCR Enabled" }) /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java index 6962057541..0488e1b309 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java @@ -81,7 +81,8 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa case PENDING_JOB: outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_jobCreated_text(), Bundle.AutoIngestJobsNode_jobCreated_text(), - Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text()); + Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text(), + Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text()); indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_priority_text()); if (indexOfColumn != INVALID_INDEX) { outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_PRIORITIZED_WIDTH); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java index 23ac9b6b6f..dc07b1d599 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java @@ -455,7 +455,7 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen } catch (AutoIngestJobNodeData.InvalidDataException | CoordinationServiceException | InterruptedException ex) { throw new AutoIngestMonitorException("Error enabling OCR for job " + job.toString(), ex); } - job.enableOcr(true); // ELTODO + job.setOcrEnabled(true); /** * Update job object in pending jobs queue @@ -472,7 +472,7 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen }).start(); } } - } + } /** * Removes the priority (set to zero) of all pending ingest jobs for a diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java index 1489112ade..cea16ad024 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java @@ -50,7 +50,7 @@ public final class AutoIngestOcrEnabledEvent extends AutopsyEvent implements Ser * @param eventType The type of OCR enabled/disabled event */ public AutoIngestOcrEnabledEvent(String nodeName, String caseName, String userName, EventType eventType) { - super(AutoIngestManager.Event.CASE_PRIORITIZED.toString(), null, null); + super(AutoIngestManager.Event.OCR_STATE_CHANGE.toString(), null, null); this.caseName = caseName; this.nodeName = nodeName; this.userName = userName; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED index d74f98b5a7..07bc2404f5 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED @@ -10,6 +10,8 @@ AinStatusNode.status.title=Status AinStatusNode.status.unknown=Unknown AutoIngestAdminActions.cancelJobAction.title=Cancel Job AutoIngestAdminActions.cancelModuleAction.title=Cancel Module +AutoIngestAdminActions.enableOCR.error=Failed to enable OCR for case "%s". +AutoIngestAdminActions.enableOCR.title=Enable OCR For This Case AutoIngestAdminActions.getThreadDump.title=Generate Thread Dump AutoIngestAdminActions.pause.title=Pause Node AutoIngestAdminActions.progressDialogAction.title=Ingest Progress @@ -71,6 +73,7 @@ AutoIngestControlPanel.JobsTableModel.ColumnHeader.HostName=Host Name AutoIngestControlPanel.JobsTableModel.ColumnHeader.ImageFolder=Data Source AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob=\ Local Job? AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath=\ Manifest File Path +AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR=OCR Enabled AutoIngestControlPanel.JobsTableModel.ColumnHeader.Priority=Prioritized AutoIngestControlPanel.JobsTableModel.ColumnHeader.Stage=Stage AutoIngestControlPanel.JobsTableModel.ColumnHeader.StageTime=Time in Stage @@ -130,6 +133,7 @@ AutoIngestJobsNode.dataSource.text=Data Source AutoIngestJobsNode.hostName.text=Host Name AutoIngestJobsNode.jobCompleted.text=Job Completed AutoIngestJobsNode.jobCreated.text=Job Created +AutoIngestJobsNode.ocr.text=OCR Enabled AutoIngestJobsNode.prioritized.false=No AutoIngestJobsNode.prioritized.true=Yes AutoIngestJobsNode.priority.text=Prioritized @@ -222,6 +226,8 @@ DeleteOrphanManifestNodesTask.progress.gettingManifestNodes=Querying the coordin DeleteOrphanManifestNodesTask.progress.lookingForOrphanedManifestFileZnodes=Looking for orphaned manifest file znodes DeleteOrphanManifestNodesTask.progress.startMessage=Starting orphaned manifest file znode cleanup HINT_CasesDashboardTopComponent=This is an adminstrative dashboard for multi-user cases +OcrIconCellRenderer.disabled.tooltiptext=This job does not have OCR enabled. +OcrIconCellRenderer.enabled.tooltiptext=This job has OCR enabled. OpenAutoIngestLogAction.deletedLogErrorMsg=The case auto ingest log has been deleted. OpenAutoIngestLogAction.logOpenFailedErrorMsg=Failed to open case auto ingest log. See application log for details. OpenAutoIngestLogAction.menuItemText=Open Auto Ingest Log File @@ -331,7 +337,7 @@ PrioritizationAction.deprioritizeCaseAction.error=Failed to deprioritize case "% PrioritizationAction.deprioritizeCaseAction.title=Deprioritize Case PrioritizationAction.deprioritizeJobAction.error=Failed to deprioritize job "%s". PrioritizationAction.deprioritizeJobAction.title=Deprioritize Job -PrioritizationAction.prioritizeCaseAction.error==Failed to prioritize case "%s". +PrioritizationAction.prioritizeCaseAction.error=Failed to prioritize case "%s". PrioritizationAction.prioritizeCaseAction.title=Prioritize Case PrioritizationAction.prioritizeJobAction.error=Failed to prioritize job "%s". PrioritizationAction.prioritizeJobAction.title=Prioritize Job diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/OcrIconCellRenderer.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/OcrIconCellRenderer.java new file mode 100755 index 0000000000..4c5874349f --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/OcrIconCellRenderer.java @@ -0,0 +1,72 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.experimental.autoingest; + +import java.awt.Component; +import java.lang.reflect.InvocationTargetException; +import javax.swing.ImageIcon; +import javax.swing.JTable; +import static javax.swing.SwingConstants.CENTER; +import org.openide.nodes.Node; +import org.openide.util.ImageUtilities; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.guiutils.GrayableCellRenderer; +import org.sleuthkit.autopsy.datamodel.NodeProperty; + +/** + * A JTable and Outline view cell renderer that represents whether OCR is enabled for the job. + */ +class OcrIconCellRenderer extends GrayableCellRenderer { + + @Messages({ + "OcrIconCellRenderer.enabled.tooltiptext=This job has OCR enabled.", + "OcrIconCellRenderer.disabled.tooltiptext=This job does not have OCR enabled." + }) + private static final long serialVersionUID = 1L; + static final ImageIcon checkedIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/experimental/images/tick.png", false)); + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + setHorizontalAlignment(CENTER); + Object switchValue = null; + if ((value instanceof NodeProperty)) { + //The Outline view has properties in the cell, the value contained in the property is what we want + try { + switchValue = ((Node.Property) value).getValue(); + } catch (IllegalAccessException | InvocationTargetException ignored) { + //Unable to get the value from the NodeProperty no Icon will be displayed + } + } else { + //JTables contain the value we want directly in the cell + switchValue = value; + } + if (switchValue instanceof Integer && (int) switchValue != 0) { + setIcon(checkedIcon); + setToolTipText(org.openide.util.NbBundle.getMessage(OcrIconCellRenderer.class, "OcrIconCellRenderer.enabled.tooltiptext")); + } else { + setIcon(null); + if (switchValue instanceof Integer) { + setToolTipText(org.openide.util.NbBundle.getMessage(OcrIconCellRenderer.class, "OcrIconCellRenderer.disabled.tooltiptext")); + } + } + grayCellIfTableNotEnabled(table, isSelected); + + return this; + } +} From 77a93b98ace9d5b7887a6df8236ab161da46dbb7 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 1 Jun 2021 15:36:11 -0400 Subject: [PATCH 05/70] UI work --- .../experimental/autoingest/AutoIngestJobsNode.java | 11 +++++++++-- .../experimental/autoingest/AutoIngestJobsPanel.java | 9 +++++++-- .../experimental/autoingest/OcrIconCellRenderer.java | 4 ++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index 5fd6eb2a6e..30b4847edf 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -124,11 +124,12 @@ final class AutoIngestJobsNode extends AbstractNode { AutoIngestJob thisJob = this.autoIngestJob; AutoIngestJob otherJob = ((AutoIngestJobWrapper) other).autoIngestJob; - // Only equal if the manifest paths and processing stage details are the same. + // Only equal if the manifest paths, processing stage details, priority, and OCR flag are the same. return thisJob.getManifest().getFilePath().equals(otherJob.getManifest().getFilePath()) && jobStage.equals(((AutoIngestJobWrapper) other).jobStage) && jobSnapshot.equals(((AutoIngestJobWrapper) other).jobSnapshot) - && jobPriority.equals(((AutoIngestJobWrapper) other).jobPriority); + && jobPriority.equals(((AutoIngestJobWrapper) other).jobPriority) + && (thisJob.getOcrEnabled() == otherJob.getOcrEnabled()); } @Override @@ -172,6 +173,10 @@ final class AutoIngestJobsNode extends AbstractNode { Integer getPriority() { return autoIngestJob.getPriority(); } + + boolean getOcrEnabled() { + return autoIngestJob.getOcrEnabled(); + } } /** @@ -328,6 +333,8 @@ final class AutoIngestJobsNode extends AbstractNode { jobWrapper.getManifest().getDateFileCreated())); ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text(), jobWrapper.getPriority())); + ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text(), + jobWrapper.getOcrEnabled())); break; case RUNNING_JOB: AutoIngestJob.StageDetails status = jobWrapper.getProcessingStageDetails(); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java index 0488e1b309..838d83febb 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2018 Basis Technology Corp. + * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -42,7 +42,7 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa private static final long serialVersionUID = 1L; private static final int INITIAL_CASENAME_WIDTH = 170; private static final int INITIAL_DATASOURCE_WIDTH = 270; - private static final int INITIAL_PRIORITIZED_WIDTH = 20; + private static final int INITIAL_PRIORITIZED_WIDTH = 20; // ELTODO private static final int INITIAL_STATUS_WIDTH = 20; private static final int INVALID_INDEX = -1; private final org.openide.explorer.view.OutlineView outlineView; @@ -88,6 +88,11 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_PRIORITIZED_WIDTH); outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new PrioritizedIconCellRenderer()); } + indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_ocr_text()); + if (indexOfColumn != INVALID_INDEX) { + outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_PRIORITIZED_WIDTH); + outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new OcrIconCellRenderer()); + } break; case RUNNING_JOB: outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(), diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/OcrIconCellRenderer.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/OcrIconCellRenderer.java index 4c5874349f..e90754adf8 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/OcrIconCellRenderer.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/OcrIconCellRenderer.java @@ -56,12 +56,12 @@ class OcrIconCellRenderer extends GrayableCellRenderer { //JTables contain the value we want directly in the cell switchValue = value; } - if (switchValue instanceof Integer && (int) switchValue != 0) { + if (switchValue instanceof Boolean && (boolean) switchValue == true) { setIcon(checkedIcon); setToolTipText(org.openide.util.NbBundle.getMessage(OcrIconCellRenderer.class, "OcrIconCellRenderer.enabled.tooltiptext")); } else { setIcon(null); - if (switchValue instanceof Integer) { + if (switchValue instanceof Boolean) { setToolTipText(org.openide.util.NbBundle.getMessage(OcrIconCellRenderer.class, "OcrIconCellRenderer.disabled.tooltiptext")); } } From 54ec1393a0886f7679a7fab74776dca5afb646e6 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 2 Jun 2021 09:49:54 -0400 Subject: [PATCH 06/70] added defaults class --- .../defaults/ContentViewerDefaults.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java b/Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java new file mode 100644 index 0000000000..19ad989969 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java @@ -0,0 +1,79 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.contentviewers.defaults; + +import java.awt.Font; +import java.awt.Insets; +import java.awt.Toolkit; +import java.util.function.Supplier; +import javax.swing.UIManager; + +/** + * + * @author gregd + */ +public class ContentViewerDefaults { + + private static class Cacheable { + + private final Supplier itemProvider; + private T item = null; + + Cacheable(Supplier itemProvider) { + this.itemProvider = itemProvider; + } + + T get() { + if (item == null) { + item = itemProvider.get(); + } + + return item; + } + } + + private static final Cacheable DEFAULT_FONT = new Cacheable<>(() -> UIManager.getDefaults().getFont("Label.font")); + + private static final Cacheable DEFAULT_FONT_PX = new Cacheable<>(() -> { + // based on https://stackoverflow.com/questions/5829703/java-getting-a-font-with-a-specific-height-in-pixels/26564924#26564924 + return (int) Math.round(DEFAULT_FONT.get().getSize() * Toolkit.getDefaultToolkit().getScreenResolution() / 72.0); + }); + + private static final Cacheable HEADER_FONT = new Cacheable<>(() -> { + Font defaultFont = DEFAULT_FONT.get(); + return defaultFont.deriveFont(Font.BOLD, defaultFont.getSize() + 2); + }); + + private static final Cacheable DEFAULT_PANEL_INSETS = new Cacheable<>(() -> UIManager.getDefaults().getInsets("TextPane.margin")); + + private static final Cacheable DEFAULT_INDENT = new Cacheable<>(() -> DEFAULT_FONT_PX.get()); + private static final Cacheable DEFAULT_SECTION_SPACING = new Cacheable<>(() -> DEFAULT_FONT_PX.get()); + + + + + public static Font getFont() { + return DEFAULT_FONT.get(); + } + + public static Font getHeaderFont() { + return HEADER_FONT.get(); + } + + public static Insets getPanelInsets() { + return DEFAULT_PANEL_INSETS.get(); + } + + public static Integer getSectionIndent() { + return DEFAULT_INDENT.get(); + } + + public static Integer getSectionSpacing() { + return DEFAULT_SECTION_SPACING.get(); + } + + // line spacing??? +} From 31ee21d2ca265e9742d7766579134303ed0daf75 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 2 Jun 2021 14:56:05 -0400 Subject: [PATCH 07/70] supplier fix --- .../defaults/ContentViewerDefaults.java | 34 +++++-------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java b/Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java index 19ad989969..267be2d302 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java @@ -5,10 +5,11 @@ */ package org.sleuthkit.autopsy.contentviewers.defaults; +import com.google.common.base.Suppliers; import java.awt.Font; import java.awt.Insets; import java.awt.Toolkit; -import java.util.function.Supplier; +import com.google.common.base.Supplier; import javax.swing.UIManager; /** @@ -16,41 +17,22 @@ import javax.swing.UIManager; * @author gregd */ public class ContentViewerDefaults { - - private static class Cacheable { - - private final Supplier itemProvider; - private T item = null; - - Cacheable(Supplier itemProvider) { - this.itemProvider = itemProvider; - } - - T get() { - if (item == null) { - item = itemProvider.get(); - } - - return item; - } - } - - private static final Cacheable DEFAULT_FONT = new Cacheable<>(() -> UIManager.getDefaults().getFont("Label.font")); + private static final Supplier DEFAULT_FONT = Suppliers.memoize(() -> UIManager.getDefaults().getFont("Label.font")); - private static final Cacheable DEFAULT_FONT_PX = new Cacheable<>(() -> { + private static final Supplier DEFAULT_FONT_PX = Suppliers.memoize(() -> { // based on https://stackoverflow.com/questions/5829703/java-getting-a-font-with-a-specific-height-in-pixels/26564924#26564924 return (int) Math.round(DEFAULT_FONT.get().getSize() * Toolkit.getDefaultToolkit().getScreenResolution() / 72.0); }); - private static final Cacheable HEADER_FONT = new Cacheable<>(() -> { + private static final Supplier HEADER_FONT = Suppliers.memoize(() -> { Font defaultFont = DEFAULT_FONT.get(); return defaultFont.deriveFont(Font.BOLD, defaultFont.getSize() + 2); }); - private static final Cacheable DEFAULT_PANEL_INSETS = new Cacheable<>(() -> UIManager.getDefaults().getInsets("TextPane.margin")); + private static final Supplier DEFAULT_PANEL_INSETS = Suppliers.memoize(() -> UIManager.getDefaults().getInsets("TextPane.margin")); - private static final Cacheable DEFAULT_INDENT = new Cacheable<>(() -> DEFAULT_FONT_PX.get()); - private static final Cacheable DEFAULT_SECTION_SPACING = new Cacheable<>(() -> DEFAULT_FONT_PX.get()); + private static final Supplier DEFAULT_INDENT = Suppliers.memoize(() -> DEFAULT_FONT_PX.get()); + private static final Supplier DEFAULT_SECTION_SPACING = Suppliers.memoize(() -> DEFAULT_FONT_PX.get()); From 44afaa7b28e8a007e0b96dc12d5d4e97f88b06b9 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 2 Jun 2021 15:11:53 -0400 Subject: [PATCH 08/70] Integrated with KWS service --- .../KeywordSearchService.java | 12 +++++++- .../autoingest/AutoIngestControlPanel.java | 9 +++--- .../autoingest/AutoIngestJobsNode.java | 2 +- .../autoingest/AutoIngestJobsPanel.java | 7 +++-- .../autoingest/AutoIngestManager.java | 30 ++++++++++++++----- .../autoingest/AutoIngestMonitor.java | 4 +-- ...ava => AutoIngestOcrStateChangeEvent.java} | 4 +-- .../keywordsearch/Bundle.properties-MERGED | 3 +- .../keywordsearch/SolrSearchService.java | 11 +++++++ 9 files changed, 60 insertions(+), 22 deletions(-) rename Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/{AutoIngestOcrEnabledEvent.java => AutoIngestOcrStateChangeEvent.java} (92%) diff --git a/Core/src/org/sleuthkit/autopsy/keywordsearchservice/KeywordSearchService.java b/Core/src/org/sleuthkit/autopsy/keywordsearchservice/KeywordSearchService.java index 981abe05de..7d197a4d11 100644 --- a/Core/src/org/sleuthkit/autopsy/keywordsearchservice/KeywordSearchService.java +++ b/Core/src/org/sleuthkit/autopsy/keywordsearchservice/KeywordSearchService.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2015-2019 Basis Technology Corp. + * Copyright 2015-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.keywordsearchservice; +import com.google.common.annotations.Beta; import java.io.Closeable; import java.io.IOException; import org.sleuthkit.autopsy.casemodule.CaseMetadata; @@ -105,5 +106,14 @@ public interface KeywordSearchService extends Closeable { * @throws KeywordSearchServiceException if unable to delete. */ void deleteDataSource(Long dataSourceId) throws KeywordSearchServiceException; + + /** + * A flag to enable or disable OCR on all future text indexing. + * + * @param state Boolean flag to enable/disable OCR. Set to True to enable + * OCR, or False to disable it. + */ + @Beta + void changeOcrState(boolean state); } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java index bdc32a4d40..6b90a01fc4 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java @@ -122,6 +122,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { private static final int RUNNING_TABLE_COL_PREFERRED_WIDTH = 175; private static final int PRIORITY_COLUMN_PREFERRED_WIDTH = 60; private static final int PRIORITY_COLUMN_MAX_WIDTH = 150; + private static final int OCR_COLUMN_PREFERRED_WIDTH = 60; + private static final int OCR_COLUMN_MAX_WIDTH = 150; private static final int ACTIVITY_TIME_COL_MIN_WIDTH = 250; private static final int ACTIVITY_TIME_COL_MAX_WIDTH = 450; private static final int TIME_COL_MIN_WIDTH = 30; @@ -410,12 +412,11 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { column.setPreferredWidth(PRIORITY_COLUMN_PREFERRED_WIDTH); column.setWidth(PRIORITY_COLUMN_PREFERRED_WIDTH); - // ELTODO column = pendingTable.getColumn(JobsTableModelColumns.OCR.getColumnHeader()); column.setCellRenderer(new OcrIconCellRenderer()); - column.setMaxWidth(PRIORITY_COLUMN_MAX_WIDTH);// ELTODO - column.setPreferredWidth(PRIORITY_COLUMN_PREFERRED_WIDTH);// ELTODO - column.setWidth(PRIORITY_COLUMN_PREFERRED_WIDTH);// ELTODO + column.setMaxWidth(OCR_COLUMN_MAX_WIDTH); + column.setPreferredWidth(OCR_COLUMN_PREFERRED_WIDTH); + column.setWidth(OCR_COLUMN_PREFERRED_WIDTH); /** * Allow sorting when a column header is clicked. diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index 30b4847edf..c5f5d75ab2 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2018-2019 Basis Technology Corp. + * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java index 838d83febb..d063c7a4f4 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java @@ -42,7 +42,8 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa private static final long serialVersionUID = 1L; private static final int INITIAL_CASENAME_WIDTH = 170; private static final int INITIAL_DATASOURCE_WIDTH = 270; - private static final int INITIAL_PRIORITIZED_WIDTH = 20; // ELTODO + private static final int INITIAL_PRIORITIZED_WIDTH = 20; + private static final int INITIAL_OCR_WIDTH = 20; private static final int INITIAL_STATUS_WIDTH = 20; private static final int INVALID_INDEX = -1; private final org.openide.explorer.view.OutlineView outlineView; @@ -90,9 +91,9 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa } indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_ocr_text()); if (indexOfColumn != INVALID_INDEX) { - outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_PRIORITIZED_WIDTH); + outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_OCR_WIDTH); outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new OcrIconCellRenderer()); - } + } break; case RUNNING_JOB: outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(), diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index beaaffffb0..968e61ae60 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -55,6 +55,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import javax.annotation.concurrent.GuardedBy; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case.CaseType; @@ -105,6 +106,7 @@ import org.sleuthkit.autopsy.ingest.IngestModuleError; import org.sleuthkit.autopsy.ingest.IngestStream; import org.sleuthkit.autopsy.keywordsearch.KeywordSearchModuleException; import org.sleuthkit.autopsy.keywordsearch.Server; +import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.SleuthkitCase; @@ -144,7 +146,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen ControlEventType.SHUTDOWN.toString(), ControlEventType.GENERATE_THREAD_DUMP_REQUEST.toString(), Event.CANCEL_JOB.toString(), - Event.REPROCESS_JOB.toString()})); + Event.REPROCESS_JOB.toString(), + Event.OCR_STATE_CHANGE.toString()})); private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED); private static final long JOB_STATUS_EVENT_INTERVAL_SECONDS = 10; private static final String JOB_STATUS_PUBLISHING_THREAD_NAME = "AIM-job-status-event-publisher-%d"; @@ -308,6 +311,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen handleRemoteJobCancelEvent((AutoIngestJobCancelEvent) event); } else if (event instanceof AutoIngestJobReprocessEvent) { handleRemoteJobReprocessEvent((AutoIngestJobReprocessEvent) event); + } else if (event instanceof AutoIngestOcrStateChangeEvent) { + handleRemoteOcrEvent((AutoIngestOcrStateChangeEvent) event); } } } @@ -476,8 +481,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * * @param event OCR enabled/disabled event from another auto ingest node. */ - private void handleRemoteOcrEvent(AutoIngestOcrEnabledEvent event) { - // ELTODO + private void handleRemoteOcrEvent(AutoIngestOcrStateChangeEvent event) { switch (event.getEventType()) { case OCR_ENABLED: sysLogger.log(Level.INFO, "Received OCR enabled event for case {0} from user {1} on machine {2}", @@ -495,9 +499,13 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen String hostName = event.getNodeName(); hostNamesToLastMsgTime.put(hostName, Instant.now()); + + // update all pending jobs and get latest ZK manifest node contents for those jobs + scanInputDirsNow(); + setChanged(); - notifyObservers(Event.OCR_STATE_CHANGE); // ELTODO - } + notifyObservers(Event.OCR_STATE_CHANGE); + } /** * Processes a case deletion event from another node by triggering an @@ -2084,10 +2092,11 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } iterator.remove(); - currentJob = job; + // create a new job object based on latest ZK node data (i.e. instead of potentially stale local pending AutoIngestJob). + currentJob = new AutoIngestJob(nodeData); break; - } catch (AutoIngestJobNodeData.InvalidDataException ex) { + } catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) { sysLogger.log(Level.WARNING, String.format("Unable to use node data for %s", manifestPath), ex); } } @@ -2269,7 +2278,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen /** * Updates the ingest system settings by downloading the latest version - * of the settings if using shared configuration. + * of the settings if using shared configuration. Also updates the OCR + * setting. * * @throws SharedConfigurationException if there is an error downloading * shared configuration. @@ -2285,6 +2295,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG, Date.from(Instant.now())); new SharedConfiguration().downloadConfiguration(); } + + // update the OCR enabled/disabled setting + KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class); + kwsService.changeOcrState(currentJob.getOcrEnabled()); } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java index dc07b1d599..8e58828c04 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java @@ -467,8 +467,8 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen * Publish the OCR enabled event. */ new Thread(() -> { - eventPublisher.publishRemotely(new AutoIngestOcrEnabledEvent(LOCAL_HOST_NAME, caseName, - AutoIngestManager.getSystemUserNameProperty(), AutoIngestOcrEnabledEvent.EventType.OCR_ENABLED)); + eventPublisher.publishRemotely(new AutoIngestOcrStateChangeEvent(LOCAL_HOST_NAME, caseName, + AutoIngestManager.getSystemUserNameProperty(), AutoIngestOcrStateChangeEvent.EventType.OCR_ENABLED)); }).start(); } } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrStateChangeEvent.java similarity index 92% rename from Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java rename to Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrStateChangeEvent.java index cea16ad024..63b4fa324c 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrEnabledEvent.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrStateChangeEvent.java @@ -24,7 +24,7 @@ import org.sleuthkit.autopsy.events.AutopsyEvent; /** * Event published when an automated ingest manager enables or disables OCR on a case. */ -public final class AutoIngestOcrEnabledEvent extends AutopsyEvent implements Serializable { +public final class AutoIngestOcrStateChangeEvent extends AutopsyEvent implements Serializable { /** * Possible event types @@ -49,7 +49,7 @@ public final class AutoIngestOcrEnabledEvent extends AutopsyEvent implements Ser * @param userName The logged in user * @param eventType The type of OCR enabled/disabled event */ - public AutoIngestOcrEnabledEvent(String nodeName, String caseName, String userName, EventType eventType) { + public AutoIngestOcrStateChangeEvent(String nodeName, String caseName, String userName, EventType eventType) { super(AutoIngestManager.Event.OCR_STATE_CHANGE.toString(), null, null); this.caseName = caseName; this.nodeName = nodeName; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED index c60c34bade..8a30223f6b 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED @@ -5,6 +5,7 @@ AccountsText.nextPage.exception.msg=No next page. AccountsText.previousItem.exception.msg=No previous item. AccountsText.previousPage.exception.msg=No previous page. CannotRunFileTypeDetection=Unable to run file type detection. +Collection.unableToIndexData.error=Unable to add data to text index. All future text indexing for the current case will be skipped. DropdownListSearchPanel.selected=Ad Hoc Search data source filter is selected DropdownSingleTermSearchPanel.selected=Ad Hoc Search data source filter is selected DropdownSingleTermSearchPanel.warning.text=Boundary characters ^ and $ do not match word boundaries. Consider\nreplacing with an explicit list of boundary characters, such as [ \\.,] @@ -51,7 +52,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found KeywordSearchResultFactory.query.exception.msg=Could not perform the query OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. +OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\nThe module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. OpenIDE-Module-Name=KeywordSearch OptionsCategory_Name_KeywordSearchOptions=Keyword Search OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java index 218be24de8..7567725b0c 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java @@ -462,4 +462,15 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService { } } + /** + * A flag to enable or disable OCR on all future text indexing. + * + * @param state Boolean flag to enable/disable OCR. Set to True to enable + * OCR, or False to disable it. + */ + @Override + public void changeOcrState(boolean state) { + KeywordSearchSettings.setOcrOption(state); + } + } From 63ad845a7984affb51633bb03e81d197d782f185 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 3 Jun 2021 10:02:43 -0400 Subject: [PATCH 09/70] More work --- .../autoingest/AutoIngestAdminActions.java | 50 ++++++++++++++++++- .../autoingest/AutoIngestJobsNode.java | 1 + .../autoingest/AutoIngestMonitor.java | 8 +-- .../AutoIngestNodeRefreshEvents.java | 2 +- .../AutoIngestOcrStateChangeEvent.java | 10 ++-- .../autoingest/Bundle.properties-MERGED | 2 + 6 files changed, 64 insertions(+), 9 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java index 994d2f91a0..c44ef22e23 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java @@ -187,7 +187,7 @@ final class AutoIngestAdminActions { dashboard.getPendingJobsPanel().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); EventQueue.invokeLater(() -> { try { - dashboard.getMonitor().enableOcrForCase(job.getManifest().getCaseName()); + dashboard.getMonitor().changeOcrStateForCase(job.getManifest().getCaseName(), true); dashboard.getPendingJobsPanel().refresh(new AutoIngestNodeRefreshEvents.RefreshCaseEvent(dashboard.getMonitor(), job.getManifest().getCaseName())); // ELTODO } catch (AutoIngestMonitor.AutoIngestMonitorException ex) { String errorMessage = String.format(Bundle.AutoIngestAdminActions_enableOCR_error(), job.getManifest().getCaseName()); @@ -200,6 +200,54 @@ final class AutoIngestAdminActions { } } + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); //To change body of generated methods, choose Tools | Templates. + } + } + + @NbBundle.Messages({"AutoIngestAdminActions.disableOCR.title=Disable OCR For This Case", + "AutoIngestAdminActions.disableOCR.error=Failed to disable OCR for case \"%s\"."}) + static final class DisableOCR extends AbstractAction { + + private static final long serialVersionUID = 1L; + private final AutoIngestJob job; + + DisableOCR(AutoIngestJob job) { + super(Bundle.AutoIngestAdminActions_disableOCR_title()); + this.job = job; + } + + @Override + public void actionPerformed(ActionEvent e) { + + if (job == null) { + return; + } + + final AutoIngestDashboardTopComponent tc = (AutoIngestDashboardTopComponent) WindowManager.getDefault().findTopComponent(AutoIngestDashboardTopComponent.PREFERRED_ID); + if (tc == null) { + return; + } + + AutoIngestDashboard dashboard = tc.getAutoIngestDashboard(); + if (dashboard != null) { + dashboard.getPendingJobsPanel().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + EventQueue.invokeLater(() -> { + try { + dashboard.getMonitor().changeOcrStateForCase(job.getManifest().getCaseName(), false); + dashboard.getPendingJobsPanel().refresh(new AutoIngestNodeRefreshEvents.RefreshCaseEvent(dashboard.getMonitor(), job.getManifest().getCaseName())); // ELTODO + } catch (AutoIngestMonitor.AutoIngestMonitorException ex) { + String errorMessage = String.format(Bundle.AutoIngestAdminActions_disableOCR_error(), job.getManifest().getCaseName()); + logger.log(Level.SEVERE, errorMessage, ex); + MessageNotifyUtil.Message.error(errorMessage); + } finally { + dashboard.getPendingJobsPanel().setCursor(Cursor.getDefaultCursor()); + } + }); + } + } + @Override public Object clone() throws CloneNotSupportedException { return super.clone(); //To change body of generated methods, choose Tools | Templates. diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index c5f5d75ab2..9f6f70f3e9 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -375,6 +375,7 @@ final class AutoIngestJobsNode extends AbstractNode { // ELTODO enable/disable based on current state actions.add(new AutoIngestAdminActions.EnableOCR(jobWrapper.getJob())); + actions.add(new AutoIngestAdminActions.DisableOCR(jobWrapper.getJob())); break; case RUNNING_JOB: actions.add(new AutoIngestAdminActions.ProgressDialogAction(jobWrapper.getJob())); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java index 8e58828c04..f9033f3235 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java @@ -437,7 +437,7 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen * @throws AutoIngestMonitorException If there is an error enabling OCR for the jobs for the case. * */ - void enableOcrForCase(final String caseName) throws AutoIngestMonitorException { + void changeOcrStateForCase(final String caseName, final boolean ocrState) throws AutoIngestMonitorException { List jobsToPrioritize = new ArrayList<>(); synchronized (jobsLock) { for (AutoIngestJob pendingJob : getPendingJobs()) { @@ -450,12 +450,12 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen String manifestNodePath = job.getManifest().getFilePath().toString(); try { AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath)); - nodeData.setOcrEnabled(true); + nodeData.setOcrEnabled(ocrState); coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath, nodeData.toArray()); } catch (AutoIngestJobNodeData.InvalidDataException | CoordinationServiceException | InterruptedException ex) { throw new AutoIngestMonitorException("Error enabling OCR for job " + job.toString(), ex); } - job.setOcrEnabled(true); + job.setOcrEnabled(ocrState); /** * Update job object in pending jobs queue @@ -468,7 +468,7 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen */ new Thread(() -> { eventPublisher.publishRemotely(new AutoIngestOcrStateChangeEvent(LOCAL_HOST_NAME, caseName, - AutoIngestManager.getSystemUserNameProperty(), AutoIngestOcrStateChangeEvent.EventType.OCR_ENABLED)); + AutoIngestManager.getSystemUserNameProperty(), ocrState)); }).start(); } } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestNodeRefreshEvents.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestNodeRefreshEvents.java index 338bce31c7..be7cc2408f 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestNodeRefreshEvents.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestNodeRefreshEvents.java @@ -69,7 +69,7 @@ class AutoIngestNodeRefreshEvents { private final String caseName; /** - * Contructs a RefreshCaseEvent + * Constructs a RefreshCaseEvent * * @param monitor The monitor that will provide access to the current state of the jobs lists. * @param name The name of the case whose nodes should be refreshed. diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrStateChangeEvent.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrStateChangeEvent.java index 63b4fa324c..682ad711eb 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrStateChangeEvent.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestOcrStateChangeEvent.java @@ -47,14 +47,18 @@ public final class AutoIngestOcrStateChangeEvent extends AutopsyEvent implements * @param caseName The name of the case. * @param nodeName The host name of the node that enabled/disabled OCR. * @param userName The logged in user - * @param eventType The type of OCR enabled/disabled event + * @param ocrState Flag whether OCR is enabled/disabled */ - public AutoIngestOcrStateChangeEvent(String nodeName, String caseName, String userName, EventType eventType) { + public AutoIngestOcrStateChangeEvent(String nodeName, String caseName, String userName, boolean ocrState) { super(AutoIngestManager.Event.OCR_STATE_CHANGE.toString(), null, null); this.caseName = caseName; this.nodeName = nodeName; this.userName = userName; - this.eventType = eventType; + if (ocrState == true) { + this.eventType = EventType.OCR_ENABLED; + } else { + this.eventType = EventType.OCR_DISABLED; + } } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED index 07bc2404f5..1eba0a4194 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED @@ -10,6 +10,8 @@ AinStatusNode.status.title=Status AinStatusNode.status.unknown=Unknown AutoIngestAdminActions.cancelJobAction.title=Cancel Job AutoIngestAdminActions.cancelModuleAction.title=Cancel Module +AutoIngestAdminActions.disableOCR.error=Failed to disable OCR for case "%s". +AutoIngestAdminActions.disableOCR.title=Disable OCR For This Case AutoIngestAdminActions.enableOCR.error=Failed to enable OCR for case "%s". AutoIngestAdminActions.enableOCR.title=Enable OCR For This Case AutoIngestAdminActions.getThreadDump.title=Generate Thread Dump From 658516059f4e65fd25980e8e8fc0838351663558 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 3 Jun 2021 13:22:54 -0400 Subject: [PATCH 10/70] working through general purpose artifact viewer --- .../GeneralPurposeArtifactViewer.java | 177 +++++++++++------- .../ContentViewerDefaults.java | 12 +- .../osaccount/OsAccountDataPanel.java | 20 +- 3 files changed, 131 insertions(+), 78 deletions(-) rename Core/src/org/sleuthkit/autopsy/contentviewers/{defaults => layout}/ContentViewerDefaults.java (80%) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java index d8150a91a2..aa1ca8d732 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.contentviewers.artifactviewers; import java.awt.Component; import java.awt.Dimension; -import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -39,9 +38,12 @@ import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTextPane; import javax.swing.SwingUtilities; +import javax.swing.border.EmptyBorder; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils; @@ -55,13 +57,18 @@ import org.sleuthkit.datamodel.TskCoreException; */ @ServiceProvider(service = ArtifactContentViewer.class) public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel implements ArtifactContentViewer { - + private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(GeneralPurposeArtifactViewer.class.getName()); // Number of columns in the gridbag layout. private final static int MAX_COLS = 4; - private final static Insets ROW_INSETS = new java.awt.Insets(0, 12, 0, 0); - private final static Insets HEADER_INSETS = new java.awt.Insets(0, 0, 0, 0); + private final static Insets ROW_INSETS = new java.awt.Insets(0, 0, 0, 0); + + private final static Insets FIRST_HEADER_INSETS = new Insets(0, 0, 0, 0); + private final static Insets HEADER_INSETS = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0); + private final static Insets VALUE_COLUMN_INSETS = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); + private final static Insets KEY_COLUMN_INSETS = new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); + private final static double GLUE_WEIGHT_X = 1.0; private final static double TEXT_WEIGHT_X = 0.0; private final static int LABEL_COLUMN = 0; @@ -78,7 +85,6 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS.getTypeID()}; private static final List TYPES_WITH_DATE_SECTION = Arrays.asList(new Integer[]{BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()}); private final GridBagLayout gridBagLayout = new GridBagLayout(); - private final GridBagConstraints gridBagConstraints = new GridBagConstraints(); private final Map orderingMap = new HashMap<>(); private final javax.swing.JPanel detailsPanel = new javax.swing.JPanel(); @@ -89,8 +95,8 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i public GeneralPurposeArtifactViewer() { addOrderings(); initComponents(); - gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START; detailsPanel.setLayout(gridBagLayout); + detailsPanel.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets())); } /** @@ -134,7 +140,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()}); } - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @NbBundle.Messages({"GeneralPurposeArtifactViewer.unknown.text=Unknown"}) @Override @@ -175,14 +181,8 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i detailsPanel.removeAll(); detailsPanel.setLayout(gridBagLayout); detailsPanel.revalidate(); - gridBagConstraints.gridy = 0; - gridBagConstraints.gridx = LABEL_COLUMN; - gridBagConstraints.weighty = 0.0; - gridBagConstraints.weightx = TEXT_WEIGHT_X; // keep components fixed horizontally. - gridBagConstraints.fill = GridBagConstraints.NONE; - gridBagConstraints.insets = ROW_INSETS; } - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override public boolean isSupported(BlackboardArtifact artifact) { @@ -197,7 +197,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID() || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL.getTypeID()); } - + @NbBundle.Messages({"GeneralPurposeArtifactViewer.details.attrHeader=Details", "GeneralPurposeArtifactViewer.details.sourceHeader=Source", "GeneralPurposeArtifactViewer.details.dataSource=Data Source", @@ -250,8 +250,10 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void updateView(BlackboardArtifact artifact, Map> attributeMap, String dataSourceName, String sourceFilePath) { final Integer artifactTypeId = artifact.getArtifactTypeID(); + int curRow = 0; if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) { - JTextPane firstTextPane = addDetailsHeader(artifactTypeId); + JTextPane firstTextPane = addDetailsHeader(artifactTypeId, curRow); + curRow++; Integer[] orderingArray = orderingMap.get(artifactTypeId); if (orderingArray == null) { orderingArray = DEFAULT_ORDERING; @@ -262,27 +264,39 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i for (BlackboardAttribute bba : attrList) { if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) { if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) { - addNameValueRow(Bundle.GeneralPurposeArtifactViewer_dates_time(), TimeZoneUtils.getFormattedTime(bba.getValueLong())); + addNameValueRow(Bundle.GeneralPurposeArtifactViewer_dates_time(), TimeZoneUtils.getFormattedTime(bba.getValueLong()), curRow); } else { - addNameValueRow(bba.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(bba.getValueLong())); + addNameValueRow(bba.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(bba.getValueLong()), curRow); } } else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID() && artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) { - addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString()); + addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString(), curRow); } else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()) { String displayString = bba.getDisplayString(); if (!attributeMap.containsKey(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID())) { displayString += Bundle.GeneralPurposeArtifactViewer_noFile_text(); } - addNameValueRow(bba.getAttributeType().getDisplayName(), displayString); + addNameValueRow(bba.getAttributeType().getDisplayName(), displayString, curRow); } else { - addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString()); + addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString(), curRow); } + curRow++; } } } if (TYPES_WITH_DATE_SECTION.contains(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID())) { boolean headerAdded = false; - headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_created(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()), headerAdded); + List> dateKeyValuePairs = Stream.of( + Pair.of(Bundle.GeneralPurposeArtifactViewer_dates_created(), + attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID())), + Pair.of(Bundle.GeneralPurposeArtifactViewer_dates_start(), + attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID())), + Pair.of(Bundle.GeneralPurposeArtifactViewer_dates_end(), + attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID())), + Pair.of(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getDisplayName(), + attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID())) + ) + ) + headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_created(), , headerAdded); headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_start(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()), headerAdded); headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_end(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()), headerAdded); addDates(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getDisplayName(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()), headerAdded); @@ -311,21 +325,25 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i detailsPanel.revalidate(); } + /** * Private helper method to add all dates in a given attribute list. * * @param label Specific String to use in place of attributes display * name. * @param attrList List of attributes to add dates for. + * @param rowStart The starting row of these dates. * @param headerExists If the "Dates" header has already been displayed. * - * @return True if the "Dates" header has been displayed, false otherwise. + * @return The next empty row. */ - private boolean addDates(String label, List attrList, boolean headerExists) { + private int addDates(String label, List attrList, int rowStart, boolean headerExists) { + int curRow = rowStart; boolean headerAdded = headerExists; if (attrList != null) { if (!headerAdded) { - addHeader(Bundle.GeneralPurposeArtifactViewer_details_datesHeader()); + addHeader(Bundle.GeneralPurposeArtifactViewer_details_datesHeader(), curRow); + curRow++; headerAdded = true; } String labelToUse = label; @@ -333,16 +351,18 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i if (StringUtils.isBlank(label)) { labelToUse = bba.getAttributeType().getDisplayName(); } - addNameValueRow(labelToUse, bba.getDisplayString()); + addNameValueRow(labelToUse, bba.getDisplayString(), curRow); + curRow++; } } - return headerAdded; + return new AddDatesData(); } /** * Helper method to add an artifact specific details header. * * @param artifactTypeId ID of artifact type to add header for. + * @param row The row of the header. */ @NbBundle.Messages({"GeneralPurposeArtifactViewer.details.bookmarkHeader=Bookmark Details", "GeneralPurposeArtifactViewer.details.historyHeader=Visit Details", @@ -350,7 +370,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i "GeneralPurposeArtifactViewer.details.searchHeader=Web Search", "GeneralPurposeArtifactViewer.details.cachedHeader=Cached File", "GeneralPurposeArtifactViewer.details.cookieHeader=Cookie Details",}) - private JTextPane addDetailsHeader(int artifactTypeId) { + private JTextPane addDetailsHeader(int artifactTypeId, int row) { String header; if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) { header = Bundle.GeneralPurposeArtifactViewer_details_historyHeader(); @@ -367,48 +387,58 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i } else { header = Bundle.GeneralPurposeArtifactViewer_details_attrHeader(); } - return addHeader(header); + return addHeader(header, row); + } + + private GridBagConstraints getDefaultConstraints(int row, int col) { + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridy = row; + gridBagConstraints.gridx = col; + gridBagConstraints.weighty = 0.0; + gridBagConstraints.weightx = TEXT_WEIGHT_X; // keep components fixed horizontally. + gridBagConstraints.fill = GridBagConstraints.NONE; + gridBagConstraints.insets = ROW_INSETS; + gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START; + return gridBagConstraints; } /** * Adds a new heading to the panel. * * @param headerString Heading string to display. + * @param row The grid row to add this header. * * @return JLabel Heading label added. */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - private JTextPane addHeader(String headerString) { + private JTextPane addHeader(String headerString, int row) { // create label for heading javax.swing.JTextPane headingLabel = new javax.swing.JTextPane(); headingLabel.setOpaque(false); headingLabel.setFocusable(false); headingLabel.setEditable(false); - // add a blank line before the start of new section, unless it's - // the first section - if (gridBagConstraints.gridy != 0) { - gridBagConstraints.gridy++; - // add to panel - addToPanel(new javax.swing.JLabel(" ")); - addLineEndGlue(); - headingLabel.setFocusable(false); - } - gridBagConstraints.gridy++; - gridBagConstraints.gridx = LABEL_COLUMN;; + + GridBagConstraints gridBagConstraints = getDefaultConstraints(row, LABEL_COLUMN); + + gridBagConstraints.insets = (row == 0) + ? FIRST_HEADER_INSETS + : HEADER_INSETS; + // let the header span all of the row gridBagConstraints.gridwidth = MAX_COLS; gridBagConstraints.insets = HEADER_INSETS; + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; // set text headingLabel.setText(headerString); // make it large and bold - headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2)); + headingLabel.setFont(ContentViewerDefaults.getHeaderFont()); // add to panel - addToPanel(headingLabel); + addToPanel(headingLabel, gridBagConstraints); // reset constraints to normal gridBagConstraints.gridwidth = LABEL_WIDTH; // add line end glue - addLineEndGlue(); - gridBagConstraints.insets = ROW_INSETS; + addLineEndGlue(row); + return headingLabel; } @@ -418,63 +448,68 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i * * @param keyString Key name to display. * @param valueString Value string to display. + * @param row The row index. */ - private JTextPane addNameValueRow(String keyString, String valueString) { - addKeyAtCol(keyString); - return addValueAtCol(valueString); + private JTextPane addNameValueRow(String keyString, String valueString, int row) { + addKeyAtCol(keyString, row); + return addValueAtCol(valueString, row); } /** * Adds a filler/glue at the end of the line to keep the other columns * aligned, in case the panel is resized. + * + * @param row The row for the line end glue. */ - private void addLineEndGlue() { + private void addLineEndGlue(int row) { // Place the filler just past the last column. - gridBagConstraints.gridx = MAX_COLS; + GridBagConstraints gridBagConstraints = getDefaultConstraints(row, MAX_COLS); gridBagConstraints.weightx = GLUE_WEIGHT_X; // take up all the horizontal space - gridBagConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; javax.swing.Box.Filler horizontalFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(32767, 0)); // add to panel - addToPanel(horizontalFiller); - // restore fill & weight - gridBagConstraints.fill = GridBagConstraints.NONE; - gridBagConstraints.weightx = TEXT_WEIGHT_X; + addToPanel(horizontalFiller, gridBagConstraints); } /** * Adds a filler/glue at the bottom of the panel to keep the data rows * aligned, in case the panel is resized. + * + * @param row The row for the line end glue. */ - private void addPageEndGlue() { + private void addPageEndGlue(int row) { + GridBagConstraints gridBagConstraints = getDefaultConstraints(row, 0); gridBagConstraints.weighty = 1.0; // take up all the vertical space gridBagConstraints.fill = GridBagConstraints.VERTICAL; javax.swing.Box.Filler vertFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(0, 32767)); // add to panel - addToPanel(vertFiller); + addToPanel(vertFiller, gridBagConstraints); } /** * Adds a label/key to the panel. * * @param keyString Key name to display. + * @param row The row for this column. * * @return Label added. */ - private JLabel addKeyAtCol(String keyString) { + private JLabel addKeyAtCol(String keyString, int row) { // create label javax.swing.JLabel keyLabel = new javax.swing.JLabel(); keyLabel.setFocusable(false); - gridBagConstraints.gridy++; - gridBagConstraints.gridx = LABEL_COLUMN; + + GridBagConstraints gridBagConstraints = getDefaultConstraints(row, LABEL_COLUMN); gridBagConstraints.gridwidth = LABEL_WIDTH; + gridBagConstraints.insets = KEY_COLUMN_INSETS; // set text - keyLabel.setText(keyString + ": "); + keyLabel.setText(keyString + ":"); // add to panel - addToPanel(keyLabel); + addToPanel(keyLabel, gridBagConstraints); return keyLabel; } - private void addToPanel(Component comp) { + private void addToPanel(Component comp, GridBagConstraints gridBagConstraints) { detailsPanel.add(comp, gridBagConstraints); detailsPanel.revalidate(); } @@ -483,20 +518,22 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i * Adds a value string to the panel at specified column. * * @param valueString Value string to display. + * @param row The row for this column. * * @return Label added. */ - private JTextPane addValueAtCol(String valueString) { + private JTextPane addValueAtCol(String valueString, int row) { // create label, JTextPane valueField = new JTextPane(); valueField.setFocusable(false); valueField.setEditable(false); valueField.setOpaque(false); - gridBagConstraints.gridx = VALUE_COLUMN; - GridBagConstraints cloneConstraints = (GridBagConstraints) gridBagConstraints.clone(); + + GridBagConstraints gridBagConstraints = getDefaultConstraints(row, VALUE_COLUMN); // let the value span 2 cols - cloneConstraints.gridwidth = VALUE_WIDTH; - cloneConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.gridwidth = VALUE_WIDTH; + gridBagConstraints.insets = VALUE_COLUMN_INSETS; + // set text valueField.setText(valueString); // attach a right click menu with Copy option @@ -507,10 +544,10 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i } }); // add label to panel with cloned contraintsF - detailsPanel.add(valueField, cloneConstraints); + detailsPanel.add(valueField, gridBagConstraints); revalidate(); // end the line - addLineEndGlue(); + addLineEndGlue(row); return valueField; } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java similarity index 80% rename from Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java rename to Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java index 267be2d302..b221e1f522 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/defaults/ContentViewerDefaults.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package org.sleuthkit.autopsy.contentviewers.defaults; +package org.sleuthkit.autopsy.contentviewers.layout; import com.google.common.base.Suppliers; import java.awt.Font; @@ -34,8 +34,12 @@ public class ContentViewerDefaults { private static final Supplier DEFAULT_INDENT = Suppliers.memoize(() -> DEFAULT_FONT_PX.get()); private static final Supplier DEFAULT_SECTION_SPACING = Suppliers.memoize(() -> DEFAULT_FONT_PX.get()); - + private static final Supplier DEFAULT_COLUMN_SPACING = Suppliers.memoize(() -> (int)(DEFAULT_FONT_PX.get() / 3)); + private static final Supplier DEFAULT_LINE_SPACING = Suppliers.memoize(() -> (int)(DEFAULT_FONT_PX.get() / 5)); + public static int getColumnSpacing() { + return DEFAULT_COLUMN_SPACING.get(); + } public static Font getFont() { return DEFAULT_FONT.get(); @@ -57,5 +61,9 @@ public class ContentViewerDefaults { return DEFAULT_SECTION_SPACING.get(); } + public static Integer getLineSpacing() { + return DEFAULT_LINE_SPACING.get(); + } + // line spacing??? } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java index 2c88660cb0..3ab02ed4d7 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.contentviewers.osaccount; import java.awt.BorderLayout; -import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -38,8 +37,10 @@ import javax.swing.Box; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingWorker; +import javax.swing.border.EmptyBorder; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.contentviewers.osaccount.SectionData.RowData; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.DataSource; @@ -61,7 +62,11 @@ public class OsAccountDataPanel extends JPanel { private static final int KEY_COLUMN = 0; private static final int VALUE_COLUMN = 1; - + + private final static Insets FIRST_HEADER_INSETS = new Insets(0, 0, 0, 0); + private final static Insets HEADER_INSETS = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0); + private final static Insets VALUE_COLUMN_INSETS = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); + private final static Insets KEY_COLUMN_INSETS = new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMM dd yyyy", US); private PanelDataFetcher dataFetcher = null; @@ -76,6 +81,7 @@ public class OsAccountDataPanel extends JPanel { */ private void initialize() { this.setLayout(new GridBagLayout()); + this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets())); } /** @@ -269,7 +275,7 @@ public class OsAccountDataPanel extends JPanel { private void addTitle(String title, int row) { JLabel label = new JLabel(title); // Make the title bold. - label.setFont(label.getFont().deriveFont(Font.BOLD)); + label.setFont(ContentViewerDefaults.getHeaderFont()); add(label, getTitleContraints(row)); } @@ -312,7 +318,9 @@ public class OsAccountDataPanel extends JPanel { constraints.anchor = GridBagConstraints.NORTHWEST; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.weightx = 1; - constraints.insets = new Insets(5, 5, 5, 9); + constraints.insets = (row == 0) + ? FIRST_HEADER_INSETS + : HEADER_INSETS; return constraints; } @@ -332,7 +340,7 @@ public class OsAccountDataPanel extends JPanel { constraints.gridwidth = 1; // The title goes across the other columns constraints.gridheight = 1; constraints.anchor = GridBagConstraints.WEST; - constraints.insets = new Insets(0, 13, 5, 5); + constraints.insets = KEY_COLUMN_INSETS; return constraints; } @@ -352,8 +360,8 @@ public class OsAccountDataPanel extends JPanel { constraints.gridwidth = 1; // The title goes across the other columns constraints.gridheight = 1; constraints.fill = GridBagConstraints.HORIZONTAL; + constraints.insets = VALUE_COLUMN_INSETS; constraints.weightx = 1; - constraints.insets = new Insets(0, 5, 5, 5); return constraints; } From 32dd9fe4e53f87361db9045ba106aefa4fa96c3a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 3 Jun 2021 14:35:20 -0400 Subject: [PATCH 11/70] changes for general purpose viewer --- .../GeneralPurposeArtifactViewer.java | 165 ++++++++---------- 1 file changed, 70 insertions(+), 95 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java index aa1ca8d732..e81b6705c6 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.contentviewers.artifactviewers; +import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; @@ -29,10 +30,13 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; @@ -62,9 +66,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i private static final Logger logger = Logger.getLogger(GeneralPurposeArtifactViewer.class.getName()); // Number of columns in the gridbag layout. private final static int MAX_COLS = 4; - private final static Insets ROW_INSETS = new java.awt.Insets(0, 0, 0, 0); + private final static Insets ZERO_INSETS = new java.awt.Insets(0, 0, 0, 0); - private final static Insets FIRST_HEADER_INSETS = new Insets(0, 0, 0, 0); + private final static Insets FIRST_HEADER_INSETS = ZERO_INSETS; private final static Insets HEADER_INSETS = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0); private final static Insets VALUE_COLUMN_INSETS = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); private final static Insets KEY_COLUMN_INSETS = new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); @@ -85,6 +89,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS.getTypeID()}; private static final List TYPES_WITH_DATE_SECTION = Arrays.asList(new Integer[]{BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()}); private final GridBagLayout gridBagLayout = new GridBagLayout(); + private final GridBagConstraints gridBagConstraints = new GridBagConstraints(); private final Map orderingMap = new HashMap<>(); private final javax.swing.JPanel detailsPanel = new javax.swing.JPanel(); @@ -95,6 +100,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i public GeneralPurposeArtifactViewer() { addOrderings(); initComponents(); + gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START; detailsPanel.setLayout(gridBagLayout); detailsPanel.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets())); } @@ -140,7 +146,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()}); } - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @NbBundle.Messages({"GeneralPurposeArtifactViewer.unknown.text=Unknown"}) @Override @@ -181,8 +187,14 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i detailsPanel.removeAll(); detailsPanel.setLayout(gridBagLayout); detailsPanel.revalidate(); + gridBagConstraints.gridy = 0; + gridBagConstraints.gridx = LABEL_COLUMN; + gridBagConstraints.weighty = 0.0; + gridBagConstraints.weightx = TEXT_WEIGHT_X; // keep components fixed horizontally. + gridBagConstraints.fill = GridBagConstraints.NONE; + gridBagConstraints.insets = ZERO_INSETS; } - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override public boolean isSupported(BlackboardArtifact artifact) { @@ -197,7 +209,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID() || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL.getTypeID()); } - + @NbBundle.Messages({"GeneralPurposeArtifactViewer.details.attrHeader=Details", "GeneralPurposeArtifactViewer.details.sourceHeader=Source", "GeneralPurposeArtifactViewer.details.dataSource=Data Source", @@ -250,10 +262,8 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void updateView(BlackboardArtifact artifact, Map> attributeMap, String dataSourceName, String sourceFilePath) { final Integer artifactTypeId = artifact.getArtifactTypeID(); - int curRow = 0; if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) { - JTextPane firstTextPane = addDetailsHeader(artifactTypeId, curRow); - curRow++; + JTextPane firstTextPane = addDetailsHeader(artifactTypeId); Integer[] orderingArray = orderingMap.get(artifactTypeId); if (orderingArray == null) { orderingArray = DEFAULT_ORDERING; @@ -264,39 +274,27 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i for (BlackboardAttribute bba : attrList) { if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) { if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) { - addNameValueRow(Bundle.GeneralPurposeArtifactViewer_dates_time(), TimeZoneUtils.getFormattedTime(bba.getValueLong()), curRow); + addNameValueRow(Bundle.GeneralPurposeArtifactViewer_dates_time(), TimeZoneUtils.getFormattedTime(bba.getValueLong())); } else { - addNameValueRow(bba.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(bba.getValueLong()), curRow); + addNameValueRow(bba.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(bba.getValueLong())); } } else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID() && artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) { - addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString(), curRow); + addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString()); } else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()) { String displayString = bba.getDisplayString(); if (!attributeMap.containsKey(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID())) { displayString += Bundle.GeneralPurposeArtifactViewer_noFile_text(); } - addNameValueRow(bba.getAttributeType().getDisplayName(), displayString, curRow); + addNameValueRow(bba.getAttributeType().getDisplayName(), displayString); } else { - addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString(), curRow); + addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString()); } - curRow++; } } } if (TYPES_WITH_DATE_SECTION.contains(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID())) { boolean headerAdded = false; - List> dateKeyValuePairs = Stream.of( - Pair.of(Bundle.GeneralPurposeArtifactViewer_dates_created(), - attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID())), - Pair.of(Bundle.GeneralPurposeArtifactViewer_dates_start(), - attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID())), - Pair.of(Bundle.GeneralPurposeArtifactViewer_dates_end(), - attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID())), - Pair.of(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getDisplayName(), - attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID())) - ) - ) - headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_created(), , headerAdded); + headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_created(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()), headerAdded); headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_start(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()), headerAdded); headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_end(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()), headerAdded); addDates(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getDisplayName(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()), headerAdded); @@ -325,25 +323,21 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i detailsPanel.revalidate(); } - /** * Private helper method to add all dates in a given attribute list. * * @param label Specific String to use in place of attributes display * name. * @param attrList List of attributes to add dates for. - * @param rowStart The starting row of these dates. * @param headerExists If the "Dates" header has already been displayed. * - * @return The next empty row. + * @return True if the "Dates" header has been displayed, false otherwise. */ - private int addDates(String label, List attrList, int rowStart, boolean headerExists) { - int curRow = rowStart; + private boolean addDates(String label, List attrList, boolean headerExists) { boolean headerAdded = headerExists; if (attrList != null) { if (!headerAdded) { - addHeader(Bundle.GeneralPurposeArtifactViewer_details_datesHeader(), curRow); - curRow++; + addHeader(Bundle.GeneralPurposeArtifactViewer_details_datesHeader()); headerAdded = true; } String labelToUse = label; @@ -351,18 +345,16 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i if (StringUtils.isBlank(label)) { labelToUse = bba.getAttributeType().getDisplayName(); } - addNameValueRow(labelToUse, bba.getDisplayString(), curRow); - curRow++; + addNameValueRow(labelToUse, bba.getDisplayString()); } } - return new AddDatesData(); + return headerAdded; } /** * Helper method to add an artifact specific details header. * * @param artifactTypeId ID of artifact type to add header for. - * @param row The row of the header. */ @NbBundle.Messages({"GeneralPurposeArtifactViewer.details.bookmarkHeader=Bookmark Details", "GeneralPurposeArtifactViewer.details.historyHeader=Visit Details", @@ -370,7 +362,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i "GeneralPurposeArtifactViewer.details.searchHeader=Web Search", "GeneralPurposeArtifactViewer.details.cachedHeader=Cached File", "GeneralPurposeArtifactViewer.details.cookieHeader=Cookie Details",}) - private JTextPane addDetailsHeader(int artifactTypeId, int row) { + private JTextPane addDetailsHeader(int artifactTypeId) { String header; if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) { header = Bundle.GeneralPurposeArtifactViewer_details_historyHeader(); @@ -387,58 +379,45 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i } else { header = Bundle.GeneralPurposeArtifactViewer_details_attrHeader(); } - return addHeader(header, row); - } - - private GridBagConstraints getDefaultConstraints(int row, int col) { - GridBagConstraints gridBagConstraints = new GridBagConstraints(); - gridBagConstraints.gridy = row; - gridBagConstraints.gridx = col; - gridBagConstraints.weighty = 0.0; - gridBagConstraints.weightx = TEXT_WEIGHT_X; // keep components fixed horizontally. - gridBagConstraints.fill = GridBagConstraints.NONE; - gridBagConstraints.insets = ROW_INSETS; - gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START; - return gridBagConstraints; + return addHeader(header); } /** * Adds a new heading to the panel. * * @param headerString Heading string to display. - * @param row The grid row to add this header. * * @return JLabel Heading label added. */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - private JTextPane addHeader(String headerString, int row) { + private JTextPane addHeader(String headerString) { // create label for heading javax.swing.JTextPane headingLabel = new javax.swing.JTextPane(); headingLabel.setOpaque(false); headingLabel.setFocusable(false); headingLabel.setEditable(false); - - GridBagConstraints gridBagConstraints = getDefaultConstraints(row, LABEL_COLUMN); - - gridBagConstraints.insets = (row == 0) + // add a blank line before the start of new section, unless it's + // the first section + gridBagConstraints.insets = (gridBagConstraints.gridy == 0) ? FIRST_HEADER_INSETS : HEADER_INSETS; - + + gridBagConstraints.gridy++; + gridBagConstraints.gridx = LABEL_COLUMN;; // let the header span all of the row gridBagConstraints.gridwidth = MAX_COLS; - gridBagConstraints.insets = HEADER_INSETS; - gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; // set text headingLabel.setText(headerString); // make it large and bold headingLabel.setFont(ContentViewerDefaults.getHeaderFont()); + headingLabel.setMargin(ZERO_INSETS); // add to panel - addToPanel(headingLabel, gridBagConstraints); + addToPanel(headingLabel); // reset constraints to normal gridBagConstraints.gridwidth = LABEL_WIDTH; // add line end glue - addLineEndGlue(row); - + addLineEndGlue(); + gridBagConstraints.insets = ZERO_INSETS; return headingLabel; } @@ -448,68 +427,64 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i * * @param keyString Key name to display. * @param valueString Value string to display. - * @param row The row index. */ - private JTextPane addNameValueRow(String keyString, String valueString, int row) { - addKeyAtCol(keyString, row); - return addValueAtCol(valueString, row); + private JTextPane addNameValueRow(String keyString, String valueString) { + addKeyAtCol(keyString); + return addValueAtCol(valueString); } /** * Adds a filler/glue at the end of the line to keep the other columns * aligned, in case the panel is resized. - * - * @param row The row for the line end glue. */ - private void addLineEndGlue(int row) { + private void addLineEndGlue() { // Place the filler just past the last column. - GridBagConstraints gridBagConstraints = getDefaultConstraints(row, MAX_COLS); + gridBagConstraints.gridx = MAX_COLS; gridBagConstraints.weightx = GLUE_WEIGHT_X; // take up all the horizontal space - gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + gridBagConstraints.fill = GridBagConstraints.BOTH; javax.swing.Box.Filler horizontalFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(32767, 0)); // add to panel - addToPanel(horizontalFiller, gridBagConstraints); + addToPanel(horizontalFiller); + // restore fill & weight + gridBagConstraints.fill = GridBagConstraints.NONE; + gridBagConstraints.weightx = TEXT_WEIGHT_X; } /** * Adds a filler/glue at the bottom of the panel to keep the data rows * aligned, in case the panel is resized. - * - * @param row The row for the line end glue. */ - private void addPageEndGlue(int row) { - GridBagConstraints gridBagConstraints = getDefaultConstraints(row, 0); + private void addPageEndGlue() { gridBagConstraints.weighty = 1.0; // take up all the vertical space gridBagConstraints.fill = GridBagConstraints.VERTICAL; javax.swing.Box.Filler vertFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(0, 32767)); // add to panel - addToPanel(vertFiller, gridBagConstraints); + addToPanel(vertFiller); } /** * Adds a label/key to the panel. * * @param keyString Key name to display. - * @param row The row for this column. * * @return Label added. */ - private JLabel addKeyAtCol(String keyString, int row) { + private JLabel addKeyAtCol(String keyString) { // create label javax.swing.JLabel keyLabel = new javax.swing.JLabel(); keyLabel.setFocusable(false); - - GridBagConstraints gridBagConstraints = getDefaultConstraints(row, LABEL_COLUMN); - gridBagConstraints.gridwidth = LABEL_WIDTH; + gridBagConstraints.gridy++; gridBagConstraints.insets = KEY_COLUMN_INSETS; + gridBagConstraints.gridx = LABEL_COLUMN; + gridBagConstraints.gridwidth = LABEL_WIDTH; // set text - keyLabel.setText(keyString + ":"); + keyLabel.setText(keyString + ": "); // add to panel - addToPanel(keyLabel, gridBagConstraints); + addToPanel(keyLabel); return keyLabel; } - private void addToPanel(Component comp, GridBagConstraints gridBagConstraints) { + private void addToPanel(Component comp) { detailsPanel.add(comp, gridBagConstraints); detailsPanel.revalidate(); } @@ -518,22 +493,22 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i * Adds a value string to the panel at specified column. * * @param valueString Value string to display. - * @param row The row for this column. * * @return Label added. */ - private JTextPane addValueAtCol(String valueString, int row) { + private JTextPane addValueAtCol(String valueString) { // create label, JTextPane valueField = new JTextPane(); valueField.setFocusable(false); valueField.setEditable(false); valueField.setOpaque(false); - - GridBagConstraints gridBagConstraints = getDefaultConstraints(row, VALUE_COLUMN); - // let the value span 2 cols - gridBagConstraints.gridwidth = VALUE_WIDTH; + valueField.setMargin(ZERO_INSETS); + gridBagConstraints.gridx = VALUE_COLUMN; gridBagConstraints.insets = VALUE_COLUMN_INSETS; - + GridBagConstraints cloneConstraints = (GridBagConstraints) gridBagConstraints.clone(); + // let the value span 2 cols + cloneConstraints.gridwidth = VALUE_WIDTH; + cloneConstraints.fill = GridBagConstraints.BOTH; // set text valueField.setText(valueString); // attach a right click menu with Copy option @@ -544,10 +519,10 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i } }); // add label to panel with cloned contraintsF - detailsPanel.add(valueField, gridBagConstraints); + detailsPanel.add(valueField, cloneConstraints); revalidate(); // end the line - addLineEndGlue(row); + addLineEndGlue(); return valueField; } From 8c9001ef6d6088b81bb3a7042c7efdefecf2801e Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 3 Jun 2021 15:16:31 -0400 Subject: [PATCH 12/70] Fixes --- .../experimental/autoingest/AutoIngestJobsNode.java | 1 + .../experimental/autoingest/AutoIngestMonitor.java | 11 +++++++++++ .../experimental/autoingest/Bundle.properties-MERGED | 2 -- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index 9f6f70f3e9..6f8ae886c1 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -139,6 +139,7 @@ final class AutoIngestJobsNode extends AbstractNode { hash = 23 * hash + Objects.hashCode(this.jobStage); hash = 23 * hash + Objects.hashCode(this.jobSnapshot); hash = 23 * hash + Objects.hashCode(this.jobPriority); + hash = 23 * hash + Objects.hashCode(this.autoIngestJob.getOcrEnabled()); return hash; } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java index f9033f3235..0022cf6609 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java @@ -167,6 +167,8 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen handleAutoIngestNodeStateEvent((AutoIngestNodeStateEvent) event); } else if (event instanceof ThreadDumpResponseEvent) { handleRemoteThreadDumpResponseEvent((ThreadDumpResponseEvent) event); + } else if (event instanceof AutoIngestOcrStateChangeEvent) { + handleOcrStateChangeEvent((AutoIngestOcrStateChangeEvent) event); } } @@ -229,6 +231,15 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen } } + /** + * Handles an OCR state change event. + * + * @param event OCR state change event. + */ + private void handleOcrStateChangeEvent(AutoIngestOcrStateChangeEvent event) { + coordSvcQueryExecutor.submit(new StateRefreshTask()); + } + /** * Handles an auto ingest job/case prioritization event. * diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED index 5e32707834..1eba0a4194 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED @@ -212,9 +212,7 @@ DeleteCaseTask.progress.parsingManifest=Parsing manifest file {0}... DeleteCaseTask.progress.releasingManifestLock=Releasing lock on the manifest file {0}... DeleteCaseTask.progress.startMessage=Starting deletion... DeleteOrphanCaseNodesAction.progressDisplayName=Cleanup Case Znodes -# {0} - item count DeleteOrphanCaseNodesDialog.additionalInit.lblNodeCount.text=Znodes found: {0} -# {0} - item count DeleteOrphanCaseNodesDialog.additionalInit.znodesTextArea.countMessage=ZNODES FOUND: {0} DeleteOrphanCaseNodesTask.progress.connectingToCoordSvc=Connecting to the coordination service # {0} - node path From b46e1cc35d7a88b68db05045c7b88144adc54e32 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 3 Jun 2021 16:11:56 -0400 Subject: [PATCH 13/70] Minor changed to clean up the return of the addNotify methods --- .../autopsy/datamodel/Artifacts.java | 3 ++- .../datamodel/AutopsyTreeChildFactory.java | 12 +++++----- .../sleuthkit/autopsy/datamodel/HostNode.java | 23 ++++++++++--------- .../autopsy/datamodel/PersonNode.java | 11 ++++----- .../autopsy/datamodel/accounts/Accounts.java | 6 ++++- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Artifacts.java b/Core/src/org/sleuthkit/autopsy/datamodel/Artifacts.java index a8c1c08b76..cd0b03fd98 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Artifacts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Artifacts.java @@ -324,7 +324,8 @@ public class Artifacts { } @Override - protected void addNotify() { + protected void addNotify() { + super.addNotify(); refreshThrottler.registerForIngestModuleEvents(); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java index 1393a6ab4d..1f3356caf7 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java @@ -84,17 +84,17 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable dataSourceToNode; + /** + * Main constructor. + * + * @param dataSourceToItem Converts a data source to a node. + * @param host The host. + */ + HostGroupingChildren(Function dataSourceToNode, Host host) { + this.host = host; + this.dataSourceToNode = dataSourceToNode; + } + /** * Listener for handling DATA_SOURCE_ADDED / HOST_DELETED events. * A host may have been deleted as part of a merge, which means its data sources could @@ -84,20 +95,10 @@ public class HostNode extends DisplayableItemNode { }; private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(dataSourceAddedPcl, null); - - /** - * Main constructor. - * - * @param dataSourceToItem Converts a data source to a node. - * @param host The host. - */ - HostGroupingChildren(Function dataSourceToNode, Host host) { - this.host = host; - this.dataSourceToNode = dataSourceToNode; - } @Override protected void addNotify() { + super.addNotify(); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), weakPcl); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java index 3820514219..ce55b25560 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java @@ -115,18 +115,17 @@ public class PersonNode extends DisplayableItemNode { private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(hostAddedDeletedPcl, null); + @Override + protected void addNotify() { + Case.addEventTypeSubscriber(HOST_EVENTS_OF_INTEREST, weakPcl); + } + @Override protected void finalize() throws Throwable { super.finalize(); Case.removeEventTypeSubscriber(HOST_EVENTS_OF_INTEREST, weakPcl); } - @Override - protected void addNotify() { - Case.addEventTypeSubscriber(HOST_EVENTS_OF_INTEREST, weakPcl); - } - - @Override protected HostNode createNodeForKey(HostGrouping key) { return key == null ? null : new HostNode(key); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 5e82a23009..7b2e1f5147 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -750,6 +750,7 @@ final public class Accounts implements AutopsyVisitableItem { IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); + super.addNotify(); } @Override @@ -894,6 +895,7 @@ final public class Accounts implements AutopsyVisitableItem { IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); + super.addNotify(); } @Override @@ -1104,10 +1106,12 @@ final public class Accounts implements AutopsyVisitableItem { private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); - BINFactory() { + @Override + protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); + super.addNotify(); } @Override From 3b9a6f6bb2ee5efca82ddca7083edf436d89d209 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 3 Jun 2021 16:35:18 -0400 Subject: [PATCH 14/70] context viewer --- .../contextviewer/ContextSourcePanel.form | 23 +++-- .../contextviewer/ContextSourcePanel.java | 16 +-- .../contextviewer/ContextUsagePanel.form | 24 +++-- .../contextviewer/ContextUsagePanel.java | 19 ++-- .../contextviewer/ContextViewer.form | 99 ++++--------------- .../contextviewer/ContextViewer.java | 96 +++++++----------- .../layout/ContentViewerDefaults.java | 37 ++++--- 7 files changed, 118 insertions(+), 196 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form index c57a0990a8..9b2e224b22 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form @@ -2,11 +2,17 @@
- - + + + + + + + + - + @@ -24,15 +30,13 @@ - - + - - + - + @@ -41,14 +45,13 @@ - - + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java index 02bd3f2ae6..9ca74d06c1 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer; import java.util.ArrayList; import java.util.List; import org.sleuthkit.autopsy.contentviewers.contextviewer.ContextViewer.DateTimePanel; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; @@ -75,8 +76,10 @@ public final class ContextSourcePanel extends javax.swing.JPanel implements Date jSourceNameLabel = new javax.swing.JLabel(); jSourceTextLabel = new javax.swing.JLabel(); - setBackground(new java.awt.Color(255, 255, 255)); - setPreferredSize(new java.awt.Dimension(495, 75)); + setBackground(ContentViewerDefaults.getPanelBackground()); + setMaximumSize(new java.awt.Dimension(495, 55)); + setMinimumSize(new java.awt.Dimension(300, 55)); + setPreferredSize(new java.awt.Dimension(495, 55)); org.openide.awt.Mnemonics.setLocalizedText(jSourceGoToResultButton, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceGoToResultButton.text")); // NOI18N jSourceGoToResultButton.addActionListener(new java.awt.event.ActionListener() { @@ -94,26 +97,23 @@ public final class ContextSourcePanel extends javax.swing.JPanel implements Date layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(50, 50, 50) .addComponent(jSourceNameLabel) .addGap(36, 36, 36) - .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(260, 260, 260)) + .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() - .addGap(90, 90, 90) + .addGap(40, 40, 40) .addComponent(jSourceGoToResultButton) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(2, 2, 2) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jSourceNameLabel) .addComponent(jSourceTextLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSourceGoToResultButton) - .addGap(0, 0, 0)) + .addGap(0, 11, Short.MAX_VALUE)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form index a3e2a90f84..2faf5bf779 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form @@ -2,11 +2,17 @@ - - + + + + + + + + - + @@ -24,30 +30,28 @@ - - + - - + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java index 4a96dfcffd..3eeb4b4442 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer; import java.util.ArrayList; import java.util.List; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; @@ -74,8 +75,10 @@ public final class ContextUsagePanel extends javax.swing.JPanel implements Conte jUsageNameLabel = new javax.swing.JLabel(); jUsageTextLabel = new javax.swing.JLabel(); - setBackground(new java.awt.Color(255, 255, 255)); - setPreferredSize(new java.awt.Dimension(495, 75)); + setBackground(ContentViewerDefaults.getPanelBackground()); + setMaximumSize(new java.awt.Dimension(32767, 55)); + setMinimumSize(new java.awt.Dimension(300, 55)); + setPreferredSize(new java.awt.Dimension(495, 55)); org.openide.awt.Mnemonics.setLocalizedText(jUsageGoToResultButton, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageGoToResultButton.text")); // NOI18N jUsageGoToResultButton.addActionListener(new java.awt.event.ActionListener() { @@ -93,25 +96,23 @@ public final class ContextUsagePanel extends javax.swing.JPanel implements Conte layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(50, 50, 50) .addComponent(jUsageNameLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 240, Short.MAX_VALUE) - .addGap(36, 36, 36)) + .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() - .addGap(90, 90, 90) + .addGap(40, 40, 40) .addComponent(jUsageGoToResultButton) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(275, javax.swing.GroupLayout.PREFERRED_SIZE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(2, 2, 2) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jUsageTextLabel) .addComponent(jUsageNameLabel, javax.swing.GroupLayout.Alignment.TRAILING)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jUsageGoToResultButton)) + .addComponent(jUsageGoToResultButton) + .addGap(0, 11, Short.MAX_VALUE)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form index 01c484ba9e..bb1a78d555 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form @@ -4,38 +4,19 @@ - - + + - - - - - - - - - - - - - - - - - - - + + - - - - + + @@ -50,38 +31,19 @@ - - + + - - - - - - - - - - - - - - - - - - - + + - - - - + + @@ -95,31 +57,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -127,6 +67,9 @@ + + + @@ -137,9 +80,6 @@ - - - @@ -170,11 +110,6 @@ - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index bfa0cfc3e9..dab7a657f9 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer; import java.awt.Component; +import java.awt.Insets; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -28,12 +29,14 @@ import java.util.Map; import java.util.logging.Level; import javax.swing.BoxLayout; import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED; +import javax.swing.border.EmptyBorder; import org.apache.commons.lang.StringUtils; import org.openide.nodes.Node; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; @@ -55,6 +58,10 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte private static final Logger logger = Logger.getLogger(ContextViewer.class.getName()); private static final int ARTIFACT_STR_MAX_LEN = 1024; private static final int ATTRIBUTE_STR_MAX_LEN = 200; + + private final static Insets FIRST_HEADER_INSETS = new Insets(0, 0, 0, 0); + private final static Insets HEADER_INSETS = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0); + private final static Insets DATA_ROW_INSETS = new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); // defines a list of artifacts that provide context for a file private static final List CONTEXT_ARTIFACTS = new ArrayList<>(); @@ -91,76 +98,29 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte javax.swing.JLabel jUnknownLabel = new javax.swing.JLabel(); jScrollPane = new javax.swing.JScrollPane(); - jSourcePanel.setBackground(javax.swing.UIManager.getDefaults().getColor("window")); + jSourcePanel.setBorder(new EmptyBorder(FIRST_HEADER_INSETS)); + jSourcePanel.setLayout(new javax.swing.BoxLayout(jSourcePanel, javax.swing.BoxLayout.PAGE_AXIS)); - jSourceLabel.setFont(jSourceLabel.getFont().deriveFont(jSourceLabel.getFont().getStyle() | java.awt.Font.BOLD, jSourceLabel.getFont().getSize()+1)); + jSourceLabel.setFont(ContentViewerDefaults.getHeaderFont()); org.openide.awt.Mnemonics.setLocalizedText(jSourceLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceLabel.text")); // NOI18N + jSourcePanel.add(jSourceLabel); - javax.swing.GroupLayout jSourcePanelLayout = new javax.swing.GroupLayout(jSourcePanel); - jSourcePanel.setLayout(jSourcePanelLayout); - jSourcePanelLayout.setHorizontalGroup( - jSourcePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jSourcePanelLayout.createSequentialGroup() - .addGap(40, 40, 40) - .addComponent(jSourceLabel) - .addContainerGap(304, Short.MAX_VALUE)) + jUsagePanel.setBorder(new EmptyBorder(HEADER_INSETS)); + jUsagePanel.setLayout(new javax.swing.BoxLayout(jUsagePanel, javax.swing.BoxLayout.PAGE_AXIS)); + + jUsageLabel.setFont(ContentViewerDefaults.getHeaderFont() ); - jSourcePanelLayout.setVerticalGroup( - jSourcePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jSourcePanelLayout.createSequentialGroup() - .addGap(5, 5, 5) - .addComponent(jSourceLabel) - .addGap(2, 2, 2)) - ); - - jUsagePanel.setBackground(javax.swing.UIManager.getDefaults().getColor("window")); - - jUsageLabel.setFont(jUsageLabel.getFont().deriveFont(jUsageLabel.getFont().getStyle() | java.awt.Font.BOLD, jUsageLabel.getFont().getSize()+1)); org.openide.awt.Mnemonics.setLocalizedText(jUsageLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUsageLabel.text")); // NOI18N + jUsagePanel.add(jUsageLabel); - javax.swing.GroupLayout jUsagePanelLayout = new javax.swing.GroupLayout(jUsagePanel); - jUsagePanel.setLayout(jUsagePanelLayout); - jUsagePanelLayout.setHorizontalGroup( - jUsagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jUsagePanelLayout.createSequentialGroup() - .addGap(40, 40, 40) - .addComponent(jUsageLabel) - .addContainerGap(298, Short.MAX_VALUE)) - ); - jUsagePanelLayout.setVerticalGroup( - jUsagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jUsagePanelLayout.createSequentialGroup() - .addGap(2, 2, 2) - .addComponent(jUsageLabel) - .addGap(2, 2, 2)) - ); - - jUnknownPanel.setBackground(new java.awt.Color(255, 255, 255)); + jUnknownPanel.setLayout(new javax.swing.BoxLayout(jUnknownPanel, javax.swing.BoxLayout.PAGE_AXIS)); org.openide.awt.Mnemonics.setLocalizedText(jUnknownLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUnknownLabel.text")); // NOI18N + jUnknownLabel.setBorder(new EmptyBorder(DATA_ROW_INSETS)); + jUnknownPanel.add(jUnknownLabel); - javax.swing.GroupLayout jUnknownPanelLayout = new javax.swing.GroupLayout(jUnknownPanel); - jUnknownPanel.setLayout(jUnknownPanelLayout); - jUnknownPanelLayout.setHorizontalGroup( - jUnknownPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jUnknownPanelLayout.createSequentialGroup() - .addGap(50, 50, 50) - .addComponent(jUnknownLabel) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - jUnknownPanelLayout.setVerticalGroup( - jUnknownPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jUnknownPanelLayout.createSequentialGroup() - .addGap(2, 2, 2) - .addComponent(jUnknownLabel) - .addGap(2, 2, 2)) - ); - - setBackground(new java.awt.Color(255, 255, 255)); setPreferredSize(new java.awt.Dimension(495, 358)); - jScrollPane.setBackground(new java.awt.Color(255, 255, 255)); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -275,6 +235,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte } } javax.swing.JPanel contextContainer = new javax.swing.JPanel(); + contextContainer.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets())); + contextContainer.add(jSourcePanel); contextContainer.setLayout(new BoxLayout(contextContainer, BoxLayout.Y_AXIS)); if (contextSourcePanels.isEmpty()) { @@ -282,6 +244,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte } else { for (javax.swing.JPanel sourcePanel : contextSourcePanels) { contextContainer.add(sourcePanel); + contextContainer.setAlignmentX(0); } } contextContainer.add(jUsagePanel); @@ -290,10 +253,11 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte } else { for (javax.swing.JPanel usagePanel : contextUsagePanels) { contextContainer.add(usagePanel); + contextContainer.setAlignmentX(0); } } - contextContainer.setBackground(javax.swing.UIManager.getDefaults().getColor("window")); + contextContainer.setBackground(ContentViewerDefaults.getPanelBackground()); contextContainer.setEnabled(foundASource); contextContainer.setVisible(foundASource); jScrollPane.getViewport().setView(contextContainer); @@ -346,6 +310,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte String sourceName = Bundle.ContextViewer_attachmentSource(); String sourceText = msgArtifactToAbbreviatedString(associatedArtifact); ContextSourcePanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, dateTime); + sourcePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS)); + sourcePanel.setAlignmentX(0); contextSourcePanels.add(sourcePanel); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID() @@ -353,18 +319,24 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte String sourceName = Bundle.ContextViewer_downloadSource(); String sourceText = webDownloadArtifactToString(associatedArtifact); ContextSourcePanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, dateTime); + sourcePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS)); + sourcePanel.setAlignmentX(0); contextSourcePanels.add(sourcePanel); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) { String sourceName = Bundle.ContextViewer_recentDocs(); String sourceText = recentDocArtifactToString(associatedArtifact); - ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime); + ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime); + usagePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS)); + usagePanel.setAlignmentX(0); contextUsagePanels.add(usagePanel); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) { String sourceName = Bundle.ContextViewer_programExecution(); String sourceText = programExecArtifactToString(associatedArtifact); - ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime); + ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime); + usagePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS)); + usagePanel.setAlignmentX(0); contextUsagePanels.add(usagePanel); } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java index b221e1f522..95c7385023 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java @@ -10,6 +10,7 @@ import java.awt.Font; import java.awt.Insets; import java.awt.Toolkit; import com.google.common.base.Supplier; +import java.awt.Color; import javax.swing.UIManager; /** @@ -17,53 +18,59 @@ import javax.swing.UIManager; * @author gregd */ public class ContentViewerDefaults { + private static final Supplier DEFAULT_FONT = Suppliers.memoize(() -> UIManager.getDefaults().getFont("Label.font")); - + private static final Supplier DEFAULT_FONT_PX = Suppliers.memoize(() -> { // based on https://stackoverflow.com/questions/5829703/java-getting-a-font-with-a-specific-height-in-pixels/26564924#26564924 return (int) Math.round(DEFAULT_FONT.get().getSize() * Toolkit.getDefaultToolkit().getScreenResolution() / 72.0); }); - + private static final Supplier HEADER_FONT = Suppliers.memoize(() -> { Font defaultFont = DEFAULT_FONT.get(); return defaultFont.deriveFont(Font.BOLD, defaultFont.getSize() + 2); }); - + private static final Supplier DEFAULT_PANEL_INSETS = Suppliers.memoize(() -> UIManager.getDefaults().getInsets("TextPane.margin")); - + private static final Supplier DEFAULT_INDENT = Suppliers.memoize(() -> DEFAULT_FONT_PX.get()); private static final Supplier DEFAULT_SECTION_SPACING = Suppliers.memoize(() -> DEFAULT_FONT_PX.get()); - - private static final Supplier DEFAULT_COLUMN_SPACING = Suppliers.memoize(() -> (int)(DEFAULT_FONT_PX.get() / 3)); - private static final Supplier DEFAULT_LINE_SPACING = Suppliers.memoize(() -> (int)(DEFAULT_FONT_PX.get() / 5)); - + + private static final Supplier DEFAULT_COLUMN_SPACING = Suppliers.memoize(() -> (DEFAULT_FONT_PX.get() / 3)); + private static final Supplier DEFAULT_LINE_SPACING = Suppliers.memoize(() -> (DEFAULT_FONT_PX.get() / 5)); + + private static final Supplier DEFAULT_BACKGROUND = Suppliers.memoize(() -> UIManager.getColor("Panel.background")); + public static int getColumnSpacing() { return DEFAULT_COLUMN_SPACING.get(); } - + public static Font getFont() { return DEFAULT_FONT.get(); } - + public static Font getHeaderFont() { return HEADER_FONT.get(); } - + public static Insets getPanelInsets() { return DEFAULT_PANEL_INSETS.get(); } - + public static Integer getSectionIndent() { return DEFAULT_INDENT.get(); } - + public static Integer getSectionSpacing() { return DEFAULT_SECTION_SPACING.get(); } - + public static Integer getLineSpacing() { return DEFAULT_LINE_SPACING.get(); } - + + public static Color getPanelBackground() { + return DEFAULT_BACKGROUND.get(); + } // line spacing??? } From 86035a633618b182e63e501b856eb45aee857267 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 3 Jun 2021 19:44:38 -0400 Subject: [PATCH 15/70] Bug fixes --- .../experimental/autoingest/AutoIngestJobNodeData.java | 6 +++++- .../autopsy/experimental/autoingest/AutoIngestJobsNode.java | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java index 7078cda1d7..5e9ab8955d 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java @@ -134,7 +134,7 @@ final class AutoIngestJobNodeData { if (null == nodeData || nodeData.length == 0) { throw new InvalidDataException(null == nodeData ? "Null nodeData byte array" : "Zero-length nodeData byte array"); } - + /* * Set default values for all fields. */ @@ -600,6 +600,10 @@ final class AutoIngestJobNodeData { if (this.version >= 2) { buffer.putLong(this.dataSourceSize); } + + if (this.version >= 3) { + buffer.putInt(this.ocrEnabled ? 1 : 0); + } } // Prepare the array diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index 6f8ae886c1..00a39914a9 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -99,12 +99,14 @@ final class AutoIngestJobsNode extends AbstractNode { private final Stage jobStage; private final List jobSnapshot; private final Integer jobPriority; + private final Boolean ocrFlag; AutoIngestJobWrapper(AutoIngestJob job) { autoIngestJob = job; jobStage = job.getProcessingStage(); jobSnapshot = job.getIngestJobSnapshots(); jobPriority = job.getPriority(); + ocrFlag = job.getOcrEnabled(); } AutoIngestJob getJob() { @@ -129,7 +131,7 @@ final class AutoIngestJobsNode extends AbstractNode { && jobStage.equals(((AutoIngestJobWrapper) other).jobStage) && jobSnapshot.equals(((AutoIngestJobWrapper) other).jobSnapshot) && jobPriority.equals(((AutoIngestJobWrapper) other).jobPriority) - && (thisJob.getOcrEnabled() == otherJob.getOcrEnabled()); + && ocrFlag.equals(((AutoIngestJobWrapper) other).ocrFlag); } @Override @@ -139,7 +141,7 @@ final class AutoIngestJobsNode extends AbstractNode { hash = 23 * hash + Objects.hashCode(this.jobStage); hash = 23 * hash + Objects.hashCode(this.jobSnapshot); hash = 23 * hash + Objects.hashCode(this.jobPriority); - hash = 23 * hash + Objects.hashCode(this.autoIngestJob.getOcrEnabled()); + hash = 23 * hash + Objects.hashCode(this.ocrFlag); return hash; } From e71633b495bdb2cd05efbc6113a37c03ea130908 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 3 Jun 2021 19:59:07 -0400 Subject: [PATCH 16/70] Bug fix --- .../org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java index 7567725b0c..3a51c69494 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java @@ -471,6 +471,7 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService { @Override public void changeOcrState(boolean state) { KeywordSearchSettings.setOcrOption(state); + KeywordSearchSettings.setLimitedOcrOption(state); } } From 5b38d899c3099c7a18d968a7fbf7de484715a50a Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 3 Jun 2021 20:28:32 -0400 Subject: [PATCH 17/70] Added OCR column to completed jobs table --- .../autoingest/AutoIngestControlPanel.java | 14 +++++++++++--- .../autoingest/AutoIngestJobsNode.java | 2 ++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java index 6b90a01fc4..763d41c027 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java @@ -122,7 +122,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { private static final int RUNNING_TABLE_COL_PREFERRED_WIDTH = 175; private static final int PRIORITY_COLUMN_PREFERRED_WIDTH = 60; private static final int PRIORITY_COLUMN_MAX_WIDTH = 150; - private static final int OCR_COLUMN_PREFERRED_WIDTH = 60; + private static final int OCR_COLUMN_PREFERRED_WIDTH = 80; private static final int OCR_COLUMN_MAX_WIDTH = 150; private static final int ACTIVITY_TIME_COL_MIN_WIDTH = 250; private static final int ACTIVITY_TIME_COL_MAX_WIDTH = 450; @@ -566,7 +566,6 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.PRIORITY.getColumnHeader())); - completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.OCR.getColumnHeader())); // ELTODO ? /* * Set up a column to display the cases associated with the jobs. @@ -618,6 +617,15 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { column.setMaxWidth(STATUS_COL_MAX_WIDTH); column.setPreferredWidth(STATUS_COL_PREFERRED_WIDTH); column.setWidth(STATUS_COL_PREFERRED_WIDTH); + + /* + * Set up a column to display OCR enabled/disabled flag. + */ + column = completedTable.getColumn(JobsTableModelColumns.OCR.getColumnHeader()); + column.setCellRenderer(new OcrIconCellRenderer()); + column.setMaxWidth(OCR_COLUMN_MAX_WIDTH); + column.setPreferredWidth(OCR_COLUMN_PREFERRED_WIDTH); + column.setWidth(OCR_COLUMN_PREFERRED_WIDTH); /* * Allow sorting when a column header is clicked. @@ -871,6 +879,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { case JOB_COMPLETED: case CASE_DELETED: case REPROCESS_JOB: + case OCR_STATE_CHANGE: updateExecutor.submit(new UpdateAllJobsTablesTask()); break; case PAUSED_BY_USER_REQUEST: @@ -897,7 +906,6 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { }); break; case CASE_PRIORITIZED: - case OCR_STATE_CHANGE: updateExecutor.submit(new UpdatePendingJobsTableTask()); break; case JOB_STATUS_UPDATED: diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index 00a39914a9..e68a1f79f6 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -355,6 +355,8 @@ final class AutoIngestJobsNode extends AbstractNode { jobWrapper.getCompletedDate())); ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text(), jobWrapper.getErrorsOccurred() ? StatusIconCellRenderer.Status.WARNING : StatusIconCellRenderer.Status.OK)); + ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text(), + jobWrapper.getOcrEnabled())); break; default: } From 8a4bd4548a9d0b192894bcaf26525dc80f53ae47 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 3 Jun 2021 20:48:35 -0400 Subject: [PATCH 18/70] Minor --- .../experimental/autoingest/AutoIngestControlPanel.java | 4 ++-- .../autopsy/experimental/autoingest/AutoIngestManager.java | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java index 763d41c027..0fcf8490f9 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java @@ -122,7 +122,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { private static final int RUNNING_TABLE_COL_PREFERRED_WIDTH = 175; private static final int PRIORITY_COLUMN_PREFERRED_WIDTH = 60; private static final int PRIORITY_COLUMN_MAX_WIDTH = 150; - private static final int OCR_COLUMN_PREFERRED_WIDTH = 80; + private static final int OCR_COLUMN_PREFERRED_WIDTH = 50; private static final int OCR_COLUMN_MAX_WIDTH = 150; private static final int ACTIVITY_TIME_COL_MIN_WIDTH = 250; private static final int ACTIVITY_TIME_COL_MAX_WIDTH = 450; @@ -182,7 +182,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { "AutoIngestControlPanel.JobsTableModel.ColumnHeader.CaseFolder=Case Folder", "AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob= Local Job?", "AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath= Manifest File Path", - "AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR=OCR Enabled" + "AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR=OCR" }) private enum JobsTableModelColumns { diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index 968e61ae60..7f72a02fd9 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -2297,6 +2297,11 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } // update the OCR enabled/disabled setting + if (currentJob.getOcrEnabled()) { + sysLogger.log(Level.INFO, "Enabling OCR for job {0}", currentJob.getManifest().getFilePath()); + } else { + sysLogger.log(Level.INFO, "Disabling OCR for job {0}", currentJob.getManifest().getFilePath()); + } KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class); kwsService.changeOcrState(currentJob.getOcrEnabled()); } From a3d0fd3a675afdbf1d6d0ea28534a984a2c90051 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 3 Jun 2021 21:32:02 -0400 Subject: [PATCH 19/70] Minor --- .../experimental/autoingest/AutoIngestControlPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java index 0fcf8490f9..656b98b278 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java @@ -135,9 +135,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { private static final int ACTIVITY_COL_MIN_WIDTH = 70; private static final int ACTIVITY_COL_MAX_WIDTH = 2000; private static final int ACTIVITY_COL_PREFERRED_WIDTH = 300; - private static final int STATUS_COL_MIN_WIDTH = 55; + private static final int STATUS_COL_MIN_WIDTH = 50; private static final int STATUS_COL_MAX_WIDTH = 250; - private static final int STATUS_COL_PREFERRED_WIDTH = 55; + private static final int STATUS_COL_PREFERRED_WIDTH = 50; private static final int COMPLETED_TIME_COL_MIN_WIDTH = 30; private static final int COMPLETED_TIME_COL_MAX_WIDTH = 2000; private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280; From 2f20e841124efb96827b0480f555b019a96464da Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 4 Jun 2021 09:38:27 -0400 Subject: [PATCH 20/70] content viewer common css --- .../layout/ContentViewerHtmlStyles.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java new file mode 100644 index 0000000000..b417e3391d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java @@ -0,0 +1,68 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.contentviewers.layout; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Insets; +import javax.swing.JLabel; + +/** + * + * @author gregd + */ +public class ContentViewerHtmlStyles { + + private static final String DEFAULT_FONT_FAMILY = new JLabel().getFont().getFamily(); + private static final int DEFAULT_FONT_SIZE = new JLabel().getFont().getSize(); + private static final Color DEFAULT_BACKGROUND = new JLabel().getBackground(); + + // html stylesheet classnames for components + private static final String ANALYSIS_RESULTS_CLASS_PREFIX = "analysisResult_"; + private static final String SPACED_SECTION_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "spacedSection"; + private static final String SUBSECTION_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "subsection"; + private static final String HEADER_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "header"; + public static final String MESSAGE_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "message"; + public static final String TD_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "td"; + + // Anchors are inserted into the navigation so that the viewer can navigate to a selection. + // This is the prefix of those anchors. + private static final String CLASSNAME_PREFIX = "ContentViewer_"; + + // how big the header should be + private static final int HEADER_FONT_SIZE = DEFAULT_FONT_SIZE + 2; + + // spacing occurring after an item + private static final int DEFAULT_SECTION_SPACING = DEFAULT_FONT_SIZE / 2; + private static final int CELL_SPACING = DEFAULT_FONT_SIZE / 2; + + // the subsection indent + private static final int DEFAULT_SUBSECTION_LEFT_PAD = DEFAULT_FONT_SIZE; + + + + + private static final Font DEFAULT_FONT = ContentViewerDefaults.getFont(); + private static final Font HEADER_FONT = ContentViewerDefaults.getHeaderFont(); + + + // additional styling for components + private static final String STYLE_SHEET_RULE + = String.format(" .%s { font-family: %s; font-size: %dpt;font-style:italic; margin: 0px; padding: 0px 0px %dpx 0px; } ", + MESSAGE_CLASSNAME, DEFAULT_FONT.getFamily(), DEFAULT_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) + + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px 0px %dpx 0px; } ", + HEADER_CLASSNAME, HEADER_FONT.getFamily(), HEADER_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) + + String.format(" .%s { font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpx 0px; } ", + TEXT_CLASSNAME, DEFAULT_FONT.getFamily(), DEFAULT_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) + + + String.format(" .%s { padding-left: %dpx } ", + INDENTED_CLASSNAME, ContentViewerDefaults.getSectionIndent()) + + String.format(" .%s { margin-top: %dpx } ", + NOT_FIRST_SECTION_CLASSNAME, ContentViewerDefaults.getSectionSpacing()) + + String.format(" .%s { margin-top: %dpx } ", + KEY_COLUMN_TD_CLASSNAME, ContentViewerDefaults.getColumnSpacing()); + +} From bc871232606ec0322c8550a4a17ea0a459cd7840 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 4 Jun 2021 09:46:15 -0400 Subject: [PATCH 21/70] Minor --- .../experimental/autoingest/AutoIngestAdminActions.java | 4 ++-- .../autopsy/experimental/autoingest/AutoIngestJobsNode.java | 5 +++-- .../autopsy/experimental/autoingest/Bundle.properties-MERGED | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java index c44ef22e23..6680074a17 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestAdminActions.java @@ -188,7 +188,7 @@ final class AutoIngestAdminActions { EventQueue.invokeLater(() -> { try { dashboard.getMonitor().changeOcrStateForCase(job.getManifest().getCaseName(), true); - dashboard.getPendingJobsPanel().refresh(new AutoIngestNodeRefreshEvents.RefreshCaseEvent(dashboard.getMonitor(), job.getManifest().getCaseName())); // ELTODO + dashboard.getPendingJobsPanel().refresh(new AutoIngestNodeRefreshEvents.RefreshCaseEvent(dashboard.getMonitor(), job.getManifest().getCaseName())); } catch (AutoIngestMonitor.AutoIngestMonitorException ex) { String errorMessage = String.format(Bundle.AutoIngestAdminActions_enableOCR_error(), job.getManifest().getCaseName()); logger.log(Level.SEVERE, errorMessage, ex); @@ -236,7 +236,7 @@ final class AutoIngestAdminActions { EventQueue.invokeLater(() -> { try { dashboard.getMonitor().changeOcrStateForCase(job.getManifest().getCaseName(), false); - dashboard.getPendingJobsPanel().refresh(new AutoIngestNodeRefreshEvents.RefreshCaseEvent(dashboard.getMonitor(), job.getManifest().getCaseName())); // ELTODO + dashboard.getPendingJobsPanel().refresh(new AutoIngestNodeRefreshEvents.RefreshCaseEvent(dashboard.getMonitor(), job.getManifest().getCaseName())); } catch (AutoIngestMonitor.AutoIngestMonitorException ex) { String errorMessage = String.format(Bundle.AutoIngestAdminActions_disableOCR_error(), job.getManifest().getCaseName()); logger.log(Level.SEVERE, errorMessage, ex); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index e68a1f79f6..ac3f64c847 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -378,9 +378,10 @@ final class AutoIngestJobsNode extends AbstractNode { deprioritizeCaseAction.setEnabled(jobWrapper.getPriority() > 0); actions.add(deprioritizeCaseAction); - // ELTODO enable/disable based on current state actions.add(new AutoIngestAdminActions.EnableOCR(jobWrapper.getJob())); - actions.add(new AutoIngestAdminActions.DisableOCR(jobWrapper.getJob())); + AutoIngestAdminActions.DisableOCR disableOCRAction = new AutoIngestAdminActions.DisableOCR(jobWrapper.getJob()); + disableOCRAction.setEnabled(jobWrapper.getOcrEnabled() == true); + actions.add(disableOCRAction); break; case RUNNING_JOB: actions.add(new AutoIngestAdminActions.ProgressDialogAction(jobWrapper.getJob())); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED index 1eba0a4194..cf4d447b0a 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED @@ -75,7 +75,7 @@ AutoIngestControlPanel.JobsTableModel.ColumnHeader.HostName=Host Name AutoIngestControlPanel.JobsTableModel.ColumnHeader.ImageFolder=Data Source AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob=\ Local Job? AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath=\ Manifest File Path -AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR=OCR Enabled +AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR=OCR AutoIngestControlPanel.JobsTableModel.ColumnHeader.Priority=Prioritized AutoIngestControlPanel.JobsTableModel.ColumnHeader.Stage=Stage AutoIngestControlPanel.JobsTableModel.ColumnHeader.StageTime=Time in Stage From 46eee0b0152d5c3eff33f25d3db0e254ecf41fa0 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 4 Jun 2021 09:53:45 -0400 Subject: [PATCH 22/70] Minor --- .../autopsy/experimental/autoingest/AutoIngestJobsNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index ac3f64c847..24a1e57fb9 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -58,7 +58,7 @@ final class AutoIngestJobsNode extends AbstractNode { "AutoIngestJobsNode.jobCompleted.text=Job Completed", "AutoIngestJobsNode.priority.text=Prioritized", "AutoIngestJobsNode.status.text=Status", - "AutoIngestJobsNode.ocr.text=OCR Enabled" + "AutoIngestJobsNode.ocr.text=OCR" }) /** From ebd776b1f196578c7ece77a692cdef10389a34f8 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 4 Jun 2021 10:20:48 -0400 Subject: [PATCH 23/70] Minor --- .../autopsy/experimental/autoingest/AutoIngestManager.java | 6 +++--- .../experimental/autoingest/Bundle.properties-MERGED | 2 +- .../sleuthkit/autopsy/keywordsearch/SolrSearchService.java | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index 7f72a02fd9..118ff453c6 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -55,7 +55,6 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import javax.annotation.concurrent.GuardedBy; -import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case.CaseType; @@ -471,6 +470,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen String hostName = event.getNodeName(); hostNamesToLastMsgTime.put(hostName, Instant.now()); + // currently the only way to the get latest ZK manifest node contents is to do an input directory scan scanInputDirsNow(); setChanged(); notifyObservers(Event.CASE_PRIORITIZED); @@ -500,7 +500,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen String hostName = event.getNodeName(); hostNamesToLastMsgTime.put(hostName, Instant.now()); - // update all pending jobs and get latest ZK manifest node contents for those jobs + // currently the only way to the get latest ZK manifest node contents is to do an input directory scan scanInputDirsNow(); setChanged(); @@ -2092,7 +2092,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } iterator.remove(); - // create a new job object based on latest ZK node data (i.e. instead of potentially stale local pending AutoIngestJob). + // create a new job object based on latest ZK node data (i.e. instead of re-using potentially stale local pending AutoIngestJob object). currentJob = new AutoIngestJob(nodeData); break; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED index cf4d447b0a..2a1e361537 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED @@ -135,7 +135,7 @@ AutoIngestJobsNode.dataSource.text=Data Source AutoIngestJobsNode.hostName.text=Host Name AutoIngestJobsNode.jobCompleted.text=Job Completed AutoIngestJobsNode.jobCreated.text=Job Created -AutoIngestJobsNode.ocr.text=OCR Enabled +AutoIngestJobsNode.ocr.text=OCR AutoIngestJobsNode.prioritized.false=No AutoIngestJobsNode.prioritized.true=Yes AutoIngestJobsNode.priority.text=Prioritized diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java index 3a51c69494..09460a0788 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java @@ -463,7 +463,8 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService { } /** - * A flag to enable or disable OCR on all future text indexing. + * A flag to enable or disable OCR on all future text indexing. Also sets the + * the "Limited OCR" functionality accordingly. * * @param state Boolean flag to enable/disable OCR. Set to True to enable * OCR, or False to disable it. From 557f4e85e8bfeca89fbd5403bee0a7bac60c9938 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 4 Jun 2021 13:21:17 -0400 Subject: [PATCH 24/70] Bug fixes --- .../experimental/autoingest/AutoIngestJobsPanel.java | 8 +++++++- .../experimental/autoingest/AutoIngestManager.java | 9 ++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java index d063c7a4f4..d335a35430 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java @@ -109,7 +109,8 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_jobCreated_text(), Bundle.AutoIngestJobsNode_jobCreated_text(), Bundle.AutoIngestJobsNode_jobCompleted_text(), Bundle.AutoIngestJobsNode_jobCompleted_text(), - Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text()); + Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text(), + Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text()); indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_jobCompleted_text()); if (indexOfColumn != INVALID_INDEX) { outline.setColumnSorted(indexOfColumn, false, 1); @@ -119,6 +120,11 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_STATUS_WIDTH); outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new StatusIconCellRenderer()); } + indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_ocr_text()); + if (indexOfColumn != INVALID_INDEX) { + outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_OCR_WIDTH); + outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new OcrIconCellRenderer()); + } break; default: } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index 118ff453c6..f40fa6d189 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -2251,21 +2251,20 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * auto ingest job. */ private void attemptJob() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, IOException, JobMetricsCollectionException { - updateConfiguration(); - if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) { - return; - } verifyRequiredSevicesAreRunning(); if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) { return; } Case caseForJob = openCase(); try { + if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) { + return; + } + updateConfiguration(); if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) { return; } runIngestForJob(caseForJob); - } finally { try { Case.closeCurrentCase(); From e5a36e9dc8147e9e9e0f9f631105118deafe3f6e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 4 Jun 2021 14:08:43 -0400 Subject: [PATCH 25/70] annotation viewer and text panes --- .../AnnotationsContentViewer.java | 49 +------- .../autopsy/contentviewers/Metadata.java | 3 +- .../AnalysisResultsContentPanel.form | 3 - .../AnalysisResultsContentPanel.java | 81 +++++-------- .../application/Annotations.java | 81 +++++++------ .../layout/ContentViewerDefaults.java | 10 +- .../layout/ContentViewerHtmlStyles.java | 106 ++++++++++++------ .../corecomponents/AutoWrappingJTextPane.java | 9 +- 8 files changed, 163 insertions(+), 179 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java index 304300cec4..3df51c9e48 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java @@ -18,14 +18,10 @@ */ package org.sleuthkit.autopsy.contentviewers; -import java.awt.Color; import java.awt.Component; import java.util.concurrent.ExecutionException; import java.util.logging.Level; -import javax.swing.JLabel; import javax.swing.SwingWorker; -import javax.swing.text.EditorKit; -import javax.swing.text.html.HTMLEditorKit; import static org.openide.util.NbBundle.Messages; import org.openide.nodes.Node; @@ -37,6 +33,7 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.contentviewers.application.Annotations; import org.sleuthkit.autopsy.coreutils.Logger; import org.jsoup.nodes.Document; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; /** * Annotations view of file contents. @@ -49,39 +46,6 @@ import org.jsoup.nodes.Document; "AnnotationsContentViewer.onEmpty=No annotations were found for this particular item." }) public class AnnotationsContentViewer extends javax.swing.JPanel implements DataContentViewer { - - private static final String DEFAULT_FONT_FAMILY = new JLabel().getFont().getFamily(); - private static final int DEFAULT_FONT_SIZE = new JLabel().getFont().getSize(); - private static final Color DEFAULT_BACKGROUND = new JLabel().getBackground(); - - // how big the subheader should be - private static final int SUBHEADER_FONT_SIZE = DEFAULT_FONT_SIZE + 1; - - // how big the header should be - private static final int HEADER_FONT_SIZE = DEFAULT_FONT_SIZE + 2; - - // the subsection indent - private static final int DEFAULT_SUBSECTION_LEFT_PAD = DEFAULT_FONT_SIZE; - - // spacing occurring after an item - private static final int DEFAULT_SECTION_SPACING = DEFAULT_FONT_SIZE * 2; - private static final int DEFAULT_SUBSECTION_SPACING = DEFAULT_FONT_SIZE / 2; - private static final int CELL_SPACING = DEFAULT_FONT_SIZE / 2; - - // additional styling for components - private static final String STYLE_SHEET_RULE - = String.format(" .%s { font-family: %s; font-size: %dpt; font-style:italic; margin: 0px; padding: 0px; } ", - Annotations.MESSAGE_CLASSNAME, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE) - + String.format(" .%s { font-family: %s; font-size:%dpt;font-weight:bold; margin: 0px; margin-top: %dpx; padding: 0px; } ", - Annotations.SUBHEADER_CLASSNAME, DEFAULT_FONT_FAMILY, SUBHEADER_FONT_SIZE, DEFAULT_SUBSECTION_SPACING) - + String.format(" .%s { font-family: %s; font-size:%dpt;font-weight:bold; margin: 0px; padding: 0px; } ", - Annotations.HEADER_CLASSNAME, DEFAULT_FONT_FAMILY, HEADER_FONT_SIZE) - + String.format(" td { vertical-align: top; font-family: %s; font-size:%dpt; text-align: left; margin: 0px; padding: 0px %dpx 0px 0px;} ", - DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, CELL_SPACING) - + String.format(" th { vertical-align: top; text-align: left; margin: 0px; padding: 0px %dpx 0px 0px} ", - DEFAULT_FONT_SIZE, CELL_SPACING) - + String.format(" .%s { margin: %dpx 0px; padding-left: %dpx; } ", Annotations.SUBSECTION_CLASSNAME, DEFAULT_SUBSECTION_SPACING, DEFAULT_SUBSECTION_LEFT_PAD) - + String.format(" .%s { margin-bottom: %dpx; } ", Annotations.SECTION_CLASSNAME, DEFAULT_SECTION_SPACING); private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(AnnotationsContentViewer.class.getName()); @@ -93,14 +57,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data */ public AnnotationsContentViewer() { initComponents(); - Utilities.configureTextPaneAsHtml(textPanel); - textPanel.setBackground(DEFAULT_BACKGROUND); - // get html editor kit and apply additional style rules - EditorKit editorKit = textPanel.getEditorKit(); - if (editorKit instanceof HTMLEditorKit) { - HTMLEditorKit htmlKit = (HTMLEditorKit) editorKit; - htmlKit.getStyleSheet().addRule(STYLE_SHEET_RULE); - } + ContentViewerHtmlStyles.setupHtmlJTextPane(textPanel); } @Override @@ -231,7 +188,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data if(doc != null) { return doc.html(); } else { - return Bundle.AnnotationsContentViewer_onEmpty(); + return "" + Bundle.AnnotationsContentViewer_onEmpty() + ""; } } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java index f37cccb028..37edf6d5c0 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java @@ -29,6 +29,7 @@ import org.openide.nodes.Node; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils; @@ -116,7 +117,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { * selectAllMenuItem.addActionListener(actList); */ - Utilities.configureTextPaneAsHtml(jTextPane1); + ContentViewerHtmlStyles.setupHtmlJTextPane(jTextPane1); } private void setText(String str) { diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.form index 22fbe9e8a1..98fb50c89a 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.form @@ -42,9 +42,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java index 72ab3c6853..aadfe4b677 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java @@ -18,11 +18,9 @@ */ package org.sleuthkit.autopsy.contentviewers.analysisresults; -import java.awt.Color; import java.text.MessageFormat; import java.util.List; import java.util.Optional; -import javax.swing.JLabel; import javax.swing.text.html.HTMLEditorKit; import org.apache.commons.lang3.tuple.Pair; import org.jsoup.Jsoup; @@ -31,6 +29,8 @@ import org.jsoup.nodes.Element; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.NodeResults; import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.ResultDisplayAttributes; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.Score; @@ -43,54 +43,16 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { private static final String EMPTY_HTML = ""; - private static final String DEFAULT_FONT_FAMILY = new JLabel().getFont().getFamily(); - private static final int DEFAULT_FONT_SIZE = new JLabel().getFont().getSize(); - private static final Color DEFAULT_BACKGROUND = new JLabel().getBackground(); - - // html stylesheet classnames for components - private static final String ANALYSIS_RESULTS_CLASS_PREFIX = "analysisResult_"; - private static final String SPACED_SECTION_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "spacedSection"; - private static final String SUBSECTION_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "subsection"; - private static final String HEADER_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "header"; - public static final String MESSAGE_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "message"; - public static final String TD_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "td"; - // Anchors are inserted into the navigation so that the viewer can navigate to a selection. // This is the prefix of those anchors. private static final String RESULT_ANCHOR_PREFIX = "AnalysisResult_"; - - // how big the header should be - private static final int HEADER_FONT_SIZE = DEFAULT_FONT_SIZE + 2; - - // spacing occurring after an item - private static final int DEFAULT_SECTION_SPACING = DEFAULT_FONT_SIZE / 2; - private static final int CELL_SPACING = DEFAULT_FONT_SIZE / 2; - - // the subsection indent - private static final int DEFAULT_SUBSECTION_LEFT_PAD = DEFAULT_FONT_SIZE; - - // additional styling for components - private static final String STYLE_SHEET_RULE - = String.format(" .%s { font-size: %dpt;font-style:italic; margin: 0px; padding: 0px; } ", MESSAGE_CLASSNAME, DEFAULT_FONT_SIZE) - + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px; } ", - HEADER_CLASSNAME, DEFAULT_FONT_FAMILY, HEADER_FONT_SIZE) - + String.format(" .%s { vertical-align: top; font-family: %s; font-size: %dpt; text-align: left; margin: 0pt; padding: 0px %dpt 0px 0px;} ", - TD_CLASSNAME, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, CELL_SPACING) - + String.format(" .%s { margin-top: %dpt; } ", SPACED_SECTION_CLASSNAME, DEFAULT_SECTION_SPACING) - + String.format(" .%s { padding-left: %dpt; }", SUBSECTION_CLASSNAME, DEFAULT_SUBSECTION_LEFT_PAD); - - /** * Creates new form AnalysisResultsContentViewer */ public AnalysisResultsContentPanel() { initComponents(); - - textPanel.setContentType("text/html;charset=UTF-8"); //NON-NLS - HTMLEditorKit kit = new HTMLEditorKit(); - textPanel.setEditorKit(kit); - kit.getStyleSheet().addRule(STYLE_SHEET_RULE); + ContentViewerHtmlStyles.setupHtmlJTextPane(textPanel); } /** @@ -101,7 +63,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { void showMessage(String message) { textPanel.setText("" + MessageFormat.format("

{1}

", - MESSAGE_CLASSNAME, + ContentViewerHtmlStyles.getMessageClassName(), message == null ? "" : message) + ""); } @@ -137,7 +99,10 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { List displayAttributes = nodeResults.getAnalysisResults(); for (int idx = 0; idx < displayAttributes.size(); idx++) { AnalysisResultsViewModel.ResultDisplayAttributes resultAttrs = displayAttributes.get(idx); - appendResult(body, idx, resultAttrs); + Element sectionDiv = appendResult(body, idx, resultAttrs); + if (idx > 0 || aggregateScore.isPresent()) { + sectionDiv.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName()); + } } // set the body html @@ -165,11 +130,12 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { * @param parent The parent element. * @param index The index of the item in the list of all items. * @param attrs The attributes of this item. + * @return The result div. */ @NbBundle.Messages({"# {0} - analysisResultsNumber", "AnalysisResultsContentPanel_result_headerKey=Analysis Result {0}" }) - private void appendResult(Element parent, int index, AnalysisResultsViewModel.ResultDisplayAttributes attrs) { + private Element appendResult(Element parent, int index, AnalysisResultsViewModel.ResultDisplayAttributes attrs) { // create a new section with appropriate header Element sectionDiv = appendSection(parent, Bundle.AnalysisResultsContentPanel_result_headerKey(index + 1), @@ -177,7 +143,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { // create a table Element table = sectionDiv.appendElement("table"); - table.attr("class", SUBSECTION_CLASSNAME); + table.attr("class", ContentViewerHtmlStyles.getIndentedClassName()); Element tableBody = table.appendElement("tbody"); @@ -187,13 +153,15 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { String keyString = keyVal.getKey() == null ? "" : keyVal.getKey() + ":"; row.appendElement("td") .text(keyString) - .attr("class", TD_CLASSNAME); + .attr("class", ContentViewerHtmlStyles.getTextClassName() + " " + ContentViewerHtmlStyles.getKeyColumnClassName()); String valueString = keyVal.getValue() == null ? "" : keyVal.getValue(); row.appendElement("td") .text(valueString) - .attr("class", TD_CLASSNAME); + .attr("class", ContentViewerHtmlStyles.getTextClassName()); } + + return sectionDiv; } /** @@ -209,18 +177,22 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { Element sectionDiv = parent.appendElement("div"); // append an anchor tag if there is one + Element anchorEl = null; if (anchorId.isPresent()) { - Element anchorEl = sectionDiv.appendElement("a"); + anchorEl = sectionDiv.appendElement("a"); anchorEl.attr("name", anchorId.get()); + anchorEl.attr("style", "padding: 0px; margin: 0px; display: inline-block;"); } - - // set the class for the section - sectionDiv.attr("class", SPACED_SECTION_CLASSNAME); - + // append the header - Element header = sectionDiv.appendElement("h1"); + Element header = null; + header = (anchorEl == null) + ? sectionDiv.appendElement("h1") + : anchorEl.appendElement("h1"); + header.text(headerText); - header.attr("class", HEADER_CLASSNAME); + header.attr("class", ContentViewerHtmlStyles.getHeaderClassName()); + header.attr("style", "display: inline-block"); // return the section element return sectionDiv; @@ -241,7 +213,6 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { setPreferredSize(new java.awt.Dimension(100, 58)); textPanel.setEditable(false); - textPanel.setBackground(DEFAULT_BACKGROUND); textPanel.setName(""); // NOI18N textPanel.setPreferredSize(new java.awt.Dimension(600, 52)); scrollPane.setViewportView(textPanel); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java b/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java index feec2703dc..9651ddc518 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.function.Function; import java.util.logging.Level; import java.util.stream.Collectors; -import javax.swing.JLabel; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.jsoup.Jsoup; @@ -39,6 +38,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -80,18 +80,6 @@ public class Annotations { private static final String EMPTY_HTML = ""; - private static final int DEFAULT_FONT_SIZE = new JLabel().getFont().getSize(); - // spacing occurring after an item - private static final int DEFAULT_TABLE_SPACING = DEFAULT_FONT_SIZE; - - // html stylesheet classnames for components - public static final String MESSAGE_CLASSNAME = "message"; - public static final String SUBSECTION_CLASSNAME = "subsection"; - public static final String SUBHEADER_CLASSNAME = "subheader"; - public static final String SECTION_CLASSNAME = "section"; - public static final String HEADER_CLASSNAME = "header"; - public static final String VERTICAL_TABLE_CLASSNAME = "vertical-table"; - // describing table values for a tag private static final List> TAG_ENTRIES = Arrays.asList( new ItemEntry<>(Bundle.Annotations_tagEntryDataLabel_tag(), @@ -200,11 +188,11 @@ public class Annotations { * @return If any content was actually rendered. */ private static boolean renderArtifact(Element parent, BlackboardArtifact bba, Content sourceContent) { - boolean contentRendered = appendEntries(parent, TAG_CONFIG, getTags(bba), false); + boolean contentRendered = appendEntries(parent, TAG_CONFIG, getTags(bba), false, true); if (CentralRepository.isEnabled()) { List centralRepoComments = getCentralRepositoryData(bba); - boolean crRendered = appendEntries(parent, CR_COMMENTS_CONFIG, centralRepoComments, false); + boolean crRendered = appendEntries(parent, CR_COMMENTS_CONFIG, centralRepoComments, false, !contentRendered); contentRendered = contentRendered || crRendered; } @@ -213,12 +201,18 @@ public class Annotations { || BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == bba.getArtifactTypeID()) && (hasTskComment(bba))) { - boolean filesetRendered = appendEntries(parent, ARTIFACT_COMMENT_CONFIG, Arrays.asList(bba), false); + boolean filesetRendered = appendEntries(parent, ARTIFACT_COMMENT_CONFIG, Arrays.asList(bba), false, !contentRendered); contentRendered = contentRendered || filesetRendered; } Element sourceFileSection = appendSection(parent, Bundle.Annotations_sourceFile_title()); - boolean sourceFileRendered = renderContent(sourceFileSection, sourceContent, true); + sourceFileSection.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName()); + + Element sourceFileContainer = sourceFileSection.appendElement("div"); + sourceFileContainer.attr("class", ContentViewerHtmlStyles.getIndentedClassName()); + + + boolean sourceFileRendered = renderContent(sourceFileContainer, sourceContent, true); if (!sourceFileRendered) { sourceFileSection.remove(); @@ -238,24 +232,27 @@ public class Annotations { * @return If any content was actually rendered. */ private static boolean renderContent(Element parent, Content sourceContent, boolean isSubheader) { - boolean contentRendered = appendEntries(parent, TAG_CONFIG, getTags(sourceContent), isSubheader); + boolean contentRendered = appendEntries(parent, TAG_CONFIG, getTags(sourceContent), isSubheader, true); if (sourceContent instanceof AbstractFile) { AbstractFile sourceFile = (AbstractFile) sourceContent; if (CentralRepository.isEnabled()) { List centralRepoComments = getCentralRepositoryData(sourceFile); - boolean crRendered = appendEntries(parent, CR_COMMENTS_CONFIG, centralRepoComments, isSubheader); + boolean crRendered = appendEntries(parent, CR_COMMENTS_CONFIG, centralRepoComments, isSubheader, + !contentRendered); contentRendered = contentRendered || crRendered; } boolean hashsetRendered = appendEntries(parent, HASHSET_CONFIG, getFileSetHits(sourceFile, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT), - isSubheader); + isSubheader, + !contentRendered); boolean interestingFileRendered = appendEntries(parent, INTERESTING_FILE_CONFIG, getFileSetHits(sourceFile, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT), - isSubheader); + isSubheader, + !contentRendered); contentRendered = contentRendered || hashsetRendered || interestingFileRendered; } @@ -456,24 +453,36 @@ public class Annotations { * will be formatted as a table in the format specified in the * SectionConfig. * - * @param parent The parent element for which the entries will be - * attached. - * @param config The display configuration for this entry type (i.e. - * table type, name, if data is not present). - * @param items The items to display. - * @param isSubsection Whether or not this should be displayed as a - * subsection. If not displayed as a top-level section. + * @param parent The parent element for which the entries will be + * attached. + * @param config The display configuration for this entry type (i.e. + * table type, name, if data is not present). + * @param items The items to display. + * @param isSubsection Whether or not this should be displayed as a + * subsection. If not displayed as a top-level + * section. + * @param isFirstSection Whether or not this is the first section appended. * * @return If there was actual content rendered for this set of entries. */ private static boolean appendEntries(Element parent, Annotations.SectionConfig config, List items, - boolean isSubsection) { + boolean isSubsection, boolean isFirstSection) { if (items == null || items.isEmpty()) { return false; } Element sectionDiv = (isSubsection) ? appendSubsection(parent, config.getTitle()) : appendSection(parent, config.getTitle()); - appendVerticalEntryTables(sectionDiv, items, config.getAttributes()); + if (!isFirstSection) { + sectionDiv.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName()); + } + + Element sectionContainer = sectionDiv.appendElement("div"); + + if (!isSubsection) { + sectionContainer.attr("class", ContentViewerHtmlStyles.getIndentedClassName()); + } + + appendVerticalEntryTables(sectionContainer, items, config.getAttributes()); return true; } @@ -499,12 +508,11 @@ public class Annotations { .collect(Collectors.toList()); Element childTable = appendTable(parent, 2, tableData, null); - childTable.attr("class", VERTICAL_TABLE_CLASSNAME); if (isFirst) { isFirst = false; } else { - childTable.attr("style", String.format("margin-top: %dpx;", DEFAULT_TABLE_SPACING)); + childTable.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName()); } } @@ -551,6 +559,7 @@ public class Annotations { Element row = rowParent.appendElement("tr"); for (int i = 0; i < columnNumber; i++) { Element cell = row.appendElement(cellType); + cell.attr("class", ContentViewerHtmlStyles.getTextClassName()); if (data != null && i < data.size()) { cell.text(StringUtils.isEmpty(data.get(i)) ? "" : data.get(i)); } @@ -568,10 +577,9 @@ public class Annotations { */ private static Element appendSection(Element parent, String headerText) { Element sectionDiv = parent.appendElement("div"); - sectionDiv.attr("class", SECTION_CLASSNAME); Element header = sectionDiv.appendElement("h1"); header.text(headerText); - header.attr("class", HEADER_CLASSNAME); + header.attr("class", ContentViewerHtmlStyles.getHeaderClassName()); return sectionDiv; } @@ -585,10 +593,9 @@ public class Annotations { */ private static Element appendSubsection(Element parent, String headerText) { Element subsectionDiv = parent.appendElement("div"); - subsectionDiv.attr("class", SUBSECTION_CLASSNAME); Element header = subsectionDiv.appendElement("h2"); header.text(headerText); - header.attr("class", SUBHEADER_CLASSNAME); + header.attr("class", ContentViewerHtmlStyles.getHeaderClassName()); return subsectionDiv; } @@ -605,7 +612,7 @@ public class Annotations { private static Element appendMessage(Element parent, String message) { Element messageEl = parent.appendElement("p"); messageEl.text(message); - messageEl.attr("class", MESSAGE_CLASSNAME); + messageEl.attr("class", ContentViewerHtmlStyles.getMessageClassName()); return messageEl; } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java index 95c7385023..fc9f7c038c 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java @@ -25,6 +25,11 @@ public class ContentViewerDefaults { // based on https://stackoverflow.com/questions/5829703/java-getting-a-font-with-a-specific-height-in-pixels/26564924#26564924 return (int) Math.round(DEFAULT_FONT.get().getSize() * Toolkit.getDefaultToolkit().getScreenResolution() / 72.0); }); + + private static final Supplier SUB_HEADER_FONT = Suppliers.memoize(() -> { + Font defaultFont = DEFAULT_FONT.get(); + return defaultFont.deriveFont(Font.BOLD); + }); private static final Supplier HEADER_FONT = Suppliers.memoize(() -> { Font defaultFont = DEFAULT_FONT.get(); @@ -72,5 +77,8 @@ public class ContentViewerDefaults { public static Color getPanelBackground() { return DEFAULT_BACKGROUND.get(); } - // line spacing??? + + public static Font getSubHeaderFont() { + return SUB_HEADER_FONT.get(); + } } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java index b417e3391d..0aa5ba98d3 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java @@ -5,64 +5,100 @@ */ package org.sleuthkit.autopsy.contentviewers.layout; -import java.awt.Color; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import java.awt.Font; -import java.awt.Insets; -import javax.swing.JLabel; +import javax.swing.JTextPane; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.StyleSheet; /** * * @author gregd */ public class ContentViewerHtmlStyles { - - private static final String DEFAULT_FONT_FAMILY = new JLabel().getFont().getFamily(); - private static final int DEFAULT_FONT_SIZE = new JLabel().getFont().getSize(); - private static final Color DEFAULT_BACKGROUND = new JLabel().getBackground(); // html stylesheet classnames for components - private static final String ANALYSIS_RESULTS_CLASS_PREFIX = "analysisResult_"; - private static final String SPACED_SECTION_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "spacedSection"; - private static final String SUBSECTION_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "subsection"; - private static final String HEADER_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "header"; - public static final String MESSAGE_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "message"; - public static final String TD_CLASSNAME = ANALYSIS_RESULTS_CLASS_PREFIX + "td"; + private static final String CLASS_PREFIX = ContentViewerHtmlStyles.class.getSimpleName(); - // Anchors are inserted into the navigation so that the viewer can navigate to a selection. - // This is the prefix of those anchors. - private static final String CLASSNAME_PREFIX = "ContentViewer_"; + private static final String HEADER_CLASSNAME = CLASS_PREFIX + "header"; + private static final String SUB_HEADER_CLASSNAME = CLASS_PREFIX + "subHeader"; - // how big the header should be - private static final int HEADER_FONT_SIZE = DEFAULT_FONT_SIZE + 2; + private static final String MESSAGE_CLASSNAME = CLASS_PREFIX + "message"; + private static final String TEXT_CLASSNAME = CLASS_PREFIX + "text"; + private static final String INDENTED_CLASSNAME = CLASS_PREFIX + "indent"; + private static final String SPACED_SECTION_CLASSNAME = CLASS_PREFIX + "spacedSection"; + private static final String KEY_COLUMN_TD_CLASSNAME = CLASS_PREFIX + "keyKolumn"; - // spacing occurring after an item - private static final int DEFAULT_SECTION_SPACING = DEFAULT_FONT_SIZE / 2; - private static final int CELL_SPACING = DEFAULT_FONT_SIZE / 2; - - // the subsection indent - private static final int DEFAULT_SUBSECTION_LEFT_PAD = DEFAULT_FONT_SIZE; - - - - private static final Font DEFAULT_FONT = ContentViewerDefaults.getFont(); private static final Font HEADER_FONT = ContentViewerDefaults.getHeaderFont(); - - + private static final Font SUB_HEADER_FONT = ContentViewerDefaults.getSubHeaderFont(); + // additional styling for components private static final String STYLE_SHEET_RULE - = String.format(" .%s { font-family: %s; font-size: %dpt;font-style:italic; margin: 0px; padding: 0px 0px %dpx 0px; } ", + = String.format(" .%s { font-family: %s; font-size: %dpt;font-style:italic; margin: 0px; padding: 0px 0px %dpx 0px; } ", MESSAGE_CLASSNAME, DEFAULT_FONT.getFamily(), DEFAULT_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px 0px %dpx 0px; } ", HEADER_CLASSNAME, HEADER_FONT.getFamily(), HEADER_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) + + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px 0px %dpx 0px; } ", + SUB_HEADER_CLASSNAME, SUB_HEADER_FONT.getFamily(), SUB_HEADER_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) + String.format(" .%s { font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpx 0px; } ", TEXT_CLASSNAME, DEFAULT_FONT.getFamily(), DEFAULT_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) - + String.format(" .%s { padding-left: %dpx } ", INDENTED_CLASSNAME, ContentViewerDefaults.getSectionIndent()) - + String.format(" .%s { margin-top: %dpx } ", - NOT_FIRST_SECTION_CLASSNAME, ContentViewerDefaults.getSectionSpacing()) - + String.format(" .%s { margin-top: %dpx } ", + + String.format(" .%s { padding-top: %dpx } ", + SPACED_SECTION_CLASSNAME, ContentViewerDefaults.getSectionSpacing()) + + String.format(" .%s { padding-right: %dpx } ", KEY_COLUMN_TD_CLASSNAME, ContentViewerDefaults.getColumnSpacing()); + private static final Supplier STYLE_SHEET = Suppliers.memoize(() -> { + StyleSheet stylesheet = new StyleSheet(); + stylesheet.addRule(STYLE_SHEET_RULE); + return stylesheet; + }); + + public static String getHeaderClassName() { + return HEADER_CLASSNAME; + } + + public static String getSubHeaderClassName() { + return SUB_HEADER_CLASSNAME; + } + + public static String getMessageClassName() { + return MESSAGE_CLASSNAME; + } + + public static String getTextClassName() { + return TEXT_CLASSNAME; + } + + public static String getIndentedClassName() { + return INDENTED_CLASSNAME; + } + + public static String getSpacedSectionClassName() { + return SPACED_SECTION_CLASSNAME; + } + + public static String getKeyColumnClassName() { + return KEY_COLUMN_TD_CLASSNAME; + } + + public static String getStyleSheetRule() { + return STYLE_SHEET_RULE; + } + + public static StyleSheet getStyleSheet() { + return STYLE_SHEET.get(); + } + + public static void setupHtmlJTextPane(JTextPane textPane) { + textPane.setContentType("text/html;charset=UTF-8"); //NON-NLS + HTMLEditorKit kit = new HTMLEditorKit(); + textPane.setEditorKit(kit); + kit.setStyleSheet(ContentViewerHtmlStyles.getStyleSheet()); + textPane.setMargin(ContentViewerDefaults.getPanelInsets()); + textPane.setBackground(ContentViewerDefaults.getPanelBackground()); + } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java index 1e4c1f4c63..4ae8b6f771 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java @@ -27,6 +27,7 @@ import javax.swing.text.ViewFactory; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.InlineView; import javax.swing.text.html.ParagraphView; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.coreutils.EscapeUtil; /** @@ -96,9 +97,15 @@ public class AutoWrappingJTextPane extends JTextPane { this.setEditorKit(editorKit); } + + @Override public void setText(String text) { - super.setText("
" + EscapeUtil.escapeHtml(text) + "
"); + // setting the text format with style to avoid problems with overridden styles. + String style = String.format("font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpx 0px;", + ContentViewerDefaults.getFont().getFamily(), ContentViewerDefaults.getFont().getSize(), ContentViewerDefaults.getLineSpacing()); + + super.setText("
" + EscapeUtil.escapeHtml(text) + "
"); } } From 6226f68a735675b0a258afb47129c74a7bec09e1 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Fri, 4 Jun 2021 15:49:08 -0400 Subject: [PATCH 26/70] Added the call to getUniquePath to the makeKey method --- .../autopsy/datamodel/ContentChildren.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java index 44885e1ef8..ce8646563c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; +import org.openide.util.Exceptions; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Directory; @@ -103,7 +104,21 @@ class ContentChildren extends AbstractContentChildren { @Override protected List makeKeys() { - return getDisplayChildren(parent); + List contentList = getDisplayChildren(parent); + + // Call the getUniquePath method to cache the value for future use + // in the EDT + contentList.forEach(content->{ + try { + content.getUniquePath(); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, String.format("Failed attempt to cache the " + + "unique path of the abstract file instance. Name: %s (objID=%d)", + content.getName(), content.getId()), ex); + } + }); + + return contentList; } @Override From 0737e48d51297f5d56685b9e5d985121de2c887a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 7 Jun 2021 10:18:27 -0400 Subject: [PATCH 27/70] work on communication artifact viewers --- .../CallLogArtifactViewer.java | 9 ++- .../CommunicationArtifactViewerHelper.java | 74 +++++++++---------- .../ContactArtifactViewer.java | 19 +++-- .../layout/ContentViewerDefaults.java | 6 ++ .../layout/ContentViewerHtmlStyles.java | 3 +- 5 files changed, 57 insertions(+), 54 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java index 8d27c6c5be..bcea405c14 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.contentviewers.artifactviewers; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; +import java.awt.Insets; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -35,6 +36,7 @@ import org.apache.commons.lang3.StringUtils; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.guiutils.ContactCache; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -444,9 +446,8 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac "CalllogArtifactViewer_cr_disabled_message=Enable Central Repository to view, create and edit personas." }) private void showCRDisabledMessage() { - CommunicationArtifactViewerHelper.addBlankLine(this, m_gridBagLayout, m_constraints); - m_constraints.gridy++; - CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message()); + Insets messageInsets = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0); + CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, messageInsets, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message()); m_constraints.gridy++; } @@ -505,7 +506,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac m_constraints.gridx = 0; m_constraints.weighty = 0.0; m_constraints.weightx = 0.0; // keep components fixed horizontally. - m_constraints.insets = new java.awt.Insets(0, CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0); + m_constraints.insets = new java.awt.Insets(0, ContentViewerDefaults.getSectionIndent(), 0, 0); m_constraints.fill = GridBagConstraints.NONE; } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java index fe5e19aff5..11a5a8df96 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.contentviewers.artifactviewers; import java.awt.Dimension; -import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -38,6 +37,7 @@ import javax.swing.JTextPane; import javax.swing.SwingUtilities; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; /** * @@ -49,8 +49,6 @@ final class CommunicationArtifactViewerHelper { // Number of columns in the gridbag layout. private final static int MAX_COLS = 4; - final static int LEFT_INSET = 12; - /** * Empty private constructor */ @@ -75,23 +73,23 @@ final class CommunicationArtifactViewerHelper { // create label for heading javax.swing.JLabel headingLabel = new javax.swing.JLabel(); - // add a blank line before the start of new section, unless it's - // the first section - if (constraints.gridy != 0) { - addBlankLine(panel, gridbagLayout, constraints); - } + constraints.gridy++; constraints.gridx = 0; // let the header span all of the row constraints.gridwidth = MAX_COLS; - constraints.insets = new Insets(0, 0, 0, 0); // No inset for header + constraints.anchor = GridBagConstraints.NORTHWEST; + constraints.fill = GridBagConstraints.NONE; + + int sectionSpacing = (constraints.gridy == 0) ? 0 : ContentViewerDefaults.getSectionSpacing(); + constraints.insets = new Insets(sectionSpacing, 0, ContentViewerDefaults.getLineSpacing(), 0); // set text headingLabel.setText(headerString); // make it large and bold - headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2)); + headingLabel.setFont(ContentViewerDefaults.getHeaderFont()); // add to panel gridbagLayout.setConstraints(headingLabel, constraints); @@ -197,24 +195,6 @@ final class CommunicationArtifactViewerHelper { constraints.fill = savedFill; } - /** - * Adds a blank line to the panel. - * - * @param panel Panel to update. - * @param gridbagLayout Layout to use. - * @param constraints Constraints to use. - */ - static void addBlankLine(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) { - constraints.gridy++; - constraints.gridx = 0; - - javax.swing.JLabel filler = new javax.swing.JLabel(" "); - gridbagLayout.setConstraints(filler, constraints); - panel.add(filler); - - addLineEndGlue(panel, gridbagLayout, constraints); - } - /** * Adds a label/key to the panel at col 0. * @@ -226,7 +206,7 @@ final class CommunicationArtifactViewerHelper { * @return Label added. */ static JLabel addKey(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString) { - return addKeyAtCol(panel, gridbagLayout, constraints, keyString, 0); + return addKeyAtCol(panel, gridbagLayout, constraints, null, keyString, 0); } /** @@ -235,19 +215,24 @@ final class CommunicationArtifactViewerHelper { * @param panel Panel to update. * @param gridbagLayout Layout to use. * @param constraints Constraints to use. + * @param insets Insets to be used. If null, default insets are assumed. * @param keyString Key name to display. * @param gridx column index, must be less than MAX_COLS - 1. * * @return Label added. */ - static JLabel addKeyAtCol(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString, int gridx) { + static JLabel addKeyAtCol(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, Insets insets, String keyString, int gridx) { // create label javax.swing.JLabel keyLabel = new javax.swing.JLabel(); constraints.gridy++; constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2; - + constraints.anchor = GridBagConstraints.NORTHWEST; + constraints.insets = (insets == null) + ? new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0) + : insets; + // set text keyLabel.setText(keyString + ": "); @@ -295,7 +280,8 @@ final class CommunicationArtifactViewerHelper { // let the value span 2 cols cloneConstraints.gridwidth = 2; - cloneConstraints.fill = GridBagConstraints.BOTH; + cloneConstraints.fill = GridBagConstraints.HORIZONTAL; + cloneConstraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); // set text valueField.setText(valueString); @@ -325,13 +311,13 @@ final class CommunicationArtifactViewerHelper { * @param panel Panel to show. * @param gridbagLayout Layout to use. * @param constraints Constraints to use. - * + * @param insets The insets to be used for the grid bag layout constraints. If null, default insets are assumed. * @param messageString Message to display. * * @return Label for message added. */ - static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String messageString) { - return addMessageRow(panel, gridbagLayout, constraints, messageString, 0); + static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, Insets insets, GridBagConstraints constraints, String messageString) { + return addMessageRow(panel, gridbagLayout, constraints, insets, messageString, 0); } /** @@ -340,26 +326,32 @@ final class CommunicationArtifactViewerHelper { * * @param panel Panel to show. * @param gridbagLayout Layout to use. + * @param insets The insets to be used for the grid bag layout constraints. * @param constraints Constraints to use. - * + * @param insets The insets to be used for the grid bag layout constraints. If null, default insets are assumed. * @param messageString Message to display. + * @param gridx The grid x location to use. * * @return Label for message added. */ - static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String messageString, int gridx) { + static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, Insets insets, String messageString, int gridx) { // create label javax.swing.JLabel messageLabel = new javax.swing.JLabel(); constraints.gridy++; constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2; - + constraints.insets = insets == null + ? new Insets(0, 0, ContentViewerDefaults.getLineSpacing(), 0) : + insets; + int savedGridwidth = constraints.gridwidth; constraints.gridwidth = 3; // set text messageLabel.setText(messageString); + messageLabel.setFont(ContentViewerDefaults.getMessageFont()); // add to panel gridbagLayout.setConstraints(messageLabel, constraints); @@ -406,7 +398,7 @@ final class CommunicationArtifactViewerHelper { Insets savedInsets = constraints.insets; // extra Indent in - constraints.insets = new java.awt.Insets(0, 2 * LEFT_INSET, 0, 0); + constraints.insets = new java.awt.Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); // create label javax.swing.JLabel personaLabel = new javax.swing.JLabel(); @@ -422,7 +414,7 @@ final class CommunicationArtifactViewerHelper { panel.add(personaLabel); // restore constraint - constraints.insets = savedInsets; + constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getColumnSpacing(), 0); constraints.gridx++; @@ -469,7 +461,7 @@ final class CommunicationArtifactViewerHelper { GridBagConstraints indentedConstraints = (GridBagConstraints) constraints.clone(); // Add an indent to match persona labels - indentedConstraints.insets = new java.awt.Insets(0, 2 * LEFT_INSET, 0, 0); + indentedConstraints.insets = new java.awt.Insets(0, 2 * ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); String contactInfo = Bundle.CommunicationArtifactViewerHelper_contact_label(contactId != null && !contactId.isEmpty() ? contactId : Bundle.CommunicationArtifactViewerHelper_contact_label_unknown()); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java index b17263a26d..66e669c919 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java @@ -57,6 +57,7 @@ import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog; import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback; import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode; import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; @@ -245,7 +246,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac Insets savedInsets = contactPanelConstraints.insets; contactPanelConstraints.gridy = 0; contactPanelConstraints.gridx = 0; - contactPanelConstraints.insets = new Insets(0, 0, 0, 0); + contactPanelConstraints.insets = new Insets(0, 0, ContentViewerDefaults.getLineSpacing(), 0); javax.swing.JLabel contactImage = new javax.swing.JLabel(); contactImage.setIcon(getImageFromArtifact(contactArtifact)); @@ -346,7 +347,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac this.personaSearchStatusLabel = new javax.swing.JLabel(); personaSearchStatusLabel.setText(personaStatusLabelText); - + personaSearchStatusLabel.setFont(ContentViewerDefaults.getMessageFont()); + m_constraints.gridx = 0; CommunicationArtifactViewerHelper.addComponent(this, m_gridBagLayout, m_constraints, personaSearchStatusLabel); @@ -359,9 +361,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac personaHeader.setEnabled(false); personaSearchStatusLabel.setEnabled(false); - CommunicationArtifactViewerHelper.addBlankLine(this, m_gridBagLayout, m_constraints); - m_constraints.gridy++; - CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message()); + Insets messageInsets = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0); + CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, messageInsets, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message()); m_constraints.gridy++; CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints); @@ -436,7 +437,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac Insets savedInsets = constraints.insets; // some label are indented 2x to appear indented w.r.t column above - Insets extraIndentInsets = new java.awt.Insets(0, 2 * CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0); + Insets extraIndentInsets = new java.awt.Insets(0, 2 * ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); // Add a Match X label in col 0. constraints.gridx = 0; @@ -461,6 +462,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac //constraints.gridwidth = 1; // TBD: this may not be needed if we use single panel constraints.gridx++; + constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); personaNameLabel.setText(personaName); gridBagLayout.setConstraints(personaNameLabel, constraints); CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaNameLabel); @@ -474,6 +476,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac // Shirnk the button height. personaButton.setMargin(new Insets(0, 5, 0, 5)); + constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); gridBagLayout.setConstraints(personaButton, constraints); CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaButton); CommunicationArtifactViewerHelper.addLineEndGlue(this, gridBagLayout, constraints); @@ -502,7 +505,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac // this needs an extra indent constraints.insets = extraIndentInsets; - CommunicationArtifactViewerHelper.addKeyAtCol(this, gridBagLayout, constraints, Bundle.ContactArtifactViewer_missing_account_label(), 1); + CommunicationArtifactViewerHelper.addKeyAtCol(this, gridBagLayout, constraints, extraIndentInsets, Bundle.ContactArtifactViewer_missing_account_label(), 1); constraints.insets = savedInsets; CommunicationArtifactViewerHelper.addValueAtCol(this, gridBagLayout, constraints, missingAccount.getIdentifier(), 2); @@ -549,7 +552,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac m_constraints.gridx = 0; m_constraints.weighty = 0.0; m_constraints.weightx = 0.0; // keep components fixed horizontally. - m_constraints.insets = new java.awt.Insets(0, CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0); + m_constraints.insets = new java.awt.Insets(0, ContentViewerDefaults.getSectionIndent(), 0, 0); m_constraints.fill = GridBagConstraints.NONE; } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java index fc9f7c038c..6c267892f9 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java @@ -36,6 +36,8 @@ public class ContentViewerDefaults { return defaultFont.deriveFont(Font.BOLD, defaultFont.getSize() + 2); }); + private static final Supplier MESSAGE_FONT = Suppliers.memoize(() -> DEFAULT_FONT.get().deriveFont(Font.ITALIC)); + private static final Supplier DEFAULT_PANEL_INSETS = Suppliers.memoize(() -> UIManager.getDefaults().getInsets("TextPane.margin")); private static final Supplier DEFAULT_INDENT = Suppliers.memoize(() -> DEFAULT_FONT_PX.get()); @@ -54,6 +56,10 @@ public class ContentViewerDefaults { return DEFAULT_FONT.get(); } + public static Font getMessageFont() { + return MESSAGE_FONT.get(); + } + public static Font getHeaderFont() { return HEADER_FONT.get(); } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java index 0aa5ba98d3..6ef8535ce9 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java @@ -31,13 +31,14 @@ public class ContentViewerHtmlStyles { private static final String KEY_COLUMN_TD_CLASSNAME = CLASS_PREFIX + "keyKolumn"; private static final Font DEFAULT_FONT = ContentViewerDefaults.getFont(); + private static final Font MESSAGE_FONT = ContentViewerDefaults.getMessageFont(); private static final Font HEADER_FONT = ContentViewerDefaults.getHeaderFont(); private static final Font SUB_HEADER_FONT = ContentViewerDefaults.getSubHeaderFont(); // additional styling for components private static final String STYLE_SHEET_RULE = String.format(" .%s { font-family: %s; font-size: %dpt;font-style:italic; margin: 0px; padding: 0px 0px %dpx 0px; } ", - MESSAGE_CLASSNAME, DEFAULT_FONT.getFamily(), DEFAULT_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) + MESSAGE_CLASSNAME, MESSAGE_FONT.getFamily(), MESSAGE_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px 0px %dpx 0px; } ", HEADER_CLASSNAME, HEADER_FONT.getFamily(), HEADER_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px 0px %dpx 0px; } ", From d2347ffa17751395155563ab55b45da2fb1ffe78 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 7 Jun 2021 14:12:50 -0400 Subject: [PATCH 28/70] call log and contact artifact viewer --- .../CallLogArtifactViewer.java | 11 ++-- .../CommunicationArtifactViewerHelper.java | 50 ++++++++++--------- .../ContactArtifactViewer.java | 36 +++++++------ 3 files changed, 53 insertions(+), 44 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java index bcea405c14..4b83bdc565 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Set; import java.util.logging.Level; import javax.swing.JScrollPane; +import javax.swing.border.EmptyBorder; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.openide.util.NbBundle; @@ -77,6 +78,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac */ public CallLogArtifactViewer() { initComponents(); + this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets())); } /** @@ -116,6 +118,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac currentAccountFetcher = null; } } + // repaint this.revalidate(); } @@ -311,7 +314,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac }) private List updateView(CallLogViewData callLogViewData) { - CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_parties()); + CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, 0, Bundle.CallLogArtifactViewer_heading_parties()); List dataList = new ArrayList<>(); // Display "From" if we have non-local device accounts @@ -386,7 +389,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac }) private void updateMetadataView(CallLogViewData callLogViewData) { - CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_metadata()); + CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.CallLogArtifactViewer_heading_metadata()); CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_direction()); if (callLogViewData.getDirection() != null) { @@ -416,7 +419,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac "CallLogArtifactViewer_heading_Source=Source", "CallLogArtifactViewer_label_datasource=Data Source",}) private void updateSourceView(CallLogViewData callLogViewData) { - CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_Source()); + CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.CallLogArtifactViewer_heading_Source()); CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_datasource()); CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName()); } @@ -434,7 +437,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac if (callLogViewData.getOtherAttributes().isEmpty()) { return; } - CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_others()); + CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.CallLogArtifactViewer_heading_others()); for (Map.Entry entry : callLogViewData.getOtherAttributes().entrySet()) { CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, entry.getKey()); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java index 11a5a8df96..3f58c723c5 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java @@ -62,11 +62,12 @@ final class CommunicationArtifactViewerHelper { * @param panel Panel to update. * @param gridbagLayout Layout to use. * @param constraints Constraints to use. + * @param spacing Spacing to add to top insets (in pixels). * @param headerString Heading string to display. * * @return JLabel Heading label added. */ - static JLabel addHeader(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String headerString) { + static JLabel addHeader(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, int topSpacing, String headerString) { Insets savedInsets = constraints.insets; @@ -79,14 +80,13 @@ final class CommunicationArtifactViewerHelper { // let the header span all of the row constraints.gridwidth = MAX_COLS; - constraints.anchor = GridBagConstraints.NORTHWEST; + constraints.anchor = GridBagConstraints.LINE_START; constraints.fill = GridBagConstraints.NONE; - int sectionSpacing = (constraints.gridy == 0) ? 0 : ContentViewerDefaults.getSectionSpacing(); - constraints.insets = new Insets(sectionSpacing, 0, ContentViewerDefaults.getLineSpacing(), 0); + constraints.insets = new Insets(topSpacing, 0, ContentViewerDefaults.getLineSpacing(), 0); // set text - headingLabel.setText(headerString); + headingLabel.setText(headerString.trim()); // make it large and bold headingLabel.setFont(ContentViewerDefaults.getHeaderFont()); @@ -157,7 +157,7 @@ final class CommunicationArtifactViewerHelper { int savedFill = constraints.fill; constraints.weightx = 1.0; // take up all the horizontal space - constraints.fill = GridBagConstraints.BOTH; + constraints.fill = GridBagConstraints.HORIZONTAL; javax.swing.Box.Filler horizontalFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(32767, 0)); gridbagLayout.setConstraints(horizontalFiller, constraints); @@ -179,6 +179,7 @@ final class CommunicationArtifactViewerHelper { static void addPageEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) { constraints.gridx = 0; + constraints.gridy++; double savedWeighty = constraints.weighty; int savedFill = constraints.fill; @@ -206,7 +207,7 @@ final class CommunicationArtifactViewerHelper { * @return Label added. */ static JLabel addKey(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString) { - return addKeyAtCol(panel, gridbagLayout, constraints, null, keyString, 0); + return addKeyAtCol(panel, gridbagLayout, constraints, keyString, 0); } /** @@ -215,26 +216,24 @@ final class CommunicationArtifactViewerHelper { * @param panel Panel to update. * @param gridbagLayout Layout to use. * @param constraints Constraints to use. - * @param insets Insets to be used. If null, default insets are assumed. * @param keyString Key name to display. * @param gridx column index, must be less than MAX_COLS - 1. * * @return Label added. */ - static JLabel addKeyAtCol(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, Insets insets, String keyString, int gridx) { + static JLabel addKeyAtCol(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString, int gridx) { // create label javax.swing.JLabel keyLabel = new javax.swing.JLabel(); constraints.gridy++; constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2; - constraints.anchor = GridBagConstraints.NORTHWEST; - constraints.insets = (insets == null) - ? new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0) - : insets; - + constraints.anchor = GridBagConstraints.LINE_START; + constraints.insets = new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); + // set text - keyLabel.setText(keyString + ": "); + String preppedKeyString = keyString == null ? null : keyString.trim() + ":"; + keyLabel.setText(preppedKeyString); // add to panel gridbagLayout.setConstraints(keyLabel, constraints); @@ -273,6 +272,7 @@ final class CommunicationArtifactViewerHelper { JTextPane valueField = new JTextPane(); valueField.setEditable(false); valueField.setOpaque(false); + valueField.setMargin(new Insets(0,0,0,0)); constraints.gridx = gridx < MAX_COLS ? gridx : MAX_COLS - 1; @@ -280,7 +280,7 @@ final class CommunicationArtifactViewerHelper { // let the value span 2 cols cloneConstraints.gridwidth = 2; - cloneConstraints.fill = GridBagConstraints.HORIZONTAL; + constraints.anchor = GridBagConstraints.LINE_START; cloneConstraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); // set text @@ -344,13 +344,14 @@ final class CommunicationArtifactViewerHelper { constraints.insets = insets == null ? new Insets(0, 0, ContentViewerDefaults.getLineSpacing(), 0) : insets; + constraints.anchor = GridBagConstraints.LINE_START; int savedGridwidth = constraints.gridwidth; constraints.gridwidth = 3; // set text - messageLabel.setText(messageString); + messageLabel.setText(messageString == null ? null : messageString.trim()); messageLabel.setFont(ContentViewerDefaults.getMessageFont()); // add to panel @@ -399,7 +400,8 @@ final class CommunicationArtifactViewerHelper { // extra Indent in constraints.insets = new java.awt.Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); - + constraints.anchor = GridBagConstraints.LINE_START; + // create label javax.swing.JLabel personaLabel = new javax.swing.JLabel(); String personaLabelText = Bundle.CommunicationArtifactViewerHelper_persona_label(); @@ -407,15 +409,12 @@ final class CommunicationArtifactViewerHelper { ? Bundle.CommunicationArtifactViewerHelper_persona_searching() : Bundle.CommunicationArtifactViewerHelper_persona_unknown()); - personaLabel.setText(personaLabelText); - + personaLabel.setText(personaLabelText == null ? null : personaLabelText.trim()); + // add to panel gridbagLayout.setConstraints(personaLabel, constraints); panel.add(personaLabel); - // restore constraint - constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getColumnSpacing(), 0); - constraints.gridx++; // Place a button as place holder. It will be enabled when persona is available. @@ -433,6 +432,9 @@ final class CommunicationArtifactViewerHelper { } else { personaLabel.setEnabled(false); } + + // restore constraint + constraints.insets = savedInsets; addLineEndGlue(panel, gridbagLayout, constraints); @@ -461,7 +463,7 @@ final class CommunicationArtifactViewerHelper { GridBagConstraints indentedConstraints = (GridBagConstraints) constraints.clone(); // Add an indent to match persona labels - indentedConstraints.insets = new java.awt.Insets(0, 2 * ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); + indentedConstraints.insets = new java.awt.Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); String contactInfo = Bundle.CommunicationArtifactViewerHelper_contact_label(contactId != null && !contactId.isEmpty() ? contactId : Bundle.CommunicationArtifactViewerHelper_contact_label_unknown()); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java index 66e669c919..06e4a37d87 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java @@ -41,9 +41,9 @@ import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.SwingWorker; +import javax.swing.border.EmptyBorder; import org.apache.commons.lang.StringUtils; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; @@ -108,7 +108,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac */ public ContactArtifactViewer() { initComponents(); - + this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets())); defaultImage = new ImageIcon(ContactArtifactViewer.class.getResource(DEFAULT_IMAGE_PATH)); } @@ -247,7 +247,10 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac contactPanelConstraints.gridy = 0; contactPanelConstraints.gridx = 0; contactPanelConstraints.insets = new Insets(0, 0, ContentViewerDefaults.getLineSpacing(), 0); - + int prevGridWidth = contactPanelConstraints.gridwidth; + contactPanelConstraints.gridwidth = 3; + contactPanelConstraints.anchor = GridBagConstraints.LINE_START; + javax.swing.JLabel contactImage = new javax.swing.JLabel(); contactImage.setIcon(getImageFromArtifact(contactArtifact)); contactImage.setText(Bundle.ContactArtifactViewer_contactImage_text()); @@ -257,6 +260,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac CommunicationArtifactViewerHelper.addLineEndGlue(this, contactPanelLayout, contactPanelConstraints); contactPanelConstraints.gridy++; + contactPanelConstraints.gridwidth = prevGridWidth; contactPanelConstraints.insets = savedInsets; } @@ -276,13 +280,13 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac if (StringUtils.isEmpty(bba.getValueString()) == false) { contactName = bba.getDisplayString(); - CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, contactName); + CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, 0, contactName); foundName = true; break; } } if (foundName == false) { - CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, Bundle.ContactArtifactViewer_contactname_unknown()); + CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, ContentViewerDefaults.getSectionSpacing(), Bundle.ContactArtifactViewer_contactname_unknown()); } } @@ -303,7 +307,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac return; } - CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, sectionHeader); + CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, ContentViewerDefaults.getSectionSpacing(), sectionHeader); for (BlackboardAttribute bba : sectionAttributesList) { CommunicationArtifactViewerHelper.addKey(this, contactPanelLayout, contactPanelConstraints, bba.getAttributeType().getDisplayName()); CommunicationArtifactViewerHelper.addValue(this, contactPanelLayout, contactPanelConstraints, bba.getDisplayString()); @@ -317,7 +321,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac "ContactArtifactViewer_heading_Source=Source", "ContactArtifactViewer_label_datasource=Data Source",}) private void updateSource() { - CommunicationArtifactViewerHelper.addHeader(this, this.m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_heading_Source()); + CommunicationArtifactViewerHelper.addHeader(this, this.m_gridBagLayout, m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.ContactArtifactViewer_heading_Source()); CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_label_datasource()); CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, datasourceName); } @@ -336,7 +340,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac private void initiatePersonasSearch() { // add a section header - JLabel personaHeader = CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_persona_header()); + JLabel personaHeader = CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.ContactArtifactViewer_persona_header()); m_constraints.gridy++; @@ -350,6 +354,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac personaSearchStatusLabel.setFont(ContentViewerDefaults.getMessageFont()); m_constraints.gridx = 0; + m_constraints.anchor = GridBagConstraints.LINE_START; CommunicationArtifactViewerHelper.addComponent(this, m_gridBagLayout, m_constraints, personaSearchStatusLabel); @@ -436,12 +441,9 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac // save the original insets Insets savedInsets = constraints.insets; - // some label are indented 2x to appear indented w.r.t column above - Insets extraIndentInsets = new java.awt.Insets(0, 2 * ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0); - // Add a Match X label in col 0. constraints.gridx = 0; - javax.swing.JLabel matchNumberLabel = CommunicationArtifactViewerHelper.addKey(this, gridBagLayout, constraints, String.format("%s %d", Bundle.ContactArtifactViewer_persona_match_num(), matchNumber)); + javax.swing.JLabel matchNumberLabel = CommunicationArtifactViewerHelper.addKey(this, gridBagLayout, constraints, String.format("%s %d", Bundle.ContactArtifactViewer_persona_match_num(), matchNumber).trim()); javax.swing.JLabel personaNameLabel = new javax.swing.JLabel(); javax.swing.JButton personaButton = new javax.swing.JButton(); @@ -463,6 +465,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac //constraints.gridwidth = 1; // TBD: this may not be needed if we use single panel constraints.gridx++; constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); + constraints.anchor = GridBagConstraints.LINE_START; personaNameLabel.setText(personaName); gridBagLayout.setConstraints(personaNameLabel, constraints); CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaNameLabel); @@ -477,6 +480,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac // Shirnk the button height. personaButton.setMargin(new Insets(0, 5, 0, 5)); constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); + constraints.anchor = GridBagConstraints.LINE_START; gridBagLayout.setConstraints(personaButton, constraints); CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaButton); CommunicationArtifactViewerHelper.addLineEndGlue(this, gridBagLayout, constraints); @@ -491,7 +495,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac //constraints.insets = labelInsets; javax.swing.JLabel accountsStatus = new javax.swing.JLabel(Bundle.ContactArtifactViewer_found_all_accounts_label()); - constraints.insets = extraIndentInsets; + constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0); + constraints.anchor = GridBagConstraints.LINE_START; CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, accountsStatus); constraints.insets = savedInsets; @@ -504,8 +509,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac constraints.gridy++; // this needs an extra indent - constraints.insets = extraIndentInsets; - CommunicationArtifactViewerHelper.addKeyAtCol(this, gridBagLayout, constraints, extraIndentInsets, Bundle.ContactArtifactViewer_missing_account_label(), 1); + CommunicationArtifactViewerHelper.addKeyAtCol(this, gridBagLayout, constraints, Bundle.ContactArtifactViewer_missing_account_label(), 1); constraints.insets = savedInsets; CommunicationArtifactViewerHelper.addValueAtCol(this, gridBagLayout, constraints, missingAccount.getIdentifier(), 2); @@ -547,7 +551,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac m_gridBagLayout = new GridBagLayout(); m_constraints = new GridBagConstraints(); - m_constraints.anchor = GridBagConstraints.FIRST_LINE_START; + m_constraints.anchor = GridBagConstraints.LINE_START; m_constraints.gridy = 0; m_constraints.gridx = 0; m_constraints.weighty = 0.0; From 24cbab97e16ae53bf96ad0da46e2fb078f37dd41 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 7 Jun 2021 15:07:14 -0400 Subject: [PATCH 29/70] 7639 refresh ingest jobs panel in a swing worker --- .../casemodule/IngestJobInfoPanel.java | 57 ++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java index 5fe65783b0..c28d36757e 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java @@ -26,8 +26,10 @@ import java.util.Date; import java.util.EnumSet; import java.util.List; import java.util.Set; +import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JOptionPane; +import javax.swing.SwingWorker; import javax.swing.event.ListSelectionEvent; import javax.swing.table.AbstractTableModel; import org.openide.util.NbBundle.Messages; @@ -51,7 +53,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED); private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE); private static final int EXTRA_ROW_HEIGHT = 4; - private List ingestJobs; + private List ingestJobs = new ArrayList<>(); private final List ingestJobsForSelectedDataSource = new ArrayList<>(); private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel(); private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null); @@ -76,19 +78,19 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { this.ingestModuleTable.setModel(this.ingestModuleTableModel); }); - IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST , (PropertyChangeEvent evt) -> { + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> { if (evt.getPropertyName().equals(IngestManager.IngestJobEvent.STARTED.toString()) || evt.getPropertyName().equals(IngestManager.IngestJobEvent.CANCELLED.toString()) || evt.getPropertyName().equals(IngestManager.IngestJobEvent.COMPLETED.toString())) { refresh(); } }); - + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> { if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) { return; } - + // Check whether we have a case open or case close event. if ((CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName()))) { if (evt.getNewValue() != null) { @@ -102,7 +104,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { }); ingestJobTable.setRowHeight(ingestJobTable.getRowHeight() + EXTRA_ROW_HEIGHT); ingestModuleTable.setRowHeight(ingestModuleTable.getRowHeight() + EXTRA_ROW_HEIGHT); - + } /** @@ -133,22 +135,39 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { * Get the updated complete list of ingest jobs. */ private void refresh() { - try { - if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event - SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - this.ingestJobs = skCase.getIngestJobs(); - setDataSource(selectedDataSource); - } else { - this.ingestJobs = new ArrayList<>(); - setDataSource(null); - } + new SwingWorker() { - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex); - JOptionPane.showMessageDialog(this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE); - } + @Override + protected Boolean doInBackground() throws Exception { + ingestJobs.clear(); + try { + if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + ingestJobs.addAll(skCase.getIngestJobs()); + setDataSource(selectedDataSource); + } else { + setDataSource(null); + } + return true; + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex); + return false; + } + } + + @Override + protected void done() { + try { + if (!get()) { + JOptionPane.showMessageDialog(IngestJobInfoPanel.this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE); + } + } catch (InterruptedException | ExecutionException ex) { + logger.log(Level.WARNING, "Error getting results from Ingest Job Info Panel's refresh worker", ex); + } + } + }.execute(); } - + /** * Reset the panel. */ From cf3cb5a0b26f04291e6a9a4129b2d883cbaf5c26 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 7 Jun 2021 15:08:28 -0400 Subject: [PATCH 30/70] 7639 formatting --- .../org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java index c28d36757e..6e1df2b8c0 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java @@ -136,7 +136,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { */ private void refresh() { new SwingWorker() { - + @Override protected Boolean doInBackground() throws Exception { ingestJobs.clear(); From 21961f3d32902da26c0346a9c4621ab271db1953 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 7 Jun 2021 15:58:19 -0400 Subject: [PATCH 31/70] message account panel changes --- .../artifactviewers/MessageAccountPanel.java | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/MessageAccountPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/MessageAccountPanel.java index fbf1ada856..fb2088c31a 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/MessageAccountPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/MessageAccountPanel.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.contentviewers.artifactviewers; import java.awt.Dimension; +import java.awt.Insets; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; @@ -44,6 +45,7 @@ import javax.swing.JTextPane; import javax.swing.LayoutStyle.ComponentPlacement; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; +import javax.swing.border.EmptyBorder; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; @@ -56,6 +58,7 @@ import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog; import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback; import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode; import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel; +import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.guiutils.ContactCache; import org.sleuthkit.datamodel.Account; @@ -77,6 +80,15 @@ final class MessageAccountPanel extends JPanel { private AccountFetcher currentFetcher = null; + + + /** + * Main constructor. + */ + MessageAccountPanel() { + this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets())); + } + /** * Set the new artifact for the panel. * @@ -170,9 +182,7 @@ final class MessageAccountPanel extends JPanel { layout.setHorizontalGroup( layout.createParallelGroup(Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(getMainHorizontalGroup(layout, dataList)) - .addContainerGap(158, Short.MAX_VALUE))); + .addGroup(getMainHorizontalGroup(layout, dataList)))); layout.setVerticalGroup(getMainVerticalGroup(layout, dataList)); setLayout(layout); @@ -186,6 +196,7 @@ final class MessageAccountPanel extends JPanel { messageLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); messageLabel.setText(Bundle.MessageAccountPanel_no_matches()); + messageLabel.setFont(ContentViewerDefaults.getMessageFont()); messageLabel.setEnabled(false); messagePanel.add(messageLabel, java.awt.BorderLayout.CENTER); @@ -224,14 +235,12 @@ final class MessageAccountPanel extends JPanel { private ParallelGroup getMainVerticalGroup(GroupLayout layout, List data) { SequentialGroup group = layout.createSequentialGroup(); for (AccountContainer o : data) { - group.addGap(5) - .addComponent(o.getAccountLabel()) + group.addComponent(o.getAccountLabel()) .addGroup(o.getContactLineVerticalGroup(layout)) .addGroup(o.getPersonLineVerticalGroup(layout)); + group.addGap(ContentViewerDefaults.getSectionSpacing()); } - group.addContainerGap(83, Short.MAX_VALUE); - return layout.createParallelGroup().addGroup(group); } @@ -259,12 +268,11 @@ final class MessageAccountPanel extends JPanel { private SequentialGroup getPersonaHorizontalGroup(GroupLayout layout, List data) { SequentialGroup group = layout.createSequentialGroup(); ParallelGroup pgroup = layout.createParallelGroup(Alignment.LEADING); - group.addGap(10); for (AccountContainer o : data) { pgroup.addGroup(o.getPersonaSequentialGroup(layout)); pgroup.addGroup(o.getContactSequentialGroup(layout)); } - group.addGap(10) + group.addGap(ContentViewerDefaults.getSectionIndent()) .addGroup(pgroup) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(getButtonGroup(layout, data)); @@ -343,7 +351,9 @@ final class MessageAccountPanel extends JPanel { button = new JButton(); button.addActionListener(new PersonaButtonListener(this)); + accountLabel.setMargin(new Insets(0, 0, 0, 0)); accountLabel.setText(account.getTypeSpecificID()); + accountLabel.setFont(ContentViewerDefaults.getHeaderFont()); contactDisplayName.setText(contactName); personaDisplayName.setText(persona != null ? persona.getName() : Bundle.MessageAccountPanel_unknown_label()); From e402f792c084317c9eee5a97f697b06959bc9599 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 7 Jun 2021 16:33:27 -0400 Subject: [PATCH 32/70] fix for html components --- .../layout/ContentViewerDefaults.java | 8 ++++- .../layout/ContentViewerHtmlStyles.java | 32 +++++++++++-------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java index 6c267892f9..86d306d636 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java @@ -21,9 +21,11 @@ public class ContentViewerDefaults { private static final Supplier DEFAULT_FONT = Suppliers.memoize(() -> UIManager.getDefaults().getFont("Label.font")); + private static final Supplier PT_TO_PX = Suppliers.memoize(() -> Toolkit.getDefaultToolkit().getScreenResolution() / 72.0); + private static final Supplier DEFAULT_FONT_PX = Suppliers.memoize(() -> { // based on https://stackoverflow.com/questions/5829703/java-getting-a-font-with-a-specific-height-in-pixels/26564924#26564924 - return (int) Math.round(DEFAULT_FONT.get().getSize() * Toolkit.getDefaultToolkit().getScreenResolution() / 72.0); + return (int) Math.round(DEFAULT_FONT.get().getSize() * PT_TO_PX.get()); }); private static final Supplier SUB_HEADER_FONT = Suppliers.memoize(() -> { @@ -87,4 +89,8 @@ public class ContentViewerDefaults { public static Font getSubHeaderFont() { return SUB_HEADER_FONT.get(); } + + public static Double getPtToPx() { + return PT_TO_PX.get(); + } } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java index 6ef8535ce9..728fbfdadb 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java @@ -37,26 +37,30 @@ public class ContentViewerHtmlStyles { // additional styling for components private static final String STYLE_SHEET_RULE - = String.format(" .%s { font-family: %s; font-size: %dpt;font-style:italic; margin: 0px; padding: 0px 0px %dpx 0px; } ", - MESSAGE_CLASSNAME, MESSAGE_FONT.getFamily(), MESSAGE_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) - + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px 0px %dpx 0px; } ", - HEADER_CLASSNAME, HEADER_FONT.getFamily(), HEADER_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) - + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px 0px %dpx 0px; } ", - SUB_HEADER_CLASSNAME, SUB_HEADER_FONT.getFamily(), SUB_HEADER_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) - + String.format(" .%s { font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpx 0px; } ", - TEXT_CLASSNAME, DEFAULT_FONT.getFamily(), DEFAULT_FONT.getSize(), ContentViewerDefaults.getLineSpacing()) - + String.format(" .%s { padding-left: %dpx } ", - INDENTED_CLASSNAME, ContentViewerDefaults.getSectionIndent()) - + String.format(" .%s { padding-top: %dpx } ", - SPACED_SECTION_CLASSNAME, ContentViewerDefaults.getSectionSpacing()) - + String.format(" .%s { padding-right: %dpx } ", - KEY_COLUMN_TD_CLASSNAME, ContentViewerDefaults.getColumnSpacing()); + = String.format(" .%s { font-family: %s; font-size: %dpt;font-style:italic; margin: 0px; padding: 0px 0px %dpt 0px; } ", + MESSAGE_CLASSNAME, MESSAGE_FONT.getFamily(), MESSAGE_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px 0px %dpt 0px; } ", + HEADER_CLASSNAME, HEADER_FONT.getFamily(), HEADER_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + + String.format(" .%s { font-family: %s; font-size: %dpt; font-weight: bold; margin: 0px; padding: 0px 0px %dpt 0px; } ", + SUB_HEADER_CLASSNAME, SUB_HEADER_FONT.getFamily(), SUB_HEADER_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + + String.format(" .%s { font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpt 0px; } ", + TEXT_CLASSNAME, DEFAULT_FONT.getFamily(), DEFAULT_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + + String.format(" .%s { padding-left: %dpt } ", + INDENTED_CLASSNAME, pxToPt(ContentViewerDefaults.getSectionIndent())) + + String.format(" .%s { padding-top: %dpt } ", + SPACED_SECTION_CLASSNAME, pxToPt(ContentViewerDefaults.getSectionSpacing())) + + String.format(" .%s { padding-right: %dpt } ", + KEY_COLUMN_TD_CLASSNAME, pxToPt(ContentViewerDefaults.getColumnSpacing())); private static final Supplier STYLE_SHEET = Suppliers.memoize(() -> { StyleSheet stylesheet = new StyleSheet(); stylesheet.addRule(STYLE_SHEET_RULE); return stylesheet; }); + + private static int pxToPt(int px) { + return (int) Math.round(((double) px) / ContentViewerDefaults.getPtToPx()); + } public static String getHeaderClassName() { return HEADER_CLASSNAME; From 4feb6e187ce921a27afff385706ba817c109c369 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Tue, 8 Jun 2021 09:10:48 -0400 Subject: [PATCH 33/70] Changed code to support encoded characters Change code to support encoded characters from regripper and reading them from regripper output file. --- .../org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java | 4 +++- thirdparty/rr-full/plugins/samparse.pl | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index cd2eefc4f4..3fd6142d53 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -29,7 +29,9 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStreamReader; import java.io.StringReader; +import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.logging.Level; @@ -1062,7 +1064,7 @@ class ExtractRegistry extends Extract { File regfile = new File(regFilePath); List newArtifacts = new ArrayList<>(); - try (BufferedReader bufferedReader = new BufferedReader(new FileReader(regfile))) { + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(regfile), StandardCharsets.UTF_8))) { // Read the file in and create a Document and elements String userInfoSection = "User Information"; String previousLine = null; diff --git a/thirdparty/rr-full/plugins/samparse.pl b/thirdparty/rr-full/plugins/samparse.pl index 8046708b3b..f8997b632f 100644 --- a/thirdparty/rr-full/plugins/samparse.pl +++ b/thirdparty/rr-full/plugins/samparse.pl @@ -23,6 +23,7 @@ #----------------------------------------------------------- package samparse; use strict; +use Encode::Unicode; my %config = (hive => "SAM", hivemask => 2, @@ -364,7 +365,8 @@ sub _translateSID { #--------------------------------------------------------------------- sub _uniToAscii { my $str = $_[0]; - $str =~ s/\x00//g; + Encode::from_to($str,'UTF-16LE','utf8'); + $str = Encode::decode_utf8($str); return $str; } From 38b26df41ebaf3e1967f2fb8da22b10cb8ac13a3 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Jun 2021 13:01:31 -0400 Subject: [PATCH 34/70] pane text --- .../autopsy/corecomponents/AutoWrappingJTextPane.java | 4 +++- .../autopsy/keywordsearch/ExtractedContentPanel.java | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java index 4ae8b6f771..94b3cc68ad 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.corecomponents; +import java.text.MessageFormat; import javax.swing.JTextPane; import javax.swing.SizeRequirements; import javax.swing.text.Element; @@ -27,6 +28,7 @@ import javax.swing.text.ViewFactory; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.InlineView; import javax.swing.text.html.ParagraphView; +import javax.swing.text.html.StyleSheet; import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.coreutils.EscapeUtil; @@ -106,6 +108,6 @@ public class AutoWrappingJTextPane extends JTextPane { String style = String.format("font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpx 0px;", ContentViewerDefaults.getFont().getFamily(), ContentViewerDefaults.getFont().getSize(), ContentViewerDefaults.getLineSpacing()); - super.setText("
" + EscapeUtil.escapeHtml(text) + "
"); + super.setText(MessageFormat.format("
{1}
", style, EscapeUtil.escapeHtml(text))); } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 8ff9c0fdcc..5d6d7689f2 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -29,10 +29,10 @@ import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.logging.Level; -import javax.swing.JLabel; import javax.swing.SizeRequirements; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; +import javax.swing.UIManager; import javax.swing.text.Element; import javax.swing.text.View; import javax.swing.text.ViewFactory; @@ -59,7 +59,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP private static final Logger logger = Logger.getLogger(ExtractedContentPanel.class.getName()); // set font as close as possible to default - private static final Font DEFAULT_FONT = new JLabel().getFont(); + private static final Font DEFAULT_FONT = UIManager.getDefaults().getFont("Label.font"); private static final long serialVersionUID = 1L; private String contentName; @@ -135,8 +135,9 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP }; } }; - // get the style sheet for editing font size + // set new style sheet to clear default styles styleSheet = editorKit.getStyleSheet(); + setStyleSheetSize(styleSheet, DEFAULT_FONT.getSize()); sourceComboBox.addItemListener(itemEvent -> { if (itemEvent.getStateChange() == ItemEvent.SELECTED) { @@ -144,6 +145,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP } }); extractedTextPane.setComponentPopupMenu(rightClickMenu); + copyMenuItem.addActionListener(actionEvent -> extractedTextPane.copy()); selectAllMenuItem.addActionListener(actionEvent -> extractedTextPane.selectAll()); @@ -160,7 +162,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP private void setStyleSheetSize(StyleSheet styleSheet, int size) { - styleSheet.addRule("body {font-family:\"" + DEFAULT_FONT.getFamily() + "\"; font-size:" + size + "pt; } "); + styleSheet.addRule("body { font-family:\"" + DEFAULT_FONT.getFamily() + "\"; font-size:" + size + "pt; } "); } From e4f6bb53b32910898450aa7750a49a9837cd08c6 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Jun 2021 13:50:32 -0400 Subject: [PATCH 35/70] context and metadata fixes --- .../sleuthkit/autopsy/contentviewers/Metadata.java | 12 +++++++----- .../analysisresults/AnalysisResultsContentPanel.java | 2 -- .../contentviewers/contextviewer/ContextViewer.form | 7 ++++++- .../contentviewers/contextviewer/ContextViewer.java | 7 +++++-- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java index 37edf6d5c0..488c96c4df 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.contentviewers; import java.awt.Component; import java.awt.Cursor; +import java.text.MessageFormat; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.logging.Level; @@ -133,11 +134,12 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { } private void addRow(StringBuilder sb, String key, String value) { - sb.append(""); //NON-NLS - sb.append(key); - sb.append(""); //NON-NLS - sb.append(value); - sb.append(""); //NON-NLS + sb.append(MessageFormat.format("{1}{3}", + ContentViewerHtmlStyles.getTextClassName() + " " + ContentViewerHtmlStyles.getKeyColumnClassName(), + key, + ContentViewerHtmlStyles.getTextClassName(), + value + )); } @Messages({ diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java index aadfe4b677..fb56971f57 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.contentviewers.analysisresults; import java.text.MessageFormat; import java.util.List; import java.util.Optional; -import javax.swing.text.html.HTMLEditorKit; import org.apache.commons.lang3.tuple.Pair; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -29,7 +28,6 @@ import org.jsoup.nodes.Element; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.NodeResults; import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.ResultDisplayAttributes; -import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.Score; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form index bb1a78d555..47c452eccb 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form @@ -81,7 +81,7 @@ - + @@ -110,6 +110,11 @@
+ + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index dab7a657f9..74ac4919cb 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -119,7 +119,9 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte jUnknownLabel.setBorder(new EmptyBorder(DATA_ROW_INSETS)); jUnknownPanel.add(jUnknownLabel); - setPreferredSize(new java.awt.Dimension(495, 358)); + setPreferredSize(new java.awt.Dimension(0, 0)); + + jScrollPane.setPreferredSize(new java.awt.Dimension(16, 16)); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -235,10 +237,11 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte } } javax.swing.JPanel contextContainer = new javax.swing.JPanel(); + contextContainer.setLayout(new BoxLayout(contextContainer, BoxLayout.Y_AXIS)); contextContainer.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets())); contextContainer.add(jSourcePanel); - contextContainer.setLayout(new BoxLayout(contextContainer, BoxLayout.Y_AXIS)); + if (contextSourcePanels.isEmpty()) { contextContainer.add(jUnknownPanel); } else { From 1ea0efd6ce3918361220cc7b6fcc3792162d97f8 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Jun 2021 15:16:43 -0400 Subject: [PATCH 36/70] commenting --- .../AnnotationsContentViewer.java | 2 +- .../CallLogArtifactViewer.java | 2 +- .../CommunicationArtifactViewerHelper.java | 2 +- .../ContactArtifactViewer.java | 2 +- .../artifactviewers/MessageAccountPanel.java | 2 +- .../contextviewer/ContextSourcePanel.java | 2 +- .../contextviewer/ContextUsagePanel.java | 2 +- .../contextviewer/ContextViewer.java | 2 +- .../layout/ContentViewerDefaults.java | 176 ++++++++++++------ .../layout/ContentViewerHtmlStyles.java | 108 ++++++++--- .../corecomponents/AutoWrappingJTextPane.java | 2 +- .../keywordsearch/ExtractedContentPanel.java | 2 +- 12 files changed, 211 insertions(+), 93 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java index 3df51c9e48..7a20a7c2ce 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2018-2020 Basis Technology Corp. + * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java index 4b83bdc565..553c139c55 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java index 3f58c723c5..6f7e4cff2f 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java index 06e4a37d87..b9ebee5c67 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/MessageAccountPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/MessageAccountPanel.java index fb2088c31a..c2847223e6 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/MessageAccountPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/MessageAccountPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java index 9ca74d06c1..0f7d2855bf 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java index 3eeb4b4442..c3c74da190 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index 74ac4919cb..eae47348d2 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java index 86d306d636..8f7b077233 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java @@ -1,96 +1,156 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.contentviewers.layout; -import com.google.common.base.Suppliers; import java.awt.Font; import java.awt.Insets; import java.awt.Toolkit; -import com.google.common.base.Supplier; import java.awt.Color; import javax.swing.UIManager; /** - * - * @author gregd + * Default values for layout of content values. */ public class ContentViewerDefaults { - private static final Supplier DEFAULT_FONT = Suppliers.memoize(() -> UIManager.getDefaults().getFont("Label.font")); + private static final Font DEFAULT_FONT = UIManager.getDefaults().getFont("Label.font"); - private static final Supplier PT_TO_PX = Suppliers.memoize(() -> Toolkit.getDefaultToolkit().getScreenResolution() / 72.0); - - private static final Supplier DEFAULT_FONT_PX = Suppliers.memoize(() -> { - // based on https://stackoverflow.com/questions/5829703/java-getting-a-font-with-a-specific-height-in-pixels/26564924#26564924 - return (int) Math.round(DEFAULT_FONT.get().getSize() * PT_TO_PX.get()); - }); - - private static final Supplier SUB_HEADER_FONT = Suppliers.memoize(() -> { - Font defaultFont = DEFAULT_FONT.get(); - return defaultFont.deriveFont(Font.BOLD); - }); + // based on https://stackoverflow.com/questions/5829703/java-getting-a-font-with-a-specific-height-in-pixels/26564924#26564924 + private static final Double PT_TO_PX = Toolkit.getDefaultToolkit().getScreenResolution() / 72.0; - private static final Supplier HEADER_FONT = Suppliers.memoize(() -> { - Font defaultFont = DEFAULT_FONT.get(); - return defaultFont.deriveFont(Font.BOLD, defaultFont.getSize() + 2); - }); + private static final int DEFAULT_FONT_PX = (int) Math.round(DEFAULT_FONT.getSize() * PT_TO_PX); - private static final Supplier MESSAGE_FONT = Suppliers.memoize(() -> DEFAULT_FONT.get().deriveFont(Font.ITALIC)); - - private static final Supplier DEFAULT_PANEL_INSETS = Suppliers.memoize(() -> UIManager.getDefaults().getInsets("TextPane.margin")); + private static final Font SUB_HEADER_FONT = DEFAULT_FONT.deriveFont(Font.BOLD); - private static final Supplier DEFAULT_INDENT = Suppliers.memoize(() -> DEFAULT_FONT_PX.get()); - private static final Supplier DEFAULT_SECTION_SPACING = Suppliers.memoize(() -> DEFAULT_FONT_PX.get()); + private static final Font HEADER_FONT = DEFAULT_FONT.deriveFont(Font.BOLD, DEFAULT_FONT.getSize() + 2); - private static final Supplier DEFAULT_COLUMN_SPACING = Suppliers.memoize(() -> (DEFAULT_FONT_PX.get() / 3)); - private static final Supplier DEFAULT_LINE_SPACING = Suppliers.memoize(() -> (DEFAULT_FONT_PX.get() / 5)); + private static final Font MESSAGE_FONT = DEFAULT_FONT.deriveFont(Font.ITALIC); - private static final Supplier DEFAULT_BACKGROUND = Suppliers.memoize(() -> UIManager.getColor("Panel.background")); + private static final Insets DEFAULT_PANEL_INSETS = UIManager.getDefaults().getInsets("TextPane.margin"); + private static final int DEFAULT_INDENT = DEFAULT_FONT_PX; + private static final int DEFAULT_SECTION_SPACING = DEFAULT_FONT_PX; + + private static final int DEFAULT_COLUMN_SPACING = (int) Math.round((double) DEFAULT_FONT_PX / 3); + + private static final int DEFAULT_LINE_SPACING = (int) Math.round((double) DEFAULT_FONT_PX / 5); + + private static final Color DEFAULT_BACKGROUND = UIManager.getColor("Panel.background"); + + /** + * Returns the horizontal spacing between columns in a table in pixels. + * + * @return The horizontal spacing between columns in a table in pixels. + */ public static int getColumnSpacing() { - return DEFAULT_COLUMN_SPACING.get(); + return DEFAULT_COLUMN_SPACING; } + /** + * Returns the default font to be used. + * + * @return the default font to be used. + */ public static Font getFont() { - return DEFAULT_FONT.get(); + return DEFAULT_FONT; } + /** + * Returns the font to be displayed for messages. + * + * @return The font to be displayed for messages. + */ public static Font getMessageFont() { - return MESSAGE_FONT.get(); + return MESSAGE_FONT; } + /** + * Returns the font to be displayed for messages. + * + * @return The font to be displayed for messages. + */ public static Font getHeaderFont() { - return HEADER_FONT.get(); + return HEADER_FONT; } - public static Insets getPanelInsets() { - return DEFAULT_PANEL_INSETS.get(); - } - - public static Integer getSectionIndent() { - return DEFAULT_INDENT.get(); - } - - public static Integer getSectionSpacing() { - return DEFAULT_SECTION_SPACING.get(); - } - - public static Integer getLineSpacing() { - return DEFAULT_LINE_SPACING.get(); - } - - public static Color getPanelBackground() { - return DEFAULT_BACKGROUND.get(); - } - + /** + * Returns the font to be displayed for sub headers. + * + * @return The font to be displayed for sub headers. + */ public static Font getSubHeaderFont() { - return SUB_HEADER_FONT.get(); + return SUB_HEADER_FONT; } - + + /** + * Returns the insets of the content within the parent content viewer panel. + * + * @return The insets of the content within the parent content viewer panel. + */ + public static Insets getPanelInsets() { + return DEFAULT_PANEL_INSETS; + } + + /** + * Returns the size in pixels that sections should be indented. + * + * @return The size in pixels that sections should be indented. + */ + public static Integer getSectionIndent() { + return DEFAULT_INDENT; + } + + /** + * Returns the spacing between sections in pixels. + * + * @return The spacing between sections in pixels. + */ + public static Integer getSectionSpacing() { + return DEFAULT_SECTION_SPACING; + } + + /** + * Returns the spacing between lines of text in pixels. + * + * @return The spacing between lines of text in pixels. + */ + public static Integer getLineSpacing() { + return DEFAULT_LINE_SPACING; + } + + /** + * Returns the color to be used as the background of the panel. + * + * @return The color to be used as the background of the panel. + */ + public static Color getPanelBackground() { + return DEFAULT_BACKGROUND; + } + + /** + * Returns the ratio of point size to pixel size for the user's screen + * resolution. + * + * @return The ratio of point size to pixel size for the user's screen + * resolution. + */ public static Double getPtToPx() { - return PT_TO_PX.get(); + return PT_TO_PX; } } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java index 728fbfdadb..fa1ae8ee0d 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java @@ -1,20 +1,31 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.contentviewers.layout; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import java.awt.Font; import javax.swing.JTextPane; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.StyleSheet; /** - * - * @author gregd + * The style sheet an class names to be used with content viewers using html + * rendering. */ public class ContentViewerHtmlStyles { @@ -52,57 +63,104 @@ public class ContentViewerHtmlStyles { + String.format(" .%s { padding-right: %dpt } ", KEY_COLUMN_TD_CLASSNAME, pxToPt(ContentViewerDefaults.getColumnSpacing())); - private static final Supplier STYLE_SHEET = Suppliers.memoize(() -> { - StyleSheet stylesheet = new StyleSheet(); - stylesheet.addRule(STYLE_SHEET_RULE); - return stylesheet; - }); - - private static int pxToPt(int px) { - return (int) Math.round(((double) px) / ContentViewerDefaults.getPtToPx()); + private static final StyleSheet STYLE_SHEET = new StyleSheet(); + + static { + // add the style rule to the style sheet. + STYLE_SHEET.addRule(STYLE_SHEET_RULE); } + /** + * Converts pixel size to point size. The html rendering seems more + * consistent with point size versus pixel size. + * + * @param px The pixel size. + * + * @return The point size. + */ + private static int pxToPt(int px) { + return (int) Math.round(((double) px) / ContentViewerDefaults.getPtToPx()); + } + + /** + * Returns the class name to use for header text. + * + * @return The class name to use for header text. + */ public static String getHeaderClassName() { return HEADER_CLASSNAME; } + /** + * Returns the class name to use for sub header text. + * + * @return The class name to use for sub header text. + */ public static String getSubHeaderClassName() { return SUB_HEADER_CLASSNAME; } - + + /** + * Returns the class name to use for message text. + * + * @return The class name to use for message text. + */ public static String getMessageClassName() { return MESSAGE_CLASSNAME; } + /** + * Returns the class name to use for regular text. + * + * @return The class name to use for regular text. + */ public static String getTextClassName() { return TEXT_CLASSNAME; } + /** + * Returns the class name to use for an indented (left padding) section. + * + * @return The class name to use for an indented (left padding) section. + */ public static String getIndentedClassName() { return INDENTED_CLASSNAME; } + /** + * Returns the class name to use for a section with spacing (top padding) + * section. + * + * @return The class name to use for a section with spacing (top padding) + * section. + */ public static String getSpacedSectionClassName() { return SPACED_SECTION_CLASSNAME; } + /** + * Returns the class name to use for a key column with right spacing (right + * padding). + * + * @return The class name to use for a key column with right spacing (right + * padding). + */ public static String getKeyColumnClassName() { return KEY_COLUMN_TD_CLASSNAME; } - public static String getStyleSheetRule() { - return STYLE_SHEET_RULE; - } - - public static StyleSheet getStyleSheet() { - return STYLE_SHEET.get(); - } - + /** + * Sets up a JTextPane for html rendering using the css class names + * specified in this class. + * + * @param textPane The JTextPane to set up for content viewer html + * rendering. + */ public static void setupHtmlJTextPane(JTextPane textPane) { textPane.setContentType("text/html;charset=UTF-8"); //NON-NLS HTMLEditorKit kit = new HTMLEditorKit(); textPane.setEditorKit(kit); - kit.setStyleSheet(ContentViewerHtmlStyles.getStyleSheet()); + kit.setStyleSheet(STYLE_SHEET); textPane.setMargin(ContentViewerDefaults.getPanelInsets()); textPane.setBackground(ContentViewerDefaults.getPanelBackground()); } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java index 94b3cc68ad..652034dacc 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutoWrappingJTextPane.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 5d6d7689f2..0e716c8168 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2020 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); From 003d391ad376a8bf46a84e9ca789c2ec5c58cbb5 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Tue, 8 Jun 2021 17:02:32 -0400 Subject: [PATCH 37/70] Removed db calls from ImageNode createSheet --- .../sleuthkit/autopsy/datamodel/ImageNode.java | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java index ea0e2bb347..5df888052b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java @@ -20,8 +20,6 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -35,7 +33,6 @@ import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; @@ -48,7 +45,6 @@ import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; -import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.VirtualDirectory; import org.sleuthkit.autopsy.datamodel.BaseChildFactory.NoSuchEventBusException; @@ -171,17 +167,10 @@ public class ImageNode extends AbstractContentNode { Bundle.ImageNode_createSheet_timezone_desc(), this.content.getTimeZone())); - try (CaseDbQuery query = Case.getCurrentCaseThrows().getSleuthkitCase().executeQuery("SELECT device_id FROM data_source_info WHERE obj_id = " + this.content.getId());) { - ResultSet deviceIdSet = query.getResultSet(); - if (deviceIdSet.next()) { - sheetSet.put(new NodeProperty<>(Bundle.ImageNode_createSheet_deviceId_name(), + sheetSet.put(new NodeProperty<>(Bundle.ImageNode_createSheet_deviceId_name(), Bundle.ImageNode_createSheet_deviceId_displayName(), Bundle.ImageNode_createSheet_deviceId_desc(), - deviceIdSet.getString("device_id"))); - } - } catch (SQLException | TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Failed to get device id for the following image: " + this.content.getId(), ex); - } + content.getDeviceId())); return sheet; } From 8d35b95c5f4126fd3bbbbd963d2d42073a89e0fa Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Jun 2021 21:03:19 -0400 Subject: [PATCH 38/70] updated metadata viewer --- .../AnnotationsContentViewer.java | 1 + .../autopsy/contentviewers/Metadata.java | 119 ++++++++++++------ .../AnalysisResultsContentPanel.java | 40 +++--- .../layout/ContentViewerHtmlStyles.java | 10 ++ 4 files changed, 113 insertions(+), 57 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java index 7a20a7c2ce..aad1fe79a8 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java @@ -200,6 +200,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data try { String text = get(); + ContentViewerHtmlStyles.setStyles(textPanel); textPanel.setText(text); textPanel.setCaretPosition(0); } catch (InterruptedException | ExecutionException ex) { diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java index 488c96c4df..72691afe64 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java @@ -21,9 +21,12 @@ package org.sleuthkit.autopsy.contentviewers; import java.awt.Component; import java.awt.Cursor; import java.text.MessageFormat; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.logging.Level; +import java.util.stream.Stream; import javax.swing.SwingWorker; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Node; @@ -65,6 +68,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { public Metadata() { initComponents(); customizeComponents(); + ContentViewerHtmlStyles.setupHtmlJTextPane(jTextPane1); } /** @@ -118,31 +122,59 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { * selectAllMenuItem.addActionListener(actList); */ - ContentViewerHtmlStyles.setupHtmlJTextPane(jTextPane1); } private void setText(String str) { - jTextPane1.setText("" + str + ""); //NON-NLS + ContentViewerHtmlStyles.setupHtmlJTextPane(jTextPane1); + jTextPane1.setText("" + str + ""); //NON-NLS + } + + private void addHeader(StringBuilder sb, String header, boolean spaced) { + sb.append(MessageFormat.format("

{2}

", + (spaced) ? ContentViewerHtmlStyles.getSpacedSectionClassName() : "", + ContentViewerHtmlStyles.getHeaderClassName(), + header)); } private void startTable(StringBuilder sb) { - sb.append(""); //NON-NLS + sb.append(MessageFormat.format("
", + ContentViewerHtmlStyles.getIndentedClassName())); //NON-NLS } private void endTable(StringBuilder sb) { - sb.append("
"); //NON-NLS + sb.append(""); //NON-NLS } private void addRow(StringBuilder sb, String key, String value) { - sb.append(MessageFormat.format("{1}{3}", - ContentViewerHtmlStyles.getTextClassName() + " " + ContentViewerHtmlStyles.getKeyColumnClassName(), - key, - ContentViewerHtmlStyles.getTextClassName(), - value - )); + sb.append(MessageFormat.format("{2}:{4}", + ContentViewerHtmlStyles.getKeyColumnClassName(), + ContentViewerHtmlStyles.getTextClassName(), + key, + ContentViewerHtmlStyles.getTextClassName(), + value + )); + } + + private void addRow(StringBuilder sb, String key) { + sb.append(MessageFormat.format("{2}", + ContentViewerHtmlStyles.getKeyColumnClassName(), + ContentViewerHtmlStyles.getTextClassName(), + key + )); + } + + private void addRowWithMultipleValues(StringBuilder sb, String key, String[] values) { + String[] safeValues = values == null || values.length < 1 ? new String[]{""} : values; + + addRow(sb, key, safeValues[0]); + Stream.of(safeValues) + .skip(1) + .filter(line -> line != null) + .forEach(line -> addRow(sb, line)); } @Messages({ + "Metadata.headerTitle=Metadata", "Metadata.tableRowTitle.mimeType=MIME Type", "Metadata.nodeText.truncated=(results truncated)", "Metadata.tableRowTitle.sha1=SHA1", @@ -222,8 +254,11 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { if (StringUtils.isEmpty(details)) { details = Bundle.Metadata_nodeText_unknown(); } - details = details.replaceAll("\n", "
"); - addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.acquisitionDetails"), details); + String[] lines = (details != null) ? details.split("\n") : new String[]{""}; + addRowWithMultipleValues(sb, + NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.acquisitionDetails"), + lines); + } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error reading acquisition details from case database", ex); //NON-NLS } @@ -243,11 +278,9 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { if (node != null && !node.getLookup().lookupAll(DataArtifact.class).isEmpty()) { return Bundle.Metadata_dataArtifactTitle(); } else { - return NbBundle.getMessage(this.getClass(), "Metadata.title"); + return NbBundle.getMessage(this.getClass(), "Metadata.title"); } } - - @Override public String getToolTip() { @@ -302,6 +335,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { } StringBuilder sb = new StringBuilder(); + addHeader(sb, Bundle.Metadata_headerTitle(), false); startTable(sb); if (file != null) { @@ -360,30 +394,35 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { * If we have a file system file, grab the more detailed * metadata text too */ - try { - if (file instanceof FsContent) { - FsContent fsFile = (FsContent) file; + if (file instanceof FsContent) { + FsContent fsFile = (FsContent) file; - sb.append("
\n"); //NON-NLS
-                        sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.text"));
-                        sb.append(" 

"); // NON-NLS - for (String str : fsFile.getMetaDataText()) { - sb.append(str).append("
"); //NON-NLS + addHeader(sb, NbBundle.getMessage(this.getClass(), "Metadata.nodeText.text"), true); + startTable(sb); - /* + List istatStrings = Collections.emptyList(); + try { + istatStrings = fsFile.getMetaDataText(); + } catch (TskCoreException ex) { + istatStrings = Arrays.asList(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text") + ex.getLocalizedMessage()); + } + + for (String str : istatStrings) { + addRow(sb, str); + + /* * Very long results can cause the UI to hang before * displaying, so truncate the results if necessary. - */ - if (sb.length() > 50000) { - sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated")); - break; - } + */ + if (sb.length() > 50000) { + addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated")); + break; } - sb.append("
\n"); //NON-NLS } - } catch (TskCoreException ex) { - sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text")).append(ex.getLocalizedMessage()); + + endTable(sb); } + } else { try { addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.name"), image.getUniquePath()); @@ -422,20 +461,18 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { // Add all the data source paths to the "Local Path" value cell. String[] imagePaths = image.getPaths(); + + if (imagePaths.length > 0) { - StringBuilder pathValues = new StringBuilder("
"); - pathValues.append(imagePaths[0]); - pathValues.append("
"); - for (int i = 1; i < imagePaths.length; i++) { - pathValues.append("
"); - pathValues.append(imagePaths[i]); - pathValues.append("
"); - } - addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), pathValues.toString()); + addRowWithMultipleValues(sb, + NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), + imagePaths); } else { addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), NbBundle.getMessage(this.getClass(), "Metadata.nodeText.none")); } + + endTable(sb); } if (isCancelled()) { diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java index fb56971f57..924be963dd 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java @@ -36,15 +36,15 @@ import org.sleuthkit.datamodel.Score; * Displays a list of analysis results in a panel. */ public class AnalysisResultsContentPanel extends javax.swing.JPanel { - + private static final long serialVersionUID = 1L; - + private static final String EMPTY_HTML = ""; // Anchors are inserted into the navigation so that the viewer can navigate to a selection. // This is the prefix of those anchors. private static final String RESULT_ANCHOR_PREFIX = "AnalysisResult_"; - + /** * Creates new form AnalysisResultsContentViewer */ @@ -59,8 +59,9 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { * @param message The message to be displayed. */ void showMessage(String message) { + ContentViewerHtmlStyles.setStyles(textPanel); textPanel.setText("" - + MessageFormat.format("

{1}

", + + MessageFormat.format("

{1}

", ContentViewerHtmlStyles.getMessageClassName(), message == null ? "" : message) + ""); @@ -104,8 +105,9 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { } // set the body html + ContentViewerHtmlStyles.setStyles(textPanel); textPanel.setText(document.html()); - + // if there is a selected result scroll to it Optional selectedResult = nodeResults.getSelectedResult(); if (selectedResult.isPresent()) { @@ -115,19 +117,22 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { /** * Returns the anchor id to use with the analysis result (based on the id). + * * @param analysisResult The analysis result. + * * @return The anchor id. */ private String getAnchor(AnalysisResult analysisResult) { return RESULT_ANCHOR_PREFIX + analysisResult.getId(); } - /** * Appends a result item to the parent element of an html document. + * * @param parent The parent element. - * @param index The index of the item in the list of all items. - * @param attrs The attributes of this item. + * @param index The index of the item in the list of all items. + * @param attrs The attributes of this item. + * * @return The result div. */ @NbBundle.Messages({"# {0} - analysisResultsNumber", @@ -138,20 +143,23 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { Element sectionDiv = appendSection(parent, Bundle.AnalysisResultsContentPanel_result_headerKey(index + 1), Optional.ofNullable(getAnchor(attrs.getAnalysisResult()))); - + // create a table Element table = sectionDiv.appendElement("table"); table.attr("class", ContentViewerHtmlStyles.getIndentedClassName()); - + Element tableBody = table.appendElement("tbody"); // append a row for each item for (Pair keyVal : attrs.getAttributesToDisplay()) { Element row = tableBody.appendElement("tr"); String keyString = keyVal.getKey() == null ? "" : keyVal.getKey() + ":"; - row.appendElement("td") + Element keyTd = row.appendElement("td") + .attr("class", ContentViewerHtmlStyles.getTextClassName()); + + keyTd.appendElement("span") .text(keyString) - .attr("class", ContentViewerHtmlStyles.getTextClassName() + " " + ContentViewerHtmlStyles.getKeyColumnClassName()); + .attr("class", ContentViewerHtmlStyles.getKeyColumnClassName()); String valueString = keyVal.getValue() == null ? "" : keyVal.getValue(); row.appendElement("td") @@ -173,7 +181,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { */ private Element appendSection(Element parent, String headerText, Optional anchorId) { Element sectionDiv = parent.appendElement("div"); - + // append an anchor tag if there is one Element anchorEl = null; if (anchorId.isPresent()) { @@ -181,17 +189,17 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { anchorEl.attr("name", anchorId.get()); anchorEl.attr("style", "padding: 0px; margin: 0px; display: inline-block;"); } - + // append the header Element header = null; - header = (anchorEl == null) + header = (anchorEl == null) ? sectionDiv.appendElement("h1") : anchorEl.appendElement("h1"); header.text(headerText); header.attr("class", ContentViewerHtmlStyles.getHeaderClassName()); header.attr("style", "display: inline-block"); - + // return the section element return sectionDiv; } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java index fa1ae8ee0d..04c417354b 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.contentviewers.layout; import java.awt.Font; import javax.swing.JTextPane; +import javax.swing.text.EditorKit; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.StyleSheet; @@ -148,6 +149,15 @@ public class ContentViewerHtmlStyles { public static String getKeyColumnClassName() { return KEY_COLUMN_TD_CLASSNAME; } + + + public static void setStyles(JTextPane textPane) { + EditorKit editorKit = textPane.getEditorKit(); + if (editorKit instanceof HTMLEditorKit) { + ((HTMLEditorKit) editorKit).setStyleSheet(STYLE_SHEET); + } + } + /** * Sets up a JTextPane for html rendering using the css class names From 73700b3eb84404cf009780bb83a30ad490f1cf55 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 9 Jun 2021 07:39:55 -0400 Subject: [PATCH 39/70] Do MIME type detection for zip bomb test during file extraction --- .../SevenZipExtractor.java | 67 ++++++++++++------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java index 35b5a7e560..b7a5f6e545 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java @@ -46,6 +46,7 @@ import net.sf.sevenzipjbinding.PropID; import net.sf.sevenzipjbinding.SevenZip; import net.sf.sevenzipjbinding.SevenZipException; import net.sf.sevenzipjbinding.SevenZipNativeInitializationException; +import org.apache.tika.Tika; import org.apache.tika.parser.txt.CharsetDetector; import org.apache.tika.parser.txt.CharsetMatch; import org.netbeans.api.progress.ProgressHandle; @@ -194,6 +195,15 @@ class SevenZipExtractor { } return false; } + + boolean isSevenZipExtractionSupported(String mimeType) { + for (SupportedArchiveExtractionFormats supportedMimeType : SupportedArchiveExtractionFormats.values()) { + if (mimeType.contains(supportedMimeType.toString())) { + return true; + } + } + return false; + } /** * Private helper method to standardize the cancellation check that is @@ -789,28 +799,10 @@ class SevenZipExtractor { // add them to the DB. We wait until the end so that we have the metadata on all of the // intermediate nodes since the order is not guaranteed try { - unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath); + unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath, parentAr, archiveFile, depthMap); if (checkForIngestCancellation(archiveFile)) { return false; } - unpackedFiles = unpackedTree.getAllFileObjects(); - //check if children are archives, update archive depth tracking - for (int i = 0; i < unpackedFiles.size(); i++) { - if (checkForIngestCancellation(archiveFile)) { - return false; - } - progress.progress(String.format("%s: Searching for nested archives (%d of %d)", currentArchiveName, i + 1, unpackedFiles.size())); - AbstractFile unpackedFile = unpackedFiles.get(i); - if (unpackedFile == null) { - continue; - } - if (isSevenZipExtractionSupported(unpackedFile)) { - Archive child = new Archive(parentAr.getDepth() + 1, parentAr.getRootArchiveId(), archiveFile); - parentAr.addChild(child); - depthMap.put(unpackedFile.getId(), child); - } - unpackedFile.close(); - } } catch (TskCoreException | NoCurrentCaseException e) { logger.log(Level.SEVERE, "Error populating complete derived file hierarchy from the unpacked dir structure", e); //NON-NLS @@ -991,6 +983,8 @@ class SevenZipExtractor { private EncodedFileOutputStream output; private String localAbsPath; private int bytesWritten; + private static final Tika tika = new Tika(); + private String mimeType = ""; UnpackStream(String localAbsPath) throws IOException { this.output = new EncodedFileOutputStream(new FileOutputStream(localAbsPath), TskData.EncodingType.XOR1); @@ -1003,6 +997,7 @@ class SevenZipExtractor { this.output = new EncodedFileOutputStream(new FileOutputStream(localAbsPath), TskData.EncodingType.XOR1); this.localAbsPath = localAbsPath; this.bytesWritten = 0; + this.mimeType = ""; } public int getSize() { @@ -1012,6 +1007,10 @@ class SevenZipExtractor { @Override public int write(byte[] bytes) throws SevenZipException { try { + // Detect MIME type now while the file is in memory + if (bytesWritten == 0) { + mimeType = tika.detect(bytes); + } output.write(bytes); this.bytesWritten += bytes.length; } catch (IOException ex) { @@ -1023,6 +1022,10 @@ class SevenZipExtractor { return bytes.length; } + public String getMIMEType() { + return mimeType; + } + public void close() throws IOException { try (EncodedFileOutputStream out = output) { out.flush(); @@ -1196,6 +1199,8 @@ class SevenZipExtractor { 0L, createTimeInSeconds, accessTimeInSeconds, modTimeInSeconds, localRelPath); return; + } else { + unpackedNode.setMimeType(unpackStream.getMIMEType()); } final String localAbsPath = archiveDetailsMap.get( @@ -1413,10 +1418,10 @@ class SevenZipExtractor { * Traverse the tree top-down after unzipping is done and create derived * files for the entire hierarchy */ - void updateOrAddFileToCaseRec(HashMap statusMap, String archiveFilePath) throws TskCoreException, NoCurrentCaseException { + void updateOrAddFileToCaseRec(HashMap statusMap, String archiveFilePath, Archive parentAr, AbstractFile archiveFile, ConcurrentHashMap depthMap) throws TskCoreException, NoCurrentCaseException { final FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager(); for (UnpackedNode child : rootNode.getChildren()) { - updateOrAddFileToCaseRec(child, fileManager, statusMap, archiveFilePath); + updateOrAddFileToCaseRec(child, fileManager, statusMap, archiveFilePath, parentAr, archiveFile, depthMap); } } @@ -1434,7 +1439,7 @@ class SevenZipExtractor { * * @throws TskCoreException */ - private void updateOrAddFileToCaseRec(UnpackedNode node, FileManager fileManager, HashMap statusMap, String archiveFilePath) throws TskCoreException { + private void updateOrAddFileToCaseRec(UnpackedNode node, FileManager fileManager, HashMap statusMap, String archiveFilePath, Archive parentAr, AbstractFile archiveFile, ConcurrentHashMap depthMap) throws TskCoreException { DerivedFile df; progress.progress(String.format("%s: Adding/updating files in case database (%d of %d)", currentArchiveName, ++nodesProcessed, numItems)); try { @@ -1497,10 +1502,17 @@ class SevenZipExtractor { } } } + + // Check for zip bombs + if (isSevenZipExtractionSupported(node.getMimeType())) { + Archive child = new Archive(parentAr.getDepth() + 1, parentAr.getRootArchiveId(), archiveFile); + parentAr.addChild(child); + depthMap.put(node.getFile().getId(), child); + } //recurse adding the children if this file was incomplete the children presumably need to be added for (UnpackedNode child : node.getChildren()) { - updateOrAddFileToCaseRec(child, fileManager, statusMap, getKeyFromUnpackedNode(node, archiveFilePath)); + updateOrAddFileToCaseRec(child, fileManager, statusMap, getKeyFromUnpackedNode(node, archiveFilePath), parentAr, archiveFile, depthMap); } } @@ -1517,6 +1529,7 @@ class SevenZipExtractor { private long size; private long ctime, crtime, atime, mtime; private boolean isFile; + private String mimeType = ""; private UnpackedNode parent; //root constructor @@ -1593,6 +1606,14 @@ class SevenZipExtractor { void setFile(AbstractFile file) { this.file = file; } + + void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + String getMimeType() { + return mimeType; + } /** * get child by name or null if it doesn't exist From 56968ec0df35db566175e55c4a339ef62dba5ba6 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 9 Jun 2021 08:34:46 -0400 Subject: [PATCH 40/70] updates in metadata --- .../autopsy/contentviewers/Metadata.form | 2 -- .../autopsy/contentviewers/Metadata.java | 19 ++++++++------- .../AnalysisResultsContentPanel.java | 3 ++- .../layout/ContentViewerDefaults.java | 11 +++++++++ .../layout/ContentViewerHtmlStyles.java | 23 ++++++++++++++++--- .../keywordsearch/ExtractedContentPanel.java | 11 ++++++--- 6 files changed, 50 insertions(+), 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.form b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.form index b175b6b512..8e6f123911 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.form @@ -41,8 +41,6 @@ - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java index 72691afe64..bd3671e44b 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java @@ -35,6 +35,7 @@ import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; +import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils; import org.sleuthkit.datamodel.AbstractFile; @@ -86,8 +87,6 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { setPreferredSize(new java.awt.Dimension(100, 52)); - jScrollPane2.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); - jScrollPane2.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); jScrollPane2.setPreferredSize(new java.awt.Dimension(610, 52)); jTextPane1.setEditable(false); @@ -149,17 +148,17 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { sb.append(MessageFormat.format("{2}:{4}", ContentViewerHtmlStyles.getKeyColumnClassName(), ContentViewerHtmlStyles.getTextClassName(), - key, + EscapeUtil.escapeHtml(key), ContentViewerHtmlStyles.getTextClassName(), - value + EscapeUtil.escapeHtml(key) )); } - private void addRow(StringBuilder sb, String key) { + private void addMonospacedRow(StringBuilder sb, String key) { sb.append(MessageFormat.format("{2}", ContentViewerHtmlStyles.getKeyColumnClassName(), - ContentViewerHtmlStyles.getTextClassName(), - key + ContentViewerHtmlStyles.getMonospacedClassName(), + EscapeUtil.escapeHtml(key) )); } @@ -170,7 +169,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { Stream.of(safeValues) .skip(1) .filter(line -> line != null) - .forEach(line -> addRow(sb, line)); + .forEach(line -> addRow(sb, "", EscapeUtil.escapeHtml(line))); } @Messages({ @@ -408,14 +407,14 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { } for (String str : istatStrings) { - addRow(sb, str); + addMonospacedRow(sb, str); /* * Very long results can cause the UI to hang before * displaying, so truncate the results if necessary. */ if (sb.length() > 50000) { - addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated")); + addMonospacedRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated")); break; } } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java index 924be963dd..13857de887 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java @@ -29,6 +29,7 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.NodeResults; import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.ResultDisplayAttributes; import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; +import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.Score; @@ -63,7 +64,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { textPanel.setText("" + MessageFormat.format("

{1}

", ContentViewerHtmlStyles.getMessageClassName(), - message == null ? "" : message) + message == null ? "" : EscapeUtil.escapeHtml(message)) + ""); } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java index 8f7b077233..65023b9110 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerDefaults.java @@ -41,6 +41,8 @@ public class ContentViewerDefaults { private static final Font HEADER_FONT = DEFAULT_FONT.deriveFont(Font.BOLD, DEFAULT_FONT.getSize() + 2); private static final Font MESSAGE_FONT = DEFAULT_FONT.deriveFont(Font.ITALIC); + + private static final Font MONOSPACED_FONT = new Font(Font.MONOSPACED, Font.PLAIN, DEFAULT_FONT.getSize()); private static final Insets DEFAULT_PANEL_INSETS = UIManager.getDefaults().getInsets("TextPane.margin"); @@ -98,6 +100,15 @@ public class ContentViewerDefaults { return SUB_HEADER_FONT; } + /** + * Returns the font to be used for normal monospace. + * + * @return The font to be used for normal monospace. + */ + public static Font getMonospacedFont() { + return MONOSPACED_FONT; + } + /** * Returns the insets of the content within the parent content viewer panel. * diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java index 04c417354b..437b67bf1b 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java @@ -38,6 +38,7 @@ public class ContentViewerHtmlStyles { private static final String MESSAGE_CLASSNAME = CLASS_PREFIX + "message"; private static final String TEXT_CLASSNAME = CLASS_PREFIX + "text"; + private static final String MONOSPACED_CLASSNAME = CLASS_PREFIX + "monospaced"; private static final String INDENTED_CLASSNAME = CLASS_PREFIX + "indent"; private static final String SPACED_SECTION_CLASSNAME = CLASS_PREFIX + "spacedSection"; private static final String KEY_COLUMN_TD_CLASSNAME = CLASS_PREFIX + "keyKolumn"; @@ -46,6 +47,7 @@ public class ContentViewerHtmlStyles { private static final Font MESSAGE_FONT = ContentViewerDefaults.getMessageFont(); private static final Font HEADER_FONT = ContentViewerDefaults.getHeaderFont(); private static final Font SUB_HEADER_FONT = ContentViewerDefaults.getSubHeaderFont(); + private static final Font MONOSPACED_FONT = ContentViewerDefaults.getMonospacedFont(); // additional styling for components private static final String STYLE_SHEET_RULE @@ -57,6 +59,8 @@ public class ContentViewerHtmlStyles { SUB_HEADER_CLASSNAME, SUB_HEADER_FONT.getFamily(), SUB_HEADER_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + String.format(" .%s { font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpt 0px; } ", TEXT_CLASSNAME, DEFAULT_FONT.getFamily(), DEFAULT_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + + String.format(" .%s { font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpt 0px; } ", + MONOSPACED_CLASSNAME, "Monospaced", MONOSPACED_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + String.format(" .%s { padding-left: %dpt } ", INDENTED_CLASSNAME, pxToPt(ContentViewerDefaults.getSectionIndent())) + String.format(" .%s { padding-top: %dpt } ", @@ -119,6 +123,15 @@ public class ContentViewerHtmlStyles { return TEXT_CLASSNAME; } + /** + * Returns the class name to use for monospaced text. + * + * @return The class name to use for monospaced text. + */ + public static String getMonospacedClassName() { + return MONOSPACED_CLASSNAME; + } + /** * Returns the class name to use for an indented (left padding) section. * @@ -149,15 +162,19 @@ public class ContentViewerHtmlStyles { public static String getKeyColumnClassName() { return KEY_COLUMN_TD_CLASSNAME; } - - + + /** + * If the textPane has an HTMLEditorKit, specifies the + * ContentViewerHTMLStyles styles to use refreshing the styles. + * + * @param textPane The text pane. + */ public static void setStyles(JTextPane textPane) { EditorKit editorKit = textPane.getEditorKit(); if (editorKit instanceof HTMLEditorKit) { ((HTMLEditorKit) editorKit).setStyleSheet(STYLE_SHEET); } } - /** * Sets up a JTextPane for html rendering using the css class names diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 0e716c8168..c64cee2565 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -72,7 +72,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP ExtractedContentPanel() { initComponents(); additionalInit(); - setSources("", new ArrayList<>()); hitPreviousButton.setEnabled(false); hitNextButton.setEnabled(false); @@ -137,7 +136,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP }; // set new style sheet to clear default styles styleSheet = editorKit.getStyleSheet(); - setStyleSheetSize(styleSheet, DEFAULT_FONT.getSize()); sourceComboBox.addItemListener(itemEvent -> { if (itemEvent.getStateChange() == ItemEvent.SELECTED) { @@ -158,11 +156,16 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP if (zoomPanel instanceof TextZoomPanel) ((TextZoomPanel) this.zoomPanel).resetSize(); }); + + setSources("", new ArrayList<>()); } private void setStyleSheetSize(StyleSheet styleSheet, int size) { - styleSheet.addRule("body { font-family:\"" + DEFAULT_FONT.getFamily() + "\"; font-size:" + size + "pt; } "); + styleSheet.addRule( + "body { font-family:\"" + DEFAULT_FONT.getFamily() + "\"; font-size:" + size + "pt; } " + + "pre { font-family:\"" + DEFAULT_FONT.getFamily() + "\"; font-size:" + size + "pt; } " + ); } @@ -501,6 +504,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); } + // refresh style + setStyleSheetSize(styleSheet, curSize); extractedTextPane.setText(safeText); extractedTextPane.setCaretPosition(0); } From b3f8a878793242ea1fb13358308e368169bec86f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 9 Jun 2021 08:44:23 -0400 Subject: [PATCH 41/70] monospace fix --- .../autopsy/contentviewers/layout/ContentViewerHtmlStyles.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java index 437b67bf1b..17632dc802 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/layout/ContentViewerHtmlStyles.java @@ -60,7 +60,7 @@ public class ContentViewerHtmlStyles { + String.format(" .%s { font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpt 0px; } ", TEXT_CLASSNAME, DEFAULT_FONT.getFamily(), DEFAULT_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + String.format(" .%s { font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpt 0px; } ", - MONOSPACED_CLASSNAME, "Monospaced", MONOSPACED_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + MONOSPACED_CLASSNAME, Font.MONOSPACED, MONOSPACED_FONT.getSize(), pxToPt(ContentViewerDefaults.getLineSpacing())) + String.format(" .%s { padding-left: %dpt } ", INDENTED_CLASSNAME, pxToPt(ContentViewerDefaults.getSectionIndent())) + String.format(" .%s { padding-top: %dpt } ", From ffce7d10b401b033af6f8be3a81e11e642e8b161 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 9 Jun 2021 12:25:47 -0400 Subject: [PATCH 42/70] 7653 eliminate null check preventing proper reset --- .../relationships/CallLogViewer.java | 2 +- .../relationships/RelationshipBrowser.java | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java index 21d7deb8bd..199a19e136 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java index 229a0067de..0894fa3b1b 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java @@ -37,15 +37,15 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider */ public RelationshipBrowser() { initComponents(); - + MessageViewer messagesViewer = new MessageViewer(); ContactsViewer contactsViewer = new ContactsViewer(); SummaryViewer summaryViewer = new SummaryViewer(); MediaViewer mediaViewer = new MediaViewer(); CallLogViewer callLogViewer = new CallLogViewer(); - + proxyLookup = new ModifiableProxyLookup(messagesViewer.getLookup()); - + tabPane.add(summaryViewer.getDisplayName(), summaryViewer); tabPane.add(messagesViewer.getDisplayName(), messagesViewer); tabPane.add(callLogViewer.getDisplayName(), callLogViewer); @@ -95,13 +95,10 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider }// //GEN-END:initComponents private void tabPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabPaneStateChanged - if(currentSelection != null) { - ((RelationshipsViewer) tabPane.getSelectedComponent()).setSelectionInfo(currentSelection); - } - + ((RelationshipsViewer) tabPane.getSelectedComponent()).setSelectionInfo(currentSelection); Component selectedComponent = tabPane.getSelectedComponent(); - if(selectedComponent instanceof Lookup.Provider) { - Lookup lookup = ((Lookup.Provider)selectedComponent).getLookup(); + if (selectedComponent instanceof Lookup.Provider) { + Lookup lookup = ((Lookup.Provider) selectedComponent).getLookup(); proxyLookup.setNewLookups(lookup); } }//GEN-LAST:event_tabPaneStateChanged From 15885df3865dd0897c3aa53e7b5dafeb5c2e4a86 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 9 Jun 2021 12:26:53 -0400 Subject: [PATCH 43/70] 7653 formatting --- .../autopsy/communications/relationships/CallLogViewer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java index 199a19e136..3fe8ec204e 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java @@ -119,9 +119,9 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie updateOutlineViewPanel(); } }); - + TableColumn column = outline.getColumnModel().getColumn(2); - column.setCellRenderer(new NodeTableCellRenderer() ); + column.setCellRenderer(new NodeTableCellRenderer()); } @@ -229,7 +229,7 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie } } - + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JScrollPane bottomScrollPane; private org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel outlineViewPanel; From c26efab04dbda2dc0b94d29b51a524238f687ebe Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 9 Jun 2021 15:45:13 -0400 Subject: [PATCH 44/70] change in analysis results header attributes --- .../AnalysisResultsContentPanel.java | 69 ++++++++++++++----- .../AnalysisResultsViewModel.java | 23 ++++++- 2 files changed, 72 insertions(+), 20 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java index 3a5a670f49..f365e8392e 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentPanel.java @@ -26,20 +26,22 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.NodeResults; import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.ResultDisplayAttributes; import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.datamodel.AnalysisResult; +import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Score; /** * Displays a list of analysis results in a panel. */ public class AnalysisResultsContentPanel extends javax.swing.JPanel { - + private static final long serialVersionUID = 1L; - + private static final String EMPTY_HTML = ""; // Anchors are inserted into the navigation so that the viewer can navigate to a selection. @@ -80,27 +82,18 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { * * @param nodeResults The analysis results data to display. */ - @NbBundle.Messages("AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score") void displayResults(NodeResults nodeResults) { Document document = Jsoup.parse(EMPTY_HTML); Element body = document.getElementsByTag("body").first(); - // if there is an aggregate score, append a section with the value - Optional aggregateScore = nodeResults.getAggregateScore(); - if (aggregateScore.isPresent()) { - appendSection(body, - MessageFormat.format("{0}: {1}", - Bundle.AnalysisResultsContentPanel_aggregateScore_displayKey(), - aggregateScore.get().getSignificance().getDisplayName()), - Optional.empty()); - } + Optional panelHeader = appendPanelHeader(body, nodeResults.getContent(), nodeResults.getAggregateScore()); // for each analysis result item, display the data. List displayAttributes = nodeResults.getAnalysisResults(); for (int idx = 0; idx < displayAttributes.size(); idx++) { AnalysisResultsViewModel.ResultDisplayAttributes resultAttrs = displayAttributes.get(idx); Element sectionDiv = appendResult(body, idx, resultAttrs); - if (idx > 0 || aggregateScore.isPresent()) { + if (idx > 0 || panelHeader.isPresent()) { sectionDiv.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName()); } } @@ -119,6 +112,48 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { } } + /** + * Appends the header to the panel. + * + * @param parent The parent html element. + * @param content The content whose name will be added if present. + * @param score The aggregate score whose significance will be added if + * present. + * + * @return The html element. + */ + @Messages({ + "AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score", + "AnalysisResultsContentPanel_content_displayKey=Item" + }) + private Optional appendPanelHeader(Element parent, Optional content, Optional score) { + if (!content.isPresent() || !score.isPresent()) { + return Optional.empty(); + } + + Element container = parent.appendElement("div"); + + // if there is content append the name + content.ifPresent((c) -> { + container.appendElement("p") + .attr("class", ContentViewerHtmlStyles.getTextClassName()) + .text(MessageFormat.format("{0}: {1}", + Bundle.AnalysisResultsContentPanel_content_displayKey(), + c.getName())); + }); + + // if there is an aggregate score, append the value + score.ifPresent((s) -> { + container.appendElement("p") + .attr("class", ContentViewerHtmlStyles.getTextClassName()) + .text(MessageFormat.format("{0}: {1}", + Bundle.AnalysisResultsContentPanel_aggregateScore_displayKey(), + s.getSignificance().getDisplayName())); + }); + + return Optional.ofNullable(container); + } + /** * Returns the anchor id to use with the analysis result (based on the id). * @@ -151,7 +186,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { // create a table Element table = sectionDiv.appendElement("table"); table.attr("class", ContentViewerHtmlStyles.getIndentedClassName()); - + Element tableBody = table.appendElement("tbody"); // append a row for each item @@ -160,7 +195,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { String keyString = keyVal.getKey() == null ? "" : keyVal.getKey() + ":"; Element keyTd = row.appendElement("td") .attr("class", ContentViewerHtmlStyles.getTextClassName()); - + keyTd.appendElement("span") .text(keyString) .attr("class", ContentViewerHtmlStyles.getKeyColumnClassName()); @@ -170,7 +205,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { .text(valueString) .attr("class", ContentViewerHtmlStyles.getTextClassName()); } - + return sectionDiv; } @@ -199,7 +234,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel { header = (anchorEl == null) ? sectionDiv.appendElement("h1") : anchorEl.appendElement("h1"); - + header.text(headerText); header.attr("class", ContentViewerHtmlStyles.getHeaderClassName()); header.attr("style", "display: inline-block"); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java index 8ba7308eb4..00cc170b14 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java @@ -94,6 +94,7 @@ public class AnalysisResultsViewModel { private final List analysisResults; private final Optional selectedResult; private final Optional aggregateScore; + private final Optional content; /** * Constructor. @@ -102,11 +103,13 @@ public class AnalysisResultsViewModel { * @param selectedResult The selected analysis result or empty if none * selected. * @param aggregateScore The aggregate score or empty if no score. + * @param content The content associated with these results. */ - NodeResults(List analysisResults, Optional selectedResult, Optional aggregateScore) { + NodeResults(List analysisResults, Optional selectedResult, Optional aggregateScore, Optional content) { this.analysisResults = analysisResults; this.selectedResult = selectedResult; this.aggregateScore = aggregateScore; + this.content = content; } /** @@ -135,6 +138,17 @@ public class AnalysisResultsViewModel { Optional getAggregateScore() { return aggregateScore; } + + /** + * Returns the content associated with these results or empty if not + * present. + * + * @return The content associated with these results or empty if not + * present. + */ + Optional getContent() { + return content; + } } /** @@ -221,10 +235,11 @@ public class AnalysisResultsViewModel { */ NodeResults getAnalysisResults(Node node) { if (node == null) { - return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty()); + return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty(), Optional.empty()); } Optional aggregateScore = Optional.empty(); + Optional nodeContent = Optional.empty(); // maps id of analysis result to analysis result to prevent duplication Map allAnalysisResults = new HashMap<>(); Optional selectedResult = Optional.empty(); @@ -236,6 +251,8 @@ public class AnalysisResultsViewModel { } try { + nodeContent = Optional.of(content); + // get the aggregate score of that content aggregateScore = Optional.ofNullable(content.getAggregateScore()); @@ -273,6 +290,6 @@ public class AnalysisResultsViewModel { // get view model representation List displayAttributes = getOrderedDisplayAttributes(allAnalysisResults.values()); - return new NodeResults(displayAttributes, selectedResult, aggregateScore); + return new NodeResults(displayAttributes, selectedResult, aggregateScore, nodeContent); } } From 68ed24c500bea88b857ce0490353e1bfcb0de299 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 9 Jun 2021 17:24:06 -0400 Subject: [PATCH 45/70] 7653 fix refreshing of callogs,media, and contacts when no info --- .../relationships/CallLogViewer.java | 2 + .../ContactsChildNodeFactory.java | 20 ++++--- .../relationships/ContactsViewer.java | 2 +- .../relationships/MediaViewer.java | 21 ++++---- .../relationships/RelationshipBrowser.java | 21 +++++--- .../CallLogArtifactViewer.java | 26 ++++----- .../ContactArtifactViewer.java | 54 +++++++++---------- 7 files changed, 75 insertions(+), 71 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java index 3fe8ec204e..664f50ce34 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java @@ -164,7 +164,9 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie @Override public void setSelectionInfo(SelectionInfo info) { + callLogDataViewer.setNode(null); nodeFactory.refresh(info); + } @Override diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsChildNodeFactory.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsChildNodeFactory.java index 28666c8fdd..ab980ee101 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsChildNodeFactory.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsChildNodeFactory.java @@ -35,7 +35,8 @@ import org.sleuthkit.datamodel.TskCoreException; /** * ChildFactory for ContactNodes. */ -final class ContactsChildNodeFactory extends ChildFactory{ +final class ContactsChildNodeFactory extends ChildFactory { + private static final Logger logger = Logger.getLogger(ContactsChildNodeFactory.class.getName()); private SelectionInfo selectionInfo; @@ -47,12 +48,13 @@ final class ContactsChildNodeFactory extends ChildFactory{ * accounts */ ContactsChildNodeFactory(SelectionInfo selectionInfo) { - this.selectionInfo = selectionInfo; + this.selectionInfo = selectionInfo; } - + /** - * Updates the current instance of selectionInfo and calls the refresh method. - * + * Updates the current instance of selectionInfo and calls the refresh + * method. + * * @param selectionInfo New instance of the currently selected accounts */ public void refresh(SelectionInfo selectionInfo) { @@ -63,13 +65,15 @@ final class ContactsChildNodeFactory extends ChildFactory{ /** * Creates a list of Keys (BlackboardArtifact) for only contacts of the * currently selected accounts + * * @param list List of BlackboardArtifact to populate + * * @return True on success */ @Override protected boolean createKeys(List list) { - - if(selectionInfo == null) { + + if (selectionInfo == null) { return true; } @@ -80,7 +84,7 @@ final class ContactsChildNodeFactory extends ChildFactory{ logger.log(Level.SEVERE, "Failed to load relationship sources.", ex); //NON-NLS return false; } - + relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> { BlackboardArtifact bba = (BlackboardArtifact) content; diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java index 1d11b3ef6d..141dc45cd1 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java @@ -35,7 +35,6 @@ import org.openide.nodes.NodeAdapter; import org.openide.nodes.NodeMemberEvent; import org.openide.util.Lookup; import org.openide.util.NbBundle; -import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.communications.ModifiableProxyLookup; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; @@ -126,6 +125,7 @@ final class ContactsViewer extends JPanel implements RelationshipsViewer { @Override public void setSelectionInfo(SelectionInfo info) { + contactPane.setNode(null); nodeFactory.refresh(info); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/MediaViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/MediaViewer.java index daffdafb81..7bd5330400 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/MediaViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/MediaViewer.java @@ -79,7 +79,7 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM tableEM.addPropertyChangeListener((PropertyChangeEvent evt) -> { if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { handleNodeSelectionChange(); - } + } }); thumbnailViewer.resetComponent(); @@ -99,18 +99,19 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM public void setSelectionInfo(SelectionInfo info) { Set relationshipSources; Set artifactList = new HashSet<>(); + contentViewer.setNode(null); + if (info != null) { + try { + relationshipSources = info.getRelationshipSources(); - try { - relationshipSources = info.getRelationshipSources(); + relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> { + artifactList.add((BlackboardArtifact) content); + }); - relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> { - artifactList.add((BlackboardArtifact) content); - }); - - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Unable to update selection.", ex); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Unable to update selection.", ex); + } } - thumbnailViewer.resetComponent(); thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new AttachmentThumbnailsChildren(artifactList)), tableEM), true, this.getClass().getName())); diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java index 0894fa3b1b..3de88f4176 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java @@ -28,7 +28,7 @@ import org.sleuthkit.autopsy.communications.ModifiableProxyLookup; * */ public final class RelationshipBrowser extends JPanel implements Lookup.Provider { - + private SelectionInfo currentSelection; private final ModifiableProxyLookup proxyLookup; @@ -37,15 +37,15 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider */ public RelationshipBrowser() { initComponents(); - + MessageViewer messagesViewer = new MessageViewer(); ContactsViewer contactsViewer = new ContactsViewer(); SummaryViewer summaryViewer = new SummaryViewer(); MediaViewer mediaViewer = new MediaViewer(); CallLogViewer callLogViewer = new CallLogViewer(); - + proxyLookup = new ModifiableProxyLookup(messagesViewer.getLookup()); - + tabPane.add(summaryViewer.getDisplayName(), summaryViewer); tabPane.add(messagesViewer.getDisplayName(), messagesViewer); tabPane.add(callLogViewer.getDisplayName(), callLogViewer); @@ -95,10 +95,15 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider }// //GEN-END:initComponents private void tabPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabPaneStateChanged - ((RelationshipsViewer) tabPane.getSelectedComponent()).setSelectionInfo(currentSelection); - Component selectedComponent = tabPane.getSelectedComponent(); - if (selectedComponent instanceof Lookup.Provider) { - Lookup lookup = ((Lookup.Provider) selectedComponent).getLookup(); + RelationshipsViewer viewer = ((RelationshipsViewer) tabPane.getSelectedComponent()); + //clear old values + viewer.setSelectionInfo(null); + //set new values when avaialable + if (currentSelection != null) { + viewer.setSelectionInfo(currentSelection); + } + if (viewer instanceof Lookup.Provider) { + Lookup lookup = ((Lookup.Provider) viewer).getLookup(); proxyLookup.setNewLookups(lookup); } }//GEN-LAST:event_tabPaneStateChanged diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java index 8d27c6c5be..af33ff1d59 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java @@ -93,29 +93,27 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac public void setArtifact(BlackboardArtifact artifact) { resetComponent(); - if (artifact == null) { - return; - } - CallLogViewData callLogViewData = null; try { callLogViewData = getCallLogViewData(artifact); } catch (TskCoreException ex) { logger.log(Level.SEVERE, String.format("Error getting attributes for Calllog artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex); } - + List personaSearchDataList = new ArrayList<>(); // update the view with the call log data if (callLogViewData != null) { - List personaSearchDataList = updateView(callLogViewData); - if (!personaSearchDataList.isEmpty()) { - currentAccountFetcher = new PersonaAccountFetcher(artifact, personaSearchDataList, this); - currentAccountFetcher.execute(); - } else { - currentAccountFetcher = null; - } + personaSearchDataList.addAll(updateView(callLogViewData)); + + } + if (!personaSearchDataList.isEmpty()) { + currentAccountFetcher = new PersonaAccountFetcher(artifact, personaSearchDataList, this); + currentAccountFetcher.execute(); + } else { + currentAccountFetcher = null; } // repaint this.revalidate(); + this.repaint(); } /** @@ -315,7 +313,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac // Display "From" if we have non-local device accounts if (callLogViewData.getFromAccount() != null) { CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_from()); - + // check if this is local account String accountDisplayString = getAccountDisplayString(callLogViewData.getFromAccount(), callLogViewData); CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, accountDisplayString); @@ -366,8 +364,6 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac this.setLayout(m_gridBagLayout); this.revalidate(); - this.repaint(); - return dataList; } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java index b17263a26d..c5f9b65ab2 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java @@ -41,7 +41,6 @@ import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.SwingWorker; import org.apache.commons.lang.StringUtils; @@ -129,19 +128,15 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac // Reset the panel. resetComponent(); - if (artifact == null) { - return; + if (artifact != null) { + try { + extractArtifactData(artifact); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, String.format("Error getting attributes for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex); + return; + } + updateView(); } - - try { - extractArtifactData(artifact); - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, String.format("Error getting attributes for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex); - return; - } - - updateView(); - this.setLayout(this.m_gridBagLayout); this.revalidate(); this.repaint(); @@ -163,6 +158,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac * Extracts data from the artifact to be displayed in the panel. * * @param artifact Artifact to show. + * * @throws TskCoreException */ private void extractArtifactData(BlackboardArtifact artifact) throws TskCoreException { @@ -234,7 +230,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac /** * Updates the contact image in the view. * - * @param contactPanelLayout Panel layout. + * @param contactPanelLayout Panel layout. * @param contactPanelConstraints Layout constraints. * */ @@ -262,7 +258,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac /** * Updates the contact name in the view. * - * @param contactPanelLayout Panel layout. + * @param contactPanelLayout Panel layout. * @param contactPanelConstraints Layout constraints. * */ @@ -289,9 +285,9 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac * Updates the view by displaying the given list of attributes in the given * section panel. * - * @param sectionAttributesList List of attributes to display. - * @param sectionHeader Section name label. - * @param contactPanelLayout Panel layout. + * @param sectionAttributesList List of attributes to display. + * @param sectionHeader Section name label. + * @param contactPanelLayout Panel layout. * @param contactPanelConstraints Layout constraints. * */ @@ -412,12 +408,12 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac /** * Displays the given persona in the persona panel. * - * @param persona Persona to display. - * @param matchNumber Number of matches. + * @param persona Persona to display. + * @param matchNumber Number of matches. * @param missingAccountsList List of contact accounts this persona may be - * missing. - * @param gridBagLayout Layout to use. - * @param constraints layout constraints. + * missing. + * @param gridBagLayout Layout to use. + * @param constraints layout constraints. * * @throws CentralRepoException */ @@ -560,7 +556,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac * @param artifact * * @return Image from a TSK_CONTACT artifact or default image if none was - * found or the artifact is not a TSK_CONTACT + * found or the artifact is not a TSK_CONTACT */ private ImageIcon getImageFromArtifact(BlackboardArtifact artifact) { ImageIcon imageIcon = defaultImage; @@ -610,7 +606,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac * Creates a persona searcher task. * * @param accountAttributesList List of attributes that may map to - * accounts. + * accounts. */ ContactPersonaSearcherTask(BlackboardArtifact artifact) { this.artifact = artifact; @@ -640,7 +636,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac } } } - + Collection personaAccounts = PersonaAccount.getPersonaAccountsForAccount(account); if (personaAccounts != null && !personaAccounts.isEmpty()) { // get personas for the account @@ -709,7 +705,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac /** * Constructor. * - * @param personaNameLabel Persona name label. + * @param personaNameLabel Persona name label. * @param personaActionButton Persona action button. */ PersonaUIComponents(JLabel personaNameLabel, JButton personaActionButton) { @@ -777,8 +773,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac for (CentralRepoAccount account : contactUniqueAccountsList) { personaPanel.addAccount(account, Bundle.ContactArtifactViewer_persona_account_justification(), Persona.Confidence.HIGH); } - - if(contactName != null && contactUniqueAccountsList.isEmpty()) { + + if (contactName != null && contactUniqueAccountsList.isEmpty()) { createPersonaDialog.setStartupPopupMessage(Bundle.ContactArtifactViewer_id_not_found_in_cr(contactName)); } From 7862ca475185d0249bed3e49e4c72b4e95da0823 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 9 Jun 2021 17:30:16 -0400 Subject: [PATCH 46/70] 7635 clean up --- .../relationships/CallLogViewer.java | 2 +- .../relationships/ContactsViewer.java | 2 +- .../relationships/MediaViewer.java | 4 ++-- .../relationships/RelationshipBrowser.java | 19 +++++++------------ .../CallLogArtifactViewer.java | 2 +- 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java index 664f50ce34..f2b99df0dd 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogViewer.java @@ -166,7 +166,7 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie public void setSelectionInfo(SelectionInfo info) { callLogDataViewer.setNode(null); nodeFactory.refresh(info); - + } @Override diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java index 141dc45cd1..6366d4e517 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/MediaViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/MediaViewer.java index 7bd5330400..63988b200d 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/MediaViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/MediaViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -79,7 +79,7 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM tableEM.addPropertyChangeListener((PropertyChangeEvent evt) -> { if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { handleNodeSelectionChange(); - } + } }); thumbnailViewer.resetComponent(); diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java index 3de88f4176..8910472295 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/RelationshipBrowser.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.communications.relationships; -import java.awt.Component; import javax.swing.JPanel; import org.openide.util.Lookup; import org.sleuthkit.autopsy.communications.ModifiableProxyLookup; @@ -28,7 +27,7 @@ import org.sleuthkit.autopsy.communications.ModifiableProxyLookup; * */ public final class RelationshipBrowser extends JPanel implements Lookup.Provider { - + private SelectionInfo currentSelection; private final ModifiableProxyLookup proxyLookup; @@ -37,15 +36,15 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider */ public RelationshipBrowser() { initComponents(); - + MessageViewer messagesViewer = new MessageViewer(); ContactsViewer contactsViewer = new ContactsViewer(); SummaryViewer summaryViewer = new SummaryViewer(); MediaViewer mediaViewer = new MediaViewer(); CallLogViewer callLogViewer = new CallLogViewer(); - + proxyLookup = new ModifiableProxyLookup(messagesViewer.getLookup()); - + tabPane.add(summaryViewer.getDisplayName(), summaryViewer); tabPane.add(messagesViewer.getDisplayName(), messagesViewer); tabPane.add(callLogViewer.getDisplayName(), callLogViewer); @@ -97,13 +96,9 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider private void tabPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabPaneStateChanged RelationshipsViewer viewer = ((RelationshipsViewer) tabPane.getSelectedComponent()); //clear old values - viewer.setSelectionInfo(null); - //set new values when avaialable - if (currentSelection != null) { - viewer.setSelectionInfo(currentSelection); - } + viewer.setSelectionInfo(currentSelection); if (viewer instanceof Lookup.Provider) { - Lookup lookup = ((Lookup.Provider) viewer).getLookup(); + Lookup lookup = viewer.getLookup(); proxyLookup.setNewLookups(lookup); } }//GEN-LAST:event_tabPaneStateChanged diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java index af33ff1d59..8393f39dfc 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); From 5a1879217c5150cc650ac17713969dab05546b1c Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 10 Jun 2021 10:03:00 -0400 Subject: [PATCH 47/70] Use more efficient version of findFiles() --- .../autopsy/casemodule/services/FileManager.java | 3 +-- .../autopsy/recentactivity/ChromeCacheExtractor.java | 5 +++-- .../org/sleuthkit/autopsy/recentactivity/Chromium.java | 2 +- .../recentactivity/DataSourceUsageAnalyzer.java | 10 +++++----- .../sleuthkit/autopsy/recentactivity/ExtractOs.java | 4 ++-- .../autopsy/recentactivity/ExtractRegistry.java | 3 +-- .../autopsy/recentactivity/ExtractSafari.java | 5 ++--- .../org/sleuthkit/autopsy/recentactivity/Firefox.java | 7 +++++-- .../autopsy/recentactivity/RecentDocumentsByLnk.java | 3 +-- .../src/org/sleuthkit/autopsy/recentactivity/Util.java | 3 +-- 10 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java index deaa0d1ca8..34f26eb1ac 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java @@ -130,8 +130,7 @@ public class FileManager implements Closeable { * @throws TskCoreException */ public List findFilesExactName(long parentId, String name) throws TskCoreException{ - String whereClause = "name = '%s'"; - return caseDb.findAllFilesInFolderWhere(parentId, String.format(whereClause, name)); + return caseDb.getFileManager().findFilesExactName(parentId, name); } /** diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java index 9435161a23..f3e073e7f9 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java @@ -596,8 +596,9 @@ final class ChromeCacheExtractor { if (fileCopyCache.containsKey(fileTableKey)) { return Optional.of(fileCopyCache.get(fileTableKey).getAbstractFile()); } - - List cacheFiles = fileManager.findFiles(dataSource, cacheFileName, cacheFolderName); //NON-NLS + + List cacheFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, + cacheFileName, cacheFolderName); if (!cacheFiles.isEmpty()) { // Sort the list for consistency. Preference is: // - In correct subfolder and allocated diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chromium.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chromium.java index a3db639b32..371394ff10 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chromium.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chromium.java @@ -633,7 +633,7 @@ class Chromium extends Extract { BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadFile, bbattributes); bbartifacts.add(webDownloadArtifact); String normalizedFullPath = FilenameUtils.normalize(fullPath, true); - for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(normalizedFullPath), FilenameUtils.getPath(normalizedFullPath))) { + for (AbstractFile downloadedFile : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, FilenameUtils.getName(normalizedFullPath), FilenameUtils.getPath(normalizedFullPath))) { bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact)); break; } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java index bd6b5836d5..2c05beb967 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java @@ -163,8 +163,9 @@ class DataSourceUsageAnalyzer extends Extract { private void checkIfOsSpecificVolume(ExtractOs.OS_TYPE osType) throws TskCoreException { FileManager fileManager = currentCase.getServices().getFileManager(); for (String filePath : osType.getFilePaths()) { - for (AbstractFile file : fileManager.findFiles(dataSource, FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) { - if ((file.getParentPath() + file.getName()).equals(filePath)) { + for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, + FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) { + if ((file.getParentPath() + file.getName()).equals(filePath)) { createDataSourceUsageArtifact(osType.getDsUsageLabel()); return; } @@ -224,10 +225,9 @@ class DataSourceUsageAnalyzer extends Extract { * @throws TskCoreException */ private boolean hasAndroidMediaCardRootNames() throws TskCoreException{ - FileManager fileManager = currentCase.getServices().getFileManager(); for (String fileName : ANDROID_MEDIACARD_ROOT_FILENAMES) { - for (AbstractFile file : fileManager.findFiles(dataSource, fileName, "/")) { // NON-NLS - if (file.getParentPath().equals("/") && file.getName().equalsIgnoreCase(fileName)) { // NON-NLS + for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, "/")) { // NON-NLS + if (file.getParentPath().equals("/") && file.getName().equalsIgnoreCase(fileName)) { // NON-NLS createDataSourceUsageArtifact(Bundle.DataSourceUsage_AndroidMedia()); return true; } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractOs.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractOs.java index a76c1652dd..b6ea418672 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractOs.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractOs.java @@ -117,9 +117,9 @@ class ExtractOs extends Extract { * search for */ private AbstractFile getFirstFileFound(List pathsToSearchFor) throws TskCoreException{ - FileManager fileManager = currentCase.getServices().getFileManager(); for (String filePath : pathsToSearchFor) { - for (AbstractFile file : fileManager.findFiles(dataSource, FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) { + + for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) { if ((file.getParentPath() + file.getName()).equals(filePath)) { return file; } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index cd2eefc4f4..6dcd977f78 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -1684,12 +1684,11 @@ class ExtractRegistry extends Extract { * @returnv BlackboardArtifact or a null value */ private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) { - org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); String fileName = FilenameUtils.getName(filePathName); String filePath = FilenameUtils.getPath(filePathName); List sourceFiles; try { - sourceFiles = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS + sourceFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, filePath); if (!sourceFiles.isEmpty()) { for (AbstractFile sourceFile : sourceFiles) { if (sourceFile.getParentPath().endsWith(filePath)) { diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractSafari.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractSafari.java index 2bf0351542..429666f8d6 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractSafari.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractSafari.java @@ -647,8 +647,6 @@ final class ExtractSafari extends Extract { Long time = null; Long pathID = null; - FileManager fileManager = getCurrentCase().getServices().getFileManager(); - NSString nsstring = (NSString) entry.get(PLIST_KEY_DOWNLOAD_URL); if (nsstring != null) { url = nsstring.toString(); @@ -669,7 +667,8 @@ final class ExtractSafari extends Extract { bbartifacts.add(webDownloadArtifact); // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact. - for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(path), FilenameUtils.getPath(path))) { + for (AbstractFile downloadedFile : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, + FilenameUtils.getName(path), FilenameUtils.getPath(path))) { bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact)); break; } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java index 6dd30ed4cc..466dfab42a 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java @@ -592,7 +592,8 @@ class Firefox extends Extract { bbartifacts.add(webDownloadArtifact); // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact. - for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) { + for (AbstractFile downloadedFile : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, + FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) { bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact)); break; } @@ -727,7 +728,9 @@ class Firefox extends Extract { bbartifacts.add(webDownloadArtifact); // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact. - for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) { + for (AbstractFile downloadedFile : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, + FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) { + //for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) { bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact)); break; } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java index b0c119ae25..d9ad0fbfb8 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java @@ -152,13 +152,12 @@ class RecentDocumentsByLnk extends Extract { * @returnv BlackboardArtifact or a null value */ private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) { - org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); String normalizePathName = FilenameUtils.normalize(filePathName, true); String fileName = FilenameUtils.getName(normalizePathName); String filePath = FilenameUtils.getPath(normalizePathName); List sourceFiles; try { - sourceFiles = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS + sourceFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, filePath); for (AbstractFile sourceFile : sourceFiles) { if (sourceFile.getParentPath().endsWith(filePath)) { return createAssociatedArtifact(sourceFile, bba); diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java index ff95c60ca8..766c3c61de 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java @@ -135,8 +135,7 @@ class Util { parent_path = parent_path.substring(0, index); List files = null; try { - FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager(); - files = fileManager.findFiles(dataSource, name, parent_path); + files = Case.getCurrentCaseThrows().getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, name, parent_path); } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); //NON-NLS } From c9337579f6f245ce3487f15fa4b1fe32e3b7e36c Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 10 Jun 2021 10:28:35 -0400 Subject: [PATCH 48/70] Change one method back. Cleanup. --- .../autopsy/recentactivity/DataSourceUsageAnalyzer.java | 5 +++-- .../src/org/sleuthkit/autopsy/recentactivity/Firefox.java | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java index 2c05beb967..d633825497 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java @@ -225,9 +225,10 @@ class DataSourceUsageAnalyzer extends Extract { * @throws TskCoreException */ private boolean hasAndroidMediaCardRootNames() throws TskCoreException{ + FileManager fileManager = currentCase.getServices().getFileManager(); for (String fileName : ANDROID_MEDIACARD_ROOT_FILENAMES) { - for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, "/")) { // NON-NLS - if (file.getParentPath().equals("/") && file.getName().equalsIgnoreCase(fileName)) { // NON-NLS + for (AbstractFile file : fileManager.findFiles(dataSource, fileName, "/")) { // NON-NLS + if (file.getParentPath().equals("/") && file.getName().equalsIgnoreCase(fileName)) { // NON-NLS createDataSourceUsageArtifact(Bundle.DataSourceUsage_AndroidMedia()); return true; } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java index 466dfab42a..87bbb0232d 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java @@ -730,7 +730,6 @@ class Firefox extends Extract { // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact. for (AbstractFile downloadedFile : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) { - //for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) { bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact)); break; } From 227a5a822fe62ac0ab5acd242f36bd64ba6e1283 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 10 Jun 2021 10:30:39 -0400 Subject: [PATCH 49/70] Cleanup --- .../autopsy/recentactivity/DataSourceUsageAnalyzer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java index d633825497..2c4556e6a3 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java @@ -227,7 +227,7 @@ class DataSourceUsageAnalyzer extends Extract { private boolean hasAndroidMediaCardRootNames() throws TskCoreException{ FileManager fileManager = currentCase.getServices().getFileManager(); for (String fileName : ANDROID_MEDIACARD_ROOT_FILENAMES) { - for (AbstractFile file : fileManager.findFiles(dataSource, fileName, "/")) { // NON-NLS + for (AbstractFile file : fileManager.findFiles(dataSource, fileName, "/")) { // NON-NLS if (file.getParentPath().equals("/") && file.getName().equalsIgnoreCase(fileName)) { // NON-NLS createDataSourceUsageArtifact(Bundle.DataSourceUsage_AndroidMedia()); return true; From 8a50a6ac7df963451192b9c63fc9821f381a675a Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 10 Jun 2021 12:35:25 -0400 Subject: [PATCH 50/70] Changed DataSourcenodes to be created asyn --- Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java index c5fae53c03..4546290007 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java @@ -122,7 +122,7 @@ public class DataSourcesNode extends DisplayableItemNode { * Main constructor. */ DataSourcesNode() { - super(Children.create(new DataSourcesByTypeChildren(), false), Lookups.singleton(NAME)); + super(Children.create(new DataSourcesByTypeChildren(), true), Lookups.singleton(NAME)); setName(NAME); setDisplayName(NAME); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/image.png"); From c2eb9a71791ef8418c29f34a949f1b90f5384a45 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 10 Jun 2021 12:48:08 -0400 Subject: [PATCH 51/70] Remove unnecessary path checks --- .../autopsy/recentactivity/DataSourceUsageAnalyzer.java | 9 ++------- .../org/sleuthkit/autopsy/recentactivity/ExtractOs.java | 8 +++----- .../autopsy/recentactivity/ExtractRegistry.java | 6 +----- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java index 2c4556e6a3..0e4fa5ecf1 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/DataSourceUsageAnalyzer.java @@ -157,18 +157,13 @@ class DataSourceUsageAnalyzer extends Extract { * does not exist with the given description. * * @param osType - the OS_TYPE to check for - * - * @return true if any specified files exist false if none exist */ private void checkIfOsSpecificVolume(ExtractOs.OS_TYPE osType) throws TskCoreException { - FileManager fileManager = currentCase.getServices().getFileManager(); for (String filePath : osType.getFilePaths()) { for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) { - if ((file.getParentPath() + file.getName()).equals(filePath)) { - createDataSourceUsageArtifact(osType.getDsUsageLabel()); - return; - } + createDataSourceUsageArtifact(osType.getDsUsageLabel()); + return; } } } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractOs.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractOs.java index b6ea418672..6bc00ada63 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractOs.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractOs.java @@ -118,11 +118,9 @@ class ExtractOs extends Extract { */ private AbstractFile getFirstFileFound(List pathsToSearchFor) throws TskCoreException{ for (String filePath : pathsToSearchFor) { - - for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) { - if ((file.getParentPath() + file.getName()).equals(filePath)) { - return file; - } + List files = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath)); + if (!files.isEmpty()) { + return files.get(0); } } return null; diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 6dcd977f78..8625431a13 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -1690,11 +1690,7 @@ class ExtractRegistry extends Extract { try { sourceFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, filePath); if (!sourceFiles.isEmpty()) { - for (AbstractFile sourceFile : sourceFiles) { - if (sourceFile.getParentPath().endsWith(filePath)) { - return createAssociatedArtifact(sourceFile, bba); - } - } + return createAssociatedArtifact(sourceFiles.get(0), bba); } } catch (TskCoreException ex) { // only catching the error and displaying the message as the file may not exist on the From 21048b038c2aefb902e0284c42448c996be23e5e Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 10 Jun 2021 15:14:51 -0400 Subject: [PATCH 52/70] Modified other locations to make sure nodes are created async --- .../autopsy/corecomponents/DataResultViewerTable.java | 6 ------ .../sleuthkit/autopsy/datamodel/AbstractContentNode.java | 2 +- .../sleuthkit/autopsy/datamodel/DataSourceFilesNode.java | 2 +- Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java | 4 ++-- Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java | 2 +- 5 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index e8c5ae4aea..7d0394d678 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -361,12 +361,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { * If the given node is not null and has children, set it as the * root context of the child OutlineView, otherwise make an * "empty"node the root context. - * - * IMPORTANT NOTE: This is the first of many times where a - * getChildren call on the current root node causes all of the - * children of the root node to be created and defeats lazy child - * node creation, if it is enabled. It also likely leads to many - * case database round trips. */ if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) { this.getExplorerManager().setRootContext(this.rootNode); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java index 7e0ee1a883..dfb3a2a75e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java @@ -112,7 +112,7 @@ public abstract class AbstractContentNode extends ContentNode * @param lookup The Lookup object for the node. */ AbstractContentNode(T content, Lookup lookup) { - super(Children.create(new ContentChildren(content), false), lookup); + super(Children.create(new ContentChildren(content), true), lookup); this.content = content; //super.setName(ContentUtils.getSystemName(content)); super.setName("content_" + Long.toString(content.getId())); //NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourceFilesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourceFilesNode.java index fd45f69bf0..b7e33860b9 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourceFilesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourceFilesNode.java @@ -69,7 +69,7 @@ public class DataSourceFilesNode extends DisplayableItemNode { } public DataSourceFilesNode(long dsObjId) { - super(Children.create(new DataSourcesNodeChildren(dsObjId), false), Lookups.singleton(NAME)); + super(Children.create(new DataSourcesNodeChildren(dsObjId), true), Lookups.singleton(NAME)); displayName = (dsObjId > 0) ? NbBundle.getMessage(DataSourceFilesNode.class, "DataSourcesNode.group_by_datasource.name") : NAME; init(); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java index 08ce15cab6..4b11bf6777 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java @@ -212,7 +212,7 @@ public class HostNode extends DisplayableItemNode { * @param hosts The HostDataSources key. */ HostNode(HostDataSources hosts) { - this(Children.create(new HostGroupingChildren(HOST_DATA_SOURCES, hosts.getHost()), false), hosts.getHost()); + this(Children.create(new HostGroupingChildren(HOST_DATA_SOURCES, hosts.getHost()), true), hosts.getHost()); } /** @@ -222,7 +222,7 @@ public class HostNode extends DisplayableItemNode { * @param hostGrouping The HostGrouping key. */ HostNode(HostGrouping hostGrouping) { - this(Children.create(new HostGroupingChildren(HOST_GROUPING_CONVERTER, hostGrouping.getHost()), false), hostGrouping.getHost()); + this(Children.create(new HostGroupingChildren(HOST_GROUPING_CONVERTER, hostGrouping.getHost()), true), hostGrouping.getHost()); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java index 99db59211b..06d52b8662 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java @@ -203,7 +203,7 @@ public class PersonNode extends DisplayableItemNode { * @param displayName The display name for the person. */ private PersonNode(Person person, String displayName) { - super(Children.create(new PersonChildren(person), false), + super(Children.create(new PersonChildren(person), true), person == null ? Lookups.fixed(displayName) : Lookups.fixed(person, displayName)); super.setName(displayName); super.setDisplayName(displayName); From 1ab5b74afd1cb9983112dcaf55abf7f0600f1a24 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 11 Jun 2021 11:25:55 -0400 Subject: [PATCH 53/70] new resize approach --- .../corecomponents/DataResultViewerTable.java | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index e8c5ae4aea..4628d7d8fb 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -215,6 +215,46 @@ public class DataResultViewerTable extends AbstractDataResultViewer { */ outline.getTableHeader().addMouseListener(outlineViewListener); } + + private static final int MIN_COLUMN_WIDTH = 30; + private static final int MAX_COLUMN_WIDTH = 300; + private static final int SAMPLE_ROW_NUM = 50; + private static final int COLUMN_PADDING = 10; + + // based on https://stackoverflow.com/questions/17627431/auto-resizing-the-jtable-column-widths + private void resizeColumnWidth(JTable table) { + final TableColumnModel columnModel = table.getColumnModel(); + + int availableTableWidth = table.getWidth(); + for (int column = 0; column < table.getColumnCount(); column++) { + int width = MIN_COLUMN_WIDTH; // Min width + + TableColumn tableColumn = columnModel.getColumn(column); + TableCellRenderer headerRenderer = tableColumn.getHeaderRenderer(); + if (headerRenderer == null) { + headerRenderer = table.getTableHeader().getDefaultRenderer(); + } + Object headerValue = tableColumn.getHeaderValue(); + Component headerComp = headerRenderer.getTableCellRendererComponent(table, headerValue, false, false, 0, column); + width = Math.max(headerComp.getPreferredSize().width + COLUMN_PADDING , width); + + for (int row = 0; row < Math.min(table.getRowCount(), SAMPLE_ROW_NUM); row++) { + TableCellRenderer renderer = table.getCellRenderer(row, column); + Component comp = table.prepareRenderer(renderer, row, column); + width = Math.max(comp.getPreferredSize().width + COLUMN_PADDING, width); + } + if(width > MAX_COLUMN_WIDTH) + width=MAX_COLUMN_WIDTH; + + if (column == table.getColumnCount() - 1) { + columnModel.getColumn(column).setMaxWidth(availableTableWidth); + columnModel.getColumn(column).setMinWidth(width); + } else { + columnModel.getColumn(column).setPreferredWidth(width); + availableTableWidth -= width; + } + } + } private void initializePagingSupport() { if (pagingSupport == null) { @@ -434,7 +474,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer { ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(firstProp.getDisplayName()); } - setColumnWidths(); + resizeColumnWidth(outline); + //setColumnWidths(); /* * Load column sorting information from preferences file and apply it to From b374c81f9315ddf19ec77621a12053038d3ce7ea Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 11 Jun 2021 13:48:35 -0400 Subject: [PATCH 54/70] updated setColumnWidths method --- .../corecomponents/DataResultViewerTable.java | 211 +++++++----------- 1 file changed, 79 insertions(+), 132 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 4628d7d8fb..cb02899faf 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -21,8 +21,6 @@ package org.sleuthkit.autopsy.corecomponents; import com.google.common.eventbus.Subscribe; import java.awt.Component; import java.awt.Cursor; -import java.awt.FontMetrics; -import java.awt.Graphics; import java.awt.dnd.DnDConstants; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -49,6 +47,7 @@ import javax.swing.JTable; import javax.swing.ListSelectionModel; import static javax.swing.SwingConstants.CENTER; import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableColumnModelEvent; @@ -106,6 +105,27 @@ public class DataResultViewerTable extends AbstractDataResultViewer { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(DataResultViewerTable.class.getName()); + // How many rows to sample in order to determine column width. + private static final int SAMPLE_ROW_NUM = 100; + + // The padding to be added in addition to content size when considering column width. + private static final int COLUMN_PADDING = 15; + + // The minimum column width. + private static final int MIN_COLUMN_WIDTH = 30; + + // The maximum column width. + private static final int MAX_COLUMN_WIDTH = 300; + + // The minimum row height to use when calculating whether scroll bar will be used. + private static final int MIN_ROW_HEIGHT = 10; + + // The width of the scroll bar. + private static final int SCROLL_BAR_WIDTH = ((Integer) UIManager.get("ScrollBar.width")).intValue(); + + // Any additional padding to be used for the first column. + private static final int FIRST_COL_ADDITIONAL_WIDTH = 0; + private static final String NOTEPAD_ICON_PATH = "org/sleuthkit/autopsy/images/notepad16.png"; private static final String RED_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/red-circle-exclamation.png"; private static final String YELLOW_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/yellow-circle-yield.png"; @@ -152,7 +172,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { * OutlineView to the actions global context. * * @param explorerManager The explorer manager of the ancestor top - * component. + * component. */ public DataResultViewerTable(ExplorerManager explorerManager) { this(explorerManager, Bundle.DataResultViewerTable_title()); @@ -165,8 +185,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer { * in the OutlineView to the actions global context. * * @param explorerManager The explorer manager of the ancestor top - * component. - * @param title The title. + * component. + * @param title The title. */ public DataResultViewerTable(ExplorerManager explorerManager, String title) { super(explorerManager); @@ -215,46 +235,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { */ outline.getTableHeader().addMouseListener(outlineViewListener); } - - private static final int MIN_COLUMN_WIDTH = 30; - private static final int MAX_COLUMN_WIDTH = 300; - private static final int SAMPLE_ROW_NUM = 50; - private static final int COLUMN_PADDING = 10; - - // based on https://stackoverflow.com/questions/17627431/auto-resizing-the-jtable-column-widths - private void resizeColumnWidth(JTable table) { - final TableColumnModel columnModel = table.getColumnModel(); - - int availableTableWidth = table.getWidth(); - for (int column = 0; column < table.getColumnCount(); column++) { - int width = MIN_COLUMN_WIDTH; // Min width - - TableColumn tableColumn = columnModel.getColumn(column); - TableCellRenderer headerRenderer = tableColumn.getHeaderRenderer(); - if (headerRenderer == null) { - headerRenderer = table.getTableHeader().getDefaultRenderer(); - } - Object headerValue = tableColumn.getHeaderValue(); - Component headerComp = headerRenderer.getTableCellRendererComponent(table, headerValue, false, false, 0, column); - width = Math.max(headerComp.getPreferredSize().width + COLUMN_PADDING , width); - - for (int row = 0; row < Math.min(table.getRowCount(), SAMPLE_ROW_NUM); row++) { - TableCellRenderer renderer = table.getCellRenderer(row, column); - Component comp = table.prepareRenderer(renderer, row, column); - width = Math.max(comp.getPreferredSize().width + COLUMN_PADDING, width); - } - if(width > MAX_COLUMN_WIDTH) - width=MAX_COLUMN_WIDTH; - - if (column == table.getColumnCount() - 1) { - columnModel.getColumn(column).setMaxWidth(availableTableWidth); - columnModel.getColumn(column).setMinWidth(width); - } else { - columnModel.getColumn(column).setPreferredWidth(width); - availableTableWidth -= width; - } - } - } private void initializePagingSupport() { if (pagingSupport == null) { @@ -410,6 +390,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { */ if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) { this.getExplorerManager().setRootContext(this.rootNode); + outline.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); setupTable(); } else { Node emptyNode = new AbstractNode(Children.LEAF); @@ -462,20 +443,12 @@ public class DataResultViewerTable extends AbstractDataResultViewer { firstProp = props.remove(0); } - /* - * show the horizontal scroll panel and show all the content & header If - * there is only one column (which was removed from props above) Just - * let the table resize itself. - */ - outline.setAutoResizeMode((props.isEmpty()) ? JTable.AUTO_RESIZE_ALL_COLUMNS : JTable.AUTO_RESIZE_OFF); - assignColumns(props); // assign columns to match the properties if (firstProp != null) { ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(firstProp.getDisplayName()); } - resizeColumnWidth(outline); - //setColumnWidths(); + setColumnWidths(); /* * Load column sorting information from preferences file and apply it to @@ -554,87 +527,59 @@ public class DataResultViewerTable extends AbstractDataResultViewer { /* * Sets the column widths for the child OutlineView of this tabular results - * viewer. + * viewer providing any additional width to last column. */ protected void setColumnWidths() { - if (rootNode.getChildren().getNodesCount() != 0) { - final Graphics graphics = outlineView.getGraphics(); + // based on https://stackoverflow.com/questions/17627431/auto-resizing-the-jtable-column-widths + final TableColumnModel columnModel = outline.getColumnModel(); - if (graphics != null) { - // Current width of the outlineView - double outlineViewWidth = outlineView.getSize().getWidth(); - // List of the column widths - List columnWidths = new ArrayList<>(); - final FontMetrics metrics = graphics.getFontMetrics(); + // the remaining table width that can be used in last row + double availableTableWidth = outlineView.getSize().getWidth(); - int margin = 4; - int padding = 8; + for (int columnIdx = 0; columnIdx < outline.getColumnCount(); columnIdx++) { + int columnPadding = (columnIdx == 0) ? FIRST_COL_ADDITIONAL_WIDTH + COLUMN_PADDING : COLUMN_PADDING; + TableColumn tableColumn = columnModel.getColumn(columnIdx); - int totalColumnWidth = 0; - int cntMaxSizeColumns = 0; + // The width of this column + int width = MIN_COLUMN_WIDTH; - // Calulate the width for each column keeping track of the number - // of columns that were set to columnwidthLimit. - for (int column = 0; column < outline.getModel().getColumnCount(); column++) { - int firstColumnPadding = (column == 0) ? 32 : 0; - int columnWidthLimit = (column == 0) ? 350 : 300; - int valuesWidth = 0; - - // find the maximum width needed to fit the values for the first 100 rows, at most - for (int row = 0; row < Math.min(100, outline.getRowCount()); row++) { - TableCellRenderer renderer = outline.getCellRenderer(row, column); - Component comp = outline.prepareRenderer(renderer, row, column); - valuesWidth = Math.max(comp.getPreferredSize().width, valuesWidth); - } - - int headerWidth = metrics.stringWidth(outline.getColumnName(column)); - valuesWidth += firstColumnPadding; // add extra padding for first column - - int columnWidth = Math.max(valuesWidth, headerWidth); - columnWidth += 2 * margin + padding; // add margin and regular padding - - columnWidth = Math.min(columnWidth, columnWidthLimit); - columnWidths.add(columnWidth); - - totalColumnWidth += columnWidth; - - if (columnWidth == columnWidthLimit) { - cntMaxSizeColumns++; - } - } - - // Figure out how much extra, if any can be given to the columns - // so that the table is as wide as outlineViewWidth. If cntMaxSizeColumns - // is greater than 0 divide the extra space between the columns - // that could use more space. Otherwise divide evenly amoung - // all columns. - int extraWidth = 0; - - if (totalColumnWidth < outlineViewWidth) { - if (cntMaxSizeColumns > 0) { - extraWidth = (int) ((outlineViewWidth - totalColumnWidth) / cntMaxSizeColumns); - } else { - extraWidth = (int) ((outlineViewWidth - totalColumnWidth) / columnWidths.size()); - } - } - - for (int column = 0; column < columnWidths.size(); column++) { - int columnWidth = columnWidths.get(column); - - if (cntMaxSizeColumns > 0) { - if (columnWidth >= ((column == 0) ? 350 : 300)) { - columnWidth += extraWidth; - } - } else { - columnWidth += extraWidth; - } - - outline.getColumnModel().getColumn(column).setPreferredWidth(columnWidth); - } + // get header cell width + // taken in part from https://stackoverflow.com/a/18381924 + TableCellRenderer headerRenderer = tableColumn.getHeaderRenderer(); + if (headerRenderer == null) { + headerRenderer = outline.getTableHeader().getDefaultRenderer(); + } + Object headerValue = tableColumn.getHeaderValue(); + Component headerComp = headerRenderer.getTableCellRendererComponent(outline, headerValue, false, false, 0, columnIdx); + width = Math.max(headerComp.getPreferredSize().width + columnPadding, width); + + // get the max of row widths from the first SAMPLE_ROW_NUM rows + Component comp = null; + int rowCount = outline.getRowCount(); + for (int row = 0; row < Math.min(rowCount, SAMPLE_ROW_NUM); row++) { + TableCellRenderer renderer = outline.getCellRenderer(row, columnIdx); + comp = outline.prepareRenderer(renderer, row, columnIdx); + width = Math.max(comp.getPreferredSize().width + columnPadding, width); + } + + // no higher than maximum column width + if (width > MAX_COLUMN_WIDTH) { + width = MAX_COLUMN_WIDTH; + } + + // if last column, calculate remaining width factoring in the possibility of a scroll bar. + if (columnIdx == outline.getColumnCount() - 1) { + int rowHeight = comp == null ? MIN_ROW_HEIGHT : comp.getPreferredSize().height; + if (headerComp.getPreferredSize().height + rowCount * rowHeight > outlineView.getSize().getHeight()) { + availableTableWidth -= SCROLL_BAR_WIDTH; + } + + columnModel.getColumn(columnIdx).setPreferredWidth(Math.max(width, (int) availableTableWidth)); + } else { + // otherwise set preferred width to width and decrement availableTableWidth accordingly + columnModel.getColumn(columnIdx).setPreferredWidth(width); + availableTableWidth -= width; } - } else { - // if there's no content just auto resize all columns - outline.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); } } @@ -790,7 +735,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { * order. * * @return a List> of the properties in the persisted - * order. + * order. */ private synchronized List> loadColumnOrder() { @@ -1307,18 +1252,20 @@ public class DataResultViewerTable extends AbstractDataResultViewer { /** * Returns the icon denoted by the Score's Significance. + * * @param significance The Score's Significance. + * * @return The icon (or null) related to that significance. */ private ImageIcon getIcon(Significance significance) { if (significance == null) { return null; } - + switch (significance) { case NOTABLE: return NOTABLE_ICON_SCORE; - case LIKELY_NOTABLE: + case LIKELY_NOTABLE: return INTERESTING_SCORE_ICON; case LIKELY_NONE: case NONE: @@ -1327,7 +1274,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { return null; } } - + @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); From f121e067ff1fb29f06fe11736f802b2d6fabffa9 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 14 Jun 2021 08:25:41 -0400 Subject: [PATCH 55/70] Japanese localization for autopsy 4.19 --- .../autopsy/casemodule/Bundle_ja.properties | 17 ++++- .../contentviewer/Bundle_ja.properties | 75 +++++++++--------- .../optionspanel/Bundle_ja.properties | 8 +- .../relationships/Bundle_ja.properties | 4 +- .../corecomponents/Bundle_ja.properties | 14 +++- .../autopsy/datamodel/Bundle_ja.properties | 25 +++++- .../datamodel/Bundle_ja.properties | 3 +- .../datasourcesummary/ui/Bundle_ja.properties | 76 ++++++++++++++++--- .../uiutils/Bundle_ja.properties | 3 +- .../directorytree/Bundle_ja.properties | 2 +- .../discovery/search/Bundle_ja.properties | 3 +- .../autopsy/discovery/ui/Bundle_ja.properties | 13 +++- .../autopsy/ingest/Bundle_ja.properties | 3 +- .../leappanalyzers/Bundle_ja.properties | 7 +- .../keywordsearch/Bundle_ja.properties | 18 ++++- .../recentactivity/Bundle_ja.properties | 4 +- .../lastupdated.properties | 4 +- 17 files changed, 199 insertions(+), 80 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties index f85f5c62d2..ccdc57d555 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 AddImageAction.ingestConfig.ongoingIngest.msg=\u5225\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u65b0\u898f\u30bd\u30fc\u30b9\u3092\u4eca\u8ffd\u52a0\u3059\u308b\u3068\u3001\u73fe\u5728\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u51e6\u7406\u304c\u9045\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002
\u7d9a\u884c\u3057\u3066\u65b0\u898f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u4eca\u3059\u3050\u8ffd\u52a0\u3057\u307e\u3059\u304b? AddImageAction.ingestConfig.ongoingIngest.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059 AddImageAction.wizard.title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0 @@ -25,10 +25,17 @@ AddImageWizardChooseDataSourceVisual.getName.text=\u30c7\u30fc\u30bf\u30bd\u30fc AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=\u53d6\u308a\u6d88\u3057 AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f\u3002 -AddImageWizardIngestConfigPanel.name.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u69cb\u6210 -AddImageWizardIngestConfigVisual.getName.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u69cb\u6210 +AddImageWizardIngestConfigPanel.name.text=\u53d6\u8fbc\u307f\u306e\u69cb\u6210 +AddImageWizardIngestConfigVisual.getName.text=\u53d6\u8fbc\u307f\u306e\u69cb\u6210 AddImageWizardIterator.stepXofN=\u624b\u9806 {0} / {1} AddImageWizardSelectDspVisual.multiUserWarning.text=\u3053\u306e\u30bf\u30a4\u30d7\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30e2\u30fc\u30c9\u3067\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 +AddImageWizardSelectHostPanel_title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3059\u308b\u30db\u30b9\u30c8\u306e\u9078\u629e +AddImageWizardSelectHostVisual.generateNewRadio.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d\u306b\u57fa\u3065\u3044\u3066\u65b0\u30db\u30b9\u30c8\u540d\u306e\u4f5c\u6210 +AddImageWizardSelectHostVisual.hostDescription.text=\u30db\u30b9\u30c8\u306f\u3001\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3084\u305d\u306e\u4ed6\u306e\u30c7\u30fc\u30bf\u3092\u6574\u7406\u3059\u308b\u305f\u3081\u306b\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002 +AddImageWizardSelectHostVisual.specifyNewHostRadio.text=\u65b0\u30db\u30b9\u30c8\u540d\u306e\u6307\u5b9a +AddImageWizardSelectHostVisual.useExistingHostRadio.text=\u65e2\u5b58\u306e\u30db\u30b9\u30c8\u306e\u4f7f\u7528 +AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=\u65e2\u5b58\u306e\u30db\u30b9\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +AddImageWizardSelectHostVisual_title=\u30db\u30b9\u30c8\u306e\u9078\u629e AddLocalFilesTask.localFileAdd.progress.text=\u6b21\u3092\u8ffd\u52a0\u4e2d\u3067\u3059\: {0}/{1} CTL_AddImage=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0 CTL_AddImageButton=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0 @@ -86,6 +93,8 @@ Case.exceptionMessage.failedToReadMetadata=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\ Case.exceptionMessage.metadataUpdateError=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f Case.exceptionMessage.unsupportedSchemaVersionMessage=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u306a\u3044\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3059\:\n{0}\u3002 Case.getCurCase.exception.noneOpen=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3002\u30b1\u30fc\u30b9\u304c\u958b\u304b\u308c\u3066\u3044\u307e\u305b\u3093\! +Case.lockingException.couldNotAcquireExclusiveLock=\u30b1\u30fc\u30b9\u306e\u6392\u4ed6\u30ed\u30c3\u30af\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 +Case.lockingException.couldNotAcquireSharedLock=\u30b1\u30fc\u30b9\u306e\u5171\u6709\u30ed\u30c3\u30af\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 Case.metaDataFileCorrupt.exception.msg=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb(.aut)\u304c\u7834\u640d\u3057\u3066\u3044\u307e\u3059\u3002 Case.open.exception.multiUserCaseNotEnabled=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u304c\u6709\u52b9\u3067\u306a\u3044\u5834\u5408\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3002[\u30c4\u30fc\u30eb]\u3001[\u30aa\u30d7\u30b7\u30e7\u30f3]\u3001[\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc] \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002 Case.open.msgDlg.updated.msg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n\u6b21\u306e\u30d1\u30b9\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\:\n {0} @@ -384,7 +393,7 @@ ReviewModeCasePanel.StatusIconHeaderText=\u30b9\u30c6\u30fc\u30bf\u30b9 ReviewModeCasePanel.cannotOpenCase=\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093 ReviewModeCasePanel.caseIsLocked=\u30b7\u30f3\u30b0\u30eb\u30e6\u30fc\u30b6\u30fc\u304c\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059\u3002 ReviewModeCasePanel.casePathNotFound=\u30b1\u30fc\u30b9\u30d1\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 -SelectDataSourceProcessorPanel.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u30bf\u30a4\u30d7\u3092\u9078\u629e\u3057\u3066\u8ffd\u52a0 +SelectDataSourceProcessorPanel.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u306e\u9078\u629e SingleUserCaseConverter.AlreadyMultiUser=\u30b1\u30fc\u30b9\u306f\u3059\u3067\u306b\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u3067\u3059\! SingleUserCaseConverter.BadDatabaseFileName=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\! SingleUserCaseConverter.CanNotOpenDatabase=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093 diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle_ja.properties index 68dfcf62be..94ea2014f5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle_ja.properties @@ -1,54 +1,49 @@ -DataContentViewerOtherCases.caseDetailsDialog.noCaseNameError=\u30a8\u30e9\u30fc -DataContentViewerOtherCases.caseDetailsDialog.noDetails=\u3053\u306e\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002 -DataContentViewerOtherCases.caseDetailsDialog.noDetailsReference=\u30b0\u30ed\u30fc\u30d0\u30eb\u30ec\u30d5\u30a1\u30ec\u30f3\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u30b1\u30fc\u30b9\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002 -DataContentViewerOtherCases.caseDetailsDialog.notSelected=\u884c\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093 -# {0} - \u5171\u6709\u6027\u306e\u5272\u5408 -# {1} - \u76f8\u95a2\u5206\u6790\u30bf\u30a4\u30d7 -# {2} - \u76f8\u95a2\u5206\u6790\u5024 -DataContentViewerOtherCases.correlatedArtifacts.byType=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e {0}% \u306b {2} \u304c\u3042\u308a\u307e\u3059(\u30bf\u30a4\u30d7: {1})\n -DataContentViewerOtherCases.correlatedArtifacts.failed=\u983b\u5ea6\u306e\u8a73\u7d30\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 -DataContentViewerOtherCases.correlatedArtifacts.isEmpty=\u76f8\u95a2\u5206\u6790\u3059\u308b\u305f\u3081\u306e\u30d5\u30a1\u30a4\u30eb\u3084\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c\u304c\u3042\u308a\u307e\u305b\u3093\u3002 -DataContentViewerOtherCases.correlatedArtifacts.title=\u5c5e\u6027\u983b\u5ea6 -DataContentViewerOtherCases.dataSources.header.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d -DataContentViewerOtherCases.earliestCaseNotAvailable=\ \u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u3002 -DataContentViewerOtherCases.foundIn.text=%d \u306e\u30b1\u30fc\u30b9\u3068 %d \u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u5185\u306b %d \u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002 -DataContentViewerOtherCases.noOpenCase.errMsg=\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u306f\u3042\u308a\u307e\u305b\u3093\u3002 -DataContentViewerOtherCases.table.noArtifacts=\u9805\u76ee\u306b\u691c\u7d22\u306b\u5229\u7528\u3067\u304d\u308b\u5c5e\u6027\u306f\u3042\u308a\u307e\u305b\u3093\u3002 -DataContentViewerOtherCases.table.noResultsFound=\u8a72\u5f53\u3059\u308b\u7d50\u679c\u304c\u3042\u308a\u307e\u305b\u3093\u3002 +#Mon Jun 14 12:23:19 UTC 2021 DataContentViewerOtherCases.table.toolTip.text=\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u30bd\u30fc\u30c8\u3057\u307e\u3059\u3002\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u3055\u3089\u306a\u308b\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8868\u793a\u3057\u307e\u3059\u3002 DataContentViewerOtherCases.title=\u305d\u306e\u4ed6\u306e\u767a\u751f DataContentViewerOtherCases.toolTip=\u305d\u306e\u4ed6\u306e\u767a\u751f\u304b\u3089\u9078\u629e\u3057\u305f\u30d5\u30a1\u30a4\u30eb/\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8868\u793a\u3057\u307e\u3059\u3002 -DataContentViewerOtherCasesModel.csvHeader.attribute=\u4e00\u81f4\u3057\u305f\u5c5e\u6027 -DataContentViewerOtherCasesModel.csvHeader.case=\u30b1\u30fc\u30b9 -DataContentViewerOtherCasesModel.csvHeader.comment=\u30b3\u30e1\u30f3\u30c8 -DataContentViewerOtherCasesModel.csvHeader.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9 -DataContentViewerOtherCasesModel.csvHeader.device=\u30c7\u30d0\u30a4\u30b9 -DataContentViewerOtherCasesModel.csvHeader.known=\u65e2\u77e5 -DataContentViewerOtherCasesModel.csvHeader.path=\u30d1\u30b9 -DataContentViewerOtherCasesModel.csvHeader.value=\u5c5e\u6027\u5024 -OccurrencePanel.caseCreatedDateLabel.text=\u4f5c\u6210\u65e5: +OccurrencePanel.caseCreatedDateLabel.text=\u4f5c\u6210\u65e5\: OccurrencePanel.caseDetails.text=\u30b1\u30fc\u30b9\u8a73\u7d30 -OccurrencePanel.caseNameLabel.text=\u540d\u524d: +OccurrencePanel.caseNameLabel.text=\u540d\u524d\: OccurrencePanel.commonProperties.text=\u5171\u901a\u306e\u30d7\u30ed\u30d1\u30c6\u30a3 -OccurrencePanel.commonPropertyCommentLabel.text=\u30b3\u30e1\u30f3\u30c8: -OccurrencePanel.commonPropertyKnownStatusLabel.text=\u65e2\u77e5\u306e\u30b9\u30c6\u30fc\u30bf\u30b9: -OccurrencePanel.commonPropertyTypeLabel.text=\u30bf\u30a4\u30d7: -OccurrencePanel.commonPropertyValueLabel.text=\u5024: +OccurrencePanel.commonPropertyCommentLabel.text=\u30b3\u30e1\u30f3\u30c8\: +OccurrencePanel.commonPropertyKnownStatusLabel.text=\u65e2\u77e5\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\: +OccurrencePanel.commonPropertyTypeLabel.text=\u30bf\u30a4\u30d7\: +OccurrencePanel.commonPropertyValueLabel.text=\u5024\: OccurrencePanel.dataSourceDetails.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u8a73\u7d30 -OccurrencePanel.dataSourceNameLabel.text=\u540d\u524d: +OccurrencePanel.dataSourceNameLabel.text=\u540d\u524d\: OccurrencePanel.fileDetails.text=\u30d5\u30a1\u30a4\u30eb\u8a73\u7d30 -OccurrencePanel.filePathLabel.text=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9: +OccurrencePanel.filePathLabel.text=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\: OtherOccurrencesCasesTableModel.case=\u30b1\u30fc\u30b9 OtherOccurrencesCasesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002 OtherOccurrencesDataSourcesTableModel.dataSourceName=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d OtherOccurrencesDataSourcesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002 OtherOccurrencesFilesTableModel.fileName=\u30d5\u30a1\u30a4\u30eb\u540d OtherOccurrencesFilesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002 -OtherOccurrencesPanel.filesTable.toolTipText=\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u30bd\u30fc\u30c8\u3057\u307e\u3059\u3002\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u3055\u3089\u306a\u308b\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8868\u793a\u3057\u307e\u3059\u3002 -OtherOccurrencesPanel.earliestCaseLabel.toolTipText= -OtherOccurrencesPanel.earliestCaseLabel.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u958b\u59cb\u65e5: -OtherOccurrencesPanel.earliestCaseDate.text=\u6700\u3082\u53e4\u3044\u30b1\u30fc\u30b9\u65e5\u4ed8 -OtherOccurrencesPanel.foundInLabel.text= +OtherOccurrencesPanel.caseDetailsDialog.noCaseNameError=\u30a8\u30e9\u30fc +OtherOccurrencesPanel.caseDetailsDialog.noDetails=\u3053\u306e\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002 +OtherOccurrencesPanel.caseDetailsDialog.noDetailsReference=\u30b0\u30ed\u30fc\u30d0\u30eb\u53c2\u7167\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002 +OtherOccurrencesPanel.caseDetailsDialog.notSelected=\u884c\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093 +OtherOccurrencesPanel.correlatedArtifacts.byType=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e{0}\uff05\u306b{2}\u304c\u3042\u308a\u307e\u3059\uff08\u30bf\u30a4\u30d7\uff1a{1}\uff09 +OtherOccurrencesPanel.correlatedArtifacts.failed=\u983b\u5ea6\u306e\u8a73\u7d30\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 +OtherOccurrencesPanel.correlatedArtifacts.isEmpty=\u95a2\u9023\u4ed8\u3051\u308b\u30d5\u30a1\u30a4\u30eb\u3084\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002 +OtherOccurrencesPanel.correlatedArtifacts.title=\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u306e\u983b\u5ea6 +OtherOccurrencesPanel.csvHeader.attribute=\u4e00\u81f4\u3057\u305f\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8 +OtherOccurrencesPanel.csvHeader.case=\u30b1\u30fc\u30b9 +OtherOccurrencesPanel.csvHeader.comment=\u30b3\u30e1\u30f3\u30c8 +OtherOccurrencesPanel.csvHeader.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9 +OtherOccurrencesPanel.csvHeader.device=\u30c7\u30d0\u30a4\u30b9 +OtherOccurrencesPanel.csvHeader.known=\u65e2\u77e5 +OtherOccurrencesPanel.csvHeader.path=\u30d1\u30b9 +OtherOccurrencesPanel.csvHeader.value=\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u5024 +OtherOccurrencesPanel.earliestCaseDate.text=\u30b1\u30fc\u30b9\u306e\u6700\u521d\u306e\u65e5\u4ed8 +OtherOccurrencesPanel.earliestCaseLabel.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u958b\u59cb\u65e5\uff1a +OtherOccurrencesPanel.earliestCaseNotAvailable=\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u3002 +OtherOccurrencesPanel.exportToCSVMenuItem.text=\u305d\u306e\u4ed6\u306e\u3059\u3079\u3066\u306e\u767a\u751f\u3092CSV\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 +OtherOccurrencesPanel.filesTable.toolTipText=\u4e26\u3079\u66ff\u3048\u306f\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3002 \u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u3001\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3002 +OtherOccurrencesPanel.foundIn.text=\uff05d\u30b1\u30fc\u30b9\u3068\uff05d\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\uff05d\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002 +OtherOccurrencesPanel.noOpenCase.errMsg=\u30aa\u30fc\u30d7\u30f3\u30b1\u30fc\u30b9\u306f\u3042\u308a\u307e\u305b\u3093\u3002 +OtherOccurrencesPanel.showCaseDetailsMenuItem.text=\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u3092\u8868\u793a OtherOccurrencesPanel.showCommonalityMenuItem.text=\u983b\u5ea6\u3092\u8868\u793a -OtherOccurrencesPanel.showCaseDetailsMenuItem.text=\u30b1\u30fc\u30b9\u8a73\u7d30\u3092\u8868\u793a -OtherOccurrencesPanel.exportToCSVMenuItem.text=\u305d\u306e\u4ed6\u3059\u3079\u3066\u306e\u767a\u751f\u3092CSV\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 +OtherOccurrencesPanel.table.noArtifacts=\u30a2\u30a4\u30c6\u30e0\u306b\u306f\u3001\u691c\u7d22\u3059\u308b\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002 +OtherOccurrencesPanel.table.noResultsFound=\u7d50\u679c\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle_ja.properties index f92bd670f4..07a447b55c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Tue Aug 18 18:09:20 UTC 2020 +#Mon Jun 14 12:23:19 UTC 2021 AddNewOrganizationDialog.addNewOrg.msg=\u65b0\u898f\u7d44\u7e54\u3092\u8ffd\u52a0 AddNewOrganizationDialog.bnCancel.text=\u53d6\u308a\u6d88\u3057 AddNewOrganizationDialog.bnOK.text=OK @@ -93,9 +93,9 @@ GlobalSettingsPanel.manageOrganizationButton.text=\u7d44\u7e54\u3092\u7ba1\u7406 GlobalSettingsPanel.onMultiUserChange.disabledMu.description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306f\u30ed\u30fc\u30ab\u30ebSQLite\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u3057\u3066\u518d\u69cb\u6210\u3055\u308c\u307e\u3059 GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=[PostgreSQL\u306e\u69cb\u6210]\u3092\u62bc\u3057\u3066\u3001PostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u5909\u66f4\u3057\u307e\u3059\u3002 GlobalSettingsPanel.onMultiUserChange.disabledMu.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306e\u5909\u66f4\u304c\u5fc5\u8981\u3067\u3059 -GlobalSettingsPanel.onMultiUserChange.enable.description=\u3053\u306ePostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f7f\u7528\u3059\u308b\u3088\u3046\u306b\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u3092\u66f4\u65b0\u3057\u307e\u3059\u304b\uff1f -GlobalSettingsPanel.onMultiUserChange.enable.description2=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306b\u306f\u904e\u53bb\u306e\u30b1\u30fc\u30b9\u304b\u3089\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3068\u30a2\u30ab\u30a6\u30f3\u30c8\u304c\u4fdd\u5b58\u3055\u308c\u307e\u3059\u3002 -GlobalSettingsPanel.onMultiUserChange.enable.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u3067\u4f7f\u7528\u3057\u307e\u3059\u304b\uff1f +GlobalSettingsPanel.onMultiUserChange.enable.description=\u3053\u306ePostgreSQL\u30b5\u30fc\u30d0\u30fc\u3092\u4f7f\u7528\u3059\u308b\u3088\u3046\u306b\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u66f4\u65b0\u3057\u307e\u3059\u304b\uff1f +GlobalSettingsPanel.onMultiUserChange.enable.description2=\u65e2\u5b58\u306eSQLite\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30c7\u30fc\u30bf\u306f\u65b0\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u8ee2\u9001\u3055\u308c\u307e\u305b\u3093\u3002 +GlobalSettingsPanel.onMultiUserChange.enable.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea GlobalSettingsPanel.organizationPanel.border.title=\u7d44\u7e54 GlobalSettingsPanel.organizationTextArea.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u5185\u3067\u7d44\u7e54\u60c5\u5831\u3092\u8ffd\u8de1\u3067\u304d\u307e\u3059\u3002 GlobalSettingsPanel.pnCorrelationProperties.border.title=\u76f8\u95a2\u5206\u6790\u30d7\u30ed\u30d1\u30c6\u30a3 diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle_ja.properties index b02216ee0e..28885c1191 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 ContactDetailsPane.nameLabel.text=\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u30fc ContactNode_Email=\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9 ContactNode_Home_Number=\u81ea\u5b85\u96fb\u8a71\u756a\u53f7 @@ -64,7 +64,7 @@ SummaryViewer_CentralRepository_Message=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u3 SummaryViewer_Creation_Date_Title=\u4f5c\u6210\u65e5 SummaryViewer_Fetching_References=<\u30d5\u30a1\u30a4\u30eb\u53c2\u7167\u306e\u53d6\u5f97> SummaryViewer_FileRefNameColumn_Title=\u30d1\u30b9 -SummaryViewer_Persona_Message=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u53ef\u80fd\u306b\u3059\u308b> +SummaryViewer_Persona_CR_Message=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b> SummaryViewer_Select_account_for_persona=<\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u3059\u308b\u306b\u306f\u3001\u30a2\u30ab\u30a6\u30f3\u30c8\u30921\u3064\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044> SummaryViewer_TabTitle=\u30b5\u30de\u30ea\u30fc SummeryViewer_FileRef_Message=<\u30a2\u30ab\u30a6\u30f3\u30c8\u30921\u3064\u9078\u629e\u3057\u3066\u30d5\u30a1\u30a4\u30eb\u30ec\u30d5\u30a1\u30ec\u30f3\u30b9\u3092\u8868\u793a> diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties index 1c6c191439..1b5307c698 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 AboutWindowPanel.actVerboseLogging.text=\u8a73\u7d30\u30ed\u30ae\u30f3\u30b0\u3092\u30a2\u30af\u30c6\u30a3\u30d6\u5316 AddExternalViewerRulePanel.browseButton.text=\u53c2\u7167 AddExternalViewerRulePanel.exePathLabel.text=\u3053\u306e\u30bf\u30a4\u30d7\u307e\u305f\u306f\u62e1\u5f35\u5b50\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u4f7f\u7528\u3059\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u306e\u30d1\u30b9 @@ -41,12 +41,18 @@ AutopsyOptionsPanel.runtimePanel.border.title=\u30e9\u30f3\u30bf\u30a4\u30e0 AutopsyOptionsPanel.sizingTextPane.text=\u9ad8DPI\u30b7\u30b9\u30c6\u30e0\u3067\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30ca\u30d3\u30b2\u30fc\u30c8\u304c\u96e3\u3057\u3044\u5834\u5408\u306f\u3001\u6b21\u306e\u5909\u66f4\u3092\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002\n\n1.\u30c7\u30b9\u30af\u30c8\u30c3\u30d7\u3001\u30b9\u30bf\u30fc\u30c8\u30e1\u30cb\u30e5\u30fc\u306a\u3069\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30a2\u30a4\u30b3\u30f3\u3092\u53f3\u30af\u30ea\u30c3\u30af\n2.\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u9078\u629e\n3. [\u4e92\u63db\u6027]\u30bf\u30d6\u306b\u79fb\u52d5\n4. [\u9ad8DPI\u8a2d\u5b9a\u306e\u5909\u66f4]\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\n5. [\u9ad8DPI\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\u52d5\u4f5c\u3092\u5909\u66f4]\u3092\u9078\u629e\n6.\u300c\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\u306e\u5b9f\u884c\uff1a\u300d\u30c9\u30ed\u30c3\u30d7\u30c0\u30a6\u30f3\u30dc\u30c3\u30af\u30b9\u3092\u300c\u30b7\u30b9\u30c6\u30e0\u300d\u306b\u5909\u66f4\u3057\u307e\u3059\u3002\n7.Autopsy\u3092\u518d\u5b9f\u884c AutopsyOptionsPanel.solrJVMHeapWarning.text=\u6ce8\: \u3053\u308c\u3092\u3042\u307e\u308a\u306b\u3082\u5927\u304d\u304f\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u5168\u4f53\u306b\u5f71\u97ff\u3059\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002 AutopsyOptionsPanel.specifyLogoRB.text=\u30ed\u30b4\u3092\u6307\u5b9a +AutopsyOptionsPanel.tempCaseRadio.text=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u4e00\u6642\u30d5\u30a9\u30eb\u30c0 +AutopsyOptionsPanel.tempCustomRadio.text=\u30ab\u30b9\u30bf\u30e0 AutopsyOptionsPanel.tempDirectoryBrowseButton.text=\u30d6\u30e9\u30a6\u30ba AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0 -AutopsyOptionsPanel.tempDirectoryPanel.border.title=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0 +AutopsyOptionsPanel.tempDirectoryPanel.border.title=\u30eb\u30fc\u30c8\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea AutopsyOptionsPanel.tempDirectoryPanel.name=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0 AutopsyOptionsPanel.tempDirectoryWarningLabel.text=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0\u3092\u5909\u66f4\u3059\u308b\u306b\u306f\u30b1\u30fc\u30b9\u3092\u9589\u3058\u3066\u4e0b\u3055\u3044\u3002 +AutopsyOptionsPanel.tempLocalRadio.text=\u30ed\u30fc\u30ab\u30eb\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea +AutopsyOptionsPanel.tempOnCustomNoPath.text=\u30ab\u30b9\u30bf\u30e0\u30eb\u30fc\u30c8\u306e\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fb\u30d1\u30b9\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 AutopsyOptionsPanel.totalMemoryLabel.text=\u5408\u8a08\u30b7\u30b9\u30c6\u30e0\u30e1\u30e2\u30ea\u30fc\: +AutopsyOptionsPanel_storeTempDir_onChoiceError_description=\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u9078\u629e\u306e\u66f4\u65b0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +AutopsyOptionsPanel_storeTempDir_onChoiceError_title=\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u9078\u629e\u306e\u4fdd\u5b58\u30a8\u30e9\u30fc AutopsyOptionsPanel_storeTempDir_onError_description=\u30b7\u30b9\u30c6\u30e0\u4e00\u6642\u30d5\u30a9\u30eb\u30c0{0}\u3092\u4f5c\u6210\u3059\u308b\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 AutopsyOptionsPanel_storeTempDir_onError_title=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_description=\u6307\u5b9a\u3055\u308c\u305f\u30d1\u30b9\u5185\u306b\u4e00\u6642\u30d5\u30a9\u30eb\u30c0\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\uff1a{0} @@ -241,6 +247,7 @@ MultiUserSettingsPanel.validationErrMsg.invalidSolr4ServerPort=Solr4\u30b5\u30fc MultiUserSettingsPanel.validationErrMsg.invalidZkServerHostName=ZooKeeper\u30b5\u30fc\u30d0\u30fc\u306e\u30db\u30b9\u30c8\u540d\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093 MultiUserSettingsPanel.validationErrMsg.invalidZkServerPort=ZooKeeper\u30b5\u30fc\u30d0\u30fc\u306e\u30dd\u30fc\u30c8\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059 MultiUserSettingsPanel.validationErrMsg.solrNotConfigured=Solr8\u3068Solr4\u30b5\u30fc\u30d0\u30fc\u306e\u3044\u305a\u308c\u304b\u3092\u69cb\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059 +MultiUserSettingsPanel_Close_Case_To_Modify=\u8a2d\u5b9a\u3092\u5909\u66f4\u3059\u308b\u306b\u306f\u30b1\u30fc\u30b9\u3092\u9589\u3058\u3066\u304f\u3060\u3055\u3044 OpenIDE-Module-Name=CoreComponents OptionsCategory_Keywords_General=Autopsy\u30aa\u30d7\u30b7\u30e7\u30f3 OptionsCategory_Keywords_Multi_User_Options=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u8a2d\u5b9a @@ -267,7 +274,6 @@ ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text=\u30c7\u30fc\u30bf\u30bd\ ViewPreferencesPanel.displayTimeLabel.text=\u6642\u523b\u8868\u793a\u6642\: ViewPreferencesPanel.fileNameTranslationColumnCheckbox.text=\u7d50\u679c\u30d3\u30e5\u30fc\u30ef\u30fc\u306b\u30d5\u30a1\u30a4\u30eb\u540d\u7ffb\u8a33\u7528\u5217\u3092\u8ffd\u52a0 ViewPreferencesPanel.globalSettingsPanel.border.title=\u30b0\u30ed\u30fc\u30d0\u30eb\u8a2d\u5b9a -ViewPreferencesPanel.groupByDataSourceCheckbox.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u5225\u306b\u30b0\u30eb\u30fc\u30d7\u5316 ViewPreferencesPanel.hideKnownFilesLabel.text=\u6b21\u306e\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb(NIST NSRL\u5185\u306e\u30d5\u30a1\u30a4\u30eb)\u3092\u975e\u8868\u793a\u306b\u3059\u308b\: ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=\u30c4\u30ea\u30fc\u5185\u306e\u30bf\u30b0\u9818\u57df ViewPreferencesPanel.hideOtherUsersTagsLabel.text=\u6b21\u306e\u305d\u306e\u4ed6\u306e\u30e6\u30fc\u30b6\u30fc\u306e\u30bf\u30b0\u3092\u975e\u8868\u793a\u306b\u3059\u308b\: @@ -277,6 +283,8 @@ ViewPreferencesPanel.keepCurrentViewerRadioButton.text=\u540c\u3058\u30d5\u30a1\ ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText=\u305f\u3068\u3048\u3070\u3001JPEG\u9078\u629e\u6642\u306f16\u9032\u30d3\u30e5\u30fc\u306e\u307e\u307e\u306b\u3057\u307e\u3059\u3002 ViewPreferencesPanel.maxResultsLabel.text=\u30c6\u30fc\u30d6\u30eb\u3067\u8868\u793a\u3059\u308b\u6700\u5927\u7d50\u679c\u6570\: ViewPreferencesPanel.maxResultsLabel.toolTipText=\n\u3053\u306e\u5024\u30920 \u306b\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u3059\u3079\u3066\u306e\u7d50\u679c\u304c\u7d50\u679c\u30c6\u30fc\u30d6\u30eb\u306b\u8868\u793a\u3055\u308c\u307e\u3059\u3002\n
\u3053\u306e\u5024\u30920 \u306b\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u7d50\u679c\u6570\u304c\u591a\u3044\u5834\u5408UI\u306e\u5fdc\u7b54\u6027\u304c\u60aa\u304f\u306a\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059 \u3002\n +ViewPreferencesPanel.radioGroupByDataType.text=\u30c7\u30fc\u30bf\u30fb\u30bf\u30a4\u30d7\u3067\u30b0\u30eb\u30fc\u30d7\u5316 +ViewPreferencesPanel.radioGroupByPersonHost.text=\u4eba/\u30db\u30b9\u30c8\u3067\u30b0\u30eb\u30fc\u30d7\u5316 ViewPreferencesPanel.scoColumnsCheckbox.text=S(\u30b9\u30b3\u30a2)\u3001C(\u30b3\u30e1\u30f3\u30c8)\u3001O(\u767a\u751f) ViewPreferencesPanel.scoColumnsLabel.text=\u6b21\u306e\u305f\u3081\u306e\u5217\u3092\u8ffd\u52a0\u3057\u306a\u3044\: ViewPreferencesPanel.scoColumnsWrapAroundText.text=\u975e\u8868\u793a\u306b\u3059\u308b\u3068\u8aad\u8fbc\u307f\u304c\u65e9\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle_ja.properties index 761b704f2d..203bd41606 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 AbstractAbstractFileNode.accessTimeColLbl=\u30a2\u30af\u30bb\u30b9\u65e5\u6642 AbstractAbstractFileNode.attrAddrColLbl=\u5c5e\u6027\u30a2\u30c9\u30ec\u30b9 AbstractAbstractFileNode.changeTimeColLbl=\u30a8\u30f3\u30c8\u30ea\u66f4\u65b0\u65e5\u6642 @@ -139,6 +139,7 @@ DataModelActionsFactory.fileInDir.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30f DataModelActionsFactory.openExtViewer.text=\u5916\u90e8\u30d3\u30e5\u30fc\u30ef\u30fc\u3067\u958b\u304f Ctrl+E DataModelActionsFactory.srcFileInDir.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u5185\u306e\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u8868\u793a DataModelActionsFactory.viewNewWin.text=\u65b0\u3057\u3044\u30a6\u30a3\u30f3\u30c9\u30a6\u3067\u8868\u793a +DataSourcesHostsNode_name=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9 DataSourcesNode.createSheet.name.desc=\u8aac\u660e\u306a\u3057 DataSourcesNode.createSheet.name.displayName=\u540d\u524d DataSourcesNode.createSheet.name.name=\u540d\u524d @@ -226,6 +227,11 @@ GetSCOTask.occurrences.multipleProperties=\u3053\u306e\u7d50\u679c\u306b\u8907\u HashsetHits.createSheet.name.desc=\u8aac\u660e\u306a\u3057 HashsetHits.createSheet.name.displayName=\u540d\u524d HashsetHits.createSheet.name.name=\u540d\u524d +HostGroupingNode_unknownHostNode_title=\u672a\u77e5\u306e\u30db\u30b9\u30c8 +HostNode_actions_associateWithExisting=\u65e2\u5b58\u306e\u4eba\u3068\u95a2\u9023\u4ed8\u3051\u308b... +HostNode_actions_associateWithNew=\u65b0\u3057\u3044\u4eba\u3068\u95a2\u9023\u4ed8\u3051\u308b... +HostNode_actions_removeFromPerson=\u4eba\u304b\u3089\u524a\u9664\uff08{0}\uff09 +HostNode_createSheet_nameProperty=\u540d\u524d ImageNode.action.runIngestMods.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5b9f\u884c ImageNode.createSheet.deviceId.desc=\u30a4\u30e1\u30fc\u30b8\u306e\u30c7\u30d0\u30a4\u30b9ID ImageNode.createSheet.deviceId.displayName=\u30c7\u30d0\u30a4\u30b9ID @@ -309,6 +315,23 @@ OpenReportAction.actionPerformed.MissingReportFileMessage=\u30ec\u30dd\u30fc\u30 OpenReportAction.actionPerformed.NoAssociatedEditorMessage=\u3053\u306e\u30bf\u30a4\u30d7\u306e\u30ec\u30dd\u30fc\u30c8\u306b\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30a8\u30c7\u30a3\u30bf\u30fc\u304c\u306a\u3044\u304b\u3001\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304c\u8d77\u52d5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 OpenReportAction.actionPerformed.NoOpenInEditorSupportMessage=\u3053\u306e\u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0(\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0)\u306f\u3053\u306e\u65b9\u6cd5\u3067\u30a8\u30c7\u30a3\u30bf\u30fc\u3067\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f\u3053\u3068\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002 OpenReportAction.actionPerformed.ReportFileOpenPermissionDeniedMessage=\u30ec\u30dd\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f\u8a31\u53ef\u304c\u62d2\u5426\u3055\u308c\u307e\u3057\u305f\u3002 +OsAccount_listNode_name=OS\u30a2\u30ab\u30a6\u30f3\u30c8 +OsAccounts_accountNameProperty_desc=OS\u30a2\u30ab\u30a6\u30f3\u30c8\u540d +OsAccounts_accountNameProperty_displayName=\u540d\u524d +OsAccounts_accountNameProperty_name=\u540d\u524d +OsAccounts_accountRealmNameProperty_desc=OS\u30a2\u30ab\u30a6\u30f3\u30c8\u5206\u91ce\u540d +OsAccounts_accountRealmNameProperty_displayName=\u5206\u91ce\u540d +OsAccounts_accountRealmNameProperty_name=\u5206\u91ce\u540d +OsAccounts_createdTimeProperty_desc=OS\u30a2\u30ab\u30a6\u30f3\u30c8\u4f5c\u6210\u6642\u9593 +OsAccounts_createdTimeProperty_displayName=\u4f5c\u6210\u6642\u9593 +OsAccounts_createdTimeProperty_name=\u4f5c\u6210\u6642\u9593 +OsAccounts_loginNameProperty_desc=OS\u30a2\u30ab\u30a6\u30f3\u30c8\u30ed\u30b0\u30a4\u30f3\u540d +OsAccounts_loginNameProperty_displayName=\u30ed\u30b0\u30a4\u30f3\u540d +OsAccounts_loginNameProperty_name=\u30ed\u30b0\u30a4\u30f3\u540d +PersonGroupingNode_actions_delete=\u4eba\u306e\u524a\u9664 +PersonGroupingNode_actions_rename=\u540d\u524d\u3092\u5909\u66f4... +PersonGroupingNode_createSheet_nameProperty=\u540d\u524d +PersonNode_unknownPersonNode_title=\u672a\u77e5\u306e\u4eba\u7269 PoolNode.createSheet.name.desc=\u8aac\u660e\u306a\u3057 PoolNode.createSheet.name.displayName=\u540d\u524d PoolNode.createSheet.name.name=\u540d\u524d diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/Bundle_ja.properties index 5873c044cc..a8185f73ff 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/Bundle_ja.properties @@ -1,4 +1,3 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 DataSourceUserActivitySummary_getRecentAccounts_calllogMessage=\u901a\u8a71\u8a18\u9332 DataSourceUserActivitySummary_getRecentAccounts_emailMessage=\u30e1\u30fc\u30eb\u30e1\u30c3\u30bb\u30fc\u30b8 -IngestModuleCheckUtil_recentActivityModuleName=\u6700\u8fd1\u306e\u6d3b\u52d5 diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle_ja.properties index 2b4d2c7dc2..053ceb7450 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle_ja.properties @@ -1,11 +1,13 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 AnalysisPanel.hashsetHitsLabel.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30d2\u30c3\u30c8 AnalysisPanel.interestingItemLabel.text=\u8208\u5473\u6df1\u3044\u30a2\u30a4\u30c6\u30e0\u306e\u30d2\u30c3\u30c8 AnalysisPanel.keywordHitsLabel.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u30d2\u30c3\u30c8 AnalysisPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8 +AnalysisPanel_hashsetHits_tabName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30fb\u30d2\u30c3\u30c8 +AnalysisPanel_interestingItemHits_tabName=\u8208\u5473\u6df1\u3044\u30a2\u30a4\u30c6\u30e0\u306e\u30d2\u30c3\u30c8 AnalysisPanel_keyColumn_title=\u540d\u524d +AnalysisPanel_keywordHits_tabName=\u30ad\u30fc\u30ef\u30fc\u30c9\u30fb\u30d2\u30c3\u30c8 AnalysisPanel_keywordSearchModuleName=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22 -BaseDataSourceSummaryPanel_defaultNotIngestMessage={0}\u53d6\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u3053\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u306f\u5b9f\u884c\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 BaseDataSourceSummaryPanel_goToArtifact=\u30bd\u30fc\u30b9\u7d50\u679c\u306e\u8868\u793a BaseDataSourceSummaryPanel_goToFile=\u30d5\u30a9\u30eb\u30c0\u30fc\u5185\u306e\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u8868\u793a CTL_DataSourceSummaryAction=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u6982\u8981 @@ -30,7 +32,21 @@ ContainerPanel.units.kilobytes=\ kB ContainerPanel.units.megabytes=\ MB ContainerPanel.units.petabytes=\ PB ContainerPanel.units.terabytes=\ TB +ContainerPanel_export_acquisitionDetails=\u8aad\u8fbc\u306e\u8a73\u7d30\uff1a +ContainerPanel_export_deviceId=\u30c7\u30d0\u30a4\u30b9ID\uff1a +ContainerPanel_export_displayName=\u8868\u793a\u540d\uff1a +ContainerPanel_export_filePaths=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\uff1a +ContainerPanel_export_imageType=\u753b\u50cf\u30bf\u30a4\u30d7\uff1a +ContainerPanel_export_md5=MD5\: +ContainerPanel_export_originalName=\u540d\u524d\uff1a +ContainerPanel_export_sectorSize=\u30bb\u30af\u30bf\u30fc\u30b5\u30a4\u30ba\uff1a +ContainerPanel_export_sha1=SHA1\: +ContainerPanel_export_sha256=SHA256\: +ContainerPanel_export_size=\u30b5\u30a4\u30ba\uff1a +ContainerPanel_export_timeZone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\uff1a +ContainerPanel_export_unallocatedSize=\u672a\u5272\u308a\u5f53\u3066\u9818\u57df\uff1a ContainerPanel_setFieldsForNonImageDataSource_na=\u8a72\u5f53\u306a\u3057 +ContainerPanel_tabName=\u30b3\u30f3\u30c6\u30ca DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=\u3059\u3079\u3066 DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=\u5272\u308a\u5f53\u3066\u6e08\u307f DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=\u30ab\u30a6\u30f3\u30c8 @@ -63,6 +79,7 @@ DataSourceSummaryNode.viewDataSourceAction.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u DataSourceSummaryTabbedPane.noDataSourceLabel.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 DataSourceSummaryTabbedPane_analysisTab_title=\u5206\u6790 DataSourceSummaryTabbedPane_detailsTab_title=\u30b3\u30f3\u30c6\u30ca +DataSourceSummaryTabbedPane_exportTab_title=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 DataSourceSummaryTabbedPane_geolocationTab_title=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3 DataSourceSummaryTabbedPane_ingestHistoryTab_title=\u53d6\u8fbc\u5c65\u6b74 DataSourceSummaryTabbedPane_pastCasesTab_title=\u904e\u53bb\u306e\u30b1\u30fc\u30b9 @@ -70,21 +87,46 @@ DataSourceSummaryTabbedPane_recentFileTab_title=\u6700\u8fd1\u4f7f\u7528\u3057\u DataSourceSummaryTabbedPane_timelineTab_title=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3 DataSourceSummaryTabbedPane_typesTab_title=\u30bf\u30a4\u30d7 DataSourceSummaryTabbedPane_userActivityTab_title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 +ExcelExportAction_exportToXLSX_beginExport=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3092\u958b\u59cb\u3057\u3066\u3044\u307e\u3059... +ExcelExportAction_exportToXLSX_gatheringTabData={0}\u30bf\u30d6\u306e\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u3057\u3066\u3044\u307e\u3059... +ExcelExportAction_exportToXLSX_writingToFile=\u30d5\u30a1\u30a4\u30eb\u3078\u306e\u66f8\u51fa\u3057\u4e2d... +ExcelExportAction_getXLSXPath_directory=DataSourceSummary +ExcelExportAction_moduleName=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u6982\u8981 +ExcelExportAction_runXLSXExport_errorMessage=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +ExcelExportAction_runXLSXExport_errorTitle=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f +ExcelExportAction_runXLSXExport_progressCancelActionTitle=\u30ad\u30e3\u30f3\u30bb\u30eb... +ExcelExportAction_runXLSXExport_progressCancelTitle=\u30ad\u30e3\u30f3\u30bb\u30eb +ExcelExportAction_runXLSXExport_progressTitle={0}\u3092XLSX\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u3059 +ExcelExportDialog.okButton.text=OK +ExcelExportDialog.titleLabel.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u6982\u8981\u306f\u6b21\u306e\u5834\u6240\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3055\u308c\u307e\u3057\u305f\uff1a +ExcelExportDialog_title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u6982\u8981\u304c\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3055\u308c\u307e\u3057\u305f +ExportPanel.xlsxExportButton.text=\u8981\u7d04\u30c7\u30fc\u30bf\u306e\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 +ExportPanel.xlsxExportMessage.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30b5\u30de\u30ea\u30fc\u304b\u3089Excel\u30d5\u30a1\u30a4\u30eb\u306b\u30c7\u30fc\u30bf\u3092\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3057\u307e\u3059\u3002 GeolocationPanel.commonViewInGeolocationBtn.text=\u5730\u56f3\u3067\u898b\u308b -GeolocationPanel.mostCommonLabel.text=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u304b\u3089\u306e\u6700\u3082\u4e00\u822c\u7684\u306a\u90fd\u5e02 -GeolocationPanel.mostRecentLabel.text=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u304b\u3089\u306e\u6700\u8fd1\u306e\u90fd\u5e02 +GeolocationPanel.mostCommonLabel.text=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u7d50\u679c\u304b\u3089\u6700\u3082\u4e00\u822c\u7684\u306a\u90fd\u5e02 +GeolocationPanel.mostRecentLabel.text=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u7d50\u679c\u3067\u306e\u6700\u8fd1\u306e\u90fd\u5e02 GeolocationPanel.recentViewInGeolocationBtn.text=\u5730\u56f3\u3067\u898b\u308b GeolocationPanel.withinDistanceLabel.text=\u90fd\u5e02\u304b\u3089150km\u4ee5\u4e0a\u96e2\u308c\u305f\u5834\u6240\u306f\u3001\u300c\u4e0d\u660e\u300d\u3068\u3057\u3066\u8868\u793a\u3055\u308c\u307e\u3059 GeolocationPanel.withinDistanceLabel1.text=\u90fd\u5e02\u304b\u3089150km\u4ee5\u4e0a\u96e2\u308c\u305f\u5834\u6240\u306f\u3001\u300c\u4e0d\u660e\u300d\u3068\u3057\u3066\u8868\u793a\u3055\u308c\u307e\u3059 GeolocationPanel_cityColumn_title=\u6700\u3082\u8fd1\u3044\u90fd\u5e02 GeolocationPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8 +GeolocationPanel_mostCommon_tabName=\u6700\u3082\u4e00\u822c\u7684\u306a\u90fd\u5e02 +GeolocationPanel_mostRecent_tabName=\u6700\u8fd1\u4f7f\u7528\u3055\u308c\u305f\u90fd\u5e02 GeolocationPanel_onNoCrIngest_message=GPX\u30d1\u30fc\u30b5\u30fc\u304c\u5b9f\u884c\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093\u3002 GeolocationPanel_unknownRow_title=\u4e0d\u660e +IngestJobExcelExport_endTimeColumn=\u7d42\u4e86\u6642\u9593 +IngestJobExcelExport_ingestStatusTimeColumn=\u53d6\u8fbc\u307f\u72b6\u6cc1 +IngestJobExcelExport_moduleNameTimeColumn=\u30e2\u30b8\u30e5\u30fc\u30eb\u540d +IngestJobExcelExport_sheetName=\u53d6\u8fbc\u307f\u6b74\u53f2 +IngestJobExcelExport_startTimeColumn=\u30b9\u30bf\u30fc\u30c8\u6642\u9593 +IngestJobExcelExport_versionColumn=\u30e2\u30b8\u30e5\u30fc\u30eb\u30d0\u30fc\u30b8\u30e7\u30f3 PastCasesPanel.notableFileLabel.text=\u300c\u6ce8\u76ee\u300d\u3068\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\u4e00\u822c\u7684\u306a\u30b1\u30fc\u30b9 PastCasesPanel.sameIdLabel.text=\u540c\u3058\u30c7\u30d0\u30a4\u30b9ID\u3092\u6301\u3064\u904e\u53bb\u306e\u30b1\u30fc\u30b9 PastCasesPanel_caseColumn_title=\u30b1\u30fc\u30b9 PastCasesPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8 +PastCasesPanel_notableFileTable_tabName=\u4e00\u822c\u7684\u306b\u6ce8\u76ee\u3059\u3079\u304d\u4e8b\u4f8b PastCasesPanel_onNoCrIngest_message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u5b9f\u884c\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093\u3002 +PastCasesPanel_sameIdsTable_tabName=\u540c\u3058\u30c7\u30d0\u30a4\u30b9\u3067\u306e\u904e\u53bb\u306e\u30b1\u30fc\u30b9 RecentFilePanel_col_header_domain=\u30c9\u30e1\u30a4\u30f3 RecentFilePanel_col_header_path=\u30d1\u30b9 RecentFilePanel_col_header_sender=\u9001\u4fe1\u8005 @@ -96,21 +138,31 @@ RecentFilesPanel.openDocsLabel.text=\u6700\u8fd1\u958b\u3044\u305f\u30c9\u30ad\u RecentFilesPanel.rightClickForMoreOptions1.text=\u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u3001\u884c\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044 RecentFilesPanel.rightClickForMoreOptions2.text=\u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u3001\u884c\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044 RecentFilesPanel.rightClickForMoreOptions3.text=\u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u3001\u884c\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044 +RecentFilesPanel_attachmentsTable_tabName=\u6700\u8fd1\u306e\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb RecentFilesPanel_col_head_date=\u65e5\u4ed8 +RecentFilesPanel_docsTable_tabName=\u6700\u8fd1\u958b\u3044\u305f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8 +RecentFilesPanel_downloadsTable_tabName=\u6700\u8fd1\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9 SizeRepresentationUtil_units_bytes=\u30d0\u30a4\u30c8 -SizeRepresentationUtil_units_gigabytes=\ GB -SizeRepresentationUtil_units_kilobytes=\ kB -SizeRepresentationUtil_units_megabytes=\ MB -SizeRepresentationUtil_units_petabytes=\ PB -SizeRepresentationUtil_units_terabytes=\ TB +SizeRepresentationUtil_units_gigabytes=GB +SizeRepresentationUtil_units_kilobytes=KB +SizeRepresentationUtil_units_megabytes=MB +SizeRepresentationUtil_units_petabytes=PB +SizeRepresentationUtil_units_terabytes=TB TimelinePanel.activityRangeLabel.text=\u6d3b\u52d5\u7bc4\u56f2 TimelinePanel.viewInTimelineBtn.text=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u3067\u8868\u793a TimelinePanel_earliestLabel_title=\u6700\u53e4 +TimelinePanel_getExports_activityRange=\u6d3b\u52d5\u7bc4\u56f2 +TimelinePanel_getExports_chartName=\u904e\u53bb30\u65e5\u9593 +TimelinePanel_getExports_dateColumnHeader=\u65e5\u4ed8 +TimelinePanel_getExports_earliest=\u6700\u53e4\uff1a +TimelinePanel_getExports_latest=\u6700\u8fd1\uff1a +TimelinePanel_getExports_sheetName=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3 TimelinePanel_latestLabel_title=\u6700\u65b0 TimlinePanel_last30DaysChart_artifactEvts_title=\u7d50\u679c\u30a4\u30d9\u30f3\u30c8 TimlinePanel_last30DaysChart_fileEvts_title=\u30d5\u30a1\u30a4\u30eb\u30a4\u30d9\u30f3\u30c8 TimlinePanel_last30DaysChart_title=\u904e\u53bb30\u65e5\u9593 TypesPanel_artifactsTypesPieChart_title=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30bf\u30a4\u30d7 +TypesPanel_excelTabName=\u30bf\u30a4\u30d7 TypesPanel_fileMimeTypesChart_audio_title=\u30aa\u30fc\u30c7\u30a3\u30aa TypesPanel_fileMimeTypesChart_documents_title=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8 TypesPanel_fileMimeTypesChart_executables_title=\u5b9f\u884c\u53ef\u80fd\u30d5\u30a1\u30a4\u30eb @@ -119,6 +171,7 @@ TypesPanel_fileMimeTypesChart_notAnalyzed_title=\u5206\u6790\u3055\u308c\u3066\u TypesPanel_fileMimeTypesChart_other_title=\u305d\u306e\u4ed6 TypesPanel_fileMimeTypesChart_title=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7 TypesPanel_fileMimeTypesChart_unknown_title=\u4e0d\u660e +TypesPanel_fileMimeTypesChart_valueLabel=\u30ab\u30a6\u30f3\u30c8 TypesPanel_fileMimeTypesChart_videos_title=\u30d3\u30c7\u30aa TypesPanel_filesByCategoryTable_allocatedRow_title=\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30d5\u30a1\u30a4\u30eb TypesPanel_filesByCategoryTable_directoryRow_title=\u30d5\u30a9\u30eb\u30c0 @@ -139,18 +192,23 @@ UserActivityPanel.topDevicesAttachedLabel.text=\u6700\u8fd1\u63a5\u7d9a\u3055\u3 UserActivityPanel.topWebSearchLabel.text=\u6700\u8fd1\u306eWeb\u691c\u7d22 UserActivityPanel_TopAccountTableModel_accountType_header=\u30a2\u30ab\u30f3\u30c8\u30bf\u30a4\u30d7 UserActivityPanel_TopAccountTableModel_lastAccess_header=\u6700\u7d42\u30a2\u30af\u30bb\u30b9\u65e5 +UserActivityPanel_TopAccountTableModel_tabName=\u6700\u8fd1\u4f7f\u7528\u3055\u308c\u305f\u30a2\u30ab\u30a6\u30f3\u30c8\u30bf\u30a4\u30d7 UserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=\u6700\u7d42\u30a2\u30af\u30bb\u30b9\u65e5 UserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=\u30c7\u30d0\u30a4\u30b9ID UserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=\u30e1\u30fc\u30ab\u30fc\u3068\u30e2\u30c7\u30eb +UserActivityPanel_TopDeviceAttachedTableModel_tabName=\u6700\u8fd1\u63a5\u7d9a\u3055\u308c\u305f\u30c7\u30d0\u30a4\u30b9 UserActivityPanel_TopDomainsTableModel_count_header=\u53c2\u89b3 UserActivityPanel_TopDomainsTableModel_domain_header=\u30c9\u30e1\u30a4\u30f3 UserActivityPanel_TopDomainsTableModel_lastAccess_header=\u6700\u7d42\u30a2\u30af\u30bb\u30b9\u65e5 +UserActivityPanel_TopDomainsTableModel_tabName=\u6700\u8fd1\u306e\u30c9\u30e1\u30a4\u30f3 UserActivityPanel_TopProgramsTableModel_count_header=\u5b9f\u884c\u6642\u9593 UserActivityPanel_TopProgramsTableModel_folder_header=\u30d5\u30a9\u30eb\u30c0 UserActivityPanel_TopProgramsTableModel_lastrun_header=\u524d\u56de\u5b9f\u884c UserActivityPanel_TopProgramsTableModel_name_header=\u30d7\u30ed\u30b0\u30e9\u30e0 +UserActivityPanel_TopProgramsTableModel_tabName=\u6700\u8fd1\u306e\u30d7\u30ed\u30b0\u30e9\u30e0 UserActivityPanel_TopWebSearchTableModel_dateAccessed_header=\u30a2\u30af\u30bb\u30b9\u65e5 UserActivityPanel_TopWebSearchTableModel_searchString_header=\u691c\u7d22\u6587\u5b57\u5217 +UserActivityPanel_TopWebSearchTableModel_tabName=\u6700\u8fd1\u306eWeb\u691c\u7d22 UserActivityPanel_TopWebSearchTableModel_translatedResult_header=\u7ffb\u8a33\u6e08\u307f UserActivityPanel_noDataExists=\u901a\u4fe1\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093 UserActivityPanel_tab_title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/Bundle_ja.properties index 25a7ef2e76..1807aad546 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/Bundle_ja.properties @@ -1,6 +1,7 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 AbstractLoadableComponent_errorMessage_defaultText=\u7d50\u679c\u306e\u8aad\u8fbc\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 AbstractLoadableComponent_loadingMessage_defaultText=\u7d50\u679c\u3092\u8aad\u8fbc\u4e2d... AbstractLoadableComponent_noDataExists_defaultText=\u30c7\u30fc\u30bf\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 +ExcelExport_writeExcel_noSheetName=\u30b7\u30fc\u30c8{0} IngestRunningLabel_defaultMessage=\u53d6\u8fbc\u307f\u5b9f\u884c\u4e2d\u3067\u3059\u3002 PieChartPanel_noDataLabel=\u30c7\u30fc\u30bf\u7121\u3057 diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties index d9ae2561f4..81e23b1ad9 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 AddExternalViewerRuleDialog.cancelButton.title=\u53d6\u308a\u6d88\u3057 AddExternalViewerRuleDialog.saveButton.title=\u4fdd\u5b58 AddExternalViewerRuleDialog.title=\u5916\u90e8\u30d3\u30e5\u30fc\u30ef\u30fc\u30eb\u30fc\u30eb diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/discovery/search/Bundle_ja.properties index 13b93f98f2..1a00933afe 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate={0}{1}\u3001{2}\u306e\u9031 DiscoveryAttributes.GroupingAttributeType.datasource.displayName=\u30c7\u30fc\u30bf\u5143 DiscoveryAttributes.GroupingAttributeType.fileType.displayName=\u30d5\u30a1\u30a4\u30eb\u306e\u7a2e\u985e @@ -48,6 +48,7 @@ FileSorter.SortingMethod.fullPath.displayName=\u30d5\u30eb\u30d1\u30b9 FileSorter.SortingMethod.keywordlist.displayName=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u540d FileSorter.SortingMethod.pageViews.displayName=\u30da\u30fc\u30b8\u30d3\u30e5\u30fc ResultDomain_getDefaultCategory=\u672a\u5206\u985e +ResultDomain_noAccountTypes=\u4e0d\u660e ResultFile.score.interestingResult.description=1\u3064\u4ee5\u4e0a\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u8208\u5473\u6df1\u3044\u7d50\u679c\u304c\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u307e\u3059\u3002 ResultFile.score.notableFile.description=1\u3064\u4ee5\u4e0a\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u6ce8\u76ee\u3059\u3079\u304d\u3082\u306e\u3068\u3057\u3066\u8a8d\u8b58\u3055\u308c\u307e\u3057\u305f\u3002 ResultFile.score.notableTaggedFile.description=1\u3064\u4ee5\u4e0a\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u6ce8\u76ee\u3059\u3079\u304d\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u3066\u3044\u307e\u3059\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle_ja.properties index f8235ab6e3..54e640b4b9 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle_ja.properties @@ -1,4 +1,5 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 +ArtifactMenuMouseAdapter.noFile.text=\u30d5\u30a1\u30a4\u30eb\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 ArtifactMenuMouseAdapter_ExternalViewer_label=\u5916\u90e8\u30d3\u30e5\u30fc\u30a2\u3067\u958b\u304f ArtifactMenuMouseAdapter_label=\u30d5\u30a1\u30a4\u30eb\u306e\u62bd\u51fa ArtifactTypeFilterPanel.artifactTypeCheckbox.text=\u7d50\u679c\u30bf\u30a4\u30d7\uff1a @@ -23,7 +24,7 @@ DateFilterPanel.dateRange.text=\u65e5\u4ed8\u7bc4\u56f2\uff08{0}\uff09\uff1a DateFilterPanel.daysLabel.text=\u6d3b\u52d5\u65e5 DateFilterPanel.endCheckBox.text=\u7d42\u4e86\uff1a DateFilterPanel.invalidRange.text=\u7bc4\u56f2\u307e\u305f\u306f\u6700\u5f8c\u3092\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 -DateFilterPanel.mostRecentRadioButton.text=\u6700\u5f8c\u306e\u307f\uff1a +DateFilterPanel.mostRecentRadioButton.text=\u6700\u7d42\u306e\u307f\uff1a DateFilterPanel.startAfterEnd.text=\u4e21\u65b9\u304c\u6709\u52b9\u306a\u5834\u5408\u3001\u958b\u59cb\u65e5\u306f\u7d42\u4e86\u65e5\u3088\u308a\u524d\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 DateFilterPanel.startCheckBox.text=\u30b9\u30bf\u30fc\u30c8\uff1a DateFilterPanel.startOrEndNeeded.text=\u7bc4\u56f2\u30d5\u30a3\u30eb\u30bf\u30fc\u3092\u4f7f\u7528\u3059\u308b\u306b\u306f\u3001\u958b\u59cb\u65e5\u307e\u305f\u306f\u7d42\u4e86\u65e5\u3092\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 @@ -63,12 +64,18 @@ DocumentPanel.numberOfImages.noImages=\u753b\u50cf\u306a\u3057 DocumentPanel.numberOfImages.text={0}\u753b\u50cf\u306e1\u3064 DocumentWrapper.previewInitialValue=\u30d7\u30ec\u30d3\u30e5\u30fc\u306f\u307e\u3060\u751f\u6210\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 DomainDetailsPanel.miniTimelineTitle.text=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3 +DomainDetailsPanel.otherOccurrencesTab.title=\u305d\u306e\u4ed6\u306e\u767a\u751f DomainFilterPanel.domainFiltersSplitPane.border.title=\u30b9\u30c6\u30c3\u30d72\uff1a\u8868\u793a\u3059\u308b\u30c9\u30e1\u30a4\u30f3\u306e\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0 DomainSummaryPanel.activity.text=\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\uff1a{0}\u304b\u3089{1} +DomainSummaryPanel.category.text=\u30ab\u30c6\u30b4\u30ea\uff1a DomainSummaryPanel.downloads.text=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305f\u30d5\u30a1\u30a4\u30eb\uff1a DomainSummaryPanel.loadingImages.text=\u30b5\u30e0\u30cd\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059... -DomainSummaryPanel.pages.text=\u904e\u53bb60\u65e5\u9593\u306e\u30da\u30fc\u30b8\u30d3\u30e5\u30fc\uff1a +DomainSummaryPanel.no.text=\u3044\u3044\u3048 +DomainSummaryPanel.notability.text=\u4ee5\u524d\u306b\u6ce8\u76ee\u3059\u3079\u304d\u306b\u30bf\u30b0\u4ed8\u3051\uff1a +DomainSummaryPanel.pages.text=\u6700\u8fd160\u65e5\u9593\u306e\u30da\u30fc\u30b8\u30d3\u30e5\u30fc\uff1a DomainSummaryPanel.totalPages.text=\u5168\u30da\u30fc\u30b8\u30d3\u30e5\u30fc\uff1a +DomainSummaryPanel.userRole.text=\u30a2\u30ab\u30a6\u30f3\u30c8\u30bf\u30a4\u30d7 +DomainSummaryPanel.yes.text=\u306f\u3044 FileDetailsPanel.instancesList.border.title=\u4f8b GroupListPanel.groupKeyList.border.title=\u30b0\u30eb\u30fc\u30d7 GroupsListPanel.noDomainResults.message.text=\u9078\u629e\u3057\u305f\u30d5\u30a3\u30eb\u30bf\u30fc\u3067\u306e\u30c9\u30e1\u30a4\u30f3\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n\n\u30ea\u30de\u30a4\u30f3\u30c0\u30fc\uff1a\n -\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u7d50\u679c\u3092\u691c\u7d22\u3059\u308b\u306b\u306f\u5404\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n -\u904e\u53bb\u306e\u767a\u751f\u3067\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\u307e\u305f\u306f\u30bd\u30fc\u30c8\u3059\u308b\u5834\u5408\u306f\u3001\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5404\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n -iOS\u30a2\u30ca\u30e9\u30a4\u30b6\u30fc\uff08iLEAPP\uff09\u30e2\u30b8\u30e5\u30fc\u30eb\u3092iOS\u30c7\u30d0\u30a4\u30b9\u306e\u30c7\u30fc\u30bf\u3092\u542b\u3080\u5404\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties index 57e96f90d4..1eb0bcd5aa 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:28 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 CTL_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8 CTL_RunIngestAction=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u5b9f\u884c DataSourceIngestCancellationPanel.cancelAllModulesRadioButton.text=\u3059\u3079\u3066\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u53d6\u308a\u6d88\u3059 @@ -7,6 +7,7 @@ DataSourceIngestPipeline.moduleError.title.text={0} \u30a8\u30e9\u30fc FileIngestCancellationPanel.cancelFileIngestRadioButton.text=\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u307f\u3092\u53d6\u308a\u6d88\u3059 FileIngestCancellationPanel.cancelIngestJobRadioButton.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3068\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u53d6\u308a\u6d88\u3059 FileIngestPipeline.moduleError.title.text={0} \u30a8\u30e9\u30fc +FileIngestPipeline_SaveResults_Activity=\u7d50\u679c\u306e\u4fdd\u5b58 HINT_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8\u30a6\u30a3\u30f3\u30c9\u30a6 IngestDialog.closeButton.title=\u7d42\u4e86 IngestDialog.startButton.title=\u958b\u59cb diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle_ja.properties index 984ae6bb6f..c2aa0bce4a 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:29 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp\u5b9f\u884c\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f ALeappAnalyzerIngestModule.completed=aLeapp\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f ALeappAnalyzerIngestModule.error.creating.output.dir=aLeapp\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 @@ -16,6 +16,7 @@ ALeappAnalyzerIngestModule.running.aLeapp=aLeapp\u5b9f\u884c\u4e2d ALeappAnalyzerIngestModule.starting.aLeapp=aLeapp\u306e\u958b\u59cb ALeappAnalyzerModuleFactory_moduleDesc=aLEAPP\u3092\u4f7f\u7528\u3057\u3066\u3001Android\u30c7\u30d0\u30a4\u30b9\u306e\u8ad6\u7406\u7684\u306a\u53d6\u5f97\u3092\u5206\u6790\u3057\u307e\u3059\u3002 ALeappAnalyzerModuleFactory_moduleName=Android\u30a2\u30ca\u30e9\u30a4\u30b6\u30fc\uff08aLEAPP\uff09 +AleappAnalyzerIngestModule.not.64.bit.os=aLeapp\u306f32\u30d3\u30c3\u30c8\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0\u3067\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093 ILeappAnalyzerIngestModule.completed=iLeapp\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f ILeappAnalyzerIngestModule.error.creating.output.dir=iLeapp\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 ILeappAnalyzerIngestModule.error.ileapp.file.processor.init=ILeappProcessFile\u306e\u521d\u671f\u5316\u306b\u5931\u6557\u3057\u307e\u3057\u305f @@ -33,8 +34,10 @@ ILeappAnalyzerIngestModule.running.iLeapp=iLeapp\u5b9f\u884c\u4e2d ILeappAnalyzerIngestModule.starting.iLeapp=iLeapp\u306e\u958b\u59cb ILeappAnalyzerModuleFactory_moduleDesc=iLEAPP\u3092\u4f7f\u7528\u3057\u3066\u3001iOS\u30c7\u30d0\u30a4\u30b9\u306e\u8ad6\u7406\u7684\u306a\u53d6\u5f97\u3092\u5206\u6790\u3057\u307e\u3059\u3002 ILeappAnalyzerModuleFactory_moduleName=iOS\u30a2\u30ca\u30e9\u30a4\u30b6\u30fc\uff08iLEAPP\uff09 +IleappAnalyzerIngestModule.not.64.bit.os=iLeapp\u306f32\u30d3\u30c3\u30c8\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0\u3067\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093 LeappFileProcessor.Leapp.cancelled=Leapp\u5b9f\u884c\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f -LeappFileProcessor.cannot.load.artifact.xml=xml\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3002 +LeappFileProcessor.cannot.create.message.relationship=TSK_MESSAGE\u95a2\u4fc2\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3002 +LeappFileProcessor.cannot.load.artifact.xml=xml\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30fb\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3002 LeappFileProcessor.cannotBuildXmlParser=XML\u30d1\u30fc\u30b5\u30fc\u3092\u69cb\u7bc9\u3067\u304d\u307e\u305b\u3093\u3002 LeappFileProcessor.completed=Leapp\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f LeappFileProcessor.error.creating.new.artifacts=\u65b0\u3057\u3044\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties index d43448a582..306f4bf3b4 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:29 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 AbstractFileStringContentStream.getSize.exception.msg=\u6587\u5b57\u5217\u5168\u4f53\u304c\u5909\u63db\u3055\u308c\u308b\u307e\u3067\u3001\u5909\u63db\u3055\u308c\u305f\u6587\u5b57\u5217\u306e\u6587\u5b57\u6570\u306f\u308f\u304b\u308a\u307e\u305b\u3093 AbstractFileStringContentStream.getSrcInfo.text=\u30d5\u30a1\u30a4\u30eb\:{0} AbstractFileTikaTextExtract.index.exception.tikaParse.msg=\u4f8b\u5916\: \u6b21\u306e\u30d5\u30a1\u30a4\u30eb\u306eTika\u89e3\u6790\u30bf\u30b9\u30af\u5b9f\u884c\u6642\u306e\u4e88\u671f\u305b\u306c\u4f8b\u5916\: {0}\u3001{1} @@ -47,6 +47,17 @@ DropdownSingleTermSearchPanel.jSaveSearchResults.toolTipText=\u30ad\u30fc\u30ef\ DropdownSingleTermSearchPanel.selected=\u30a2\u30c9\u30db\u30c3\u30af\u691c\u7d22\u30bd\u30fc\u30b9\u30d5\u30a3\u30eb\u30bf\u30fc\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u3059 DropdownSingleTermSearchPanel.warning.text=\u5883\u754c\u6587\u5b57 ^ \u3068 $ \u304c\u5358\u8a9e\u9818\u57df\u3068\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002[ \\.,] \u306a\u3069\u306e\u660e\u793a\u7684\u306a\u5883\u754c\u6587\u5b57\u30ea\u30b9\u30c8\u3068\u306e\u7f6e\u63db\u3092\n\u691c\u8a0e\u3057\u3066\u304f\u3060\u3055\u3044 DropdownSingleTermSearchPanel.warning.title=\u8b66\u544a +ExtractAllTermsReport.description.text=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u304b\u3089\u3059\u3079\u3066\u306e\u30e6\u30cb\u30fc\u30af\u306e\u5358\u8a9e\u3092\u62bd\u51fa\u3057\u307e\u3059\u3002 \u6ce8\uff1a\u62bd\u51fa\u3055\u308c\u305f\u5358\u8a9e\u306f\u5c0f\u6587\u5b57\u3067\u3059\u3002 +ExtractAllTermsReport.error.noOpenCase=\u73fe\u5728\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u306f\u3042\u308a\u307e\u305b\u3093\u3002 +ExtractAllTermsReport.export.error=\u30e6\u30cb\u30fc\u30af\u306e\u5358\u8a9e\u306e\u62bd\u51fa\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f +ExtractAllTermsReport.exportComplete=\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u62bd\u51fa\u5b8c\u4e86 +ExtractAllTermsReport.getName.text=\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u3092\u62bd\u51fa\u3059\u308b +ExtractAllTermsReport.numberExtractedTerms={0}\u7528\u8a9e.\u304c\u62bd\u51fa\u3055\u308c\u307e\u3057\u305f.. +ExtractAllTermsReport.search.ingestInProgressBody=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u53d6\u8fbc\u307f\u306f\u73fe\u5728\u5b9f\u884c\u4e2d\u3067\u3059\u3002
\u5168\u3066\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u767b\u9332\u3055\u308c\u3066\u307e\u305b\u3093\u3001\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u3092\u62bd\u51fa\u3059\u308b\u3068\u4e0d\u5b8c\u5168\u306a\u7d50\u679c\u306b\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002
\u305d\u308c\u3067\u3082\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u306e\u62bd\u51fa\u3092\u7d9a\u884c\u3057\u307e\u3059\u304b\uff1f +ExtractAllTermsReport.search.noFilesInIdxMsg=\u307e\u3060\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u30d5\u30a1\u30a4\u30eb\u306f\u3042\u308a\u307e\u305b\u3093\u3002 \u3042\u3068\u3067\u3082\u3046\u4e00\u5ea6\u8a66\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306f{0}\u5206\u3054\u3068\u306b\u66f4\u65b0\u3055\u308c\u307e\u3059\u3002 +ExtractAllTermsReport.search.noFilesInIdxMsg2=\u307e\u3060\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u30d5\u30a1\u30a4\u30eb\u306f\u3042\u308a\u307e\u305b\u3093\u3002 \u3042\u3068\u3067\u3082\u3046\u4e00\u5ea6\u8a66\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +ExtractAllTermsReport.search.searchIngestInProgressTitle=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u306e\u53d6\u8fbc\u307f\u304c\u9032\u884c\u4e2d +ExtractAllTermsReport.startExport=\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u62bd\u51fa\u306e\u958b\u59cb ExtractedContentPanel.SetMarkup.progress.loading={0} \u306e\u30c6\u30ad\u30b9\u30c8\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059 ExtractedContentPanel.copyMenuItem.text=\u30b3\u30d4\u30fc ExtractedContentPanel.hitButtonsLabel.text=\u4e00\u81f4\u3059\u308b\u7d50\u679c @@ -333,11 +344,12 @@ Server.deleteCore.exception.msg=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3{0}\u306 Server.exceptionMessage.unableToBackupCollection=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3067\u304d\u307e\u305b\u3093 Server.exceptionMessage.unableToCreateCollection=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093 Server.exceptionMessage.unableToRestoreCollection=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u5fa9\u5143\u3067\u304d\u307e\u305b\u3093 +Server.getAllTerms.error=\u5168\u3066\u306e\u30e6\u30cb\u30fc\u30af\u306aSolr\u7528\u8a9e\u306e\u62bd\u51fa\u306b\u5931\u6557\u3057\u307e\u3057\u305f\uff1a Server.isRunning.exception.errCheckSolrRunning.msg=Solr\u30b5\u30fc\u30d0\u30fc\u304c\u5b9f\u884c\u4e2d\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f Server.isRunning.exception.errCheckSolrRunning.msg2=Solr\u30b5\u30fc\u30d0\u30fc\u304c\u5b9f\u884c\u4e2d\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f Server.openCore.exception.alreadyOpen.msg=\u958b\u3044\u3066\u3044\u308bSolr\u306e\u30b3\u30a2\u304c\u3059\u3067\u306b\u3042\u308a\u307e\u3059\u3002\u6700\u521d\u306b\u30b3\u30a2\u3092\u660e\u793a\u7684\u306b\u9589\u3058\u3066\u304f\u3060\u3055\u3044\u3002 Server.openCore.exception.cantOpen.msg=\u7d22\u5f15\u3092\u4f5c\u6210\u307e\u305f\u306f\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f -Server.openCore.exception.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30b5\u30fc\u30d3\u30b9\u306f\u307e\u3060\u5b9f\u884c\u3057\u3066\u3044\u307e\u305b\u3093 +Server.openCore.exception.msg=\u30ed\u30fc\u30ab\u30eb\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30b5\u30fc\u30d3\u30b9\u306f\u307e\u3060\u5b9f\u884c\u3055\u308c\u3066\u3044\u307e\u305b\u3093 Server.openCore.exception.noIndexDir.msg=\u7d22\u5f15\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u4f5c\u6210\u3067\u304d\u306a\u304b\u3063\u305f\u304b\u3001\u898b\u3064\u304b\u308a\u307e\u305b\u3093 Server.query.exception.msg=\u6b21\u306e\u30af\u30a8\u30ea\u306e\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\: {0} Server.query2.exception.msg=\u6b21\u306e\u30af\u30a8\u30ea\u306e\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\: {0} @@ -360,10 +372,12 @@ SolrSearch.checkingForLatestIndex.msg=\u6700\u65b0\u306eSolr\u3068\u30b9\u30ad\u SolrSearch.complete.msg=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u304c\u6b63\u5e38\u306b\u958b\u304d\u307e\u3057\u305f SolrSearch.creatingNewIndex.msg=\u65b0\u898f\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u3092\u751f\u6210\u4e2d\u3067\u3059 SolrSearch.findingIndexes.msg=\u65e2\u5b58\u306e\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u691c\u7d22\u4e2d\u3067\u3059 +SolrSearch.futureIndexVersion.msg=\u30b1\u30fc\u30b9\u306e\u30c6\u30ad\u30b9\u30c8\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306fSolr {0}\u7528\u3067\u3059\u3002 \u3053\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306eAutopsy\u306f\u3001Solr {1}\u3068\u4e92\u63db\u6027\u304c\u3042\u308a\u307e\u3059\u3002 SolrSearch.indentifyingIndex.msg=\u4f7f\u7528\u3059\u308b\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u3092\u7279\u5b9a\u4e2d\u3067\u3059 SolrSearch.lookingForMetadata.msg=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u4e2d\u3067\u3059 SolrSearch.openCore.msg=\u30c6\u30ad\u30b9\u30c8\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u958b\u304d\u307e\u3059\u3002 \u3053\u308c\u306b\u306f\u6570\u5206\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002 SolrSearch.readingIndexes.msg=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u307f\u4e2d\u3067\u3059 +SolrSearch.unableToFindIndex.msg=\u30b1\u30fc\u30b9\u306b\u4f7f\u7528\u3067\u304d\u308b\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 SolrSearchService.ServiceName=Solr\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30b5\u30fc\u30d3\u30b9 SolrSearchService.exceptionMessage.failedToDeleteIndexFiles={0} \u306e\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f SolrSearchService.exceptionMessage.noCurrentSolrCore=IndexMetadata\u306b\u306f\u73fe\u5728\u306eSolr\u306e\u30b3\u30a2\u304c\u542b\u307e\u308c\u3066\u3044\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u30b1\u30fc\u30b9\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle_ja.properties b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle_ja.properties index e1ea4fb368..ab01f5b7cc 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle_ja.properties +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle_ja.properties @@ -1,4 +1,4 @@ -#Fri Feb 12 16:56:29 UTC 2021 +#Mon Jun 14 12:23:19 UTC 2021 Chrome.getBookmark.errMsg.errAnalyzeFile={0}\:\u30d5\u30a1\u30a4\u30eb\:{1}\u3092\u89e3\u6790\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f Chrome.getBookmark.errMsg.errAnalyzingFile={0}\:\u30d5\u30a1\u30a4\u30eb\:{1}\u3092\u89e3\u6790\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f Chrome.getBookmark.errMsg.errAnalyzingFile3={0}\:\u30d5\u30a1\u30a4\u30eb\:{1}\u3092\u89e3\u6790\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f @@ -80,7 +80,7 @@ Firefox.moduleName=FireFox Firefox.parentModuleName=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 Firefox.parentModuleName.noSpace=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 OpenIDE-Module-Display-Category=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb -OpenIDE-Module-Long-Description=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3002\n\n\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u306e\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u304b\u3089\u6709\u7528\u306a\u6700\u8fd1\u306e\u30e6\u30fc\u30b6\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u3092\u62bd\u51fa\u3057\u307e\u3059\u3002\u4f8b\u3048\u3070\uff1a\n\n-\u6700\u8fd1\u958b\u3044\u305f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3001\n-\u30a6\u30a7\u30d6\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\uff08\u8a2a\u308c\u305f\u30b5\u30a4\u30c8\u3001\u4fdd\u5b58\u3055\u308c\u305fCookie\u3001\u30d6\u30c3\u30af\u30de\u30fc\u30af\u3055\u308c\u305f\u30b5\u30a4\u30c8\u3001\u30b5\u30fc\u30c1\u30a8\u30f3\u30b8\u30f3\u30af\u30a8\u30ea\u3001\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\uff09\u3001\n-\u6700\u8fd1\u63a5\u7d9a\u3057\u305f\u30c7\u30d0\u30a4\u30b9\u3001\n-\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u305f\u30d7\u30ed\u30b0\u30e9\u30e0\u3002\n\n\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u73fe\u5728Windows\u306e\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u3057\u304b\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002\n\u30d7\u30e9\u30b0\u30a4\u30f3\u306fWindows\u7248\u306eAutopsy\u3092\u5229\u7528\u3059\u308b\u3068\u5168\u3066\u306e\u6a5f\u80fd\u304c\u4f7f\u3048\u307e\u3059\u3002 +OpenIDE-Module-Long-Description=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u53d6\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u3002\n\n\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u3001\u53d6\u8fbc\u307e\u308c\u3066\u3044\u308b\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u3067\u306e\u6700\u8fd1\u306e\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u306b\u95a2\u3059\u308b\u6709\u7528\u306a\u60c5\u5831\u3092\u62bd\u51fa\u3057\u307e\u3059\u3002\n\n-\u6700\u8fd1\u958b\u3044\u305f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3001\n-Web\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\uff08\u30a2\u30af\u30bb\u30b9\u3057\u305f\u30b5\u30a4\u30c8\u3001\u4fdd\u5b58\u3055\u308c\u305fCookie\u3001\u30d6\u30c3\u30af\u30de\u30fc\u30af\u3055\u308c\u305f\u30b5\u30a4\u30c8\u3001\u691c\u7d22\u30a8\u30f3\u30b8\u30f3\u30af\u30a8\u30ea\u3001\u30d5\u30a1\u30a4\u30eb\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\uff09\u3001\n-\u6700\u8fd1\u63a5\u7d9a\u3055\u308c\u305f\u30c7\u30d0\u30a4\u30b9\u3001\n-\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u305f\u30d7\u30ed\u30b0\u30e9\u30e0\u3002\n\n\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306fWindows\u306e\u307f\u306e\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u3059\u3002\nWindows\u30d0\u30fc\u30b8\u30e7\u30f3\u306eAutopsy\u306b\u30c7\u30d7\u30ed\u30a4\u3059\u308b\u3068\u30d7\u30e9\u30b0\u30a4\u30f3\u306f\u5b8c\u5168\u306b\u6a5f\u80fd\u3057\u307e\u3059\u3002 OpenIDE-Module-Name=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 OpenIDE-Module-Short-Description=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u30d5\u30a1\u30a4\u30f3\u30c0\u30fc\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb Progress_Message_Chrome_AutoFill=Chrome\u81ea\u52d5\u5165\u529b\u30d6\u30e9\u30a6\u30b6{0} diff --git a/release_scripts/localization_scripts/lastupdated.properties b/release_scripts/localization_scripts/lastupdated.properties index c31c7c9180..beebdc0034 100644 --- a/release_scripts/localization_scripts/lastupdated.properties +++ b/release_scripts/localization_scripts/lastupdated.properties @@ -1,2 +1,2 @@ -#Fri Feb 12 16:56:29 UTC 2021 -bundles.ja.lastupdated=c2a4ececfba59d230d1a263f7124e67f88e8d3e6 +#Mon Jun 14 12:23:19 UTC 2021 +bundles.ja.lastupdated=0952403cf485350f4db73ab6426ad5d6eb273e31 From ff04e29b425a89bfd880564054b3f4315aaa3898 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 14 Jun 2021 08:25:48 -0400 Subject: [PATCH 56/70] Japanese localization for autopsy 4.19 --- .../autopsy/apputils/Bundle_ja.properties | 4 ++ .../osaccount/Bundle_ja.properties | 21 ++++++++++ .../datamodel/hosts/Bundle_ja.properties | 41 +++++++++++++++++++ .../datamodel/persons/Bundle_ja.properties | 19 +++++++++ .../domaincategorization/Bundle_ja.properties | 35 ++++++++++++++++ .../volatilityDSP/Bundle_ja.properties | 3 ++ 6 files changed, 123 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/apputils/Bundle_ja.properties create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/Bundle_ja.properties create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle_ja.properties create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/persons/Bundle_ja.properties create mode 100644 Core/src/org/sleuthkit/autopsy/url/analytics/domaincategorization/Bundle_ja.properties create mode 100644 Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/Bundle_ja.properties diff --git a/Core/src/org/sleuthkit/autopsy/apputils/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/apputils/Bundle_ja.properties new file mode 100644 index 0000000000..72a20f2a27 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/apputils/Bundle_ja.properties @@ -0,0 +1,4 @@ +#Mon Jun 14 12:23:19 UTC 2021 +CTL_ResetWindowsAction=\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u30ea\u30bb\u30c3\u30c8 +ResetWindowAction.confirm.text=\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u9589\u3058\u3066\u518d\u8d77\u52d5\u3057\u3001\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u4f4d\u7f6e\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u307e\u3059\u3002\n\n\u3059\u3079\u3066\u306e\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u4f4d\u7f6e\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f +ResetWindowAction.confirm.title=\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u30ea\u30bb\u30c3\u30c8 diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/Bundle_ja.properties new file mode 100644 index 0000000000..9b0e640012 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/Bundle_ja.properties @@ -0,0 +1,21 @@ +#Mon Jun 14 12:23:19 UTC 2021 +OsAccountDataPanel_administrator_title=\u7ba1\u7406\u8005 +OsAccountDataPanel_basic_address=\u4f4f\u6240 +OsAccountDataPanel_basic_admin=\u7ba1\u7406\u8005 +OsAccountDataPanel_basic_creationDate=\u4f5c\u6210\u65e5 +OsAccountDataPanel_basic_fullname=\u6c0f\u540d +OsAccountDataPanel_basic_login=\u30ed\u30b0\u30a4\u30f3 +OsAccountDataPanel_basic_title=\u57fa\u672c\u30d7\u30ed\u30d1\u30c6\u30a3 +OsAccountDataPanel_basic_type=\u30bf\u30a4\u30d7 +OsAccountDataPanel_data_accessed_title=\u524d\u56de\u306e\u30ed\u30b0\u30a4\u30f3 +OsAccountDataPanel_host_count_title=\u30ed\u30b0\u30a4\u30f3\u6570 +OsAccountDataPanel_host_section_title={0} \u8a73\u7d30 +OsAccountDataPanel_realm_address=\u4f4f\u6240 +OsAccountDataPanel_realm_confidence=\u4fe1\u983c\u5ea6 +OsAccountDataPanel_realm_name=\u540d\u524d +OsAccountDataPanel_realm_scope=\u30b9\u30b3\u30fc\u30d7 +OsAccountDataPanel_realm_title=\u5206\u91ce\u30d7\u30ed\u30d1\u30c6\u30a3 +OsAccountDataPanel_realm_unknown=\u4e0d\u660e +OsAccountViewer_title=OS\u30a2\u30ab\u30a6\u30f3\u30c8 +OsAccountViewer_tooltip=\u9078\u629e\u3057\u305f\u30ce\u30fc\u30c9\u306b\u95a2\u9023\u3059\u308b\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30d3\u30e5\u30fc\u30a2\u3002 +TableDataPanel.titleLabel.text=\u79f0\u53f7 diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle_ja.properties new file mode 100644 index 0000000000..2798b41330 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle_ja.properties @@ -0,0 +1,41 @@ +#Mon Jun 14 12:23:19 UTC 2021 +AddEditHostDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb +AddEditHostDialog.inputTextField.text=jTextField1 +AddEditHostDialog.nameLabel.text=\u540d\u524d\uff1a +AddEditHostDialog.okButton.text=OK +AddEditHostDialog_addHost_title=\u30db\u30b9\u30c8\u3092\u8ffd\u52a0 +AddEditHostDialog_editHost_title=\u30db\u30b9\u30c8\u306e\u7de8\u96c6 +AssociateNewPersonAction_menuTitle=\u65b0\u3057\u3044\u4eba... +AssociateNewPersonAction_onError_description=\u30db\u30b9\u30c8{0}\u3092\u65b0\u3057\u3044\u4eba{1}\u306b\u95a2\u9023\u4ed8\u3051\u308b\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +AssociateNewPersonAction_onError_title=\u65b0\u3057\u3044\u4eba\u306e\u95a2\u9023\u4ed8\u3051\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f +AssociatePersonAction_onError_description=\u30db\u30b9\u30c8{0}\u3068\u500b\u4eba{1}\u306e\u95a2\u9023\u4ed8\u3051\u3067\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +AssociatePersonAction_onError_title=\u30db\u30b9\u30c8\u3068\u500b\u4eba\u306e\u95a2\u9023\u4ed8\u3051\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f +AssociatePersonAction_unknownPerson=\u5931\u540d\u6c0f +AssociatePersonsMenuAction_menuTitle=\u4eba\u3068\u95a2\u9023\u4ed8\u3051\u308b +CTL_OpenHosts=\u30db\u30b9\u30c8\u306e\u7ba1\u7406 +HostNameValidator_getValidationMessage_onDuplicate=\u5225\u306e\u30db\u30b9\u30c8\u306f\u3059\u3067\u306b\u540c\u3058\u540d\u524d\u3092\u6301\u3063\u3066\u3044\u307e\u3059\u3002 \u5225\u306e\u540d\u524d\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +HostNameValidator_getValidationMessage_onEmpty=\u30db\u30b9\u30c8\u540d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +HostNameValidator_getValidationMessage_sameAsOriginal=\u3053\u306e\u30db\u30b9\u30c8\u306e\u65b0\u3057\u3044\u540d\u524d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +ManageHostsDialog.closeButton.text=\u9589\u3058\u308b +ManageHostsDialog.deleteButton.text=\u524a\u9664 +ManageHostsDialog.editButton.text=\u7de8\u96c6 +ManageHostsDialog.hostDescriptionTextArea.text=\u30db\u30b9\u30c8\u306f\u3001\u8907\u6570\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u6301\u3064\u53ef\u80fd\u6027\u306e\u3042\u308b\u500b\u3005\u306e\u30c7\u30d0\u30a4\u30b9\u3092\u8868\u3057\u307e\u3059\u3002 +ManageHostsDialog.hostDetailsLabel.text=\u30db\u30b9\u30c8\u306e\u8a73\u7d30 +ManageHostsDialog.hostListLabel.text=\u30db\u30b9\u30c8 +ManageHostsDialog.hostNameLabel.text=\u30db\u30b9\u30c8\u540d\uff1a +ManageHostsDialog.newButton.text=\u65b0 +ManageHostsDialog_title_text=\u30db\u30b9\u30c8\u306e\u7ba1\u7406 +MergeHostAction.confirmText={0}\u3092{1}\u306b\u30de\u30fc\u30b8\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f\n\u3053\u308c\u306b\u306fOS\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30de\u30fc\u30b8\u304c\u542b\u307e\u308c\u308b\u5834\u5408\u304c\u3042\u308a\u3001\u5143\u306b\u623b\u3059\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002 +MergeHostAction.confirmTitle=\u78ba\u8a8d +MergeHostAction.errorText=\u30db\u30b9\u30c8\u306e\u30de\u30fc\u30b8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\n\u6570\u5206\u5f8c\u306b\u3082\u3046\u4e00\u5ea6\u8a66\u3059\u304b\u3001\u30ed\u30b0\u3067\u8a73\u7d30\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +MergeHostAction.errorTitle=\u30db\u30b9\u30c8\u306e\u30de\u30fc\u30b8\u30a8\u30e9\u30fc +MergeHostAction.progressIndicatorName=\u30db\u30b9\u30c8\u306e\u30de\u30fc\u30b8 +MergeHostAction.progressText={0}\u3092{1}\u306b\u30de\u30fc\u30b8\u3057\u3066\u3044\u307e\u3059... +MergeHostAction_onError_description=\u30db\u30b9\u30c8{0}\u3092\u30db\u30b9\u30c8{1}\u306b\u30de\u30fc\u30b8\u3059\u308b\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +MergeHostAction_onError_title=\u30db\u30b9\u30c8\u306e\u30de\u30fc\u30b8\u30a8\u30e9\u30fc +MergeHostMenuAction_menuTitle=\u4ed6\u306e\u30db\u30b9\u30c8\u306b\u30de\u30fc\u30b8\u3059\u308b +OpenHostsAction_displayName=\u30db\u30b9\u30c8 +RemoveParentPersonAction_menuTitle=\u4eba\u304b\u3089\u524a\u9664\uff08{0}\uff09 +RemoveParentPersonAction_onError_description=\u30db\u30b9\u30c8\u304b\u3089\u4eba\u3092\u524a\u9664\u3059\u308b\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a{0}\u3002 +RemoveParentPersonAction_onError_title=\u500b\u4eba\u304b\u3089\u30db\u30b9\u30c8\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f +RemoveParentPersonAction_unknownPerson=\u5931\u540d\u6c0f diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/persons/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/datamodel/persons/Bundle_ja.properties new file mode 100644 index 0000000000..5e808b7db7 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/persons/Bundle_ja.properties @@ -0,0 +1,19 @@ +#Mon Jun 14 12:23:19 UTC 2021 +AddEditPersonDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb +AddEditPersonDialog.cancelButton.text_1=\u30ad\u30e3\u30f3\u30bb\u30eb +AddEditPersonDialog.inputTextField.text_1=jTextField1 +AddEditPersonDialog.nameLabel.text=\u540d\u524d\uff1a +AddEditPersonDialog.nameLabel.text_1=\u540d\u524d\uff1a +AddEditPersonDialog.okButton.text=OK +AddEditPersonDialog.okButton.text_1=OK +AddEditPersonDialog_addPerson_title=\u4eba\u3092\u8ffd\u52a0 +AddEditPersonDialog_editPerson_title=\u4eba\u306e\u7de8\u96c6 +DeletePersonAction_menuTitle=\u4eba\u306e\u524a\u9664 +DeletePersonAction_onError_description=\u4eba\u306e\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a{0}\u3002 +DeletePersonAction_onError_title=\u500b\u4eba\u304b\u3089\u30db\u30b9\u30c8\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f +EditPersonAction_menuTitle=\u4eba\u306e\u7de8\u96c6\u3002\u3002\u3002 +EditPersonAction_onError_description=\u4eba\u306e\u7de8\u96c6\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a{0}\u3002 +EditPersonAction_onError_title=\u4eba\u306e\u7de8\u96c6\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f +PersonNameValidator_getValidationMessage_onDuplicate=\u540c\u3058\u540d\u524d\u304c\u65e2\u306b\u5b58\u5728\u3057\u3066\u3044\u307e\u3059\u3002 \u5225\u306e\u540d\u524d\u3092\u9078\u3093\u3067\u304f\u3060\u3055\u3044\u3002 +PersonNameValidator_getValidationMessage_onEmpty=\u540d\u524d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +PersonNameValidator_getValidationMessage_sameAsOriginal=\u3053\u306e\u4eba\u306e\u65b0\u3057\u3044\u540d\u524d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/url/analytics/domaincategorization/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/url/analytics/domaincategorization/Bundle_ja.properties new file mode 100644 index 0000000000..a670858371 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/url/analytics/domaincategorization/Bundle_ja.properties @@ -0,0 +1,35 @@ +#Mon Jun 14 12:23:19 UTC 2021 +AddEditCategoryDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb +AddEditCategoryDialog.categoryLabel.text=\u30ab\u30c6\u30b4\u30ea\u30fc\uff1a +AddEditCategoryDialog.domainSuffixLabel.text=\u30c9\u30e1\u30a4\u30f3\u30fb\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\uff1a +AddEditCategoryDialog.saveButton.text=\u4fdd\u5168 +AddEditCategoryDialog_Add=\u30a8\u30f3\u30c8\u30ea\u3092\u8ffd\u52a0 +AddEditCategoryDialog_Edit=\u30a8\u30f3\u30c8\u30ea\u306e\u7de8\u96c6 +AddEditCategoryDialog_onValueUpdate_badCategory={0}\u6587\u5b57\u4ee5\u4e0b\u306e\u30ab\u30c6\u30b4\u30ea\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +AddEditCategoryDialog_onValueUpdate_badSuffix=1\u3064\u4ee5\u4e0a\u306e\u30d4\u30ea\u30aa\u30c9\u3092\u542b\u3080{0}\u6587\u5b57\u4ee5\u4e0b\u306e\u30c9\u30e1\u30a4\u30f3\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +AddEditCategoryDialog_onValueUpdate_sameCategory=\u3053\u306e\u30c9\u30e1\u30a4\u30f3\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u306e\u65b0\u3057\u3044\u30ab\u30c6\u30b4\u30ea\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +AddEditCategoryDialog_onValueUpdate_suffixRepeat=\u30e6\u30cb\u30fc\u30af\u306e\u30c9\u30e1\u30a4\u30f3\u30fb\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u30fb +WebCategoriesOptionsPanel.categoriesTitle.text=\u30ab\u30c6\u30b4\u30ea\uff1a +WebCategoriesOptionsPanel.deleteEntryButton.text=\u30a8\u30f3\u30c8\u30ea\u3092\u524a\u9664 +WebCategoriesOptionsPanel.editEntryButton.text=\u30a8\u30f3\u30c8\u30ea\u306e\u7de8\u96c6 +WebCategoriesOptionsPanel.exportSetButton.text=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u30fb\u30bb\u30c3\u30c8 +WebCategoriesOptionsPanel.importSetButton.text=\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30bb\u30c3\u30c8 +WebCategoriesOptionsPanel.ingestRunningWarning.text=\u53d6\u8fbc\u307f\u306f\u73fe\u5728\u5b9f\u884c\u4e2d\u3067\u3059\u3002 \u4eca\u306f\u7de8\u96c6\u306f\u3067\u304d\u307e\u305b\u3093\u3002 +WebCategoriesOptionsPanel.newEntryButton.text=\u65b0\u898f\u30a8\u30f3\u30c8\u30ea\u30fc +WebCategoriesOptionsPanel.panelDescription.text=\u3053\u306e\u6a5f\u80fd\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u306e\u53d6\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u3001\u30c9\u30e1\u30a4\u30f3\u306e\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u306b\u57fa\u3065\u3044\u3066Web\u30b5\u30a4\u30c8\u306e\u30ab\u30b9\u30bf\u30e0\u5206\u985e\u3092\u5b9f\u884c\u3067\u304d\u307e\u3059\u3002 +WebCategoriesOptionsPanel_categoryTable_categoryColumnName=\u30ab\u30c6\u30b4\u30ea\uff1a +WebCategoriesOptionsPanel_categoryTable_suffixColumnName=\u30c9\u30e1\u30a4\u30f3\u30fb\u30b5\u30d5\u30a3\u30c3\u30af\u30b9 +WebCategoriesOptionsPanel_exportSetButtonActionPerformed_defaultFileName=\u30ab\u30b9\u30bf\u30e0\u30fb\u30ab\u30c6\u30b4\u30ea\u306e\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 +WebCategoriesOptionsPanel_exportSetButtonActionPerformed_duplicateMessage=\u9078\u629e\u3057\u305f\u30d1\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059\u3002 \u30ab\u30c6\u30b4\u30ea\u306f\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3055\u308c\u307e\u305b\u3093\u3002 +WebCategoriesOptionsPanel_exportSetButtonActionPerformed_duplicateTitle=\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059 +WebCategoriesOptionsPanel_exportSetButtonActionPerformed_errorMessage=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +WebCategoriesOptionsPanel_exportSetButtonActionPerformed_errorTitle=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u30a8\u30e9\u30fc +WebCategoriesOptionsPanel_importSetButtonActionPerformed_errorMessage=json\u30d5\u30a1\u30a4\u30eb\u306e\u30a4\u30f3\u30dd\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +WebCategoriesOptionsPanel_importSetButtonActionPerformed_errorTitle=\u30a4\u30f3\u30dd\u30fc\u30c8\u30a8\u30e9\u30fc +WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictCancel=\u30ad\u30e3\u30f3\u30bb\u30eb +WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictMessage=\u30c9\u30e1\u30a4\u30f3\u30b5\u30d5\u30a3\u30c3\u30af\u30b9{0}\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059\u3002 \u4f55\u3092\u3057\u307e\u3059\u304b\uff1f +WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictOverwrite=\u4e0a\u66f8\u304d\u3059\u308b +WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictSkip=\u7121\u8996 +WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictTitle=\u30c9\u30e1\u30a4\u30f3\u30fb\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059 +WebCategoryOptionsController_keywords=\u30ab\u30b9\u30bf\u30e0Web\u30ab\u30c6\u30b4\u30ea +WebCategoryOptionsController_title=\u30ab\u30b9\u30bf\u30e0Web\u30ab\u30c6\u30b4\u30ea diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/Bundle_ja.properties b/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/Bundle_ja.properties new file mode 100644 index 0000000000..ac4a0e8259 --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/Bundle_ja.properties @@ -0,0 +1,3 @@ +#Mon Jun 14 12:23:19 UTC 2021 +MemoryDSInputPanel.deselectAllButton.text=\u5168\u9078\u629e\u3092\u30af\u30ea\u30a2 +MemoryDSInputPanel.selectAllButton.text=\u3059\u3079\u3066\u9078\u629e From 9609c53e484cb120625d5cda384f27d93d8ac2de Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Mon, 14 Jun 2021 11:14:29 -0400 Subject: [PATCH 57/70] Updated a few more locations that were creating nodes sync --- .../autopsy/commonpropertiessearch/InstanceCountNode.java | 4 ++-- .../autopsy/datasourcesummary/ui/DataSourceSummaryNode.java | 5 ++--- .../autopsy/experimental/autoingest/AinStatusNode.java | 4 ++-- .../autopsy/experimental/autoingest/AutoIngestJobsNode.java | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InstanceCountNode.java b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InstanceCountNode.java index 5be8f8bae2..628bec9291 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InstanceCountNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InstanceCountNode.java @@ -2,7 +2,7 @@ * * Autopsy Forensic Browser * - * Copyright 2018-2019 Basis Technology Corp. + * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -60,7 +60,7 @@ public final class InstanceCountNode extends DisplayableItemNode { "InstanceCountNode.displayName=Exists in %s data sources (%s)" }) public InstanceCountNode(int instanceCount, CommonAttributeValueList attributeValues, CorrelationAttributeInstance.Type type) { - super(Children.create(new CommonAttributeValueNodeFactory(attributeValues.getMetadataList(), type), false)); + super(Children.create(new CommonAttributeValueNodeFactory(attributeValues.getMetadataList(), type), true)); this.type = type; this.instanceCount = instanceCount; this.attributeValues = attributeValues; diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryNode.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryNode.java index a4c48e7adf..4aa3cf1be3 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,7 +30,6 @@ import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.autopsy.directorytree.ViewContextAction; import org.sleuthkit.datamodel.DataSource; @@ -59,7 +58,7 @@ final class DataSourceSummaryNode extends AbstractNode { * DataSources which are this nodes children */ DataSourceSummaryNode(List dataSourceList) { - super(Children.create(new DataSourceSummaryChildren(dataSourceList), false)); + super(Children.create(new DataSourceSummaryChildren(dataSourceList), true)); } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AinStatusNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AinStatusNode.java index 8c7ba7cdd9..9d72539841 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AinStatusNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AinStatusNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2018 Basis Technology Corp. + * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,7 +40,7 @@ final class AinStatusNode extends AbstractNode { * Construct a new AinStatusNode. */ AinStatusNode(AutoIngestMonitor monitor) { - super(Children.create(new AinStatusChildren(monitor), false)); + super(Children.create(new AinStatusChildren(monitor), true)); } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java index ffe8e19f01..3142181117 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2018-2019 Basis Technology Corp. + * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -69,7 +69,7 @@ final class AutoIngestJobsNode extends AbstractNode { * refresh events */ AutoIngestJobsNode(AutoIngestMonitor monitor, AutoIngestJobStatus status, EventBus eventBus) { - super(Children.create(new AutoIngestNodeChildren(monitor, status, eventBus), false)); + super(Children.create(new AutoIngestNodeChildren(monitor, status, eventBus), true)); refreshChildrenEventBus = eventBus; } From 4af1a2f578d99766fa0cf7732331f5f5251e2d39 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Mon, 14 Jun 2021 14:16:37 -0400 Subject: [PATCH 58/70] Updated a few more locations to use weak references --- .../autopsy/datamodel/DataSourcesNode.java | 10 ++++++--- .../autopsy/datamodel/KeywordHits.java | 19 +++++++++------- .../autopsy/datamodel/accounts/Accounts.java | 22 ++++++++++--------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java index c5fae53c03..c2f63d5787 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java @@ -31,6 +31,7 @@ import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; +import org.openide.util.WeakListeners; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -76,15 +77,18 @@ public class DataSourcesNode extends DisplayableItemNode { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); @Override protected void addNotify() { - Case.addEventTypeSubscriber(UPDATE_EVTS, pcl); + Case.addEventTypeSubscriber(UPDATE_EVTS, weakPcl); } @Override - protected void removeNotify() { - Case.removeEventTypeSubscriber(UPDATE_EVTS, pcl); + protected void finalize() throws Throwable{ + Case.removeEventTypeSubscriber(UPDATE_EVTS, weakPcl); + super.finalize(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index 5d8976b77d..4406944fa3 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -42,6 +42,7 @@ import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.Lookup; import org.openide.util.NbBundle; +import org.openide.util.WeakListeners; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -505,22 +506,24 @@ public class KeywordHits implements AutopsyVisitableItem { } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); @Override protected void addNotify() { - 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); + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); keywordResults.update(); super.addNotify(); } @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); - super.removeNotify(); + protected void finalize() throws Throwable{ + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); + super.finalize(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 7b2e1f5147..bf7ee1caba 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -219,8 +219,8 @@ final public class Accounts implements AutopsyVisitableItem { abstract void handleDataAdded(ModuleDataEvent event); @Override - protected void removeNotify() { - super.removeNotify(); + protected void finalize() throws Throwable { + super.finalize(); reviewStatusBus.unregister(ObservingChildren.this); } @@ -416,6 +416,8 @@ final public class Accounts implements AutopsyVisitableItem { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null); @Subscribe @Override @@ -474,18 +476,18 @@ final public class Accounts implements AutopsyVisitableItem { } @Override - protected void removeNotify() { - IngestManager.getInstance().removeIngestJobEventListener(pcl); - IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); - super.removeNotify(); + protected void finalize() throws Throwable { + IngestManager.getInstance().removeIngestJobEventListener(weakPcl); + IngestManager.getInstance().removeIngestModuleEventListener(weakPcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); + super.finalize(); } @Override protected void addNotify() { - 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); + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl); super.addNotify(); refresh(true); } From 637c4571f6bdb097472dfd6f87ee301e8dc5623c Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 14 Jun 2021 14:51:50 -0400 Subject: [PATCH 59/70] bug fix --- .../autopsy/directorytree/ViewContextAction.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index c8f5848243..f3e73f1ff8 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -31,6 +31,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.sleuthkit.autopsy.coreutils.Logger; import javax.swing.AbstractAction; +import org.apache.commons.lang3.StringUtils; import org.openide.nodes.AbstractNode; import org.openide.explorer.ExplorerManager; import org.openide.explorer.view.TreeView; @@ -275,6 +276,11 @@ public class ViewContextAction extends AbstractAction { } } } + + // if no node is found, do nothing + if (parentTreeViewNode == null) { + return; + } /* * Set the child selection info of the parent tree node, then select @@ -377,6 +383,11 @@ public class ViewContextAction extends AbstractAction { Node dummyRootNode = new DirectoryTreeFilterNode(new AbstractNode(new RootContentChildren(contentBranch)), true); Children ancestorChildren = dummyRootNode.getChildren(); + // if content is the data source provided, return that. + if (ancestorChildren.getNodesCount() == 1 && StringUtils.equals(ancestorChildren.getNodeAt(0).getName(), node.getName())) { + return node; + } + /* * Search the tree for the parent node. Note that this algorithm * simply discards "extra" ancestor nodes not shown in the tree, From b437454b34be5653686a4dc83c002eb90c17583f Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Mon, 14 Jun 2021 16:35:34 -0400 Subject: [PATCH 60/70] Removed unused import --- Core/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java index ce8646563c..7b0987f623 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Directory; From 2a64c3029c291409b717c741ac2de1312055eeed Mon Sep 17 00:00:00 2001 From: apriestman Date: Mon, 14 Jun 2021 18:46:38 -0400 Subject: [PATCH 61/70] Restore line fetching new files --- .../modules/embeddedfileextractor/SevenZipExtractor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java index b7a5f6e545..6fa1e93c5a 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java @@ -808,6 +808,9 @@ class SevenZipExtractor { logger.log(Level.SEVERE, "Error populating complete derived file hierarchy from the unpacked dir structure", e); //NON-NLS //TODO decide if anything to cleanup, for now bailing } + + // Get the new files to be added to the case. + unpackedFiles = unpackedTree.getAllFileObjects(); } catch (SevenZipException | IllegalArgumentException ex) { logger.log(Level.WARNING, "Error unpacking file: " + archiveFile, ex); //NON-NLS From 64061c0fe70baa6fbcb5caf137eba59572d53f92 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Tue, 15 Jun 2021 12:11:44 -0400 Subject: [PATCH 62/70] Some HostNodes will be created syncronously --- Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java index 4b11bf6777..1f349fdfc4 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java @@ -222,7 +222,7 @@ public class HostNode extends DisplayableItemNode { * @param hostGrouping The HostGrouping key. */ HostNode(HostGrouping hostGrouping) { - this(Children.create(new HostGroupingChildren(HOST_GROUPING_CONVERTER, hostGrouping.getHost()), true), hostGrouping.getHost()); + this(Children.create(new HostGroupingChildren(HOST_GROUPING_CONVERTER, hostGrouping.getHost()), false), hostGrouping.getHost()); } /** From a42cf4eb638051c06cfd82e7d4b0413c705936b7 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 15 Jun 2021 14:11:58 -0400 Subject: [PATCH 63/70] refactoring --- .../directorytree/ViewContextAction.java | 286 +++++++++--------- 1 file changed, 148 insertions(+), 138 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index f3e73f1ff8..2c07c8f8df 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -169,159 +170,168 @@ public class ViewContextAction extends AbstractAction { public void actionPerformed(ActionEvent event) { EventQueue.invokeLater(() -> { - /* - * Get the parent content for the content to be selected in the - * results view. If the parent content is null, then the specified - * content is a data source, and the parent tree view node is the - * "Data Sources" node. Otherwise, the tree view needs to be - * searched to find the parent treeview node. - */ - Content parentContent = null; - try { - parentContent = content.getParent(); - } catch (TskCoreException ex) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory()); - logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS - return; - } + Content parentContent = getParentContent(this.content); - if ((parentContent != null) - && (parentContent instanceof UnsupportedContent)) { + if ((parentContent != null) && (parentContent instanceof UnsupportedContent)) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_unsupportedParent()); logger.log(Level.WARNING, String.format("Could not navigate to unsupported content with id: %d", parentContent.getId())); //NON-NLS - return; } - - /* - * Get the "Data Sources" node from the tree view. - */ + + // Get the "Data Sources" node from the tree view. DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance(); ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager(); + Node parentTreeViewNode = null; - if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { // 'Group by Data Source' view - - SleuthkitCase skCase; - String dsname; - try { - // get the objid/name of the datasource of the selected content. - skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - long contentDSObjid = content.getDataSource().getId(); - DataSource datasource = skCase.getDataSource(contentDSObjid); - dsname = datasource.getName(); - Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren(); - - if (null != parentContent) { - // the tree view needs to be searched to find the parent treeview node. - /* NOTE: we can't do a lookup by data source name here, becase if there - are multiple data sources with the same name, then "getChildren().findChild(dsname)" - simply returns the first one that it finds. Instead we have to loop over all - data sources with that name, and make sure we find the correct one. - */ - List dataSourceLevelNodes = Stream.of(rootChildren.getNodes()) - .flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream()) - .collect(Collectors.toList()); - - for (Node treeNode : dataSourceLevelNodes) { - // in the root, look for a data source node with the name of interest - if (!(treeNode.getName().equals(dsname))) { - continue; - } - - // for this data source, get the "Data Sources" child node - Node datasourceGroupingNode = treeNode.getChildren().findChild(DataSourceFilesNode.getNameIdentifier()); - - // check whether this is the data source we are looking for - parentTreeViewNode = findParentNodeInTree(parentContent, datasourceGroupingNode); - if (parentTreeViewNode != null) { - // found the data source node - break; - } - } - } else { - /* If the parent content is null, then the specified - * content is a data source, and the parent tree view node is the - * "Data Sources" node. */ - Node datasourceGroupingNode = rootChildren.findChild(dsname); - if (!Objects.isNull(datasourceGroupingNode)) { - Children dsChildren = datasourceGroupingNode.getChildren(); - parentTreeViewNode = dsChildren.findChild(DataSourceFilesNode.getNameIdentifier()); - } - } - - if (parentTreeViewNode == null) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); - logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS - return; - } - } catch (NoCurrentCaseException | TskDataException | TskCoreException ex) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); - logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS - return; - } - } else { // Classic view - // Start the search at the DataSourcesNode - Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren(); - Node rootDsNode = rootChildren == null ? null : rootChildren.findChild(DataSourcesNode.getNameIdentifier()); - if (rootDsNode != null) { - for (Node dataSourceLevelNode : getDataSourceLevelNodes(rootDsNode)) { - DataSource dataSource = dataSourceLevelNode.getLookup().lookup(DataSource.class); - if (dataSource != null) { - // the tree view needs to be searched to find the parent treeview node. - Node potentialParentTreeViewNode = findParentNodeInTree(parentContent, dataSourceLevelNode); - if (potentialParentTreeViewNode != null) { - parentTreeViewNode = potentialParentTreeViewNode; - break; - } - } - } - } + if (parentContent != null) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { + parentTreeViewNode = getParentNodeGroupedByPersonHost(treeViewExplorerMgr, parentContent); + } else { + parentTreeViewNode = getParentNodeGroupedByDataSource(treeViewExplorerMgr, parentContent); + } } - // if no node is found, do nothing + // if no node is found, report error and do nothing if (parentTreeViewNode == null) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); + logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS return; } - /* - * Set the child selection info of the parent tree node, then select - * the parent node in the tree view. The results view will retrieve - * this selection info and use it to complete this action when the - * tree view top component responds to the selection of the parent - * node by pushing it into the results view top component. - */ - DisplayableItemNode undecoratedParentNode = (DisplayableItemNode) ((DirectoryTreeFilterNode) parentTreeViewNode).getOriginal(); - undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content)); - if (content instanceof BlackboardArtifact) { - BlackboardArtifact artifact = ((BlackboardArtifact) content); - long associatedId = artifact.getObjectID(); - try { - Content associatedFileContent = artifact.getSleuthkitCase().getContentById(associatedId); - undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(associatedFileContent)); - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Could not find associated content from artifact with id %d", artifact.getId()); - } - } - - TreeView treeView = treeViewTopComponent.getTree(); - treeView.expandNode(parentTreeViewNode); - if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) { - //In the case where our tree view already has the destination directory selected - //due to an optimization in the ExplorerManager.setExploredContextAndSelection method - //the property change we listen for to call DirectoryTreeTopComponent.respondSelection - //will not be sent so we call it manually ourselves after making - //the directory listing the active tab. - treeViewTopComponent.setDirectoryListingActive(); - treeViewTopComponent.respondSelection(treeViewExplorerMgr.getSelectedNodes(), new Node[]{parentTreeViewNode}); - } else { - try { - treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode}); - } catch (PropertyVetoException ex) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory()); - logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS - } - } + setNodeSelection(this.content, parentTreeViewNode, treeViewTopComponent, treeViewExplorerMgr); }); } + + private Content getParentContent(Content content) { + /* + * Get the parent content for the content to be selected in the + * results view. If the parent content is null, then the specified + * content is a data source, and the parent tree view node is the + * "Data Sources" node. Otherwise, the tree view needs to be + * searched to find the parent treeview node. + */ + try { + Content parent = content.getParent(); + if (parent == null && content instanceof DataSource) { + parent = content; + } + return parent; + } catch (TskCoreException ex) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory()); + logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS + return null; + } + } + + + private Node getParentNodeGroupedByDataSource(ExplorerManager treeViewExplorerMgr, Content parentContent) { + // Classic view + // Start the search at the DataSourcesNode + Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren(); + Node rootDsNode = rootChildren == null ? null : rootChildren.findChild(DataSourcesNode.getNameIdentifier()); + if (rootDsNode != null) { + for (Node dataSourceLevelNode : getDataSourceLevelNodes(rootDsNode)) { + DataSource dataSource = dataSourceLevelNode.getLookup().lookup(DataSource.class); + if (dataSource != null) { + // the tree view needs to be searched to find the parent treeview node. + Node potentialParentTreeViewNode = findParentNodeInTree(parentContent, dataSourceLevelNode); + if (potentialParentTreeViewNode != null) { + return potentialParentTreeViewNode; + } + } + } + } + + return null; + } + + private Node getParentNodeGroupedByPersonHost(ExplorerManager treeViewExplorerMgr, Content parentContent) { + // 'Group by Data Source' view + + SleuthkitCase skCase; + String dsname; + try { + // get the objid/name of the datasource of the selected content. + skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + long contentDSObjid = parentContent.getDataSource().getId(); + DataSource datasource = skCase.getDataSource(contentDSObjid); + dsname = datasource.getName(); + Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren(); + + // the tree view needs to be searched to find the parent treeview node. + /* NOTE: we can't do a lookup by data source name here, becase if there + are multiple data sources with the same name, then "getChildren().findChild(dsname)" + simply returns the first one that it finds. Instead we have to loop over all + data sources with that name, and make sure we find the correct one. + */ + List dataSourceLevelNodes = Stream.of(rootChildren.getNodes()) + .flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream()) + .collect(Collectors.toList()); + + for (Node treeNode : dataSourceLevelNodes) { + // in the root, look for a data source node with the name of interest + if (!(treeNode.getName().equals(dsname))) { + continue; + } + + // for this data source, get the "Data Sources" child node + Node datasourceGroupingNode = treeNode.getChildren().findChild(DataSourceFilesNode.getNameIdentifier()); + + // check whether this is the data source we are looking for + Node parentTreeViewNode = findParentNodeInTree(parentContent, datasourceGroupingNode); + if (parentTreeViewNode != null) { + // found the data source node + return parentTreeViewNode; + } + } + } catch (NoCurrentCaseException | TskDataException | TskCoreException ex) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); + logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS + } + + return null; + } + + + private void setNodeSelection(Content content, Node parentTreeViewNode, DirectoryTreeTopComponent treeViewTopComponent, ExplorerManager treeViewExplorerMgr) { + /* + * Set the child selection info of the parent tree node, then select + * the parent node in the tree view. The results view will retrieve + * this selection info and use it to complete this action when the + * tree view top component responds to the selection of the parent + * node by pushing it into the results view top component. + */ + DisplayableItemNode undecoratedParentNode = (DisplayableItemNode) ((DirectoryTreeFilterNode) parentTreeViewNode).getOriginal(); + undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content)); + if (content instanceof BlackboardArtifact) { + BlackboardArtifact artifact = ((BlackboardArtifact) content); + long associatedId = artifact.getObjectID(); + try { + Content associatedFileContent = artifact.getSleuthkitCase().getContentById(associatedId); + undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(associatedFileContent)); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Could not find associated content from artifact with id %d", artifact.getId()); + } + } + + TreeView treeView = treeViewTopComponent.getTree(); + treeView.expandNode(parentTreeViewNode); + if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) { + //In the case where our tree view already has the destination directory selected + //due to an optimization in the ExplorerManager.setExploredContextAndSelection method + //the property change we listen for to call DirectoryTreeTopComponent.respondSelection + //will not be sent so we call it manually ourselves after making + //the directory listing the active tab. + treeViewTopComponent.setDirectoryListingActive(); + treeViewTopComponent.respondSelection(treeViewExplorerMgr.getSelectedNodes(), new Node[]{parentTreeViewNode}); + } else { + try { + treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode}); + } catch (PropertyVetoException ex) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory()); + logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS + } + } + } /** * If the node has lookup of host or person, returns children. If not, just From 7f2ffe526a4eb518d22df554a3df8d32bc5314ac Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 15 Jun 2021 14:25:24 -0400 Subject: [PATCH 64/70] no person hosts fix --- .../sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java index 282ed83418..775afec6a4 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyTreeChildFactory.java @@ -128,7 +128,7 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable Date: Tue, 15 Jun 2021 15:01:27 -0400 Subject: [PATCH 65/70] commenting --- .../directorytree/ViewContextAction.java | 121 +++++++++++------- 1 file changed, 77 insertions(+), 44 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index 2c07c8f8df..7dcbcf85de 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -26,7 +26,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -86,7 +85,7 @@ public class ViewContextAction extends AbstractAction { * parent of the content, selecting the parent in the tree view, then * selecting the content in the results view. * - * @param displayName The display name for the action. + * @param displayName The display name for the action. * @param artifactNode The artifact node for the artifact. */ public ViewContextAction(String displayName, BlackboardArtifactNode artifactNode) { @@ -108,9 +107,9 @@ public class ViewContextAction extends AbstractAction { * parent of the content, selecting the parent in the tree view, then * selecting the content in the results view. * - * @param displayName The display name for the action. + * @param displayName The display name for the action. * @param fileSystemContentNode The file system content node for the - * content. + * content. */ public ViewContextAction(String displayName, AbstractFsContentNode fileSystemContentNode) { super(displayName); @@ -123,9 +122,9 @@ public class ViewContextAction extends AbstractAction { * content, selecting the parent in the tree view, then selecting the * content in the results view. * - * @param displayName The display name for the action. + * @param displayName The display name for the action. * @param abstractAbstractFileNode The AbstractAbstractFileNode node for the - * content. + * content. */ public ViewContextAction(String displayName, AbstractAbstractFileNode abstractAbstractFileNode) { super(displayName); @@ -139,7 +138,7 @@ public class ViewContextAction extends AbstractAction { * content in the results view. * * @param displayName The display name for the action. - * @param content The content. + * @param content The content. */ public ViewContextAction(String displayName, Content content) { super(displayName); @@ -151,7 +150,7 @@ public class ViewContextAction extends AbstractAction { * branch of the tree view to the level of the parent of the content, * selecting the parent in the tree view, then selecting the content in the * results view. - * + * * NOTE: This code will likely need updating in the event that the structure * of the nodes is changed (i.e. adding parent levels). Places to look when * changing node structure include: @@ -171,25 +170,25 @@ public class ViewContextAction extends AbstractAction { EventQueue.invokeLater(() -> { Content parentContent = getParentContent(this.content); - + if ((parentContent != null) && (parentContent instanceof UnsupportedContent)) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_unsupportedParent()); logger.log(Level.WARNING, String.format("Could not navigate to unsupported content with id: %d", parentContent.getId())); //NON-NLS } - + // Get the "Data Sources" node from the tree view. DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance(); ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager(); - + Node parentTreeViewNode = null; if (parentContent != null) { - if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { + if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { parentTreeViewNode = getParentNodeGroupedByPersonHost(treeViewExplorerMgr, parentContent); - } else { + } else { parentTreeViewNode = getParentNodeGroupedByDataSource(treeViewExplorerMgr, parentContent); - } + } } - + // if no node is found, report error and do nothing if (parentTreeViewNode == null) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); @@ -200,29 +199,44 @@ public class ViewContextAction extends AbstractAction { setNodeSelection(this.content, parentTreeViewNode, treeViewTopComponent, treeViewExplorerMgr); }); } - + + /** + * Get the parent content for the content to be selected in the results + * view. If the parent content is null, then the specified content is a data + * source, and the parent tree view node is the "Data Sources" node. + * Otherwise, the tree view needs to be searched to find the parent treeview + * node. + * + * @param content The content whose parent will be returned. If this item is + * a datasource, it will be returned. + * + * @return The content if content is a data source or the parent of this + * content. + */ private Content getParentContent(Content content) { - /* - * Get the parent content for the content to be selected in the - * results view. If the parent content is null, then the specified - * content is a data source, and the parent tree view node is the - * "Data Sources" node. Otherwise, the tree view needs to be - * searched to find the parent treeview node. - */ + try { - Content parent = content.getParent(); - if (parent == null && content instanceof DataSource) { - parent = content; - } - return parent; + return (content instanceof DataSource) + ? content + : content.getParent(); } catch (TskCoreException ex) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory()); logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS return null; } } - + /** + * Returns the node in the tree related to the parentContent or null if + * can't be found. This method should be used when view is grouped by data + * source. + * + * @param treeViewExplorerMgr The explorer manager. + * @param parentContent The content whose equivalent node will be + * returned if found. + * + * @return The node if found or null. + */ private Node getParentNodeGroupedByDataSource(ExplorerManager treeViewExplorerMgr, Content parentContent) { // Classic view // Start the search at the DataSourcesNode @@ -240,13 +254,24 @@ public class ViewContextAction extends AbstractAction { } } } - + return null; } + /** + * Returns the node in the tree related to the parentContent or null if + * can't be found. This method should be used when view is grouped by + * hosts/persons. + * + * @param treeViewExplorerMgr The explorer manager. + * @param parentContent The content whose equivalent node will be + * returned if found. + * + * @return The node if found or null. + */ private Node getParentNodeGroupedByPersonHost(ExplorerManager treeViewExplorerMgr, Content parentContent) { // 'Group by Data Source' view - + SleuthkitCase skCase; String dsname; try { @@ -262,7 +287,7 @@ public class ViewContextAction extends AbstractAction { are multiple data sources with the same name, then "getChildren().findChild(dsname)" simply returns the first one that it finds. Instead we have to loop over all data sources with that name, and make sure we find the correct one. - */ + */ List dataSourceLevelNodes = Stream.of(rootChildren.getNodes()) .flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream()) .collect(Collectors.toList()); @@ -282,16 +307,22 @@ public class ViewContextAction extends AbstractAction { // found the data source node return parentTreeViewNode; } - } + } } catch (NoCurrentCaseException | TskDataException | TskCoreException ex) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS } - + return null; } - - + + /** + * Set the node selection in the tree. + * @param content The content to select. + * @param parentTreeViewNode The node that is the parent of the content. + * @param treeViewTopComponent The DirectoryTreeTopComponent. + * @param treeViewExplorerMgr The ExplorerManager. + */ private void setNodeSelection(Content content, Node parentTreeViewNode, DirectoryTreeTopComponent treeViewTopComponent, ExplorerManager treeViewExplorerMgr) { /* * Set the child selection info of the parent tree node, then select @@ -299,7 +330,7 @@ public class ViewContextAction extends AbstractAction { * this selection info and use it to complete this action when the * tree view top component responds to the selection of the parent * node by pushing it into the results view top component. - */ + */ DisplayableItemNode undecoratedParentNode = (DisplayableItemNode) ((DirectoryTreeFilterNode) parentTreeViewNode).getOriginal(); undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content)); if (content instanceof BlackboardArtifact) { @@ -312,7 +343,7 @@ public class ViewContextAction extends AbstractAction { logger.log(Level.SEVERE, "Could not find associated content from artifact with id %d", artifact.getId()); } } - + TreeView treeView = treeViewTopComponent.getTree(); treeView.expandNode(parentTreeViewNode); if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) { @@ -338,15 +369,16 @@ public class ViewContextAction extends AbstractAction { * returns itself. * * @param node The node. + * * @return The child nodes that are at the data source level. */ private List getDataSourceLevelNodes(Node node) { if (node == null) { return Collections.emptyList(); - } else if (node.getLookup().lookup(Host.class) != null || - node.getLookup().lookup(Person.class) != null || - DataSourcesNode.getNameIdentifier().equals(node.getLookup().lookup(String.class)) || - PersonNode.getUnknownPersonId().equals(node.getLookup().lookup(String.class))) { + } else if (node.getLookup().lookup(Host.class) != null + || node.getLookup().lookup(Person.class) != null + || DataSourcesNode.getNameIdentifier().equals(node.getLookup().lookup(String.class)) + || PersonNode.getUnknownPersonId().equals(node.getLookup().lookup(String.class))) { Children children = node.getChildren(); Node[] childNodes = children == null ? null : children.getNodes(); if (childNodes == null) { @@ -366,7 +398,8 @@ public class ViewContextAction extends AbstractAction { * of the specified content. * * @param parentContent parent content for the content to be searched for - * @param node Node tree to search + * @param node Node tree to search + * * @return Node object of the matching parent, NULL if not found */ private Node findParentNodeInTree(Content parentContent, Node node) { @@ -397,7 +430,7 @@ public class ViewContextAction extends AbstractAction { if (ancestorChildren.getNodesCount() == 1 && StringUtils.equals(ancestorChildren.getNodeAt(0).getName(), node.getName())) { return node; } - + /* * Search the tree for the parent node. Note that this algorithm * simply discards "extra" ancestor nodes not shown in the tree, From 976180eb11561edcf91cf6a12f5aaea20e1406e6 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 15 Jun 2021 18:52:45 -0400 Subject: [PATCH 66/70] load optimal --- .../autopsy/directorytree/ViewContextAction.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index 7dcbcf85de..f3f2dc0419 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -288,7 +288,7 @@ public class ViewContextAction extends AbstractAction { simply returns the first one that it finds. Instead we have to loop over all data sources with that name, and make sure we find the correct one. */ - List dataSourceLevelNodes = Stream.of(rootChildren.getNodes()) + List dataSourceLevelNodes = Stream.of(rootChildren.getNodes(true)) .flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream()) .collect(Collectors.toList()); @@ -380,12 +380,12 @@ public class ViewContextAction extends AbstractAction { || DataSourcesNode.getNameIdentifier().equals(node.getLookup().lookup(String.class)) || PersonNode.getUnknownPersonId().equals(node.getLookup().lookup(String.class))) { Children children = node.getChildren(); - Node[] childNodes = children == null ? null : children.getNodes(); + Node[] childNodes = children == null ? null : children.getNodes(true); if (childNodes == null) { return Collections.emptyList(); } - return Stream.of(node.getChildren().getNodes()) + return Stream.of(node.getChildren().getNodes(true)) .flatMap(parent -> getDataSourceLevelNodes(parent).stream()) .collect(Collectors.toList()); } else { @@ -441,8 +441,9 @@ public class ViewContextAction extends AbstractAction { Node parentTreeViewNode = null; for (int i = 0; i < ancestorChildren.getNodesCount(); i++) { Node ancestorNode = ancestorChildren.getNodeAt(i); - for (int j = 0; j < treeNodeChildren.getNodesCount(); j++) { - Node treeNode = treeNodeChildren.getNodeAt(j); + Node[] treeNodeChilds = treeNodeChildren.getNodes(true); + for (int j = 0; j < treeNodeChilds.length; j++) { + Node treeNode = treeNodeChilds[j]; if (ancestorNode.getName().equals(treeNode.getName())) { parentTreeViewNode = treeNode; treeNodeChildren = treeNode.getChildren(); From 61f6a436de5aae9baa14d3e223bd193917b5b41a Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 16 Jun 2021 10:09:05 -0400 Subject: [PATCH 67/70] 7639 add cancelation to ingest jobs panel --- .../autopsy/casemodule/IngestJobInfoPanel.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java index 6e1df2b8c0..d57df36767 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java @@ -59,6 +59,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null); private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); private DataSource selectedDataSource; + private static SwingWorker refreshWorker = null; /** * Creates new form IngestJobInfoPanel @@ -135,7 +136,10 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { * Get the updated complete list of ingest jobs. */ private void refresh() { - new SwingWorker() { + if (refreshWorker != null && !refreshWorker.isDone()){ + refreshWorker.cancel(true); + } + refreshWorker = new SwingWorker() { @Override protected Boolean doInBackground() throws Exception { @@ -165,7 +169,8 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { logger.log(Level.WARNING, "Error getting results from Ingest Job Info Panel's refresh worker", ex); } } - }.execute(); + }; + refreshWorker.execute(); } /** @@ -174,6 +179,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { private void reset() { this.ingestJobs = new ArrayList<>(); setDataSource(null); + refreshWorker.cancel(true); } @Messages({"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time", From 5f3a9ff04a0ee9f06940802c18e0ff8bcc2e1c17 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 16 Jun 2021 10:47:21 -0400 Subject: [PATCH 68/70] early return --- .../org/sleuthkit/autopsy/directorytree/ViewContextAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index f3f2dc0419..323b340c7f 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -174,6 +174,7 @@ public class ViewContextAction extends AbstractAction { if ((parentContent != null) && (parentContent instanceof UnsupportedContent)) { MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_unsupportedParent()); logger.log(Level.WARNING, String.format("Could not navigate to unsupported content with id: %d", parentContent.getId())); //NON-NLS + return; } // Get the "Data Sources" node from the tree view. From e74def1be1b1f1eba6c02695d74f0ec74b217d6b Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 16 Jun 2021 10:53:50 -0400 Subject: [PATCH 69/70] 7639 - add null check --- .../sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java index d57df36767..016027263a 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java @@ -59,7 +59,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null); private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); private DataSource selectedDataSource; - private static SwingWorker refreshWorker = null; + private static SwingWorker refreshWorker = null; /** * Creates new form IngestJobInfoPanel @@ -136,7 +136,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { * Get the updated complete list of ingest jobs. */ private void refresh() { - if (refreshWorker != null && !refreshWorker.isDone()){ + if (refreshWorker != null && !refreshWorker.isDone()) { refreshWorker.cancel(true); } refreshWorker = new SwingWorker() { @@ -179,7 +179,9 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { private void reset() { this.ingestJobs = new ArrayList<>(); setDataSource(null); - refreshWorker.cancel(true); + if (refreshWorker != null) { + refreshWorker.cancel(true); + } } @Messages({"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time", From f122de443d98e832d775e748b146a8d3fbf90475 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 16 Jun 2021 11:19:50 -0400 Subject: [PATCH 70/70] 7639 re-order reset action to cancel before clearing --- .../sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java index 016027263a..5161a544ca 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java @@ -53,7 +53,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED); private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE); private static final int EXTRA_ROW_HEIGHT = 4; - private List ingestJobs = new ArrayList<>(); + private final List ingestJobs = new ArrayList<>(); private final List ingestJobsForSelectedDataSource = new ArrayList<>(); private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel(); private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null); @@ -177,11 +177,11 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { * Reset the panel. */ private void reset() { - this.ingestJobs = new ArrayList<>(); - setDataSource(null); if (refreshWorker != null) { refreshWorker.cancel(true); } + this.ingestJobs.clear(); + setDataSource(null); } @Messages({"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time",