mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge branch 'develop' of github.com:sleuthkit/autopsy into 7696-viewContextFix
This commit is contained in:
commit
b67fc4f95a
@ -130,8 +130,7 @@ public class FileManager implements Closeable {
|
|||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
public List<AbstractFile> findFilesExactName(long parentId, String name) throws TskCoreException{
|
public List<AbstractFile> findFilesExactName(long parentId, String name) throws TskCoreException{
|
||||||
String whereClause = "name = '%s'";
|
return caseDb.getFileManager().findFilesExactName(parentId, name);
|
||||||
return caseDb.findAllFilesInFolderWhere(parentId, String.format(whereClause, name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2018-2019 Basis Technology Corp.
|
* Copyright 2018-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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)"
|
"InstanceCountNode.displayName=Exists in %s data sources (%s)"
|
||||||
})
|
})
|
||||||
public InstanceCountNode(int instanceCount, CommonAttributeValueList attributeValues, CorrelationAttributeInstance.Type type) {
|
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.type = type;
|
||||||
this.instanceCount = instanceCount;
|
this.instanceCount = instanceCount;
|
||||||
this.attributeValues = attributeValues;
|
this.attributeValues = attributeValues;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2018-2020 Basis Technology Corp.
|
* Copyright 2018-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -21,10 +21,7 @@ package org.sleuthkit.autopsy.contentviewers;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
import javax.swing.text.EditorKit;
|
|
||||||
import javax.swing.text.html.HTMLEditorKit;
|
|
||||||
|
|
||||||
import static org.openide.util.NbBundle.Messages;
|
import static org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
@ -36,6 +33,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
import org.sleuthkit.autopsy.contentviewers.application.Annotations;
|
import org.sleuthkit.autopsy.contentviewers.application.Annotations;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotations view of file contents.
|
* Annotations view of file contents.
|
||||||
@ -48,33 +46,6 @@ import org.jsoup.nodes.Document;
|
|||||||
"AnnotationsContentViewer.onEmpty=No annotations were found for this particular item."
|
"AnnotationsContentViewer.onEmpty=No annotations were found for this particular item."
|
||||||
})
|
})
|
||||||
public class AnnotationsContentViewer extends javax.swing.JPanel implements DataContentViewer {
|
public class AnnotationsContentViewer extends javax.swing.JPanel implements DataContentViewer {
|
||||||
|
|
||||||
private static final int DEFAULT_FONT_SIZE = new JLabel().getFont().getSize();
|
|
||||||
|
|
||||||
// how big the subheader should be
|
|
||||||
private static final int SUBHEADER_FONT_SIZE = DEFAULT_FONT_SIZE * 12 / 11;
|
|
||||||
|
|
||||||
// how big the header should be
|
|
||||||
private static final int HEADER_FONT_SIZE = DEFAULT_FONT_SIZE * 14 / 11;
|
|
||||||
|
|
||||||
// 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-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 { 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 long serialVersionUID = 1L;
|
||||||
private static final Logger logger = Logger.getLogger(AnnotationsContentViewer.class.getName());
|
private static final Logger logger = Logger.getLogger(AnnotationsContentViewer.class.getName());
|
||||||
@ -86,13 +57,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
|||||||
*/
|
*/
|
||||||
public AnnotationsContentViewer() {
|
public AnnotationsContentViewer() {
|
||||||
initComponents();
|
initComponents();
|
||||||
Utilities.configureTextPaneAsHtml(textPanel);
|
ContentViewerHtmlStyles.setupHtmlJTextPane(textPanel);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -223,7 +188,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
|||||||
if(doc != null) {
|
if(doc != null) {
|
||||||
return doc.html();
|
return doc.html();
|
||||||
} else {
|
} else {
|
||||||
return Bundle.AnnotationsContentViewer_onEmpty();
|
return "<span class='" + ContentViewerHtmlStyles.getMessageClassName() + "'>" + Bundle.AnnotationsContentViewer_onEmpty() + "</span>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +200,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
String text = get();
|
String text = get();
|
||||||
|
ContentViewerHtmlStyles.setStyles(textPanel);
|
||||||
textPanel.setText(text);
|
textPanel.setText(text);
|
||||||
textPanel.setCaretPosition(0);
|
textPanel.setCaretPosition(0);
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
|
@ -41,8 +41,6 @@
|
|||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
|
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="horizontalScrollBarPolicy" type="int" value="32"/>
|
|
||||||
<Property name="verticalScrollBarPolicy" type="int" value="22"/>
|
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[610, 52]"/>
|
<Dimension value="[610, 52]"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
@ -20,16 +20,22 @@ package org.sleuthkit.autopsy.contentviewers;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
@ -63,6 +69,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
public Metadata() {
|
public Metadata() {
|
||||||
initComponents();
|
initComponents();
|
||||||
customizeComponents();
|
customizeComponents();
|
||||||
|
ContentViewerHtmlStyles.setupHtmlJTextPane(jTextPane1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,8 +87,6 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
|
|
||||||
setPreferredSize(new java.awt.Dimension(100, 52));
|
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));
|
jScrollPane2.setPreferredSize(new java.awt.Dimension(610, 52));
|
||||||
|
|
||||||
jTextPane1.setEditable(false);
|
jTextPane1.setEditable(false);
|
||||||
@ -116,30 +121,59 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
* selectAllMenuItem.addActionListener(actList);
|
* selectAllMenuItem.addActionListener(actList);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Utilities.configureTextPaneAsHtml(jTextPane1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setText(String str) {
|
private void setText(String str) {
|
||||||
jTextPane1.setText("<html><body>" + str + "</body></html>"); //NON-NLS
|
ContentViewerHtmlStyles.setupHtmlJTextPane(jTextPane1);
|
||||||
|
jTextPane1.setText("<html><head></head><body>" + str + "</body></html>"); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHeader(StringBuilder sb, String header, boolean spaced) {
|
||||||
|
sb.append(MessageFormat.format("<div class=\"{0}\"><h1 class=\"{1}\">{2}</h1></div>",
|
||||||
|
(spaced) ? ContentViewerHtmlStyles.getSpacedSectionClassName() : "",
|
||||||
|
ContentViewerHtmlStyles.getHeaderClassName(),
|
||||||
|
header));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startTable(StringBuilder sb) {
|
private void startTable(StringBuilder sb) {
|
||||||
sb.append("<table>"); //NON-NLS
|
sb.append(MessageFormat.format("<table class=\"{0}\"><tbody>",
|
||||||
|
ContentViewerHtmlStyles.getIndentedClassName())); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
private void endTable(StringBuilder sb) {
|
private void endTable(StringBuilder sb) {
|
||||||
sb.append("</table>"); //NON-NLS
|
sb.append("</tbody></table>"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRow(StringBuilder sb, String key, String value) {
|
private void addRow(StringBuilder sb, String key, String value) {
|
||||||
sb.append("<tr><td valign=\"top\">"); //NON-NLS
|
sb.append(MessageFormat.format("<tr><td class=\"{0}\"><span class=\"{1}\">{2}:</span></td><td class=\"{3}\">{4}</td></tr>",
|
||||||
sb.append(key);
|
ContentViewerHtmlStyles.getKeyColumnClassName(),
|
||||||
sb.append("</td><td>"); //NON-NLS
|
ContentViewerHtmlStyles.getTextClassName(),
|
||||||
sb.append(value);
|
EscapeUtil.escapeHtml(key),
|
||||||
sb.append("</td></tr>"); //NON-NLS
|
ContentViewerHtmlStyles.getTextClassName(),
|
||||||
|
EscapeUtil.escapeHtml(key)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMonospacedRow(StringBuilder sb, String key) {
|
||||||
|
sb.append(MessageFormat.format("<tr><td class=\"{0}\"><span class=\"{1}\">{2}</span></td></tr>",
|
||||||
|
ContentViewerHtmlStyles.getKeyColumnClassName(),
|
||||||
|
ContentViewerHtmlStyles.getMonospacedClassName(),
|
||||||
|
EscapeUtil.escapeHtml(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, "", EscapeUtil.escapeHtml(line)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Messages({
|
@Messages({
|
||||||
|
"Metadata.headerTitle=Metadata",
|
||||||
"Metadata.tableRowTitle.mimeType=MIME Type",
|
"Metadata.tableRowTitle.mimeType=MIME Type",
|
||||||
"Metadata.nodeText.truncated=(results truncated)",
|
"Metadata.nodeText.truncated=(results truncated)",
|
||||||
"Metadata.tableRowTitle.sha1=SHA1",
|
"Metadata.tableRowTitle.sha1=SHA1",
|
||||||
@ -219,8 +253,11 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
if (StringUtils.isEmpty(details)) {
|
if (StringUtils.isEmpty(details)) {
|
||||||
details = Bundle.Metadata_nodeText_unknown();
|
details = Bundle.Metadata_nodeText_unknown();
|
||||||
}
|
}
|
||||||
details = details.replaceAll("\n", "<br>");
|
String[] lines = (details != null) ? details.split("\n") : new String[]{""};
|
||||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.acquisitionDetails"), details);
|
addRowWithMultipleValues(sb,
|
||||||
|
NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.acquisitionDetails"),
|
||||||
|
lines);
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error reading acquisition details from case database", ex); //NON-NLS
|
LOGGER.log(Level.SEVERE, "Error reading acquisition details from case database", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
@ -240,11 +277,9 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
if (node != null && !node.getLookup().lookupAll(DataArtifact.class).isEmpty()) {
|
if (node != null && !node.getLookup().lookupAll(DataArtifact.class).isEmpty()) {
|
||||||
return Bundle.Metadata_dataArtifactTitle();
|
return Bundle.Metadata_dataArtifactTitle();
|
||||||
} else {
|
} else {
|
||||||
return NbBundle.getMessage(this.getClass(), "Metadata.title");
|
return NbBundle.getMessage(this.getClass(), "Metadata.title");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getToolTip() {
|
public String getToolTip() {
|
||||||
@ -299,6 +334,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
addHeader(sb, Bundle.Metadata_headerTitle(), false);
|
||||||
startTable(sb);
|
startTable(sb);
|
||||||
|
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
@ -357,30 +393,35 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
* If we have a file system file, grab the more detailed
|
* If we have a file system file, grab the more detailed
|
||||||
* metadata text too
|
* metadata text too
|
||||||
*/
|
*/
|
||||||
try {
|
if (file instanceof FsContent) {
|
||||||
if (file instanceof FsContent) {
|
FsContent fsFile = (FsContent) file;
|
||||||
FsContent fsFile = (FsContent) file;
|
|
||||||
|
|
||||||
sb.append("<hr /><pre>\n"); //NON-NLS
|
addHeader(sb, NbBundle.getMessage(this.getClass(), "Metadata.nodeText.text"), true);
|
||||||
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.text"));
|
startTable(sb);
|
||||||
sb.append(" <br /><br />"); // NON-NLS
|
|
||||||
for (String str : fsFile.getMetaDataText()) {
|
|
||||||
sb.append(str).append("<br />"); //NON-NLS
|
|
||||||
|
|
||||||
/*
|
List<String> 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) {
|
||||||
|
addMonospacedRow(sb, str);
|
||||||
|
|
||||||
|
/*
|
||||||
* Very long results can cause the UI to hang before
|
* Very long results can cause the UI to hang before
|
||||||
* displaying, so truncate the results if necessary.
|
* displaying, so truncate the results if necessary.
|
||||||
*/
|
*/
|
||||||
if (sb.length() > 50000) {
|
if (sb.length() > 50000) {
|
||||||
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated"));
|
addMonospacedRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated"));
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sb.append("</pre>\n"); //NON-NLS
|
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text")).append(ex.getLocalizedMessage());
|
endTable(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.name"), image.getUniquePath());
|
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.name"), image.getUniquePath());
|
||||||
@ -419,20 +460,18 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
|
|
||||||
// Add all the data source paths to the "Local Path" value cell.
|
// Add all the data source paths to the "Local Path" value cell.
|
||||||
String[] imagePaths = image.getPaths();
|
String[] imagePaths = image.getPaths();
|
||||||
|
|
||||||
|
|
||||||
if (imagePaths.length > 0) {
|
if (imagePaths.length > 0) {
|
||||||
StringBuilder pathValues = new StringBuilder("<div>");
|
addRowWithMultipleValues(sb,
|
||||||
pathValues.append(imagePaths[0]);
|
NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"),
|
||||||
pathValues.append("</div>");
|
imagePaths);
|
||||||
for (int i = 1; i < imagePaths.length; i++) {
|
|
||||||
pathValues.append("<div>");
|
|
||||||
pathValues.append(imagePaths[i]);
|
|
||||||
pathValues.append("</div>");
|
|
||||||
}
|
|
||||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), pathValues.toString());
|
|
||||||
} else {
|
} else {
|
||||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"),
|
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"),
|
||||||
NbBundle.getMessage(this.getClass(), "Metadata.nodeText.none"));
|
NbBundle.getMessage(this.getClass(), "Metadata.nodeText.none"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
endTable(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
|
@ -42,9 +42,6 @@
|
|||||||
<Component class="javax.swing.JTextPane" name="textPanel">
|
<Component class="javax.swing.JTextPane" name="textPanel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="editable" type="boolean" value="false"/>
|
<Property name="editable" type="boolean" value="false"/>
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
|
||||||
<Connection code="DEFAULT_BACKGROUND" type="code"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[600, 52]"/>
|
<Dimension value="[600, 52]"/>
|
||||||
|
@ -18,12 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.contentviewers.analysisresults;
|
package org.sleuthkit.autopsy.contentviewers.analysisresults;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.text.html.HTMLEditorKit;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
@ -31,6 +28,8 @@ import org.jsoup.nodes.Element;
|
|||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.NodeResults;
|
import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.NodeResults;
|
||||||
import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.ResultDisplayAttributes;
|
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.AnalysisResult;
|
||||||
import org.sleuthkit.datamodel.Score;
|
import org.sleuthkit.datamodel.Score;
|
||||||
|
|
||||||
@ -38,59 +37,21 @@ import org.sleuthkit.datamodel.Score;
|
|||||||
* Displays a list of analysis results in a panel.
|
* Displays a list of analysis results in a panel.
|
||||||
*/
|
*/
|
||||||
public class AnalysisResultsContentPanel extends javax.swing.JPanel {
|
public class AnalysisResultsContentPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private static final String EMPTY_HTML = "<html><head></head><body></body></html>";
|
private static final String EMPTY_HTML = "<html><head></head><body></body></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.
|
// Anchors are inserted into the navigation so that the viewer can navigate to a selection.
|
||||||
// This is the prefix of those anchors.
|
// This is the prefix of those anchors.
|
||||||
private static final String RESULT_ANCHOR_PREFIX = "AnalysisResult_";
|
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
|
* Creates new form AnalysisResultsContentViewer
|
||||||
*/
|
*/
|
||||||
public AnalysisResultsContentPanel() {
|
public AnalysisResultsContentPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
ContentViewerHtmlStyles.setupHtmlJTextPane(textPanel);
|
||||||
textPanel.setContentType("text/html;charset=UTF-8"); //NON-NLS
|
|
||||||
HTMLEditorKit kit = new HTMLEditorKit();
|
|
||||||
textPanel.setEditorKit(kit);
|
|
||||||
kit.getStyleSheet().addRule(STYLE_SHEET_RULE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,10 +60,11 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
|
|||||||
* @param message The message to be displayed.
|
* @param message The message to be displayed.
|
||||||
*/
|
*/
|
||||||
void showMessage(String message) {
|
void showMessage(String message) {
|
||||||
|
ContentViewerHtmlStyles.setStyles(textPanel);
|
||||||
textPanel.setText("<html><head></head><body>"
|
textPanel.setText("<html><head></head><body>"
|
||||||
+ MessageFormat.format("<p class='{0}'>{1}</p>",
|
+ MessageFormat.format("<p class=\"{0}\">{1}</p>",
|
||||||
MESSAGE_CLASSNAME,
|
ContentViewerHtmlStyles.getMessageClassName(),
|
||||||
message == null ? "" : message)
|
message == null ? "" : EscapeUtil.escapeHtml(message))
|
||||||
+ "</body></html>");
|
+ "</body></html>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,12 +99,16 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
|
|||||||
List<ResultDisplayAttributes> displayAttributes = nodeResults.getAnalysisResults();
|
List<ResultDisplayAttributes> displayAttributes = nodeResults.getAnalysisResults();
|
||||||
for (int idx = 0; idx < displayAttributes.size(); idx++) {
|
for (int idx = 0; idx < displayAttributes.size(); idx++) {
|
||||||
AnalysisResultsViewModel.ResultDisplayAttributes resultAttrs = displayAttributes.get(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
|
// set the body html
|
||||||
|
ContentViewerHtmlStyles.setStyles(textPanel);
|
||||||
textPanel.setText(document.html());
|
textPanel.setText(document.html());
|
||||||
|
|
||||||
// if there is a selected result scroll to it
|
// if there is a selected result scroll to it
|
||||||
Optional<AnalysisResult> selectedResult = nodeResults.getSelectedResult();
|
Optional<AnalysisResult> selectedResult = nodeResults.getSelectedResult();
|
||||||
if (selectedResult.isPresent()) {
|
if (selectedResult.isPresent()) {
|
||||||
@ -155,48 +121,57 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the anchor id to use with the analysis result (based on the id).
|
* Returns the anchor id to use with the analysis result (based on the id).
|
||||||
|
*
|
||||||
* @param analysisResult The analysis result.
|
* @param analysisResult The analysis result.
|
||||||
|
*
|
||||||
* @return The anchor id.
|
* @return The anchor id.
|
||||||
*/
|
*/
|
||||||
private String getAnchor(AnalysisResult analysisResult) {
|
private String getAnchor(AnalysisResult analysisResult) {
|
||||||
return RESULT_ANCHOR_PREFIX + analysisResult.getId();
|
return RESULT_ANCHOR_PREFIX + analysisResult.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends a result item to the parent element of an html document.
|
* Appends a result item to the parent element of an html document.
|
||||||
|
*
|
||||||
* @param parent The parent element.
|
* @param parent The parent element.
|
||||||
* @param index The index of the item in the list of all items.
|
* @param index The index of the item in the list of all items.
|
||||||
* @param attrs The attributes of this item.
|
* @param attrs The attributes of this item.
|
||||||
|
*
|
||||||
|
* @return The result div.
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({"# {0} - analysisResultsNumber",
|
@NbBundle.Messages({"# {0} - analysisResultsNumber",
|
||||||
"AnalysisResultsContentPanel_result_headerKey=Analysis Result {0}"
|
"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
|
// create a new section with appropriate header
|
||||||
Element sectionDiv = appendSection(parent,
|
Element sectionDiv = appendSection(parent,
|
||||||
Bundle.AnalysisResultsContentPanel_result_headerKey(index + 1),
|
Bundle.AnalysisResultsContentPanel_result_headerKey(index + 1),
|
||||||
Optional.ofNullable(getAnchor(attrs.getAnalysisResult())));
|
Optional.ofNullable(getAnchor(attrs.getAnalysisResult())));
|
||||||
|
|
||||||
// create a table
|
// create a table
|
||||||
Element table = sectionDiv.appendElement("table");
|
Element table = sectionDiv.appendElement("table");
|
||||||
table.attr("class", SUBSECTION_CLASSNAME);
|
table.attr("class", ContentViewerHtmlStyles.getIndentedClassName());
|
||||||
|
|
||||||
Element tableBody = table.appendElement("tbody");
|
Element tableBody = table.appendElement("tbody");
|
||||||
|
|
||||||
// append a row for each item
|
// append a row for each item
|
||||||
for (Pair<String, String> keyVal : attrs.getAttributesToDisplay()) {
|
for (Pair<String, String> keyVal : attrs.getAttributesToDisplay()) {
|
||||||
Element row = tableBody.appendElement("tr");
|
Element row = tableBody.appendElement("tr");
|
||||||
String keyString = keyVal.getKey() == null ? "" : keyVal.getKey() + ":";
|
String keyString = keyVal.getKey() == null ? "" : keyVal.getKey() + ":";
|
||||||
row.appendElement("td")
|
Element keyTd = row.appendElement("td")
|
||||||
|
.attr("class", ContentViewerHtmlStyles.getTextClassName());
|
||||||
|
|
||||||
|
keyTd.appendElement("span")
|
||||||
.text(keyString)
|
.text(keyString)
|
||||||
.attr("class", TD_CLASSNAME);
|
.attr("class", ContentViewerHtmlStyles.getKeyColumnClassName());
|
||||||
|
|
||||||
String valueString = keyVal.getValue() == null ? "" : keyVal.getValue();
|
String valueString = keyVal.getValue() == null ? "" : keyVal.getValue();
|
||||||
row.appendElement("td")
|
row.appendElement("td")
|
||||||
.text(valueString)
|
.text(valueString)
|
||||||
.attr("class", TD_CLASSNAME);
|
.attr("class", ContentViewerHtmlStyles.getTextClassName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return sectionDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -210,21 +185,25 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
|
|||||||
*/
|
*/
|
||||||
private Element appendSection(Element parent, String headerText, Optional<String> anchorId) {
|
private Element appendSection(Element parent, String headerText, Optional<String> anchorId) {
|
||||||
Element sectionDiv = parent.appendElement("div");
|
Element sectionDiv = parent.appendElement("div");
|
||||||
|
|
||||||
// append an anchor tag if there is one
|
// append an anchor tag if there is one
|
||||||
|
Element anchorEl = null;
|
||||||
if (anchorId.isPresent()) {
|
if (anchorId.isPresent()) {
|
||||||
Element anchorEl = sectionDiv.appendElement("a");
|
anchorEl = sectionDiv.appendElement("a");
|
||||||
anchorEl.attr("name", anchorId.get());
|
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
|
// append the header
|
||||||
Element header = sectionDiv.appendElement("h1");
|
Element header = null;
|
||||||
header.text(headerText);
|
header = (anchorEl == null)
|
||||||
header.attr("class", HEADER_CLASSNAME);
|
? 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 the section element
|
||||||
return sectionDiv;
|
return sectionDiv;
|
||||||
}
|
}
|
||||||
@ -244,7 +223,6 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
|
|||||||
setPreferredSize(new java.awt.Dimension(100, 58));
|
setPreferredSize(new java.awt.Dimension(100, 58));
|
||||||
|
|
||||||
textPanel.setEditable(false);
|
textPanel.setEditable(false);
|
||||||
textPanel.setBackground(DEFAULT_BACKGROUND);
|
|
||||||
textPanel.setName(""); // NOI18N
|
textPanel.setName(""); // NOI18N
|
||||||
textPanel.setPreferredSize(new java.awt.Dimension(600, 52));
|
textPanel.setPreferredSize(new java.awt.Dimension(600, 52));
|
||||||
scrollPane.setViewportView(textPanel);
|
scrollPane.setViewportView(textPanel);
|
||||||
|
@ -24,7 +24,6 @@ import java.util.List;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.swing.JLabel;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.jsoup.Jsoup;
|
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.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
@ -80,18 +80,6 @@ public class Annotations {
|
|||||||
|
|
||||||
private static final String EMPTY_HTML = "<html><head></head><body></body></html>";
|
private static final String EMPTY_HTML = "<html><head></head><body></body></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
|
// describing table values for a tag
|
||||||
private static final List<ItemEntry<Tag>> TAG_ENTRIES = Arrays.asList(
|
private static final List<ItemEntry<Tag>> TAG_ENTRIES = Arrays.asList(
|
||||||
new ItemEntry<>(Bundle.Annotations_tagEntryDataLabel_tag(),
|
new ItemEntry<>(Bundle.Annotations_tagEntryDataLabel_tag(),
|
||||||
@ -200,11 +188,11 @@ public class Annotations {
|
|||||||
* @return If any content was actually rendered.
|
* @return If any content was actually rendered.
|
||||||
*/
|
*/
|
||||||
private static boolean renderArtifact(Element parent, BlackboardArtifact bba, Content sourceContent) {
|
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()) {
|
if (CentralRepository.isEnabled()) {
|
||||||
List<CorrelationAttributeInstance> centralRepoComments = getCentralRepositoryData(bba);
|
List<CorrelationAttributeInstance> 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;
|
contentRendered = contentRendered || crRendered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,12 +201,18 @@ public class Annotations {
|
|||||||
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == bba.getArtifactTypeID())
|
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == bba.getArtifactTypeID())
|
||||||
&& (hasTskComment(bba))) {
|
&& (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;
|
contentRendered = contentRendered || filesetRendered;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element sourceFileSection = appendSection(parent, Bundle.Annotations_sourceFile_title());
|
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) {
|
if (!sourceFileRendered) {
|
||||||
sourceFileSection.remove();
|
sourceFileSection.remove();
|
||||||
@ -238,24 +232,27 @@ public class Annotations {
|
|||||||
* @return If any content was actually rendered.
|
* @return If any content was actually rendered.
|
||||||
*/
|
*/
|
||||||
private static boolean renderContent(Element parent, Content sourceContent, boolean isSubheader) {
|
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) {
|
if (sourceContent instanceof AbstractFile) {
|
||||||
AbstractFile sourceFile = (AbstractFile) sourceContent;
|
AbstractFile sourceFile = (AbstractFile) sourceContent;
|
||||||
|
|
||||||
if (CentralRepository.isEnabled()) {
|
if (CentralRepository.isEnabled()) {
|
||||||
List<CorrelationAttributeInstance> centralRepoComments = getCentralRepositoryData(sourceFile);
|
List<CorrelationAttributeInstance> 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;
|
contentRendered = contentRendered || crRendered;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hashsetRendered = appendEntries(parent, HASHSET_CONFIG,
|
boolean hashsetRendered = appendEntries(parent, HASHSET_CONFIG,
|
||||||
getFileSetHits(sourceFile, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT),
|
getFileSetHits(sourceFile, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT),
|
||||||
isSubheader);
|
isSubheader,
|
||||||
|
!contentRendered);
|
||||||
|
|
||||||
boolean interestingFileRendered = appendEntries(parent, INTERESTING_FILE_CONFIG,
|
boolean interestingFileRendered = appendEntries(parent, INTERESTING_FILE_CONFIG,
|
||||||
getFileSetHits(sourceFile, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT),
|
getFileSetHits(sourceFile, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT),
|
||||||
isSubheader);
|
isSubheader,
|
||||||
|
!contentRendered);
|
||||||
|
|
||||||
contentRendered = contentRendered || hashsetRendered || interestingFileRendered;
|
contentRendered = contentRendered || hashsetRendered || interestingFileRendered;
|
||||||
}
|
}
|
||||||
@ -456,24 +453,36 @@ public class Annotations {
|
|||||||
* will be formatted as a table in the format specified in the
|
* will be formatted as a table in the format specified in the
|
||||||
* SectionConfig.
|
* SectionConfig.
|
||||||
*
|
*
|
||||||
* @param parent The parent element for which the entries will be
|
* @param parent The parent element for which the entries will be
|
||||||
* attached.
|
* attached.
|
||||||
* @param config The display configuration for this entry type (i.e.
|
* @param config The display configuration for this entry type (i.e.
|
||||||
* table type, name, if data is not present).
|
* table type, name, if data is not present).
|
||||||
* @param items The items to display.
|
* @param items The items to display.
|
||||||
* @param isSubsection Whether or not this should be displayed as a
|
* @param isSubsection Whether or not this should be displayed as a
|
||||||
* subsection. If not displayed as a top-level section.
|
* 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.
|
* @return If there was actual content rendered for this set of entries.
|
||||||
*/
|
*/
|
||||||
private static <T> boolean appendEntries(Element parent, Annotations.SectionConfig<T> config, List<? extends T> items,
|
private static <T> boolean appendEntries(Element parent, Annotations.SectionConfig<T> config, List<? extends T> items,
|
||||||
boolean isSubsection) {
|
boolean isSubsection, boolean isFirstSection) {
|
||||||
if (items == null || items.isEmpty()) {
|
if (items == null || items.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element sectionDiv = (isSubsection) ? appendSubsection(parent, config.getTitle()) : appendSection(parent, config.getTitle());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,12 +508,11 @@ public class Annotations {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
Element childTable = appendTable(parent, 2, tableData, null);
|
Element childTable = appendTable(parent, 2, tableData, null);
|
||||||
childTable.attr("class", VERTICAL_TABLE_CLASSNAME);
|
|
||||||
|
|
||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
} else {
|
} 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");
|
Element row = rowParent.appendElement("tr");
|
||||||
for (int i = 0; i < columnNumber; i++) {
|
for (int i = 0; i < columnNumber; i++) {
|
||||||
Element cell = row.appendElement(cellType);
|
Element cell = row.appendElement(cellType);
|
||||||
|
cell.attr("class", ContentViewerHtmlStyles.getTextClassName());
|
||||||
if (data != null && i < data.size()) {
|
if (data != null && i < data.size()) {
|
||||||
cell.text(StringUtils.isEmpty(data.get(i)) ? "" : data.get(i));
|
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) {
|
private static Element appendSection(Element parent, String headerText) {
|
||||||
Element sectionDiv = parent.appendElement("div");
|
Element sectionDiv = parent.appendElement("div");
|
||||||
sectionDiv.attr("class", SECTION_CLASSNAME);
|
|
||||||
Element header = sectionDiv.appendElement("h1");
|
Element header = sectionDiv.appendElement("h1");
|
||||||
header.text(headerText);
|
header.text(headerText);
|
||||||
header.attr("class", HEADER_CLASSNAME);
|
header.attr("class", ContentViewerHtmlStyles.getHeaderClassName());
|
||||||
return sectionDiv;
|
return sectionDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,10 +593,9 @@ public class Annotations {
|
|||||||
*/
|
*/
|
||||||
private static Element appendSubsection(Element parent, String headerText) {
|
private static Element appendSubsection(Element parent, String headerText) {
|
||||||
Element subsectionDiv = parent.appendElement("div");
|
Element subsectionDiv = parent.appendElement("div");
|
||||||
subsectionDiv.attr("class", SUBSECTION_CLASSNAME);
|
|
||||||
Element header = subsectionDiv.appendElement("h2");
|
Element header = subsectionDiv.appendElement("h2");
|
||||||
header.text(headerText);
|
header.text(headerText);
|
||||||
header.attr("class", SUBHEADER_CLASSNAME);
|
header.attr("class", ContentViewerHtmlStyles.getHeaderClassName());
|
||||||
return subsectionDiv;
|
return subsectionDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,7 +612,7 @@ public class Annotations {
|
|||||||
private static Element appendMessage(Element parent, String message) {
|
private static Element appendMessage(Element parent, String message) {
|
||||||
Element messageEl = parent.appendElement("p");
|
Element messageEl = parent.appendElement("p");
|
||||||
messageEl.text(message);
|
messageEl.text(message);
|
||||||
messageEl.attr("class", MESSAGE_CLASSNAME);
|
messageEl.attr("class", ContentViewerHtmlStyles.getMessageClassName());
|
||||||
return messageEl;
|
return messageEl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2020 Basis Technology Corp.
|
* Copyright 2020-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
|
import java.awt.Insets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -30,11 +31,13 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.guiutils.ContactCache;
|
import org.sleuthkit.autopsy.guiutils.ContactCache;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
@ -75,6 +78,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
*/
|
*/
|
||||||
public CallLogArtifactViewer() {
|
public CallLogArtifactViewer() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,6 +118,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
currentAccountFetcher = null;
|
currentAccountFetcher = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// repaint
|
// repaint
|
||||||
this.revalidate();
|
this.revalidate();
|
||||||
}
|
}
|
||||||
@ -309,7 +314,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
})
|
})
|
||||||
private List<AccountPersonaSearcherData> updateView(CallLogViewData callLogViewData) {
|
private List<AccountPersonaSearcherData> 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<AccountPersonaSearcherData> dataList = new ArrayList<>();
|
List<AccountPersonaSearcherData> dataList = new ArrayList<>();
|
||||||
// Display "From" if we have non-local device accounts
|
// Display "From" if we have non-local device accounts
|
||||||
@ -384,7 +389,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
})
|
})
|
||||||
private void updateMetadataView(CallLogViewData callLogViewData) {
|
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());
|
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_direction());
|
||||||
if (callLogViewData.getDirection() != null) {
|
if (callLogViewData.getDirection() != null) {
|
||||||
@ -414,7 +419,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
"CallLogArtifactViewer_heading_Source=Source",
|
"CallLogArtifactViewer_heading_Source=Source",
|
||||||
"CallLogArtifactViewer_label_datasource=Data Source",})
|
"CallLogArtifactViewer_label_datasource=Data Source",})
|
||||||
private void updateSourceView(CallLogViewData callLogViewData) {
|
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.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_datasource());
|
||||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName());
|
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName());
|
||||||
}
|
}
|
||||||
@ -432,7 +437,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
if (callLogViewData.getOtherAttributes().isEmpty()) {
|
if (callLogViewData.getOtherAttributes().isEmpty()) {
|
||||||
return;
|
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<String, String> entry : callLogViewData.getOtherAttributes().entrySet()) {
|
for (Map.Entry<String, String> entry : callLogViewData.getOtherAttributes().entrySet()) {
|
||||||
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, entry.getKey());
|
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, entry.getKey());
|
||||||
@ -444,9 +449,8 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
"CalllogArtifactViewer_cr_disabled_message=Enable Central Repository to view, create and edit personas."
|
"CalllogArtifactViewer_cr_disabled_message=Enable Central Repository to view, create and edit personas."
|
||||||
})
|
})
|
||||||
private void showCRDisabledMessage() {
|
private void showCRDisabledMessage() {
|
||||||
CommunicationArtifactViewerHelper.addBlankLine(this, m_gridBagLayout, m_constraints);
|
Insets messageInsets = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0);
|
||||||
m_constraints.gridy++;
|
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, messageInsets, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
|
||||||
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
|
|
||||||
m_constraints.gridy++;
|
m_constraints.gridy++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,7 +509,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
m_constraints.gridx = 0;
|
m_constraints.gridx = 0;
|
||||||
m_constraints.weighty = 0.0;
|
m_constraints.weighty = 0.0;
|
||||||
m_constraints.weightx = 0.0; // keep components fixed horizontally.
|
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;
|
m_constraints.fill = GridBagConstraints.NONE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2020 Basis Technology Corp.
|
* Copyright 2020-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,7 +19,6 @@
|
|||||||
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
@ -38,6 +37,7 @@ import javax.swing.JTextPane;
|
|||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
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.
|
// Number of columns in the gridbag layout.
|
||||||
private final static int MAX_COLS = 4;
|
private final static int MAX_COLS = 4;
|
||||||
|
|
||||||
final static int LEFT_INSET = 12;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty private constructor
|
* Empty private constructor
|
||||||
*/
|
*/
|
||||||
@ -64,34 +62,34 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
* @param panel Panel to update.
|
* @param panel Panel to update.
|
||||||
* @param gridbagLayout Layout to use.
|
* @param gridbagLayout Layout to use.
|
||||||
* @param constraints Constraints to use.
|
* @param constraints Constraints to use.
|
||||||
|
* @param spacing Spacing to add to top insets (in pixels).
|
||||||
* @param headerString Heading string to display.
|
* @param headerString Heading string to display.
|
||||||
*
|
*
|
||||||
* @return JLabel Heading label added.
|
* @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;
|
Insets savedInsets = constraints.insets;
|
||||||
|
|
||||||
// create label for heading
|
// create label for heading
|
||||||
javax.swing.JLabel headingLabel = new javax.swing.JLabel();
|
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.gridy++;
|
||||||
constraints.gridx = 0;
|
constraints.gridx = 0;
|
||||||
|
|
||||||
// let the header span all of the row
|
// let the header span all of the row
|
||||||
constraints.gridwidth = MAX_COLS;
|
constraints.gridwidth = MAX_COLS;
|
||||||
constraints.insets = new Insets(0, 0, 0, 0); // No inset for header
|
constraints.anchor = GridBagConstraints.LINE_START;
|
||||||
|
constraints.fill = GridBagConstraints.NONE;
|
||||||
|
|
||||||
|
constraints.insets = new Insets(topSpacing, 0, ContentViewerDefaults.getLineSpacing(), 0);
|
||||||
|
|
||||||
// set text
|
// set text
|
||||||
headingLabel.setText(headerString);
|
headingLabel.setText(headerString.trim());
|
||||||
|
|
||||||
// make it large and bold
|
// make it large and bold
|
||||||
headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2));
|
headingLabel.setFont(ContentViewerDefaults.getHeaderFont());
|
||||||
|
|
||||||
// add to panel
|
// add to panel
|
||||||
gridbagLayout.setConstraints(headingLabel, constraints);
|
gridbagLayout.setConstraints(headingLabel, constraints);
|
||||||
@ -159,7 +157,7 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
int savedFill = constraints.fill;
|
int savedFill = constraints.fill;
|
||||||
|
|
||||||
constraints.weightx = 1.0; // take up all the horizontal space
|
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));
|
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);
|
gridbagLayout.setConstraints(horizontalFiller, constraints);
|
||||||
@ -181,6 +179,7 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
static void addPageEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
static void addPageEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||||
|
|
||||||
constraints.gridx = 0;
|
constraints.gridx = 0;
|
||||||
|
constraints.gridy++;
|
||||||
|
|
||||||
double savedWeighty = constraints.weighty;
|
double savedWeighty = constraints.weighty;
|
||||||
int savedFill = constraints.fill;
|
int savedFill = constraints.fill;
|
||||||
@ -197,24 +196,6 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
constraints.fill = savedFill;
|
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.
|
* Adds a label/key to the panel at col 0.
|
||||||
*
|
*
|
||||||
@ -247,9 +228,12 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
|
|
||||||
constraints.gridy++;
|
constraints.gridy++;
|
||||||
constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
|
constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
|
||||||
|
constraints.anchor = GridBagConstraints.LINE_START;
|
||||||
|
constraints.insets = new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||||
|
|
||||||
// set text
|
// set text
|
||||||
keyLabel.setText(keyString + ": ");
|
String preppedKeyString = keyString == null ? null : keyString.trim() + ":";
|
||||||
|
keyLabel.setText(preppedKeyString);
|
||||||
|
|
||||||
// add to panel
|
// add to panel
|
||||||
gridbagLayout.setConstraints(keyLabel, constraints);
|
gridbagLayout.setConstraints(keyLabel, constraints);
|
||||||
@ -288,6 +272,7 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
JTextPane valueField = new JTextPane();
|
JTextPane valueField = new JTextPane();
|
||||||
valueField.setEditable(false);
|
valueField.setEditable(false);
|
||||||
valueField.setOpaque(false);
|
valueField.setOpaque(false);
|
||||||
|
valueField.setMargin(new Insets(0,0,0,0));
|
||||||
|
|
||||||
constraints.gridx = gridx < MAX_COLS ? gridx : MAX_COLS - 1;
|
constraints.gridx = gridx < MAX_COLS ? gridx : MAX_COLS - 1;
|
||||||
|
|
||||||
@ -295,7 +280,8 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
|
|
||||||
// let the value span 2 cols
|
// let the value span 2 cols
|
||||||
cloneConstraints.gridwidth = 2;
|
cloneConstraints.gridwidth = 2;
|
||||||
cloneConstraints.fill = GridBagConstraints.BOTH;
|
constraints.anchor = GridBagConstraints.LINE_START;
|
||||||
|
cloneConstraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||||
|
|
||||||
// set text
|
// set text
|
||||||
valueField.setText(valueString);
|
valueField.setText(valueString);
|
||||||
@ -325,13 +311,13 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
* @param panel Panel to show.
|
* @param panel Panel to show.
|
||||||
* @param gridbagLayout Layout to use.
|
* @param gridbagLayout Layout to use.
|
||||||
* @param constraints Constraints 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.
|
* @param messageString Message to display.
|
||||||
*
|
*
|
||||||
* @return Label for message added.
|
* @return Label for message added.
|
||||||
*/
|
*/
|
||||||
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String messageString) {
|
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, Insets insets, GridBagConstraints constraints, String messageString) {
|
||||||
return addMessageRow(panel, gridbagLayout, constraints, messageString, 0);
|
return addMessageRow(panel, gridbagLayout, constraints, insets, messageString, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -340,26 +326,33 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
*
|
*
|
||||||
* @param panel Panel to show.
|
* @param panel Panel to show.
|
||||||
* @param gridbagLayout Layout to use.
|
* @param gridbagLayout Layout to use.
|
||||||
|
* @param insets The insets to be used for the grid bag layout constraints.
|
||||||
* @param constraints Constraints 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.
|
* @param messageString Message to display.
|
||||||
|
* @param gridx The grid x location to use.
|
||||||
*
|
*
|
||||||
* @return Label for message added.
|
* @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
|
// create label
|
||||||
javax.swing.JLabel messageLabel = new javax.swing.JLabel();
|
javax.swing.JLabel messageLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
constraints.gridy++;
|
constraints.gridy++;
|
||||||
constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
|
constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
|
||||||
|
constraints.insets = insets == null
|
||||||
|
? new Insets(0, 0, ContentViewerDefaults.getLineSpacing(), 0) :
|
||||||
|
insets;
|
||||||
|
constraints.anchor = GridBagConstraints.LINE_START;
|
||||||
|
|
||||||
int savedGridwidth = constraints.gridwidth;
|
int savedGridwidth = constraints.gridwidth;
|
||||||
|
|
||||||
constraints.gridwidth = 3;
|
constraints.gridwidth = 3;
|
||||||
|
|
||||||
// set text
|
// set text
|
||||||
messageLabel.setText(messageString);
|
messageLabel.setText(messageString == null ? null : messageString.trim());
|
||||||
|
messageLabel.setFont(ContentViewerDefaults.getMessageFont());
|
||||||
|
|
||||||
// add to panel
|
// add to panel
|
||||||
gridbagLayout.setConstraints(messageLabel, constraints);
|
gridbagLayout.setConstraints(messageLabel, constraints);
|
||||||
@ -406,8 +399,9 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
Insets savedInsets = constraints.insets;
|
Insets savedInsets = constraints.insets;
|
||||||
|
|
||||||
// extra Indent in
|
// 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);
|
||||||
|
constraints.anchor = GridBagConstraints.LINE_START;
|
||||||
|
|
||||||
// create label
|
// create label
|
||||||
javax.swing.JLabel personaLabel = new javax.swing.JLabel();
|
javax.swing.JLabel personaLabel = new javax.swing.JLabel();
|
||||||
String personaLabelText = Bundle.CommunicationArtifactViewerHelper_persona_label();
|
String personaLabelText = Bundle.CommunicationArtifactViewerHelper_persona_label();
|
||||||
@ -415,15 +409,12 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
? Bundle.CommunicationArtifactViewerHelper_persona_searching()
|
? Bundle.CommunicationArtifactViewerHelper_persona_searching()
|
||||||
: Bundle.CommunicationArtifactViewerHelper_persona_unknown());
|
: Bundle.CommunicationArtifactViewerHelper_persona_unknown());
|
||||||
|
|
||||||
personaLabel.setText(personaLabelText);
|
personaLabel.setText(personaLabelText == null ? null : personaLabelText.trim());
|
||||||
|
|
||||||
// add to panel
|
// add to panel
|
||||||
gridbagLayout.setConstraints(personaLabel, constraints);
|
gridbagLayout.setConstraints(personaLabel, constraints);
|
||||||
panel.add(personaLabel);
|
panel.add(personaLabel);
|
||||||
|
|
||||||
// restore constraint
|
|
||||||
constraints.insets = savedInsets;
|
|
||||||
|
|
||||||
constraints.gridx++;
|
constraints.gridx++;
|
||||||
|
|
||||||
// Place a button as place holder. It will be enabled when persona is available.
|
// Place a button as place holder. It will be enabled when persona is available.
|
||||||
@ -441,6 +432,9 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
} else {
|
} else {
|
||||||
personaLabel.setEnabled(false);
|
personaLabel.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// restore constraint
|
||||||
|
constraints.insets = savedInsets;
|
||||||
|
|
||||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||||
|
|
||||||
@ -469,7 +463,7 @@ final class CommunicationArtifactViewerHelper {
|
|||||||
GridBagConstraints indentedConstraints = (GridBagConstraints) constraints.clone();
|
GridBagConstraints indentedConstraints = (GridBagConstraints) constraints.clone();
|
||||||
|
|
||||||
// Add an indent to match persona labels
|
// 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, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||||
|
|
||||||
String contactInfo = Bundle.CommunicationArtifactViewerHelper_contact_label(contactId != null && !contactId.isEmpty() ? contactId : Bundle.CommunicationArtifactViewerHelper_contact_label_unknown());
|
String contactInfo = Bundle.CommunicationArtifactViewerHelper_contact_label(contactId != null && !contactId.isEmpty() ? contactId : Bundle.CommunicationArtifactViewerHelper_contact_label_unknown());
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2020 Basis Technology Corp.
|
* Copyright 2020-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -41,9 +41,9 @@ import javax.imageio.ImageIO;
|
|||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
@ -57,6 +57,7 @@ import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
|
|||||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
|
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
|
||||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
||||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
|
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.Account;
|
import org.sleuthkit.datamodel.Account;
|
||||||
@ -107,7 +108,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
*/
|
*/
|
||||||
public ContactArtifactViewer() {
|
public ContactArtifactViewer() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
|
||||||
defaultImage = new ImageIcon(ContactArtifactViewer.class.getResource(DEFAULT_IMAGE_PATH));
|
defaultImage = new ImageIcon(ContactArtifactViewer.class.getResource(DEFAULT_IMAGE_PATH));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,8 +246,11 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
Insets savedInsets = contactPanelConstraints.insets;
|
Insets savedInsets = contactPanelConstraints.insets;
|
||||||
contactPanelConstraints.gridy = 0;
|
contactPanelConstraints.gridy = 0;
|
||||||
contactPanelConstraints.gridx = 0;
|
contactPanelConstraints.gridx = 0;
|
||||||
contactPanelConstraints.insets = new Insets(0, 0, 0, 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();
|
javax.swing.JLabel contactImage = new javax.swing.JLabel();
|
||||||
contactImage.setIcon(getImageFromArtifact(contactArtifact));
|
contactImage.setIcon(getImageFromArtifact(contactArtifact));
|
||||||
contactImage.setText(Bundle.ContactArtifactViewer_contactImage_text());
|
contactImage.setText(Bundle.ContactArtifactViewer_contactImage_text());
|
||||||
@ -256,6 +260,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
CommunicationArtifactViewerHelper.addLineEndGlue(this, contactPanelLayout, contactPanelConstraints);
|
CommunicationArtifactViewerHelper.addLineEndGlue(this, contactPanelLayout, contactPanelConstraints);
|
||||||
contactPanelConstraints.gridy++;
|
contactPanelConstraints.gridy++;
|
||||||
|
|
||||||
|
contactPanelConstraints.gridwidth = prevGridWidth;
|
||||||
contactPanelConstraints.insets = savedInsets;
|
contactPanelConstraints.insets = savedInsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,13 +280,13 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
if (StringUtils.isEmpty(bba.getValueString()) == false) {
|
if (StringUtils.isEmpty(bba.getValueString()) == false) {
|
||||||
contactName = bba.getDisplayString();
|
contactName = bba.getDisplayString();
|
||||||
|
|
||||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, contactName);
|
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, 0, contactName);
|
||||||
foundName = true;
|
foundName = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (foundName == false) {
|
if (foundName == false) {
|
||||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, Bundle.ContactArtifactViewer_contactname_unknown());
|
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, ContentViewerDefaults.getSectionSpacing(), Bundle.ContactArtifactViewer_contactname_unknown());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +307,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, sectionHeader);
|
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, ContentViewerDefaults.getSectionSpacing(), sectionHeader);
|
||||||
for (BlackboardAttribute bba : sectionAttributesList) {
|
for (BlackboardAttribute bba : sectionAttributesList) {
|
||||||
CommunicationArtifactViewerHelper.addKey(this, contactPanelLayout, contactPanelConstraints, bba.getAttributeType().getDisplayName());
|
CommunicationArtifactViewerHelper.addKey(this, contactPanelLayout, contactPanelConstraints, bba.getAttributeType().getDisplayName());
|
||||||
CommunicationArtifactViewerHelper.addValue(this, contactPanelLayout, contactPanelConstraints, bba.getDisplayString());
|
CommunicationArtifactViewerHelper.addValue(this, contactPanelLayout, contactPanelConstraints, bba.getDisplayString());
|
||||||
@ -316,7 +321,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
"ContactArtifactViewer_heading_Source=Source",
|
"ContactArtifactViewer_heading_Source=Source",
|
||||||
"ContactArtifactViewer_label_datasource=Data Source",})
|
"ContactArtifactViewer_label_datasource=Data Source",})
|
||||||
private void updateSource() {
|
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.addKey(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_label_datasource());
|
||||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, datasourceName);
|
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, datasourceName);
|
||||||
}
|
}
|
||||||
@ -335,7 +340,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
private void initiatePersonasSearch() {
|
private void initiatePersonasSearch() {
|
||||||
|
|
||||||
// add a section header
|
// 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++;
|
m_constraints.gridy++;
|
||||||
|
|
||||||
@ -346,8 +351,10 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
|
|
||||||
this.personaSearchStatusLabel = new javax.swing.JLabel();
|
this.personaSearchStatusLabel = new javax.swing.JLabel();
|
||||||
personaSearchStatusLabel.setText(personaStatusLabelText);
|
personaSearchStatusLabel.setText(personaStatusLabelText);
|
||||||
|
personaSearchStatusLabel.setFont(ContentViewerDefaults.getMessageFont());
|
||||||
|
|
||||||
m_constraints.gridx = 0;
|
m_constraints.gridx = 0;
|
||||||
|
m_constraints.anchor = GridBagConstraints.LINE_START;
|
||||||
|
|
||||||
CommunicationArtifactViewerHelper.addComponent(this, m_gridBagLayout, m_constraints, personaSearchStatusLabel);
|
CommunicationArtifactViewerHelper.addComponent(this, m_gridBagLayout, m_constraints, personaSearchStatusLabel);
|
||||||
|
|
||||||
@ -359,9 +366,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
personaHeader.setEnabled(false);
|
personaHeader.setEnabled(false);
|
||||||
personaSearchStatusLabel.setEnabled(false);
|
personaSearchStatusLabel.setEnabled(false);
|
||||||
|
|
||||||
CommunicationArtifactViewerHelper.addBlankLine(this, m_gridBagLayout, m_constraints);
|
Insets messageInsets = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0);
|
||||||
m_constraints.gridy++;
|
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, messageInsets, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
|
||||||
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
|
|
||||||
m_constraints.gridy++;
|
m_constraints.gridy++;
|
||||||
|
|
||||||
CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints);
|
CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints);
|
||||||
@ -435,12 +441,9 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
// save the original insets
|
// save the original insets
|
||||||
Insets savedInsets = constraints.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 * CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0);
|
|
||||||
|
|
||||||
// Add a Match X label in col 0.
|
// Add a Match X label in col 0.
|
||||||
constraints.gridx = 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.JLabel personaNameLabel = new javax.swing.JLabel();
|
||||||
javax.swing.JButton personaButton = new javax.swing.JButton();
|
javax.swing.JButton personaButton = new javax.swing.JButton();
|
||||||
@ -461,6 +464,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
|
|
||||||
//constraints.gridwidth = 1; // TBD: this may not be needed if we use single panel
|
//constraints.gridwidth = 1; // TBD: this may not be needed if we use single panel
|
||||||
constraints.gridx++;
|
constraints.gridx++;
|
||||||
|
constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||||
|
constraints.anchor = GridBagConstraints.LINE_START;
|
||||||
personaNameLabel.setText(personaName);
|
personaNameLabel.setText(personaName);
|
||||||
gridBagLayout.setConstraints(personaNameLabel, constraints);
|
gridBagLayout.setConstraints(personaNameLabel, constraints);
|
||||||
CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaNameLabel);
|
CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaNameLabel);
|
||||||
@ -474,6 +479,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
|
|
||||||
// Shirnk the button height.
|
// Shirnk the button height.
|
||||||
personaButton.setMargin(new Insets(0, 5, 0, 5));
|
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);
|
gridBagLayout.setConstraints(personaButton, constraints);
|
||||||
CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaButton);
|
CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaButton);
|
||||||
CommunicationArtifactViewerHelper.addLineEndGlue(this, gridBagLayout, constraints);
|
CommunicationArtifactViewerHelper.addLineEndGlue(this, gridBagLayout, constraints);
|
||||||
@ -488,7 +495,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
//constraints.insets = labelInsets;
|
//constraints.insets = labelInsets;
|
||||||
|
|
||||||
javax.swing.JLabel accountsStatus = new javax.swing.JLabel(Bundle.ContactArtifactViewer_found_all_accounts_label());
|
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);
|
CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, accountsStatus);
|
||||||
constraints.insets = savedInsets;
|
constraints.insets = savedInsets;
|
||||||
|
|
||||||
@ -501,7 +509,6 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
constraints.gridy++;
|
constraints.gridy++;
|
||||||
|
|
||||||
// this needs an extra indent
|
// this needs an extra indent
|
||||||
constraints.insets = extraIndentInsets;
|
|
||||||
CommunicationArtifactViewerHelper.addKeyAtCol(this, gridBagLayout, constraints, Bundle.ContactArtifactViewer_missing_account_label(), 1);
|
CommunicationArtifactViewerHelper.addKeyAtCol(this, gridBagLayout, constraints, Bundle.ContactArtifactViewer_missing_account_label(), 1);
|
||||||
constraints.insets = savedInsets;
|
constraints.insets = savedInsets;
|
||||||
|
|
||||||
@ -544,12 +551,12 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
|||||||
m_gridBagLayout = new GridBagLayout();
|
m_gridBagLayout = new GridBagLayout();
|
||||||
m_constraints = new GridBagConstraints();
|
m_constraints = new GridBagConstraints();
|
||||||
|
|
||||||
m_constraints.anchor = GridBagConstraints.FIRST_LINE_START;
|
m_constraints.anchor = GridBagConstraints.LINE_START;
|
||||||
m_constraints.gridy = 0;
|
m_constraints.gridy = 0;
|
||||||
m_constraints.gridx = 0;
|
m_constraints.gridx = 0;
|
||||||
m_constraints.weighty = 0.0;
|
m_constraints.weighty = 0.0;
|
||||||
m_constraints.weightx = 0.0; // keep components fixed horizontally.
|
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;
|
m_constraints.fill = GridBagConstraints.NONE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
@ -30,18 +30,24 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.JTextPane;
|
import javax.swing.JTextPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
||||||
@ -55,13 +61,18 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
*/
|
*/
|
||||||
@ServiceProvider(service = ArtifactContentViewer.class)
|
@ServiceProvider(service = ArtifactContentViewer.class)
|
||||||
public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel implements ArtifactContentViewer {
|
public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel implements ArtifactContentViewer {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger logger = Logger.getLogger(GeneralPurposeArtifactViewer.class.getName());
|
private static final Logger logger = Logger.getLogger(GeneralPurposeArtifactViewer.class.getName());
|
||||||
// Number of columns in the gridbag layout.
|
// Number of columns in the gridbag layout.
|
||||||
private final static int MAX_COLS = 4;
|
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 ZERO_INSETS = new java.awt.Insets(0, 0, 0, 0);
|
||||||
private final static Insets HEADER_INSETS = new java.awt.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);
|
||||||
|
|
||||||
private final static double GLUE_WEIGHT_X = 1.0;
|
private final static double GLUE_WEIGHT_X = 1.0;
|
||||||
private final static double TEXT_WEIGHT_X = 0.0;
|
private final static double TEXT_WEIGHT_X = 0.0;
|
||||||
private final static int LABEL_COLUMN = 0;
|
private final static int LABEL_COLUMN = 0;
|
||||||
@ -91,6 +102,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
|||||||
initComponents();
|
initComponents();
|
||||||
gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
|
gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
|
||||||
detailsPanel.setLayout(gridBagLayout);
|
detailsPanel.setLayout(gridBagLayout);
|
||||||
|
detailsPanel.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,7 +192,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
|||||||
gridBagConstraints.weighty = 0.0;
|
gridBagConstraints.weighty = 0.0;
|
||||||
gridBagConstraints.weightx = TEXT_WEIGHT_X; // keep components fixed horizontally.
|
gridBagConstraints.weightx = TEXT_WEIGHT_X; // keep components fixed horizontally.
|
||||||
gridBagConstraints.fill = GridBagConstraints.NONE;
|
gridBagConstraints.fill = GridBagConstraints.NONE;
|
||||||
gridBagConstraints.insets = ROW_INSETS;
|
gridBagConstraints.insets = ZERO_INSETS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
@ -386,29 +398,26 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
|||||||
headingLabel.setEditable(false);
|
headingLabel.setEditable(false);
|
||||||
// add a blank line before the start of new section, unless it's
|
// add a blank line before the start of new section, unless it's
|
||||||
// the first section
|
// the first section
|
||||||
if (gridBagConstraints.gridy != 0) {
|
gridBagConstraints.insets = (gridBagConstraints.gridy == 0)
|
||||||
gridBagConstraints.gridy++;
|
? FIRST_HEADER_INSETS
|
||||||
// add to panel
|
: HEADER_INSETS;
|
||||||
addToPanel(new javax.swing.JLabel(" "));
|
|
||||||
addLineEndGlue();
|
|
||||||
headingLabel.setFocusable(false);
|
|
||||||
}
|
|
||||||
gridBagConstraints.gridy++;
|
gridBagConstraints.gridy++;
|
||||||
gridBagConstraints.gridx = LABEL_COLUMN;;
|
gridBagConstraints.gridx = LABEL_COLUMN;;
|
||||||
// let the header span all of the row
|
// let the header span all of the row
|
||||||
gridBagConstraints.gridwidth = MAX_COLS;
|
gridBagConstraints.gridwidth = MAX_COLS;
|
||||||
gridBagConstraints.insets = HEADER_INSETS;
|
|
||||||
// set text
|
// set text
|
||||||
headingLabel.setText(headerString);
|
headingLabel.setText(headerString);
|
||||||
// make it large and bold
|
// make it large and bold
|
||||||
headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2));
|
headingLabel.setFont(ContentViewerDefaults.getHeaderFont());
|
||||||
|
headingLabel.setMargin(ZERO_INSETS);
|
||||||
// add to panel
|
// add to panel
|
||||||
addToPanel(headingLabel);
|
addToPanel(headingLabel);
|
||||||
// reset constraints to normal
|
// reset constraints to normal
|
||||||
gridBagConstraints.gridwidth = LABEL_WIDTH;
|
gridBagConstraints.gridwidth = LABEL_WIDTH;
|
||||||
// add line end glue
|
// add line end glue
|
||||||
addLineEndGlue();
|
addLineEndGlue();
|
||||||
gridBagConstraints.insets = ROW_INSETS;
|
gridBagConstraints.insets = ZERO_INSETS;
|
||||||
return headingLabel;
|
return headingLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,6 +474,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
|||||||
javax.swing.JLabel keyLabel = new javax.swing.JLabel();
|
javax.swing.JLabel keyLabel = new javax.swing.JLabel();
|
||||||
keyLabel.setFocusable(false);
|
keyLabel.setFocusable(false);
|
||||||
gridBagConstraints.gridy++;
|
gridBagConstraints.gridy++;
|
||||||
|
gridBagConstraints.insets = KEY_COLUMN_INSETS;
|
||||||
gridBagConstraints.gridx = LABEL_COLUMN;
|
gridBagConstraints.gridx = LABEL_COLUMN;
|
||||||
gridBagConstraints.gridwidth = LABEL_WIDTH;
|
gridBagConstraints.gridwidth = LABEL_WIDTH;
|
||||||
// set text
|
// set text
|
||||||
@ -492,7 +502,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
|||||||
valueField.setFocusable(false);
|
valueField.setFocusable(false);
|
||||||
valueField.setEditable(false);
|
valueField.setEditable(false);
|
||||||
valueField.setOpaque(false);
|
valueField.setOpaque(false);
|
||||||
|
valueField.setMargin(ZERO_INSETS);
|
||||||
gridBagConstraints.gridx = VALUE_COLUMN;
|
gridBagConstraints.gridx = VALUE_COLUMN;
|
||||||
|
gridBagConstraints.insets = VALUE_COLUMN_INSETS;
|
||||||
GridBagConstraints cloneConstraints = (GridBagConstraints) gridBagConstraints.clone();
|
GridBagConstraints cloneConstraints = (GridBagConstraints) gridBagConstraints.clone();
|
||||||
// let the value span 2 cols
|
// let the value span 2 cols
|
||||||
cloneConstraints.gridwidth = VALUE_WIDTH;
|
cloneConstraints.gridwidth = VALUE_WIDTH;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2020 Basis Technology Corp.
|
* Copyright 2020-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,6 +19,7 @@
|
|||||||
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Insets;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.datatransfer.StringSelection;
|
import java.awt.datatransfer.StringSelection;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
@ -44,6 +45,7 @@ import javax.swing.JTextPane;
|
|||||||
import javax.swing.LayoutStyle.ComponentPlacement;
|
import javax.swing.LayoutStyle.ComponentPlacement;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
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.PersonaDetailsDialogCallback;
|
||||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
||||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
|
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.guiutils.ContactCache;
|
import org.sleuthkit.autopsy.guiutils.ContactCache;
|
||||||
import org.sleuthkit.datamodel.Account;
|
import org.sleuthkit.datamodel.Account;
|
||||||
@ -77,6 +80,15 @@ final class MessageAccountPanel extends JPanel {
|
|||||||
|
|
||||||
private AccountFetcher currentFetcher = null;
|
private AccountFetcher currentFetcher = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*/
|
||||||
|
MessageAccountPanel() {
|
||||||
|
this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the new artifact for the panel.
|
* Set the new artifact for the panel.
|
||||||
*
|
*
|
||||||
@ -170,9 +182,7 @@ final class MessageAccountPanel extends JPanel {
|
|||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(Alignment.LEADING)
|
layout.createParallelGroup(Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addGroup(getMainHorizontalGroup(layout, dataList))));
|
||||||
.addGroup(getMainHorizontalGroup(layout, dataList))
|
|
||||||
.addContainerGap(158, Short.MAX_VALUE)));
|
|
||||||
|
|
||||||
layout.setVerticalGroup(getMainVerticalGroup(layout, dataList));
|
layout.setVerticalGroup(getMainVerticalGroup(layout, dataList));
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
@ -186,6 +196,7 @@ final class MessageAccountPanel extends JPanel {
|
|||||||
|
|
||||||
messageLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
messageLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||||
messageLabel.setText(Bundle.MessageAccountPanel_no_matches());
|
messageLabel.setText(Bundle.MessageAccountPanel_no_matches());
|
||||||
|
messageLabel.setFont(ContentViewerDefaults.getMessageFont());
|
||||||
messageLabel.setEnabled(false);
|
messageLabel.setEnabled(false);
|
||||||
messagePanel.add(messageLabel, java.awt.BorderLayout.CENTER);
|
messagePanel.add(messageLabel, java.awt.BorderLayout.CENTER);
|
||||||
|
|
||||||
@ -224,14 +235,12 @@ final class MessageAccountPanel extends JPanel {
|
|||||||
private ParallelGroup getMainVerticalGroup(GroupLayout layout, List<AccountContainer> data) {
|
private ParallelGroup getMainVerticalGroup(GroupLayout layout, List<AccountContainer> data) {
|
||||||
SequentialGroup group = layout.createSequentialGroup();
|
SequentialGroup group = layout.createSequentialGroup();
|
||||||
for (AccountContainer o : data) {
|
for (AccountContainer o : data) {
|
||||||
group.addGap(5)
|
group.addComponent(o.getAccountLabel())
|
||||||
.addComponent(o.getAccountLabel())
|
|
||||||
.addGroup(o.getContactLineVerticalGroup(layout))
|
.addGroup(o.getContactLineVerticalGroup(layout))
|
||||||
.addGroup(o.getPersonLineVerticalGroup(layout));
|
.addGroup(o.getPersonLineVerticalGroup(layout));
|
||||||
|
group.addGap(ContentViewerDefaults.getSectionSpacing());
|
||||||
}
|
}
|
||||||
|
|
||||||
group.addContainerGap(83, Short.MAX_VALUE);
|
|
||||||
|
|
||||||
return layout.createParallelGroup().addGroup(group);
|
return layout.createParallelGroup().addGroup(group);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -259,12 +268,11 @@ final class MessageAccountPanel extends JPanel {
|
|||||||
private SequentialGroup getPersonaHorizontalGroup(GroupLayout layout, List<AccountContainer> data) {
|
private SequentialGroup getPersonaHorizontalGroup(GroupLayout layout, List<AccountContainer> data) {
|
||||||
SequentialGroup group = layout.createSequentialGroup();
|
SequentialGroup group = layout.createSequentialGroup();
|
||||||
ParallelGroup pgroup = layout.createParallelGroup(Alignment.LEADING);
|
ParallelGroup pgroup = layout.createParallelGroup(Alignment.LEADING);
|
||||||
group.addGap(10);
|
|
||||||
for (AccountContainer o : data) {
|
for (AccountContainer o : data) {
|
||||||
pgroup.addGroup(o.getPersonaSequentialGroup(layout));
|
pgroup.addGroup(o.getPersonaSequentialGroup(layout));
|
||||||
pgroup.addGroup(o.getContactSequentialGroup(layout));
|
pgroup.addGroup(o.getContactSequentialGroup(layout));
|
||||||
}
|
}
|
||||||
group.addGap(10)
|
group.addGap(ContentViewerDefaults.getSectionIndent())
|
||||||
.addGroup(pgroup)
|
.addGroup(pgroup)
|
||||||
.addPreferredGap(ComponentPlacement.RELATED)
|
.addPreferredGap(ComponentPlacement.RELATED)
|
||||||
.addGroup(getButtonGroup(layout, data));
|
.addGroup(getButtonGroup(layout, data));
|
||||||
@ -343,7 +351,9 @@ final class MessageAccountPanel extends JPanel {
|
|||||||
button = new JButton();
|
button = new JButton();
|
||||||
button.addActionListener(new PersonaButtonListener(this));
|
button.addActionListener(new PersonaButtonListener(this));
|
||||||
|
|
||||||
|
accountLabel.setMargin(new Insets(0, 0, 0, 0));
|
||||||
accountLabel.setText(account.getTypeSpecificID());
|
accountLabel.setText(account.getTypeSpecificID());
|
||||||
|
accountLabel.setFont(ContentViewerDefaults.getHeaderFont());
|
||||||
contactDisplayName.setText(contactName);
|
contactDisplayName.setText(contactName);
|
||||||
personaDisplayName.setText(persona != null ? persona.getName() : Bundle.MessageAccountPanel_unknown_label());
|
personaDisplayName.setText(persona != null ? persona.getName() : Bundle.MessageAccountPanel_unknown_label());
|
||||||
|
|
||||||
|
@ -2,11 +2,17 @@
|
|||||||
|
|
||||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
<Property name="background" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
<Connection code="ContentViewerDefaults.getPanelBackground()" type="code"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[495, 55]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[300, 55]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[495, 75]"/>
|
<Dimension value="[495, 55]"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -24,15 +30,13 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
|
||||||
<Component id="jSourceNameLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="jSourceNameLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
|
||||||
<Component id="jSourceTextLabel" max="32767" attributes="0"/>
|
<Component id="jSourceTextLabel" pref="360" max="32767" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="260" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="90" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
|
||||||
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
|
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
@ -41,14 +45,13 @@
|
|||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<Component id="jSourceNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="jSourceNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="jSourceTextLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="jSourceTextLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
|
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="0" pref="11" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2020 Basis Technology Corp.
|
* Copyright 2020-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.sleuthkit.autopsy.contentviewers.contextviewer.ContextViewer.DateTimePanel;
|
import org.sleuthkit.autopsy.contentviewers.contextviewer.ContextViewer.DateTimePanel;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||||
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
|
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();
|
jSourceNameLabel = new javax.swing.JLabel();
|
||||||
jSourceTextLabel = new javax.swing.JLabel();
|
jSourceTextLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
setBackground(new java.awt.Color(255, 255, 255));
|
setBackground(ContentViewerDefaults.getPanelBackground());
|
||||||
setPreferredSize(new java.awt.Dimension(495, 75));
|
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
|
org.openide.awt.Mnemonics.setLocalizedText(jSourceGoToResultButton, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceGoToResultButton.text")); // NOI18N
|
||||||
jSourceGoToResultButton.addActionListener(new java.awt.event.ActionListener() {
|
jSourceGoToResultButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
@ -94,26 +97,23 @@ public final class ContextSourcePanel extends javax.swing.JPanel implements Date
|
|||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(50, 50, 50)
|
|
||||||
.addComponent(jSourceNameLabel)
|
.addComponent(jSourceNameLabel)
|
||||||
.addGap(36, 36, 36)
|
.addGap(36, 36, 36)
|
||||||
.addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE))
|
||||||
.addGap(260, 260, 260))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(90, 90, 90)
|
.addGap(40, 40, 40)
|
||||||
.addComponent(jSourceGoToResultButton)
|
.addComponent(jSourceGoToResultButton)
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(2, 2, 2)
|
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(jSourceNameLabel)
|
.addComponent(jSourceNameLabel)
|
||||||
.addComponent(jSourceTextLabel))
|
.addComponent(jSourceTextLabel))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(jSourceGoToResultButton)
|
.addComponent(jSourceGoToResultButton)
|
||||||
.addGap(0, 0, 0))
|
.addGap(0, 11, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
@ -2,11 +2,17 @@
|
|||||||
|
|
||||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
<Property name="background" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
<Connection code="ContentViewerDefaults.getPanelBackground()" type="code"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 55]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[300, 55]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[495, 75]"/>
|
<Dimension value="[495, 55]"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -24,30 +30,28 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
|
||||||
<Component id="jUsageNameLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="jUsageNameLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Component id="jUsageTextLabel" pref="240" max="32767" attributes="0"/>
|
<Component id="jUsageTextLabel" pref="420" max="32767" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="90" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
|
||||||
<Component id="jUsageGoToResultButton" min="-2" max="-2" attributes="0"/>
|
<Component id="jUsageGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace pref="275" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="jUsageTextLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="jUsageTextLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="jUsageNameLabel" alignment="1" min="-2" max="-2" attributes="0"/>
|
<Component id="jUsageNameLabel" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jUsageGoToResultButton" min="-2" max="-2" attributes="0"/>
|
<Component id="jUsageGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="11" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2020 Basis Technology Corp.
|
* Copyright 2020-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||||
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
|
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();
|
jUsageNameLabel = new javax.swing.JLabel();
|
||||||
jUsageTextLabel = new javax.swing.JLabel();
|
jUsageTextLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
setBackground(new java.awt.Color(255, 255, 255));
|
setBackground(ContentViewerDefaults.getPanelBackground());
|
||||||
setPreferredSize(new java.awt.Dimension(495, 75));
|
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
|
org.openide.awt.Mnemonics.setLocalizedText(jUsageGoToResultButton, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageGoToResultButton.text")); // NOI18N
|
||||||
jUsageGoToResultButton.addActionListener(new java.awt.event.ActionListener() {
|
jUsageGoToResultButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
@ -93,25 +96,23 @@ public final class ContextUsagePanel extends javax.swing.JPanel implements Conte
|
|||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(50, 50, 50)
|
|
||||||
.addComponent(jUsageNameLabel)
|
.addComponent(jUsageNameLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 240, Short.MAX_VALUE)
|
.addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE))
|
||||||
.addGap(36, 36, 36))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(90, 90, 90)
|
.addGap(40, 40, 40)
|
||||||
.addComponent(jUsageGoToResultButton)
|
.addComponent(jUsageGoToResultButton)
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addContainerGap(275, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(2, 2, 2)
|
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(jUsageTextLabel)
|
.addComponent(jUsageTextLabel)
|
||||||
.addComponent(jUsageNameLabel, javax.swing.GroupLayout.Alignment.TRAILING))
|
.addComponent(jUsageNameLabel, javax.swing.GroupLayout.Alignment.TRAILING))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(jUsageGoToResultButton))
|
.addComponent(jUsageGoToResultButton)
|
||||||
|
.addGap(0, 11, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
@ -4,38 +4,19 @@
|
|||||||
<NonVisualComponents>
|
<NonVisualComponents>
|
||||||
<Container class="javax.swing.JPanel" name="jSourcePanel">
|
<Container class="javax.swing.JPanel" name="jSourcePanel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Color blue="ff" green="ff" id="window" palette="3" red="ff" type="palette"/>
|
<Connection code="new EmptyBorder(FIRST_HEADER_INSETS)" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
|
||||||
<Layout>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||||
<DimensionLayout dim="0">
|
<Property name="axis" type="int" value="3"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
|
|
||||||
<Component id="jSourceLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace pref="304" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
|
|
||||||
<Component id="jSourceLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="javax.swing.JLabel" name="jSourceLabel">
|
<Component class="javax.swing.JLabel" name="jSourceLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<FontInfo relative="true">
|
<Connection code="ContentViewerDefaults.getHeaderFont()" type="code"/>
|
||||||
<Font bold="true" component="jSourceLabel" property="font" relativeSize="true" size="1"/>
|
|
||||||
</FontInfo>
|
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jSourceLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jSourceLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
@ -50,38 +31,19 @@
|
|||||||
</Container>
|
</Container>
|
||||||
<Container class="javax.swing.JPanel" name="jUsagePanel">
|
<Container class="javax.swing.JPanel" name="jUsagePanel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Color blue="ff" green="ff" id="window" palette="3" red="ff" type="palette"/>
|
<Connection code="new EmptyBorder(HEADER_INSETS)" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
|
||||||
<Layout>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||||
<DimensionLayout dim="0">
|
<Property name="axis" type="int" value="3"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
|
|
||||||
<Component id="jUsageLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace pref="298" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
|
||||||
<Component id="jUsageLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="javax.swing.JLabel" name="jUsageLabel">
|
<Component class="javax.swing.JLabel" name="jUsageLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<FontInfo relative="true">
|
<Connection code="ContentViewerDefaults.getHeaderFont()
" type="code"/>
|
||||||
<Font bold="true" component="jUsageLabel" property="font" relativeSize="true" size="1"/>
|
|
||||||
</FontInfo>
|
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jUsageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jUsageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
@ -95,31 +57,9 @@
|
|||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
<Container class="javax.swing.JPanel" name="jUnknownPanel">
|
<Container class="javax.swing.JPanel" name="jUnknownPanel">
|
||||||
<Properties>
|
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
|
||||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
|
|
||||||
<Layout>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||||
<DimensionLayout dim="0">
|
<Property name="axis" type="int" value="3"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
|
||||||
<Component id="jUnknownLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
|
||||||
<Component id="jUnknownLabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="javax.swing.JLabel" name="jUnknownLabel">
|
<Component class="javax.swing.JLabel" name="jUnknownLabel">
|
||||||
@ -127,6 +67,9 @@
|
|||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jUnknownLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jUnknownLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
|
<Connection code="new EmptyBorder(DATA_ROW_INSETS)" type="code"/>
|
||||||
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
@ -137,11 +80,8 @@
|
|||||||
</Container>
|
</Container>
|
||||||
</NonVisualComponents>
|
</NonVisualComponents>
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
|
||||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[495, 358]"/>
|
<Dimension value="[0, 0]"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -171,8 +111,8 @@
|
|||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Container class="javax.swing.JScrollPane" name="jScrollPane">
|
<Container class="javax.swing.JScrollPane" name="jScrollPane">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
<Dimension value="[16, 16]"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2019 Basis Technology Corp.
|
* Copyright 2019-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,6 +19,7 @@
|
|||||||
package org.sleuthkit.autopsy.contentviewers.contextviewer;
|
package org.sleuthkit.autopsy.contentviewers.contextviewer;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Insets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@ -28,12 +29,14 @@ import java.util.Map;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
|
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
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 Logger logger = Logger.getLogger(ContextViewer.class.getName());
|
||||||
private static final int ARTIFACT_STR_MAX_LEN = 1024;
|
private static final int ARTIFACT_STR_MAX_LEN = 1024;
|
||||||
private static final int ATTRIBUTE_STR_MAX_LEN = 200;
|
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
|
// defines a list of artifacts that provide context for a file
|
||||||
private static final List<BlackboardArtifact.ARTIFACT_TYPE> CONTEXT_ARTIFACTS = new ArrayList<>();
|
private static final List<BlackboardArtifact.ARTIFACT_TYPE> CONTEXT_ARTIFACTS = new ArrayList<>();
|
||||||
@ -91,75 +98,30 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
|
|||||||
javax.swing.JLabel jUnknownLabel = new javax.swing.JLabel();
|
javax.swing.JLabel jUnknownLabel = new javax.swing.JLabel();
|
||||||
jScrollPane = new javax.swing.JScrollPane();
|
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
|
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);
|
jUsagePanel.setBorder(new EmptyBorder(HEADER_INSETS));
|
||||||
jSourcePanel.setLayout(jSourcePanelLayout);
|
jUsagePanel.setLayout(new javax.swing.BoxLayout(jUsagePanel, javax.swing.BoxLayout.PAGE_AXIS));
|
||||||
jSourcePanelLayout.setHorizontalGroup(
|
|
||||||
jSourcePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
jUsageLabel.setFont(ContentViewerDefaults.getHeaderFont()
|
||||||
.addGroup(jSourcePanelLayout.createSequentialGroup()
|
|
||||||
.addGap(40, 40, 40)
|
|
||||||
.addComponent(jSourceLabel)
|
|
||||||
.addContainerGap(304, Short.MAX_VALUE))
|
|
||||||
);
|
);
|
||||||
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
|
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);
|
jUnknownPanel.setLayout(new javax.swing.BoxLayout(jUnknownPanel, javax.swing.BoxLayout.PAGE_AXIS));
|
||||||
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));
|
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(jUnknownLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUnknownLabel.text")); // NOI18N
|
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);
|
setPreferredSize(new java.awt.Dimension(0, 0));
|
||||||
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));
|
jScrollPane.setPreferredSize(new java.awt.Dimension(16, 16));
|
||||||
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);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
@ -275,13 +237,17 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
javax.swing.JPanel contextContainer = new javax.swing.JPanel();
|
javax.swing.JPanel contextContainer = new javax.swing.JPanel();
|
||||||
contextContainer.add(jSourcePanel);
|
|
||||||
contextContainer.setLayout(new BoxLayout(contextContainer, BoxLayout.Y_AXIS));
|
contextContainer.setLayout(new BoxLayout(contextContainer, BoxLayout.Y_AXIS));
|
||||||
|
contextContainer.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
|
||||||
|
|
||||||
|
contextContainer.add(jSourcePanel);
|
||||||
|
|
||||||
if (contextSourcePanels.isEmpty()) {
|
if (contextSourcePanels.isEmpty()) {
|
||||||
contextContainer.add(jUnknownPanel);
|
contextContainer.add(jUnknownPanel);
|
||||||
} else {
|
} else {
|
||||||
for (javax.swing.JPanel sourcePanel : contextSourcePanels) {
|
for (javax.swing.JPanel sourcePanel : contextSourcePanels) {
|
||||||
contextContainer.add(sourcePanel);
|
contextContainer.add(sourcePanel);
|
||||||
|
contextContainer.setAlignmentX(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contextContainer.add(jUsagePanel);
|
contextContainer.add(jUsagePanel);
|
||||||
@ -290,10 +256,11 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
|
|||||||
} else {
|
} else {
|
||||||
for (javax.swing.JPanel usagePanel : contextUsagePanels) {
|
for (javax.swing.JPanel usagePanel : contextUsagePanels) {
|
||||||
contextContainer.add(usagePanel);
|
contextContainer.add(usagePanel);
|
||||||
|
contextContainer.setAlignmentX(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contextContainer.setBackground(javax.swing.UIManager.getDefaults().getColor("window"));
|
contextContainer.setBackground(ContentViewerDefaults.getPanelBackground());
|
||||||
contextContainer.setEnabled(foundASource);
|
contextContainer.setEnabled(foundASource);
|
||||||
contextContainer.setVisible(foundASource);
|
contextContainer.setVisible(foundASource);
|
||||||
jScrollPane.getViewport().setView(contextContainer);
|
jScrollPane.getViewport().setView(contextContainer);
|
||||||
@ -346,6 +313,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
|
|||||||
String sourceName = Bundle.ContextViewer_attachmentSource();
|
String sourceName = Bundle.ContextViewer_attachmentSource();
|
||||||
String sourceText = msgArtifactToAbbreviatedString(associatedArtifact);
|
String sourceText = msgArtifactToAbbreviatedString(associatedArtifact);
|
||||||
ContextSourcePanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, dateTime);
|
ContextSourcePanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, dateTime);
|
||||||
|
sourcePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS));
|
||||||
|
sourcePanel.setAlignmentX(0);
|
||||||
contextSourcePanels.add(sourcePanel);
|
contextSourcePanels.add(sourcePanel);
|
||||||
|
|
||||||
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID()
|
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID()
|
||||||
@ -353,18 +322,24 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
|
|||||||
String sourceName = Bundle.ContextViewer_downloadSource();
|
String sourceName = Bundle.ContextViewer_downloadSource();
|
||||||
String sourceText = webDownloadArtifactToString(associatedArtifact);
|
String sourceText = webDownloadArtifactToString(associatedArtifact);
|
||||||
ContextSourcePanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, dateTime);
|
ContextSourcePanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, dateTime);
|
||||||
|
sourcePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS));
|
||||||
|
sourcePanel.setAlignmentX(0);
|
||||||
contextSourcePanels.add(sourcePanel);
|
contextSourcePanels.add(sourcePanel);
|
||||||
|
|
||||||
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) {
|
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) {
|
||||||
String sourceName = Bundle.ContextViewer_recentDocs();
|
String sourceName = Bundle.ContextViewer_recentDocs();
|
||||||
String sourceText = recentDocArtifactToString(associatedArtifact);
|
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);
|
contextUsagePanels.add(usagePanel);
|
||||||
|
|
||||||
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) {
|
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) {
|
||||||
String sourceName = Bundle.ContextViewer_programExecution();
|
String sourceName = Bundle.ContextViewer_programExecution();
|
||||||
String sourceText = programExecArtifactToString(associatedArtifact);
|
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);
|
contextUsagePanels.add(usagePanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2021 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.contentviewers.layout;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.Color;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default values for layout of content values.
|
||||||
|
*/
|
||||||
|
public class ContentViewerDefaults {
|
||||||
|
|
||||||
|
private static final Font DEFAULT_FONT = UIManager.getDefaults().getFont("Label.font");
|
||||||
|
|
||||||
|
// 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 int DEFAULT_FONT_PX = (int) Math.round(DEFAULT_FONT.getSize() * PT_TO_PX);
|
||||||
|
|
||||||
|
private static final Font SUB_HEADER_FONT = DEFAULT_FONT.deriveFont(Font.BOLD);
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default font to be used.
|
||||||
|
*
|
||||||
|
* @return the default font to be used.
|
||||||
|
*/
|
||||||
|
public static Font getFont() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the font to be displayed for messages.
|
||||||
|
*
|
||||||
|
* @return The font to be displayed for messages.
|
||||||
|
*/
|
||||||
|
public static Font getHeaderFont() {
|
||||||
|
return HEADER_FONT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2021 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The style sheet an class names to be used with content viewers using html
|
||||||
|
* rendering.
|
||||||
|
*/
|
||||||
|
public class ContentViewerHtmlStyles {
|
||||||
|
|
||||||
|
// html stylesheet classnames for components
|
||||||
|
private static final String CLASS_PREFIX = ContentViewerHtmlStyles.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final String HEADER_CLASSNAME = CLASS_PREFIX + "header";
|
||||||
|
private static final String SUB_HEADER_CLASSNAME = CLASS_PREFIX + "subHeader";
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
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();
|
||||||
|
private static final Font MONOSPACED_FONT = ContentViewerDefaults.getMonospacedFont();
|
||||||
|
|
||||||
|
// 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 %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 { font-family: %s; font-size: %dpt; margin: 0px; padding: 0px 0px %dpt 0px; } ",
|
||||||
|
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 } ",
|
||||||
|
SPACED_SECTION_CLASSNAME, pxToPt(ContentViewerDefaults.getSectionSpacing()))
|
||||||
|
+ String.format(" .%s { padding-right: %dpt } ",
|
||||||
|
KEY_COLUMN_TD_CLASSNAME, pxToPt(ContentViewerDefaults.getColumnSpacing()));
|
||||||
|
|
||||||
|
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 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.
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* 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(STYLE_SHEET);
|
||||||
|
textPane.setMargin(ContentViewerDefaults.getPanelInsets());
|
||||||
|
textPane.setBackground(ContentViewerDefaults.getPanelBackground());
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,6 @@
|
|||||||
package org.sleuthkit.autopsy.contentviewers.osaccount;
|
package org.sleuthkit.autopsy.contentviewers.osaccount;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
@ -38,8 +37,10 @@ import javax.swing.Box;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||||
import org.sleuthkit.autopsy.contentviewers.osaccount.SectionData.RowData;
|
import org.sleuthkit.autopsy.contentviewers.osaccount.SectionData.RowData;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
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 KEY_COLUMN = 0;
|
||||||
private static final int VALUE_COLUMN = 1;
|
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 static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMM dd yyyy", US);
|
||||||
|
|
||||||
private PanelDataFetcher dataFetcher = null;
|
private PanelDataFetcher dataFetcher = null;
|
||||||
@ -76,6 +81,7 @@ public class OsAccountDataPanel extends JPanel {
|
|||||||
*/
|
*/
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
this.setLayout(new GridBagLayout());
|
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) {
|
private void addTitle(String title, int row) {
|
||||||
JLabel label = new JLabel(title);
|
JLabel label = new JLabel(title);
|
||||||
// Make the title bold.
|
// Make the title bold.
|
||||||
label.setFont(label.getFont().deriveFont(Font.BOLD));
|
label.setFont(ContentViewerDefaults.getHeaderFont());
|
||||||
add(label, getTitleContraints(row));
|
add(label, getTitleContraints(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +318,9 @@ public class OsAccountDataPanel extends JPanel {
|
|||||||
constraints.anchor = GridBagConstraints.NORTHWEST;
|
constraints.anchor = GridBagConstraints.NORTHWEST;
|
||||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||||
constraints.weightx = 1;
|
constraints.weightx = 1;
|
||||||
constraints.insets = new Insets(5, 5, 5, 9);
|
constraints.insets = (row == 0)
|
||||||
|
? FIRST_HEADER_INSETS
|
||||||
|
: HEADER_INSETS;
|
||||||
|
|
||||||
return constraints;
|
return constraints;
|
||||||
}
|
}
|
||||||
@ -332,7 +340,7 @@ public class OsAccountDataPanel extends JPanel {
|
|||||||
constraints.gridwidth = 1; // The title goes across the other columns
|
constraints.gridwidth = 1; // The title goes across the other columns
|
||||||
constraints.gridheight = 1;
|
constraints.gridheight = 1;
|
||||||
constraints.anchor = GridBagConstraints.WEST;
|
constraints.anchor = GridBagConstraints.WEST;
|
||||||
constraints.insets = new Insets(0, 13, 5, 5);
|
constraints.insets = KEY_COLUMN_INSETS;
|
||||||
|
|
||||||
return constraints;
|
return constraints;
|
||||||
}
|
}
|
||||||
@ -352,8 +360,8 @@ public class OsAccountDataPanel extends JPanel {
|
|||||||
constraints.gridwidth = 1; // The title goes across the other columns
|
constraints.gridwidth = 1; // The title goes across the other columns
|
||||||
constraints.gridheight = 1;
|
constraints.gridheight = 1;
|
||||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
constraints.insets = VALUE_COLUMN_INSETS;
|
||||||
constraints.weightx = 1;
|
constraints.weightx = 1;
|
||||||
constraints.insets = new Insets(0, 5, 5, 5);
|
|
||||||
|
|
||||||
return constraints;
|
return constraints;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2019 Basis Technology Corp.
|
* Copyright 2019-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corecomponents;
|
package org.sleuthkit.autopsy.corecomponents;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
import javax.swing.JTextPane;
|
import javax.swing.JTextPane;
|
||||||
import javax.swing.SizeRequirements;
|
import javax.swing.SizeRequirements;
|
||||||
import javax.swing.text.Element;
|
import javax.swing.text.Element;
|
||||||
@ -27,6 +28,8 @@ import javax.swing.text.ViewFactory;
|
|||||||
import javax.swing.text.html.HTMLEditorKit;
|
import javax.swing.text.html.HTMLEditorKit;
|
||||||
import javax.swing.text.html.InlineView;
|
import javax.swing.text.html.InlineView;
|
||||||
import javax.swing.text.html.ParagraphView;
|
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;
|
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,9 +99,15 @@ public class AutoWrappingJTextPane extends JTextPane {
|
|||||||
|
|
||||||
this.setEditorKit(editorKit);
|
this.setEditorKit(editorKit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setText(String text) {
|
public void setText(String text) {
|
||||||
super.setText("<pre>" + EscapeUtil.escapeHtml(text) + "</pre>");
|
// 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(MessageFormat.format("<pre style=\"{0}\">{1}</pre>", style, EscapeUtil.escapeHtml(text)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,6 @@ package org.sleuthkit.autopsy.corecomponents;
|
|||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.FontMetrics;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.dnd.DnDConstants;
|
import java.awt.dnd.DnDConstants;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
@ -49,6 +47,7 @@ import javax.swing.JTable;
|
|||||||
import javax.swing.ListSelectionModel;
|
import javax.swing.ListSelectionModel;
|
||||||
import static javax.swing.SwingConstants.CENTER;
|
import static javax.swing.SwingConstants.CENTER;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.UIManager;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.TableColumnModelEvent;
|
import javax.swing.event.TableColumnModelEvent;
|
||||||
@ -106,6 +105,27 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger LOGGER = Logger.getLogger(DataResultViewerTable.class.getName());
|
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 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 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";
|
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.
|
* OutlineView to the actions global context.
|
||||||
*
|
*
|
||||||
* @param explorerManager The explorer manager of the ancestor top
|
* @param explorerManager The explorer manager of the ancestor top
|
||||||
* component.
|
* component.
|
||||||
*/
|
*/
|
||||||
public DataResultViewerTable(ExplorerManager explorerManager) {
|
public DataResultViewerTable(ExplorerManager explorerManager) {
|
||||||
this(explorerManager, Bundle.DataResultViewerTable_title());
|
this(explorerManager, Bundle.DataResultViewerTable_title());
|
||||||
@ -165,8 +185,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
* in the OutlineView to the actions global context.
|
* in the OutlineView to the actions global context.
|
||||||
*
|
*
|
||||||
* @param explorerManager The explorer manager of the ancestor top
|
* @param explorerManager The explorer manager of the ancestor top
|
||||||
* component.
|
* component.
|
||||||
* @param title The title.
|
* @param title The title.
|
||||||
*/
|
*/
|
||||||
public DataResultViewerTable(ExplorerManager explorerManager, String title) {
|
public DataResultViewerTable(ExplorerManager explorerManager, String title) {
|
||||||
super(explorerManager);
|
super(explorerManager);
|
||||||
@ -361,15 +381,10 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
* If the given node is not null and has children, set it as the
|
* If the given node is not null and has children, set it as the
|
||||||
* root context of the child OutlineView, otherwise make an
|
* root context of the child OutlineView, otherwise make an
|
||||||
* "empty"node the root context.
|
* "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) {
|
if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) {
|
||||||
this.getExplorerManager().setRootContext(this.rootNode);
|
this.getExplorerManager().setRootContext(this.rootNode);
|
||||||
|
outline.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
||||||
setupTable();
|
setupTable();
|
||||||
} else {
|
} else {
|
||||||
Node emptyNode = new AbstractNode(Children.LEAF);
|
Node emptyNode = new AbstractNode(Children.LEAF);
|
||||||
@ -422,13 +437,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
firstProp = props.remove(0);
|
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
|
assignColumns(props); // assign columns to match the properties
|
||||||
if (firstProp != null) {
|
if (firstProp != null) {
|
||||||
((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(firstProp.getDisplayName());
|
((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(firstProp.getDisplayName());
|
||||||
@ -513,87 +521,59 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the column widths for the child OutlineView of this tabular results
|
* Sets the column widths for the child OutlineView of this tabular results
|
||||||
* viewer.
|
* viewer providing any additional width to last column.
|
||||||
*/
|
*/
|
||||||
protected void setColumnWidths() {
|
protected void setColumnWidths() {
|
||||||
if (rootNode.getChildren().getNodesCount() != 0) {
|
// based on https://stackoverflow.com/questions/17627431/auto-resizing-the-jtable-column-widths
|
||||||
final Graphics graphics = outlineView.getGraphics();
|
final TableColumnModel columnModel = outline.getColumnModel();
|
||||||
|
|
||||||
if (graphics != null) {
|
// the remaining table width that can be used in last row
|
||||||
// Current width of the outlineView
|
double availableTableWidth = outlineView.getSize().getWidth();
|
||||||
double outlineViewWidth = outlineView.getSize().getWidth();
|
|
||||||
// List of the column widths
|
|
||||||
List<Integer> columnWidths = new ArrayList<>();
|
|
||||||
final FontMetrics metrics = graphics.getFontMetrics();
|
|
||||||
|
|
||||||
int margin = 4;
|
for (int columnIdx = 0; columnIdx < outline.getColumnCount(); columnIdx++) {
|
||||||
int padding = 8;
|
int columnPadding = (columnIdx == 0) ? FIRST_COL_ADDITIONAL_WIDTH + COLUMN_PADDING : COLUMN_PADDING;
|
||||||
|
TableColumn tableColumn = columnModel.getColumn(columnIdx);
|
||||||
|
|
||||||
int totalColumnWidth = 0;
|
// The width of this column
|
||||||
int cntMaxSizeColumns = 0;
|
int width = MIN_COLUMN_WIDTH;
|
||||||
|
|
||||||
// Calulate the width for each column keeping track of the number
|
// get header cell width
|
||||||
// of columns that were set to columnwidthLimit.
|
// taken in part from https://stackoverflow.com/a/18381924
|
||||||
for (int column = 0; column < outline.getModel().getColumnCount(); column++) {
|
TableCellRenderer headerRenderer = tableColumn.getHeaderRenderer();
|
||||||
int firstColumnPadding = (column == 0) ? 32 : 0;
|
if (headerRenderer == null) {
|
||||||
int columnWidthLimit = (column == 0) ? 350 : 300;
|
headerRenderer = outline.getTableHeader().getDefaultRenderer();
|
||||||
int valuesWidth = 0;
|
}
|
||||||
|
Object headerValue = tableColumn.getHeaderValue();
|
||||||
// find the maximum width needed to fit the values for the first 100 rows, at most
|
Component headerComp = headerRenderer.getTableCellRendererComponent(outline, headerValue, false, false, 0, columnIdx);
|
||||||
for (int row = 0; row < Math.min(100, outline.getRowCount()); row++) {
|
width = Math.max(headerComp.getPreferredSize().width + columnPadding, width);
|
||||||
TableCellRenderer renderer = outline.getCellRenderer(row, column);
|
|
||||||
Component comp = outline.prepareRenderer(renderer, row, column);
|
// get the max of row widths from the first SAMPLE_ROW_NUM rows
|
||||||
valuesWidth = Math.max(comp.getPreferredSize().width, valuesWidth);
|
Component comp = null;
|
||||||
}
|
int rowCount = outline.getRowCount();
|
||||||
|
for (int row = 0; row < Math.min(rowCount, SAMPLE_ROW_NUM); row++) {
|
||||||
int headerWidth = metrics.stringWidth(outline.getColumnName(column));
|
TableCellRenderer renderer = outline.getCellRenderer(row, columnIdx);
|
||||||
valuesWidth += firstColumnPadding; // add extra padding for first column
|
comp = outline.prepareRenderer(renderer, row, columnIdx);
|
||||||
|
width = Math.max(comp.getPreferredSize().width + columnPadding, width);
|
||||||
int columnWidth = Math.max(valuesWidth, headerWidth);
|
}
|
||||||
columnWidth += 2 * margin + padding; // add margin and regular padding
|
|
||||||
|
// no higher than maximum column width
|
||||||
columnWidth = Math.min(columnWidth, columnWidthLimit);
|
if (width > MAX_COLUMN_WIDTH) {
|
||||||
columnWidths.add(columnWidth);
|
width = MAX_COLUMN_WIDTH;
|
||||||
|
}
|
||||||
totalColumnWidth += columnWidth;
|
|
||||||
|
// if last column, calculate remaining width factoring in the possibility of a scroll bar.
|
||||||
if (columnWidth == columnWidthLimit) {
|
if (columnIdx == outline.getColumnCount() - 1) {
|
||||||
cntMaxSizeColumns++;
|
int rowHeight = comp == null ? MIN_ROW_HEIGHT : comp.getPreferredSize().height;
|
||||||
}
|
if (headerComp.getPreferredSize().height + rowCount * rowHeight > outlineView.getSize().getHeight()) {
|
||||||
}
|
availableTableWidth -= SCROLL_BAR_WIDTH;
|
||||||
|
}
|
||||||
// Figure out how much extra, if any can be given to the columns
|
|
||||||
// so that the table is as wide as outlineViewWidth. If cntMaxSizeColumns
|
columnModel.getColumn(columnIdx).setPreferredWidth(Math.max(width, (int) availableTableWidth));
|
||||||
// is greater than 0 divide the extra space between the columns
|
} else {
|
||||||
// that could use more space. Otherwise divide evenly amoung
|
// otherwise set preferred width to width and decrement availableTableWidth accordingly
|
||||||
// all columns.
|
columnModel.getColumn(columnIdx).setPreferredWidth(width);
|
||||||
int extraWidth = 0;
|
availableTableWidth -= width;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// if there's no content just auto resize all columns
|
|
||||||
outline.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,7 +729,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
* order.
|
* order.
|
||||||
*
|
*
|
||||||
* @return a List<Node.Property<?>> of the properties in the persisted
|
* @return a List<Node.Property<?>> of the properties in the persisted
|
||||||
* order.
|
* order.
|
||||||
*/
|
*/
|
||||||
private synchronized List<Node.Property<?>> loadColumnOrder() {
|
private synchronized List<Node.Property<?>> loadColumnOrder() {
|
||||||
|
|
||||||
@ -1266,18 +1246,20 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the icon denoted by the Score's Significance.
|
* Returns the icon denoted by the Score's Significance.
|
||||||
|
*
|
||||||
* @param significance The Score's Significance.
|
* @param significance The Score's Significance.
|
||||||
|
*
|
||||||
* @return The icon (or null) related to that significance.
|
* @return The icon (or null) related to that significance.
|
||||||
*/
|
*/
|
||||||
private ImageIcon getIcon(Significance significance) {
|
private ImageIcon getIcon(Significance significance) {
|
||||||
if (significance == null) {
|
if (significance == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (significance) {
|
switch (significance) {
|
||||||
case NOTABLE:
|
case NOTABLE:
|
||||||
return NOTABLE_ICON_SCORE;
|
return NOTABLE_ICON_SCORE;
|
||||||
case LIKELY_NOTABLE:
|
case LIKELY_NOTABLE:
|
||||||
return INTERESTING_SCORE_ICON;
|
return INTERESTING_SCORE_ICON;
|
||||||
case LIKELY_NONE:
|
case LIKELY_NONE:
|
||||||
case NONE:
|
case NONE:
|
||||||
@ -1286,7 +1268,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
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);
|
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||||
|
@ -112,7 +112,7 @@ public abstract class AbstractContentNode<T extends Content> extends ContentNode
|
|||||||
* @param lookup The Lookup object for the node.
|
* @param lookup The Lookup object for the node.
|
||||||
*/
|
*/
|
||||||
AbstractContentNode(T content, Lookup lookup) {
|
AbstractContentNode(T content, Lookup lookup) {
|
||||||
super(Children.create(new ContentChildren(content), false), lookup);
|
super(Children.create(new ContentChildren(content), true), lookup);
|
||||||
this.content = content;
|
this.content = content;
|
||||||
//super.setName(ContentUtils.getSystemName(content));
|
//super.setName(ContentUtils.getSystemName(content));
|
||||||
super.setName("content_" + Long.toString(content.getId())); //NON-NLS
|
super.setName("content_" + Long.toString(content.getId())); //NON-NLS
|
||||||
|
@ -103,7 +103,21 @@ class ContentChildren extends AbstractContentChildren<Content> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<Content> makeKeys() {
|
protected List<Content> makeKeys() {
|
||||||
return getDisplayChildren(parent);
|
List<Content> 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
|
@Override
|
||||||
|
@ -69,7 +69,7 @@ public class DataSourceFilesNode extends DisplayableItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DataSourceFilesNode(long dsObjId) {
|
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;
|
displayName = (dsObjId > 0) ? NbBundle.getMessage(DataSourceFilesNode.class, "DataSourcesNode.group_by_datasource.name") : NAME;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ public class DataSourcesNode extends DisplayableItemNode {
|
|||||||
* Main constructor.
|
* Main constructor.
|
||||||
*/
|
*/
|
||||||
DataSourcesNode() {
|
DataSourcesNode() {
|
||||||
super(Children.create(new DataSourcesByTypeChildren(), false), Lookups.singleton(NAME));
|
super(Children.create(new DataSourcesByTypeChildren(), true), Lookups.singleton(NAME));
|
||||||
setName(NAME);
|
setName(NAME);
|
||||||
setDisplayName(NAME);
|
setDisplayName(NAME);
|
||||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/image.png");
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/image.png");
|
||||||
|
@ -212,7 +212,7 @@ public class HostNode extends DisplayableItemNode {
|
|||||||
* @param hosts The HostDataSources key.
|
* @param hosts The HostDataSources key.
|
||||||
*/
|
*/
|
||||||
HostNode(HostDataSources hosts) {
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,8 +20,6 @@ package org.sleuthkit.autopsy.datamodel;
|
|||||||
|
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
@ -35,7 +33,6 @@ import org.openide.util.NbBundle;
|
|||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction;
|
import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction;
|
import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
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.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.Image;
|
import org.sleuthkit.datamodel.Image;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
|
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.VirtualDirectory;
|
import org.sleuthkit.datamodel.VirtualDirectory;
|
||||||
import org.sleuthkit.autopsy.datamodel.BaseChildFactory.NoSuchEventBusException;
|
import org.sleuthkit.autopsy.datamodel.BaseChildFactory.NoSuchEventBusException;
|
||||||
@ -171,17 +167,10 @@ public class ImageNode extends AbstractContentNode<Image> {
|
|||||||
Bundle.ImageNode_createSheet_timezone_desc(),
|
Bundle.ImageNode_createSheet_timezone_desc(),
|
||||||
this.content.getTimeZone()));
|
this.content.getTimeZone()));
|
||||||
|
|
||||||
try (CaseDbQuery query = Case.getCurrentCaseThrows().getSleuthkitCase().executeQuery("SELECT device_id FROM data_source_info WHERE obj_id = " + this.content.getId());) {
|
sheetSet.put(new NodeProperty<>(Bundle.ImageNode_createSheet_deviceId_name(),
|
||||||
ResultSet deviceIdSet = query.getResultSet();
|
|
||||||
if (deviceIdSet.next()) {
|
|
||||||
sheetSet.put(new NodeProperty<>(Bundle.ImageNode_createSheet_deviceId_name(),
|
|
||||||
Bundle.ImageNode_createSheet_deviceId_displayName(),
|
Bundle.ImageNode_createSheet_deviceId_displayName(),
|
||||||
Bundle.ImageNode_createSheet_deviceId_desc(),
|
Bundle.ImageNode_createSheet_deviceId_desc(),
|
||||||
deviceIdSet.getString("device_id")));
|
content.getDeviceId()));
|
||||||
}
|
|
||||||
} catch (SQLException | TskCoreException | NoCurrentCaseException ex) {
|
|
||||||
logger.log(Level.SEVERE, "Failed to get device id for the following image: " + this.content.getId(), ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sheet;
|
return sheet;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ public class PersonNode extends DisplayableItemNode {
|
|||||||
* @param displayName The display name for the person.
|
* @param displayName The display name for the person.
|
||||||
*/
|
*/
|
||||||
private PersonNode(Person person, String displayName) {
|
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));
|
person == null ? Lookups.fixed(displayName) : Lookups.fixed(person, displayName));
|
||||||
super.setName(displayName);
|
super.setName(displayName);
|
||||||
super.setDisplayName(displayName);
|
super.setDisplayName(displayName);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2019 Basis Technology Corp.
|
* Copyright 2019-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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.Node;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
@ -59,7 +58,7 @@ final class DataSourceSummaryNode extends AbstractNode {
|
|||||||
* DataSources which are this nodes children
|
* DataSources which are this nodes children
|
||||||
*/
|
*/
|
||||||
DataSourceSummaryNode(List<DataSourceSummary> dataSourceList) {
|
DataSourceSummaryNode(List<DataSourceSummary> dataSourceList) {
|
||||||
super(Children.create(new DataSourceSummaryChildren(dataSourceList), false));
|
super(Children.create(new DataSourceSummaryChildren(dataSourceList), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,6 +46,7 @@ import net.sf.sevenzipjbinding.PropID;
|
|||||||
import net.sf.sevenzipjbinding.SevenZip;
|
import net.sf.sevenzipjbinding.SevenZip;
|
||||||
import net.sf.sevenzipjbinding.SevenZipException;
|
import net.sf.sevenzipjbinding.SevenZipException;
|
||||||
import net.sf.sevenzipjbinding.SevenZipNativeInitializationException;
|
import net.sf.sevenzipjbinding.SevenZipNativeInitializationException;
|
||||||
|
import org.apache.tika.Tika;
|
||||||
import org.apache.tika.parser.txt.CharsetDetector;
|
import org.apache.tika.parser.txt.CharsetDetector;
|
||||||
import org.apache.tika.parser.txt.CharsetMatch;
|
import org.apache.tika.parser.txt.CharsetMatch;
|
||||||
import org.netbeans.api.progress.ProgressHandle;
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
@ -194,6 +195,15 @@ class SevenZipExtractor {
|
|||||||
}
|
}
|
||||||
return false;
|
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
|
* Private helper method to standardize the cancellation check that is
|
||||||
@ -789,33 +799,18 @@ class SevenZipExtractor {
|
|||||||
// add them to the DB. We wait until the end so that we have the metadata on all of the
|
// 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
|
// intermediate nodes since the order is not guaranteed
|
||||||
try {
|
try {
|
||||||
unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath);
|
unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath, parentAr, archiveFile, depthMap);
|
||||||
if (checkForIngestCancellation(archiveFile)) {
|
if (checkForIngestCancellation(archiveFile)) {
|
||||||
return false;
|
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) {
|
} catch (TskCoreException | NoCurrentCaseException e) {
|
||||||
logger.log(Level.SEVERE, "Error populating complete derived file hierarchy from the unpacked dir structure", e); //NON-NLS
|
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
|
//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) {
|
} catch (SevenZipException | IllegalArgumentException ex) {
|
||||||
logger.log(Level.WARNING, "Error unpacking file: " + archiveFile, ex); //NON-NLS
|
logger.log(Level.WARNING, "Error unpacking file: " + archiveFile, ex); //NON-NLS
|
||||||
@ -991,6 +986,8 @@ class SevenZipExtractor {
|
|||||||
private EncodedFileOutputStream output;
|
private EncodedFileOutputStream output;
|
||||||
private String localAbsPath;
|
private String localAbsPath;
|
||||||
private int bytesWritten;
|
private int bytesWritten;
|
||||||
|
private static final Tika tika = new Tika();
|
||||||
|
private String mimeType = "";
|
||||||
|
|
||||||
UnpackStream(String localAbsPath) throws IOException {
|
UnpackStream(String localAbsPath) throws IOException {
|
||||||
this.output = new EncodedFileOutputStream(new FileOutputStream(localAbsPath), TskData.EncodingType.XOR1);
|
this.output = new EncodedFileOutputStream(new FileOutputStream(localAbsPath), TskData.EncodingType.XOR1);
|
||||||
@ -1003,6 +1000,7 @@ class SevenZipExtractor {
|
|||||||
this.output = new EncodedFileOutputStream(new FileOutputStream(localAbsPath), TskData.EncodingType.XOR1);
|
this.output = new EncodedFileOutputStream(new FileOutputStream(localAbsPath), TskData.EncodingType.XOR1);
|
||||||
this.localAbsPath = localAbsPath;
|
this.localAbsPath = localAbsPath;
|
||||||
this.bytesWritten = 0;
|
this.bytesWritten = 0;
|
||||||
|
this.mimeType = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
@ -1012,6 +1010,10 @@ class SevenZipExtractor {
|
|||||||
@Override
|
@Override
|
||||||
public int write(byte[] bytes) throws SevenZipException {
|
public int write(byte[] bytes) throws SevenZipException {
|
||||||
try {
|
try {
|
||||||
|
// Detect MIME type now while the file is in memory
|
||||||
|
if (bytesWritten == 0) {
|
||||||
|
mimeType = tika.detect(bytes);
|
||||||
|
}
|
||||||
output.write(bytes);
|
output.write(bytes);
|
||||||
this.bytesWritten += bytes.length;
|
this.bytesWritten += bytes.length;
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
@ -1023,6 +1025,10 @@ class SevenZipExtractor {
|
|||||||
return bytes.length;
|
return bytes.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMIMEType() {
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
try (EncodedFileOutputStream out = output) {
|
try (EncodedFileOutputStream out = output) {
|
||||||
out.flush();
|
out.flush();
|
||||||
@ -1196,6 +1202,8 @@ class SevenZipExtractor {
|
|||||||
0L, createTimeInSeconds, accessTimeInSeconds, modTimeInSeconds,
|
0L, createTimeInSeconds, accessTimeInSeconds, modTimeInSeconds,
|
||||||
localRelPath);
|
localRelPath);
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
unpackedNode.setMimeType(unpackStream.getMIMEType());
|
||||||
}
|
}
|
||||||
|
|
||||||
final String localAbsPath = archiveDetailsMap.get(
|
final String localAbsPath = archiveDetailsMap.get(
|
||||||
@ -1413,10 +1421,10 @@ class SevenZipExtractor {
|
|||||||
* Traverse the tree top-down after unzipping is done and create derived
|
* Traverse the tree top-down after unzipping is done and create derived
|
||||||
* files for the entire hierarchy
|
* files for the entire hierarchy
|
||||||
*/
|
*/
|
||||||
void updateOrAddFileToCaseRec(HashMap<String, ZipFileStatusWrapper> statusMap, String archiveFilePath) throws TskCoreException, NoCurrentCaseException {
|
void updateOrAddFileToCaseRec(HashMap<String, ZipFileStatusWrapper> statusMap, String archiveFilePath, Archive parentAr, AbstractFile archiveFile, ConcurrentHashMap<Long, Archive> depthMap) throws TskCoreException, NoCurrentCaseException {
|
||||||
final FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager();
|
final FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager();
|
||||||
for (UnpackedNode child : rootNode.getChildren()) {
|
for (UnpackedNode child : rootNode.getChildren()) {
|
||||||
updateOrAddFileToCaseRec(child, fileManager, statusMap, archiveFilePath);
|
updateOrAddFileToCaseRec(child, fileManager, statusMap, archiveFilePath, parentAr, archiveFile, depthMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1434,7 +1442,7 @@ class SevenZipExtractor {
|
|||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
private void updateOrAddFileToCaseRec(UnpackedNode node, FileManager fileManager, HashMap<String, ZipFileStatusWrapper> statusMap, String archiveFilePath) throws TskCoreException {
|
private void updateOrAddFileToCaseRec(UnpackedNode node, FileManager fileManager, HashMap<String, ZipFileStatusWrapper> statusMap, String archiveFilePath, Archive parentAr, AbstractFile archiveFile, ConcurrentHashMap<Long, Archive> depthMap) throws TskCoreException {
|
||||||
DerivedFile df;
|
DerivedFile df;
|
||||||
progress.progress(String.format("%s: Adding/updating files in case database (%d of %d)", currentArchiveName, ++nodesProcessed, numItems));
|
progress.progress(String.format("%s: Adding/updating files in case database (%d of %d)", currentArchiveName, ++nodesProcessed, numItems));
|
||||||
try {
|
try {
|
||||||
@ -1497,10 +1505,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
|
//recurse adding the children if this file was incomplete the children presumably need to be added
|
||||||
for (UnpackedNode child : node.getChildren()) {
|
for (UnpackedNode child : node.getChildren()) {
|
||||||
updateOrAddFileToCaseRec(child, fileManager, statusMap, getKeyFromUnpackedNode(node, archiveFilePath));
|
updateOrAddFileToCaseRec(child, fileManager, statusMap, getKeyFromUnpackedNode(node, archiveFilePath), parentAr, archiveFile, depthMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1517,6 +1532,7 @@ class SevenZipExtractor {
|
|||||||
private long size;
|
private long size;
|
||||||
private long ctime, crtime, atime, mtime;
|
private long ctime, crtime, atime, mtime;
|
||||||
private boolean isFile;
|
private boolean isFile;
|
||||||
|
private String mimeType = "";
|
||||||
private UnpackedNode parent;
|
private UnpackedNode parent;
|
||||||
|
|
||||||
//root constructor
|
//root constructor
|
||||||
@ -1593,6 +1609,14 @@ class SevenZipExtractor {
|
|||||||
void setFile(AbstractFile file) {
|
void setFile(AbstractFile file) {
|
||||||
this.file = 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
|
* get child by name or null if it doesn't exist
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2018 Basis Technology Corp.
|
* Copyright 2018-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -40,7 +40,7 @@ final class AinStatusNode extends AbstractNode {
|
|||||||
* Construct a new AinStatusNode.
|
* Construct a new AinStatusNode.
|
||||||
*/
|
*/
|
||||||
AinStatusNode(AutoIngestMonitor monitor) {
|
AinStatusNode(AutoIngestMonitor monitor) {
|
||||||
super(Children.create(new AinStatusChildren(monitor), false));
|
super(Children.create(new AinStatusChildren(monitor), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2018-2019 Basis Technology Corp.
|
* Copyright 2018-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -69,7 +69,7 @@ final class AutoIngestJobsNode extends AbstractNode {
|
|||||||
* refresh events
|
* refresh events
|
||||||
*/
|
*/
|
||||||
AutoIngestJobsNode(AutoIngestMonitor monitor, AutoIngestJobStatus status, EventBus eventBus) {
|
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;
|
refreshChildrenEventBus = eventBus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2020 Basis Technology Corp.
|
* Copyright 2011-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -29,10 +29,10 @@ import java.util.List;
|
|||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.SizeRequirements;
|
import javax.swing.SizeRequirements;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
|
import javax.swing.UIManager;
|
||||||
import javax.swing.text.Element;
|
import javax.swing.text.Element;
|
||||||
import javax.swing.text.View;
|
import javax.swing.text.View;
|
||||||
import javax.swing.text.ViewFactory;
|
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());
|
private static final Logger logger = Logger.getLogger(ExtractedContentPanel.class.getName());
|
||||||
|
|
||||||
// set font as close as possible to default
|
// 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 static final long serialVersionUID = 1L;
|
||||||
private String contentName;
|
private String contentName;
|
||||||
@ -72,7 +72,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
|||||||
ExtractedContentPanel() {
|
ExtractedContentPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
additionalInit();
|
additionalInit();
|
||||||
setSources("", new ArrayList<>());
|
|
||||||
hitPreviousButton.setEnabled(false);
|
hitPreviousButton.setEnabled(false);
|
||||||
hitNextButton.setEnabled(false);
|
hitNextButton.setEnabled(false);
|
||||||
|
|
||||||
@ -135,7 +134,7 @@ 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();
|
styleSheet = editorKit.getStyleSheet();
|
||||||
|
|
||||||
sourceComboBox.addItemListener(itemEvent -> {
|
sourceComboBox.addItemListener(itemEvent -> {
|
||||||
@ -144,6 +143,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
extractedTextPane.setComponentPopupMenu(rightClickMenu);
|
extractedTextPane.setComponentPopupMenu(rightClickMenu);
|
||||||
|
|
||||||
copyMenuItem.addActionListener(actionEvent -> extractedTextPane.copy());
|
copyMenuItem.addActionListener(actionEvent -> extractedTextPane.copy());
|
||||||
selectAllMenuItem.addActionListener(actionEvent -> extractedTextPane.selectAll());
|
selectAllMenuItem.addActionListener(actionEvent -> extractedTextPane.selectAll());
|
||||||
|
|
||||||
@ -156,11 +156,16 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
|||||||
if (zoomPanel instanceof TextZoomPanel)
|
if (zoomPanel instanceof TextZoomPanel)
|
||||||
((TextZoomPanel) this.zoomPanel).resetSize();
|
((TextZoomPanel) this.zoomPanel).resetSize();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setSources("", new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setStyleSheetSize(StyleSheet styleSheet, int size) {
|
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; } "
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -499,6 +504,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
|||||||
extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// refresh style
|
||||||
|
setStyleSheetSize(styleSheet, curSize);
|
||||||
extractedTextPane.setText(safeText);
|
extractedTextPane.setText(safeText);
|
||||||
extractedTextPane.setCaretPosition(0);
|
extractedTextPane.setCaretPosition(0);
|
||||||
}
|
}
|
||||||
|
@ -596,8 +596,9 @@ final class ChromeCacheExtractor {
|
|||||||
if (fileCopyCache.containsKey(fileTableKey)) {
|
if (fileCopyCache.containsKey(fileTableKey)) {
|
||||||
return Optional.of(fileCopyCache.get(fileTableKey).getAbstractFile());
|
return Optional.of(fileCopyCache.get(fileTableKey).getAbstractFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<AbstractFile> cacheFiles = fileManager.findFiles(dataSource, cacheFileName, cacheFolderName); //NON-NLS
|
List<AbstractFile> cacheFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource,
|
||||||
|
cacheFileName, cacheFolderName);
|
||||||
if (!cacheFiles.isEmpty()) {
|
if (!cacheFiles.isEmpty()) {
|
||||||
// Sort the list for consistency. Preference is:
|
// Sort the list for consistency. Preference is:
|
||||||
// - In correct subfolder and allocated
|
// - In correct subfolder and allocated
|
||||||
|
@ -633,7 +633,7 @@ class Chromium extends Extract {
|
|||||||
BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadFile, bbattributes);
|
BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadFile, bbattributes);
|
||||||
bbartifacts.add(webDownloadArtifact);
|
bbartifacts.add(webDownloadArtifact);
|
||||||
String normalizedFullPath = FilenameUtils.normalize(fullPath, true);
|
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));
|
bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -157,17 +157,13 @@ class DataSourceUsageAnalyzer extends Extract {
|
|||||||
* does not exist with the given description.
|
* does not exist with the given description.
|
||||||
*
|
*
|
||||||
* @param osType - the OS_TYPE to check for
|
* @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 {
|
private void checkIfOsSpecificVolume(ExtractOs.OS_TYPE osType) throws TskCoreException {
|
||||||
FileManager fileManager = currentCase.getServices().getFileManager();
|
|
||||||
for (String filePath : osType.getFilePaths()) {
|
for (String filePath : osType.getFilePaths()) {
|
||||||
for (AbstractFile file : fileManager.findFiles(dataSource, FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) {
|
for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource,
|
||||||
if ((file.getParentPath() + file.getName()).equals(filePath)) {
|
FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) {
|
||||||
createDataSourceUsageArtifact(osType.getDsUsageLabel());
|
createDataSourceUsageArtifact(osType.getDsUsageLabel());
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,12 +117,10 @@ class ExtractOs extends Extract {
|
|||||||
* search for
|
* search for
|
||||||
*/
|
*/
|
||||||
private AbstractFile getFirstFileFound(List<String> pathsToSearchFor) throws TskCoreException{
|
private AbstractFile getFirstFileFound(List<String> pathsToSearchFor) throws TskCoreException{
|
||||||
FileManager fileManager = currentCase.getServices().getFileManager();
|
|
||||||
for (String filePath : pathsToSearchFor) {
|
for (String filePath : pathsToSearchFor) {
|
||||||
for (AbstractFile file : fileManager.findFiles(dataSource, FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) {
|
List<AbstractFile> files = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath));
|
||||||
if ((file.getParentPath() + file.getName()).equals(filePath)) {
|
if (!files.isEmpty()) {
|
||||||
return file;
|
return files.get(0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1686,18 +1686,13 @@ class ExtractRegistry extends Extract {
|
|||||||
* @returnv BlackboardArtifact or a null value
|
* @returnv BlackboardArtifact or a null value
|
||||||
*/
|
*/
|
||||||
private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
|
private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
|
||||||
org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
|
|
||||||
String fileName = FilenameUtils.getName(filePathName);
|
String fileName = FilenameUtils.getName(filePathName);
|
||||||
String filePath = FilenameUtils.getPath(filePathName);
|
String filePath = FilenameUtils.getPath(filePathName);
|
||||||
List<AbstractFile> sourceFiles;
|
List<AbstractFile> sourceFiles;
|
||||||
try {
|
try {
|
||||||
sourceFiles = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS
|
sourceFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, filePath);
|
||||||
if (!sourceFiles.isEmpty()) {
|
if (!sourceFiles.isEmpty()) {
|
||||||
for (AbstractFile sourceFile : sourceFiles) {
|
return createAssociatedArtifact(sourceFiles.get(0), bba);
|
||||||
if (sourceFile.getParentPath().endsWith(filePath)) {
|
|
||||||
return createAssociatedArtifact(sourceFile, bba);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
// only catching the error and displaying the message as the file may not exist on the
|
// only catching the error and displaying the message as the file may not exist on the
|
||||||
|
@ -647,8 +647,6 @@ final class ExtractSafari extends Extract {
|
|||||||
Long time = null;
|
Long time = null;
|
||||||
Long pathID = null;
|
Long pathID = null;
|
||||||
|
|
||||||
FileManager fileManager = getCurrentCase().getServices().getFileManager();
|
|
||||||
|
|
||||||
NSString nsstring = (NSString) entry.get(PLIST_KEY_DOWNLOAD_URL);
|
NSString nsstring = (NSString) entry.get(PLIST_KEY_DOWNLOAD_URL);
|
||||||
if (nsstring != null) {
|
if (nsstring != null) {
|
||||||
url = nsstring.toString();
|
url = nsstring.toString();
|
||||||
@ -669,7 +667,8 @@ final class ExtractSafari extends Extract {
|
|||||||
bbartifacts.add(webDownloadArtifact);
|
bbartifacts.add(webDownloadArtifact);
|
||||||
|
|
||||||
// find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
|
// 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));
|
bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -592,7 +592,8 @@ class Firefox extends Extract {
|
|||||||
bbartifacts.add(webDownloadArtifact);
|
bbartifacts.add(webDownloadArtifact);
|
||||||
|
|
||||||
// find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
|
// 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));
|
bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -727,7 +728,8 @@ class Firefox extends Extract {
|
|||||||
bbartifacts.add(webDownloadArtifact);
|
bbartifacts.add(webDownloadArtifact);
|
||||||
|
|
||||||
// find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
|
// 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));
|
bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -152,13 +152,12 @@ class RecentDocumentsByLnk extends Extract {
|
|||||||
* @returnv BlackboardArtifact or a null value
|
* @returnv BlackboardArtifact or a null value
|
||||||
*/
|
*/
|
||||||
private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
|
private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
|
||||||
org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
|
|
||||||
String normalizePathName = FilenameUtils.normalize(filePathName, true);
|
String normalizePathName = FilenameUtils.normalize(filePathName, true);
|
||||||
String fileName = FilenameUtils.getName(normalizePathName);
|
String fileName = FilenameUtils.getName(normalizePathName);
|
||||||
String filePath = FilenameUtils.getPath(normalizePathName);
|
String filePath = FilenameUtils.getPath(normalizePathName);
|
||||||
List<AbstractFile> sourceFiles;
|
List<AbstractFile> sourceFiles;
|
||||||
try {
|
try {
|
||||||
sourceFiles = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS
|
sourceFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, filePath);
|
||||||
for (AbstractFile sourceFile : sourceFiles) {
|
for (AbstractFile sourceFile : sourceFiles) {
|
||||||
if (sourceFile.getParentPath().endsWith(filePath)) {
|
if (sourceFile.getParentPath().endsWith(filePath)) {
|
||||||
return createAssociatedArtifact(sourceFile, bba);
|
return createAssociatedArtifact(sourceFile, bba);
|
||||||
|
@ -135,8 +135,7 @@ class Util {
|
|||||||
parent_path = parent_path.substring(0, index);
|
parent_path = parent_path.substring(0, index);
|
||||||
List<AbstractFile> files = null;
|
List<AbstractFile> files = null;
|
||||||
try {
|
try {
|
||||||
FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager();
|
files = Case.getCurrentCaseThrows().getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, name, parent_path);
|
||||||
files = fileManager.findFiles(dataSource, name, parent_path);
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); //NON-NLS
|
logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); //NON-NLS
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user