Merge branch 'develop' of github.com:sleuthkit/autopsy into 7663-artifactUniquePath

This commit is contained in:
Greg DiCristofaro 2021-06-17 11:49:02 -04:00
commit 60e0125189
101 changed files with 2476 additions and 1201 deletions

View File

@ -0,0 +1,4 @@
#Mon Jun 14 12:23:19 UTC 2021
CTL_ResetWindowsAction=\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u30ea\u30bb\u30c3\u30c8
ResetWindowAction.confirm.text=\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u9589\u3058\u3066\u518d\u8d77\u52d5\u3057\u3001\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u4f4d\u7f6e\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u307e\u3059\u3002\n\n\u3059\u3079\u3066\u306e\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u4f4d\u7f6e\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f
ResetWindowAction.confirm.title=\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u30ea\u30bb\u30c3\u30c8

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
AddImageAction.ingestConfig.ongoingIngest.msg=<html>\u5225\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u65b0\u898f\u30bd\u30fc\u30b9\u3092\u4eca\u8ffd\u52a0\u3059\u308b\u3068\u3001\u73fe\u5728\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u51e6\u7406\u304c\u9045\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<br />\u7d9a\u884c\u3057\u3066\u65b0\u898f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u4eca\u3059\u3050\u8ffd\u52a0\u3057\u307e\u3059\u304b?</html> AddImageAction.ingestConfig.ongoingIngest.msg=<html>\u5225\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u65b0\u898f\u30bd\u30fc\u30b9\u3092\u4eca\u8ffd\u52a0\u3059\u308b\u3068\u3001\u73fe\u5728\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u51e6\u7406\u304c\u9045\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<br />\u7d9a\u884c\u3057\u3066\u65b0\u898f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u4eca\u3059\u3050\u8ffd\u52a0\u3057\u307e\u3059\u304b?</html>
AddImageAction.ingestConfig.ongoingIngest.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059 AddImageAction.ingestConfig.ongoingIngest.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059
AddImageAction.wizard.title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0 AddImageAction.wizard.title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
@ -25,10 +25,17 @@ AddImageWizardChooseDataSourceVisual.getName.text=\u30c7\u30fc\u30bf\u30bd\u30fc
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=\u53d6\u308a\u6d88\u3057 AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=\u53d6\u308a\u6d88\u3057
AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f\u3002 AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f\u3002
AddImageWizardIngestConfigPanel.name.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u69cb\u6210 AddImageWizardIngestConfigPanel.name.text=\u53d6\u8fbc\u307f\u306e\u69cb\u6210
AddImageWizardIngestConfigVisual.getName.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u69cb\u6210 AddImageWizardIngestConfigVisual.getName.text=\u53d6\u8fbc\u307f\u306e\u69cb\u6210
AddImageWizardIterator.stepXofN=\u624b\u9806 {0} / {1} AddImageWizardIterator.stepXofN=\u624b\u9806 {0} / {1}
AddImageWizardSelectDspVisual.multiUserWarning.text=\u3053\u306e\u30bf\u30a4\u30d7\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30e2\u30fc\u30c9\u3067\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 AddImageWizardSelectDspVisual.multiUserWarning.text=\u3053\u306e\u30bf\u30a4\u30d7\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30e2\u30fc\u30c9\u3067\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
AddImageWizardSelectHostPanel_title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3059\u308b\u30db\u30b9\u30c8\u306e\u9078\u629e
AddImageWizardSelectHostVisual.generateNewRadio.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d\u306b\u57fa\u3065\u3044\u3066\u65b0\u30db\u30b9\u30c8\u540d\u306e\u4f5c\u6210
AddImageWizardSelectHostVisual.hostDescription.text=\u30db\u30b9\u30c8\u306f\u3001\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3084\u305d\u306e\u4ed6\u306e\u30c7\u30fc\u30bf\u3092\u6574\u7406\u3059\u308b\u305f\u3081\u306b\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002
AddImageWizardSelectHostVisual.specifyNewHostRadio.text=\u65b0\u30db\u30b9\u30c8\u540d\u306e\u6307\u5b9a
AddImageWizardSelectHostVisual.useExistingHostRadio.text=\u65e2\u5b58\u306e\u30db\u30b9\u30c8\u306e\u4f7f\u7528
AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=\u65e2\u5b58\u306e\u30db\u30b9\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002
AddImageWizardSelectHostVisual_title=\u30db\u30b9\u30c8\u306e\u9078\u629e
AddLocalFilesTask.localFileAdd.progress.text=\u6b21\u3092\u8ffd\u52a0\u4e2d\u3067\u3059\: {0}/{1} AddLocalFilesTask.localFileAdd.progress.text=\u6b21\u3092\u8ffd\u52a0\u4e2d\u3067\u3059\: {0}/{1}
CTL_AddImage=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0 CTL_AddImage=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
CTL_AddImageButton=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0 CTL_AddImageButton=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
@ -86,6 +93,8 @@ Case.exceptionMessage.failedToReadMetadata=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\
Case.exceptionMessage.metadataUpdateError=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f Case.exceptionMessage.metadataUpdateError=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f
Case.exceptionMessage.unsupportedSchemaVersionMessage=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u306a\u3044\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3059\:\n{0}\u3002 Case.exceptionMessage.unsupportedSchemaVersionMessage=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u306a\u3044\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3059\:\n{0}\u3002
Case.getCurCase.exception.noneOpen=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3002\u30b1\u30fc\u30b9\u304c\u958b\u304b\u308c\u3066\u3044\u307e\u305b\u3093\! Case.getCurCase.exception.noneOpen=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3002\u30b1\u30fc\u30b9\u304c\u958b\u304b\u308c\u3066\u3044\u307e\u305b\u3093\!
Case.lockingException.couldNotAcquireExclusiveLock=\u30b1\u30fc\u30b9\u306e\u6392\u4ed6\u30ed\u30c3\u30af\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
Case.lockingException.couldNotAcquireSharedLock=\u30b1\u30fc\u30b9\u306e\u5171\u6709\u30ed\u30c3\u30af\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
Case.metaDataFileCorrupt.exception.msg=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb(.aut)\u304c\u7834\u640d\u3057\u3066\u3044\u307e\u3059\u3002 Case.metaDataFileCorrupt.exception.msg=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb(.aut)\u304c\u7834\u640d\u3057\u3066\u3044\u307e\u3059\u3002
Case.open.exception.multiUserCaseNotEnabled=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u304c\u6709\u52b9\u3067\u306a\u3044\u5834\u5408\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3002[\u30c4\u30fc\u30eb]\u3001[\u30aa\u30d7\u30b7\u30e7\u30f3]\u3001[\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc] \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002 Case.open.exception.multiUserCaseNotEnabled=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u304c\u6709\u52b9\u3067\u306a\u3044\u5834\u5408\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3002[\u30c4\u30fc\u30eb]\u3001[\u30aa\u30d7\u30b7\u30e7\u30f3]\u3001[\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc] \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002
Case.open.msgDlg.updated.msg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n\u6b21\u306e\u30d1\u30b9\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\:\n {0} Case.open.msgDlg.updated.msg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n\u6b21\u306e\u30d1\u30b9\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\:\n {0}
@ -384,7 +393,7 @@ ReviewModeCasePanel.StatusIconHeaderText=\u30b9\u30c6\u30fc\u30bf\u30b9
ReviewModeCasePanel.cannotOpenCase=\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093 ReviewModeCasePanel.cannotOpenCase=\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093
ReviewModeCasePanel.caseIsLocked=\u30b7\u30f3\u30b0\u30eb\u30e6\u30fc\u30b6\u30fc\u304c\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059\u3002 ReviewModeCasePanel.caseIsLocked=\u30b7\u30f3\u30b0\u30eb\u30e6\u30fc\u30b6\u30fc\u304c\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059\u3002
ReviewModeCasePanel.casePathNotFound=\u30b1\u30fc\u30b9\u30d1\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 ReviewModeCasePanel.casePathNotFound=\u30b1\u30fc\u30b9\u30d1\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
SelectDataSourceProcessorPanel.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u30bf\u30a4\u30d7\u3092\u9078\u629e\u3057\u3066\u8ffd\u52a0 SelectDataSourceProcessorPanel.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u306e\u9078\u629e
SingleUserCaseConverter.AlreadyMultiUser=\u30b1\u30fc\u30b9\u306f\u3059\u3067\u306b\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u3067\u3059\! SingleUserCaseConverter.AlreadyMultiUser=\u30b1\u30fc\u30b9\u306f\u3059\u3067\u306b\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u3067\u3059\!
SingleUserCaseConverter.BadDatabaseFileName=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\! SingleUserCaseConverter.BadDatabaseFileName=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\!
SingleUserCaseConverter.CanNotOpenDatabase=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093 SingleUserCaseConverter.CanNotOpenDatabase=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093

View File

@ -26,8 +26,10 @@ import java.util.Date;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
@ -51,12 +53,13 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED); private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED);
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE); private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE);
private static final int EXTRA_ROW_HEIGHT = 4; private static final int EXTRA_ROW_HEIGHT = 4;
private List<IngestJobInfo> ingestJobs; private final List<IngestJobInfo> ingestJobs = new ArrayList<>();
private final List<IngestJobInfo> ingestJobsForSelectedDataSource = new ArrayList<>(); private final List<IngestJobInfo> ingestJobsForSelectedDataSource = new ArrayList<>();
private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel(); private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel();
private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null); private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null);
private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
private DataSource selectedDataSource; private DataSource selectedDataSource;
private static SwingWorker<Boolean, Void> refreshWorker = null;
/** /**
* Creates new form IngestJobInfoPanel * Creates new form IngestJobInfoPanel
@ -76,7 +79,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
this.ingestModuleTable.setModel(this.ingestModuleTableModel); this.ingestModuleTable.setModel(this.ingestModuleTableModel);
}); });
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST , (PropertyChangeEvent evt) -> { IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
if (evt.getPropertyName().equals(IngestManager.IngestJobEvent.STARTED.toString()) if (evt.getPropertyName().equals(IngestManager.IngestJobEvent.STARTED.toString())
|| evt.getPropertyName().equals(IngestManager.IngestJobEvent.CANCELLED.toString()) || evt.getPropertyName().equals(IngestManager.IngestJobEvent.CANCELLED.toString())
|| evt.getPropertyName().equals(IngestManager.IngestJobEvent.COMPLETED.toString())) { || evt.getPropertyName().equals(IngestManager.IngestJobEvent.COMPLETED.toString())) {
@ -133,27 +136,51 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
* Get the updated complete list of ingest jobs. * Get the updated complete list of ingest jobs.
*/ */
private void refresh() { private void refresh() {
if (refreshWorker != null && !refreshWorker.isDone()) {
refreshWorker.cancel(true);
}
refreshWorker = new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
ingestJobs.clear();
try { try {
if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
this.ingestJobs = skCase.getIngestJobs(); ingestJobs.addAll(skCase.getIngestJobs());
setDataSource(selectedDataSource); setDataSource(selectedDataSource);
} else { } else {
this.ingestJobs = new ArrayList<>();
setDataSource(null); setDataSource(null);
} }
return true;
} catch (TskCoreException | NoCurrentCaseException ex) { } catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex); logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
JOptionPane.showMessageDialog(this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE); return false;
} }
} }
@Override
protected void done() {
try {
if (!get()) {
JOptionPane.showMessageDialog(IngestJobInfoPanel.this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
}
} catch (InterruptedException | ExecutionException ex) {
logger.log(Level.WARNING, "Error getting results from Ingest Job Info Panel's refresh worker", ex);
}
}
};
refreshWorker.execute();
}
/** /**
* Reset the panel. * Reset the panel.
*/ */
private void reset() { private void reset() {
this.ingestJobs = new ArrayList<>(); if (refreshWorker != null) {
refreshWorker.cancel(true);
}
this.ingestJobs.clear();
setDataSource(null); setDataSource(null);
} }

View File

@ -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));
} }
/** /**

View File

@ -1,54 +1,49 @@
DataContentViewerOtherCases.caseDetailsDialog.noCaseNameError=\u30a8\u30e9\u30fc #Mon Jun 14 12:23:19 UTC 2021
DataContentViewerOtherCases.caseDetailsDialog.noDetails=\u3053\u306e\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002
DataContentViewerOtherCases.caseDetailsDialog.noDetailsReference=\u30b0\u30ed\u30fc\u30d0\u30eb\u30ec\u30d5\u30a1\u30ec\u30f3\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u30b1\u30fc\u30b9\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002
DataContentViewerOtherCases.caseDetailsDialog.notSelected=\u884c\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
# {0} - \u5171\u6709\u6027\u306e\u5272\u5408
# {1} - \u76f8\u95a2\u5206\u6790\u30bf\u30a4\u30d7
# {2} - \u76f8\u95a2\u5206\u6790\u5024
DataContentViewerOtherCases.correlatedArtifacts.byType=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e {0}% \u306b {2} \u304c\u3042\u308a\u307e\u3059(\u30bf\u30a4\u30d7: {1})\n
DataContentViewerOtherCases.correlatedArtifacts.failed=\u983b\u5ea6\u306e\u8a73\u7d30\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
DataContentViewerOtherCases.correlatedArtifacts.isEmpty=\u76f8\u95a2\u5206\u6790\u3059\u308b\u305f\u3081\u306e\u30d5\u30a1\u30a4\u30eb\u3084\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c\u304c\u3042\u308a\u307e\u305b\u3093\u3002
DataContentViewerOtherCases.correlatedArtifacts.title=\u5c5e\u6027\u983b\u5ea6
DataContentViewerOtherCases.dataSources.header.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d
DataContentViewerOtherCases.earliestCaseNotAvailable=\ \u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u3002
DataContentViewerOtherCases.foundIn.text=%d \u306e\u30b1\u30fc\u30b9\u3068 %d \u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u5185\u306b %d \u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002
DataContentViewerOtherCases.noOpenCase.errMsg=\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u306f\u3042\u308a\u307e\u305b\u3093\u3002
DataContentViewerOtherCases.table.noArtifacts=\u9805\u76ee\u306b\u691c\u7d22\u306b\u5229\u7528\u3067\u304d\u308b\u5c5e\u6027\u306f\u3042\u308a\u307e\u305b\u3093\u3002
DataContentViewerOtherCases.table.noResultsFound=\u8a72\u5f53\u3059\u308b\u7d50\u679c\u304c\u3042\u308a\u307e\u305b\u3093\u3002
DataContentViewerOtherCases.table.toolTip.text=\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u30bd\u30fc\u30c8\u3057\u307e\u3059\u3002\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u3055\u3089\u306a\u308b\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8868\u793a\u3057\u307e\u3059\u3002 DataContentViewerOtherCases.table.toolTip.text=\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u30bd\u30fc\u30c8\u3057\u307e\u3059\u3002\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u3055\u3089\u306a\u308b\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8868\u793a\u3057\u307e\u3059\u3002
DataContentViewerOtherCases.title=\u305d\u306e\u4ed6\u306e\u767a\u751f DataContentViewerOtherCases.title=\u305d\u306e\u4ed6\u306e\u767a\u751f
DataContentViewerOtherCases.toolTip=\u305d\u306e\u4ed6\u306e\u767a\u751f\u304b\u3089\u9078\u629e\u3057\u305f\u30d5\u30a1\u30a4\u30eb/\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8868\u793a\u3057\u307e\u3059\u3002 DataContentViewerOtherCases.toolTip=\u305d\u306e\u4ed6\u306e\u767a\u751f\u304b\u3089\u9078\u629e\u3057\u305f\u30d5\u30a1\u30a4\u30eb/\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8868\u793a\u3057\u307e\u3059\u3002
DataContentViewerOtherCasesModel.csvHeader.attribute=\u4e00\u81f4\u3057\u305f\u5c5e\u6027 OccurrencePanel.caseCreatedDateLabel.text=\u4f5c\u6210\u65e5\:
DataContentViewerOtherCasesModel.csvHeader.case=\u30b1\u30fc\u30b9
DataContentViewerOtherCasesModel.csvHeader.comment=\u30b3\u30e1\u30f3\u30c8
DataContentViewerOtherCasesModel.csvHeader.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
DataContentViewerOtherCasesModel.csvHeader.device=\u30c7\u30d0\u30a4\u30b9
DataContentViewerOtherCasesModel.csvHeader.known=\u65e2\u77e5
DataContentViewerOtherCasesModel.csvHeader.path=\u30d1\u30b9
DataContentViewerOtherCasesModel.csvHeader.value=\u5c5e\u6027\u5024
OccurrencePanel.caseCreatedDateLabel.text=\u4f5c\u6210\u65e5:
OccurrencePanel.caseDetails.text=\u30b1\u30fc\u30b9\u8a73\u7d30 OccurrencePanel.caseDetails.text=\u30b1\u30fc\u30b9\u8a73\u7d30
OccurrencePanel.caseNameLabel.text=\u540d\u524d: OccurrencePanel.caseNameLabel.text=\u540d\u524d\:
OccurrencePanel.commonProperties.text=\u5171\u901a\u306e\u30d7\u30ed\u30d1\u30c6\u30a3 OccurrencePanel.commonProperties.text=\u5171\u901a\u306e\u30d7\u30ed\u30d1\u30c6\u30a3
OccurrencePanel.commonPropertyCommentLabel.text=\u30b3\u30e1\u30f3\u30c8: OccurrencePanel.commonPropertyCommentLabel.text=\u30b3\u30e1\u30f3\u30c8\:
OccurrencePanel.commonPropertyKnownStatusLabel.text=\u65e2\u77e5\u306e\u30b9\u30c6\u30fc\u30bf\u30b9: OccurrencePanel.commonPropertyKnownStatusLabel.text=\u65e2\u77e5\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\:
OccurrencePanel.commonPropertyTypeLabel.text=\u30bf\u30a4\u30d7: OccurrencePanel.commonPropertyTypeLabel.text=\u30bf\u30a4\u30d7\:
OccurrencePanel.commonPropertyValueLabel.text=\u5024: OccurrencePanel.commonPropertyValueLabel.text=\u5024\:
OccurrencePanel.dataSourceDetails.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u8a73\u7d30 OccurrencePanel.dataSourceDetails.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u8a73\u7d30
OccurrencePanel.dataSourceNameLabel.text=\u540d\u524d: OccurrencePanel.dataSourceNameLabel.text=\u540d\u524d\:
OccurrencePanel.fileDetails.text=\u30d5\u30a1\u30a4\u30eb\u8a73\u7d30 OccurrencePanel.fileDetails.text=\u30d5\u30a1\u30a4\u30eb\u8a73\u7d30
OccurrencePanel.filePathLabel.text=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9: OccurrencePanel.filePathLabel.text=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\:
OtherOccurrencesCasesTableModel.case=\u30b1\u30fc\u30b9 OtherOccurrencesCasesTableModel.case=\u30b1\u30fc\u30b9
OtherOccurrencesCasesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002 OtherOccurrencesCasesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002
OtherOccurrencesDataSourcesTableModel.dataSourceName=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d OtherOccurrencesDataSourcesTableModel.dataSourceName=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d
OtherOccurrencesDataSourcesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002 OtherOccurrencesDataSourcesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002
OtherOccurrencesFilesTableModel.fileName=\u30d5\u30a1\u30a4\u30eb\u540d OtherOccurrencesFilesTableModel.fileName=\u30d5\u30a1\u30a4\u30eb\u540d
OtherOccurrencesFilesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002 OtherOccurrencesFilesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002
OtherOccurrencesPanel.filesTable.toolTipText=\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u30bd\u30fc\u30c8\u3057\u307e\u3059\u3002\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u3055\u3089\u306a\u308b\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8868\u793a\u3057\u307e\u3059\u3002 OtherOccurrencesPanel.caseDetailsDialog.noCaseNameError=\u30a8\u30e9\u30fc
OtherOccurrencesPanel.earliestCaseLabel.toolTipText= OtherOccurrencesPanel.caseDetailsDialog.noDetails=\u3053\u306e\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002
OtherOccurrencesPanel.earliestCaseLabel.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u958b\u59cb\u65e5: OtherOccurrencesPanel.caseDetailsDialog.noDetailsReference=\u30b0\u30ed\u30fc\u30d0\u30eb\u53c2\u7167\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002
OtherOccurrencesPanel.earliestCaseDate.text=\u6700\u3082\u53e4\u3044\u30b1\u30fc\u30b9\u65e5\u4ed8 OtherOccurrencesPanel.caseDetailsDialog.notSelected=\u884c\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
OtherOccurrencesPanel.foundInLabel.text= OtherOccurrencesPanel.correlatedArtifacts.byType=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e{0}\uff05\u306b{2}\u304c\u3042\u308a\u307e\u3059\uff08\u30bf\u30a4\u30d7\uff1a{1}\uff09
OtherOccurrencesPanel.correlatedArtifacts.failed=\u983b\u5ea6\u306e\u8a73\u7d30\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
OtherOccurrencesPanel.correlatedArtifacts.isEmpty=\u95a2\u9023\u4ed8\u3051\u308b\u30d5\u30a1\u30a4\u30eb\u3084\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002
OtherOccurrencesPanel.correlatedArtifacts.title=\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u306e\u983b\u5ea6
OtherOccurrencesPanel.csvHeader.attribute=\u4e00\u81f4\u3057\u305f\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8
OtherOccurrencesPanel.csvHeader.case=\u30b1\u30fc\u30b9
OtherOccurrencesPanel.csvHeader.comment=\u30b3\u30e1\u30f3\u30c8
OtherOccurrencesPanel.csvHeader.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
OtherOccurrencesPanel.csvHeader.device=\u30c7\u30d0\u30a4\u30b9
OtherOccurrencesPanel.csvHeader.known=\u65e2\u77e5
OtherOccurrencesPanel.csvHeader.path=\u30d1\u30b9
OtherOccurrencesPanel.csvHeader.value=\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u5024
OtherOccurrencesPanel.earliestCaseDate.text=\u30b1\u30fc\u30b9\u306e\u6700\u521d\u306e\u65e5\u4ed8
OtherOccurrencesPanel.earliestCaseLabel.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u958b\u59cb\u65e5\uff1a
OtherOccurrencesPanel.earliestCaseNotAvailable=\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u3002
OtherOccurrencesPanel.exportToCSVMenuItem.text=\u305d\u306e\u4ed6\u306e\u3059\u3079\u3066\u306e\u767a\u751f\u3092CSV\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8
OtherOccurrencesPanel.filesTable.toolTipText=\u4e26\u3079\u66ff\u3048\u306f\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3002 \u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u3001\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3002
OtherOccurrencesPanel.foundIn.text=\uff05d\u30b1\u30fc\u30b9\u3068\uff05d\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\uff05d\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002
OtherOccurrencesPanel.noOpenCase.errMsg=\u30aa\u30fc\u30d7\u30f3\u30b1\u30fc\u30b9\u306f\u3042\u308a\u307e\u305b\u3093\u3002
OtherOccurrencesPanel.showCaseDetailsMenuItem.text=\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u3092\u8868\u793a
OtherOccurrencesPanel.showCommonalityMenuItem.text=\u983b\u5ea6\u3092\u8868\u793a OtherOccurrencesPanel.showCommonalityMenuItem.text=\u983b\u5ea6\u3092\u8868\u793a
OtherOccurrencesPanel.showCaseDetailsMenuItem.text=\u30b1\u30fc\u30b9\u8a73\u7d30\u3092\u8868\u793a OtherOccurrencesPanel.table.noArtifacts=\u30a2\u30a4\u30c6\u30e0\u306b\u306f\u3001\u691c\u7d22\u3059\u308b\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002
OtherOccurrencesPanel.exportToCSVMenuItem.text=\u305d\u306e\u4ed6\u3059\u3079\u3066\u306e\u767a\u751f\u3092CSV\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 OtherOccurrencesPanel.table.noResultsFound=\u7d50\u679c\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002

View File

@ -1,4 +1,4 @@
#Tue Aug 18 18:09:20 UTC 2020 #Mon Jun 14 12:23:19 UTC 2021
AddNewOrganizationDialog.addNewOrg.msg=\u65b0\u898f\u7d44\u7e54\u3092\u8ffd\u52a0 AddNewOrganizationDialog.addNewOrg.msg=\u65b0\u898f\u7d44\u7e54\u3092\u8ffd\u52a0
AddNewOrganizationDialog.bnCancel.text=\u53d6\u308a\u6d88\u3057 AddNewOrganizationDialog.bnCancel.text=\u53d6\u308a\u6d88\u3057
AddNewOrganizationDialog.bnOK.text=OK AddNewOrganizationDialog.bnOK.text=OK
@ -93,9 +93,9 @@ GlobalSettingsPanel.manageOrganizationButton.text=\u7d44\u7e54\u3092\u7ba1\u7406
GlobalSettingsPanel.onMultiUserChange.disabledMu.description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306f\u30ed\u30fc\u30ab\u30ebSQLite\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u3057\u3066\u518d\u69cb\u6210\u3055\u308c\u307e\u3059 GlobalSettingsPanel.onMultiUserChange.disabledMu.description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306f\u30ed\u30fc\u30ab\u30ebSQLite\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u3057\u3066\u518d\u69cb\u6210\u3055\u308c\u307e\u3059
GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=[PostgreSQL\u306e\u69cb\u6210]\u3092\u62bc\u3057\u3066\u3001PostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u5909\u66f4\u3057\u307e\u3059\u3002 GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=[PostgreSQL\u306e\u69cb\u6210]\u3092\u62bc\u3057\u3066\u3001PostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u5909\u66f4\u3057\u307e\u3059\u3002
GlobalSettingsPanel.onMultiUserChange.disabledMu.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306e\u5909\u66f4\u304c\u5fc5\u8981\u3067\u3059 GlobalSettingsPanel.onMultiUserChange.disabledMu.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306e\u5909\u66f4\u304c\u5fc5\u8981\u3067\u3059
GlobalSettingsPanel.onMultiUserChange.enable.description=\u3053\u306ePostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f7f\u7528\u3059\u308b\u3088\u3046\u306b\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u3092\u66f4\u65b0\u3057\u307e\u3059\u304b\uff1f GlobalSettingsPanel.onMultiUserChange.enable.description=\u3053\u306ePostgreSQL\u30b5\u30fc\u30d0\u30fc\u3092\u4f7f\u7528\u3059\u308b\u3088\u3046\u306b\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u66f4\u65b0\u3057\u307e\u3059\u304b\uff1f
GlobalSettingsPanel.onMultiUserChange.enable.description2=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306b\u306f\u904e\u53bb\u306e\u30b1\u30fc\u30b9\u304b\u3089\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3068\u30a2\u30ab\u30a6\u30f3\u30c8\u304c\u4fdd\u5b58\u3055\u308c\u307e\u3059\u3002 GlobalSettingsPanel.onMultiUserChange.enable.description2=\u65e2\u5b58\u306eSQLite\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30c7\u30fc\u30bf\u306f\u65b0\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u8ee2\u9001\u3055\u308c\u307e\u305b\u3093\u3002
GlobalSettingsPanel.onMultiUserChange.enable.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u3067\u4f7f\u7528\u3057\u307e\u3059\u304b\uff1f GlobalSettingsPanel.onMultiUserChange.enable.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea
GlobalSettingsPanel.organizationPanel.border.title=\u7d44\u7e54 GlobalSettingsPanel.organizationPanel.border.title=\u7d44\u7e54
GlobalSettingsPanel.organizationTextArea.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u5185\u3067\u7d44\u7e54\u60c5\u5831\u3092\u8ffd\u8de1\u3067\u304d\u307e\u3059\u3002 GlobalSettingsPanel.organizationTextArea.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u5185\u3067\u7d44\u7e54\u60c5\u5831\u3092\u8ffd\u8de1\u3067\u304d\u307e\u3059\u3002
GlobalSettingsPanel.pnCorrelationProperties.border.title=\u76f8\u95a2\u5206\u6790\u30d7\u30ed\u30d1\u30c6\u30a3 GlobalSettingsPanel.pnCorrelationProperties.border.title=\u76f8\u95a2\u5206\u6790\u30d7\u30ed\u30d1\u30c6\u30a3

View File

@ -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;

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
ContactDetailsPane.nameLabel.text=\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u30fc ContactDetailsPane.nameLabel.text=\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u30fc
ContactNode_Email=\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9 ContactNode_Email=\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9
ContactNode_Home_Number=\u81ea\u5b85\u96fb\u8a71\u756a\u53f7 ContactNode_Home_Number=\u81ea\u5b85\u96fb\u8a71\u756a\u53f7
@ -64,7 +64,7 @@ SummaryViewer_CentralRepository_Message=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u3
SummaryViewer_Creation_Date_Title=\u4f5c\u6210\u65e5 SummaryViewer_Creation_Date_Title=\u4f5c\u6210\u65e5
SummaryViewer_Fetching_References=<\u30d5\u30a1\u30a4\u30eb\u53c2\u7167\u306e\u53d6\u5f97> SummaryViewer_Fetching_References=<\u30d5\u30a1\u30a4\u30eb\u53c2\u7167\u306e\u53d6\u5f97>
SummaryViewer_FileRefNameColumn_Title=\u30d1\u30b9 SummaryViewer_FileRefNameColumn_Title=\u30d1\u30b9
SummaryViewer_Persona_Message=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u53ef\u80fd\u306b\u3059\u308b> SummaryViewer_Persona_CR_Message=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b>
SummaryViewer_Select_account_for_persona=<\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u3059\u308b\u306b\u306f\u3001\u30a2\u30ab\u30a6\u30f3\u30c8\u30921\u3064\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044> SummaryViewer_Select_account_for_persona=<\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u3059\u308b\u306b\u306f\u3001\u30a2\u30ab\u30a6\u30f3\u30c8\u30921\u3064\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044>
SummaryViewer_TabTitle=\u30b5\u30de\u30ea\u30fc SummaryViewer_TabTitle=\u30b5\u30de\u30ea\u30fc
SummeryViewer_FileRef_Message=<\u30a2\u30ab\u30a6\u30f3\u30c8\u30921\u3064\u9078\u629e\u3057\u3066\u30d5\u30a1\u30a4\u30eb\u30ec\u30d5\u30a1\u30ec\u30f3\u30b9\u3092\u8868\u793a> SummeryViewer_FileRef_Message=<\u30a2\u30ab\u30a6\u30f3\u30c8\u30921\u3064\u9078\u629e\u3057\u3066\u30d5\u30a1\u30a4\u30eb\u30ec\u30d5\u30a1\u30ec\u30f3\u30b9\u3092\u8868\u793a>

View File

@ -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");
@ -121,7 +121,7 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie
}); });
TableColumn column = outline.getColumnModel().getColumn(2); TableColumn column = outline.getColumnModel().getColumn(2);
column.setCellRenderer(new NodeTableCellRenderer() ); column.setCellRenderer(new NodeTableCellRenderer());
} }
@ -164,7 +164,9 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie
@Override @Override
public void setSelectionInfo(SelectionInfo info) { public void setSelectionInfo(SelectionInfo info) {
callLogDataViewer.setNode(null);
nodeFactory.refresh(info); nodeFactory.refresh(info);
} }
@Override @Override

View File

@ -35,7 +35,8 @@ import org.sleuthkit.datamodel.TskCoreException;
/** /**
* ChildFactory for ContactNodes. * ChildFactory for ContactNodes.
*/ */
final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{ final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact> {
private static final Logger logger = Logger.getLogger(ContactsChildNodeFactory.class.getName()); private static final Logger logger = Logger.getLogger(ContactsChildNodeFactory.class.getName());
private SelectionInfo selectionInfo; private SelectionInfo selectionInfo;
@ -51,7 +52,8 @@ final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{
} }
/** /**
* Updates the current instance of selectionInfo and calls the refresh method. * Updates the current instance of selectionInfo and calls the refresh
* method.
* *
* @param selectionInfo New instance of the currently selected accounts * @param selectionInfo New instance of the currently selected accounts
*/ */
@ -63,13 +65,15 @@ final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{
/** /**
* Creates a list of Keys (BlackboardArtifact) for only contacts of the * Creates a list of Keys (BlackboardArtifact) for only contacts of the
* currently selected accounts * currently selected accounts
*
* @param list List of BlackboardArtifact to populate * @param list List of BlackboardArtifact to populate
*
* @return True on success * @return True on success
*/ */
@Override @Override
protected boolean createKeys(List<BlackboardArtifact> list) { protected boolean createKeys(List<BlackboardArtifact> list) {
if(selectionInfo == null) { if (selectionInfo == null) {
return true; return true;
} }

View File

@ -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");
@ -35,7 +35,6 @@ import org.openide.nodes.NodeAdapter;
import org.openide.nodes.NodeMemberEvent; import org.openide.nodes.NodeMemberEvent;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup; import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
@ -126,6 +125,7 @@ final class ContactsViewer extends JPanel implements RelationshipsViewer {
@Override @Override
public void setSelectionInfo(SelectionInfo info) { public void setSelectionInfo(SelectionInfo info) {
contactPane.setNode(null);
nodeFactory.refresh(info); nodeFactory.refresh(info);
} }

View File

@ -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");
@ -99,7 +99,8 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM
public void setSelectionInfo(SelectionInfo info) { public void setSelectionInfo(SelectionInfo info) {
Set<Content> relationshipSources; Set<Content> relationshipSources;
Set<BlackboardArtifact> artifactList = new HashSet<>(); Set<BlackboardArtifact> artifactList = new HashSet<>();
contentViewer.setNode(null);
if (info != null) {
try { try {
relationshipSources = info.getRelationshipSources(); relationshipSources = info.getRelationshipSources();
@ -110,7 +111,7 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.WARNING, "Unable to update selection.", ex); logger.log(Level.WARNING, "Unable to update selection.", ex);
} }
}
thumbnailViewer.resetComponent(); thumbnailViewer.resetComponent();
thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new AttachmentThumbnailsChildren(artifactList)), tableEM), true, this.getClass().getName())); thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new AttachmentThumbnailsChildren(artifactList)), tableEM), true, this.getClass().getName()));

View File

@ -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,7 +18,6 @@
*/ */
package org.sleuthkit.autopsy.communications.relationships; package org.sleuthkit.autopsy.communications.relationships;
import java.awt.Component;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup; import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
@ -95,13 +94,11 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void tabPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabPaneStateChanged private void tabPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabPaneStateChanged
if(currentSelection != null) { RelationshipsViewer viewer = ((RelationshipsViewer) tabPane.getSelectedComponent());
((RelationshipsViewer) tabPane.getSelectedComponent()).setSelectionInfo(currentSelection); //clear old values
} viewer.setSelectionInfo(currentSelection);
if (viewer instanceof Lookup.Provider) {
Component selectedComponent = tabPane.getSelectedComponent(); Lookup lookup = viewer.getLookup();
if(selectedComponent instanceof Lookup.Provider) {
Lookup lookup = ((Lookup.Provider)selectedComponent).getLookup();
proxyLookup.setNewLookups(lookup); proxyLookup.setNewLookups(lookup);
} }
}//GEN-LAST:event_tabPaneStateChanged }//GEN-LAST:event_tabPaneStateChanged

View File

@ -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.
@ -49,33 +47,6 @@ import org.jsoup.nodes.Document;
}) })
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) {

View File

@ -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>

View File

@ -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
} }
@ -244,8 +281,6 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
} }
} }
@Override @Override
public String getToolTip() { public String getToolTip() {
return NbBundle.getMessage(this.getClass(), "Metadata.toolTip"); return NbBundle.getMessage(this.getClass(), "Metadata.toolTip");
@ -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()) { List<String> istatStrings = Collections.emptyList();
sb.append(str).append("<br />"); //NON-NLS 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
} endTable(sb);
} catch (TskCoreException ex) {
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text")).append(ex.getLocalizedMessage());
} }
} 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()) {

View File

@ -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]"/>

View File

@ -18,20 +18,21 @@
*/ */
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;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.NodeResults; import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.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.Content;
import org.sleuthkit.datamodel.Score; import org.sleuthkit.datamodel.Score;
/** /**
@ -43,54 +44,16 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
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 +62,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>");
} }
@ -118,29 +82,24 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
* *
* @param nodeResults The analysis results data to display. * @param nodeResults The analysis results data to display.
*/ */
@NbBundle.Messages("AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score")
void displayResults(NodeResults nodeResults) { void displayResults(NodeResults nodeResults) {
Document document = Jsoup.parse(EMPTY_HTML); Document document = Jsoup.parse(EMPTY_HTML);
Element body = document.getElementsByTag("body").first(); Element body = document.getElementsByTag("body").first();
// if there is an aggregate score, append a section with the value Optional<Element> panelHeader = appendPanelHeader(body, nodeResults.getContent(), nodeResults.getAggregateScore());
Optional<Score> aggregateScore = nodeResults.getAggregateScore();
if (aggregateScore.isPresent()) {
appendSection(body,
MessageFormat.format("{0}: {1}",
Bundle.AnalysisResultsContentPanel_aggregateScore_displayKey(),
aggregateScore.get().getSignificance().getDisplayName()),
Optional.empty());
}
// for each analysis result item, display the data. // for each analysis result item, display the data.
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 || panelHeader.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
@ -153,26 +112,72 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
} }
} }
/**
* Appends the header to the panel.
*
* @param parent The parent html element.
* @param content The content whose name will be added if present.
* @param score The aggregate score whose significance will be added if
* present.
*
* @return The html element.
*/
@Messages({
"AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score",
"AnalysisResultsContentPanel_content_displayKey=Item"
})
private Optional<Element> appendPanelHeader(Element parent, Optional<Content> content, Optional<Score> score) {
if (!content.isPresent() || !score.isPresent()) {
return Optional.empty();
}
Element container = parent.appendElement("div");
// if there is content append the name
content.ifPresent((c) -> {
container.appendElement("p")
.attr("class", ContentViewerHtmlStyles.getTextClassName())
.text(MessageFormat.format("{0}: {1}",
Bundle.AnalysisResultsContentPanel_content_displayKey(),
c.getName()));
});
// if there is an aggregate score, append the value
score.ifPresent((s) -> {
container.appendElement("p")
.attr("class", ContentViewerHtmlStyles.getTextClassName())
.text(MessageFormat.format("{0}: {1}",
Bundle.AnalysisResultsContentPanel_aggregateScore_displayKey(),
s.getSignificance().getDisplayName()));
});
return Optional.ofNullable(container);
}
/** /**
* Returns the anchor id to use with the analysis result (based on the id). * 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),
@ -180,7 +185,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
// 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");
@ -188,15 +193,20 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
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;
} }
/** /**
@ -212,18 +222,22 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
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 = (anchorEl == null)
? sectionDiv.appendElement("h1")
: anchorEl.appendElement("h1");
header.text(headerText); header.text(headerText);
header.attr("class", HEADER_CLASSNAME); 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 +258,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);

View File

@ -94,6 +94,7 @@ public class AnalysisResultsViewModel {
private final List<ResultDisplayAttributes> analysisResults; private final List<ResultDisplayAttributes> analysisResults;
private final Optional<AnalysisResult> selectedResult; private final Optional<AnalysisResult> selectedResult;
private final Optional<Score> aggregateScore; private final Optional<Score> aggregateScore;
private final Optional<Content> content;
/** /**
* Constructor. * Constructor.
@ -102,11 +103,13 @@ public class AnalysisResultsViewModel {
* @param selectedResult The selected analysis result or empty if none * @param selectedResult The selected analysis result or empty if none
* selected. * selected.
* @param aggregateScore The aggregate score or empty if no score. * @param aggregateScore The aggregate score or empty if no score.
* @param content The content associated with these results.
*/ */
NodeResults(List<ResultDisplayAttributes> analysisResults, Optional<AnalysisResult> selectedResult, Optional<Score> aggregateScore) { NodeResults(List<ResultDisplayAttributes> analysisResults, Optional<AnalysisResult> selectedResult, Optional<Score> aggregateScore, Optional<Content> content) {
this.analysisResults = analysisResults; this.analysisResults = analysisResults;
this.selectedResult = selectedResult; this.selectedResult = selectedResult;
this.aggregateScore = aggregateScore; this.aggregateScore = aggregateScore;
this.content = content;
} }
/** /**
@ -135,6 +138,17 @@ public class AnalysisResultsViewModel {
Optional<Score> getAggregateScore() { Optional<Score> getAggregateScore() {
return aggregateScore; return aggregateScore;
} }
/**
* Returns the content associated with these results or empty if not
* present.
*
* @return The content associated with these results or empty if not
* present.
*/
Optional<Content> getContent() {
return content;
}
} }
/** /**
@ -221,10 +235,11 @@ public class AnalysisResultsViewModel {
*/ */
NodeResults getAnalysisResults(Node node) { NodeResults getAnalysisResults(Node node) {
if (node == null) { if (node == null) {
return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty()); return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty(), Optional.empty());
} }
Optional<Score> aggregateScore = Optional.empty(); Optional<Score> aggregateScore = Optional.empty();
Optional<Content> nodeContent = Optional.empty();
// maps id of analysis result to analysis result to prevent duplication // maps id of analysis result to analysis result to prevent duplication
Map<Long, AnalysisResult> allAnalysisResults = new HashMap<>(); Map<Long, AnalysisResult> allAnalysisResults = new HashMap<>();
Optional<AnalysisResult> selectedResult = Optional.empty(); Optional<AnalysisResult> selectedResult = Optional.empty();
@ -236,6 +251,8 @@ public class AnalysisResultsViewModel {
} }
try { try {
nodeContent = Optional.of(content);
// get the aggregate score of that content // get the aggregate score of that content
aggregateScore = Optional.ofNullable(content.getAggregateScore()); aggregateScore = Optional.ofNullable(content.getAggregateScore());
@ -273,6 +290,6 @@ public class AnalysisResultsViewModel {
// get view model representation // get view model representation
List<ResultDisplayAttributes> displayAttributes = getOrderedDisplayAttributes(allAnalysisResults.values()); List<ResultDisplayAttributes> displayAttributes = getOrderedDisplayAttributes(allAnalysisResults.values());
return new NodeResults(displayAttributes, selectedResult, aggregateScore); return new NodeResults(displayAttributes, selectedResult, aggregateScore, nodeContent);
} }
} }

View File

@ -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;
} }
@ -462,18 +459,30 @@ public class Annotations {
* 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;
} }

View File

@ -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()));
} }
/** /**
@ -93,29 +97,28 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
public void setArtifact(BlackboardArtifact artifact) { public void setArtifact(BlackboardArtifact artifact) {
resetComponent(); resetComponent();
if (artifact == null) {
return;
}
CallLogViewData callLogViewData = null; CallLogViewData callLogViewData = null;
try { try {
callLogViewData = getCallLogViewData(artifact); callLogViewData = getCallLogViewData(artifact);
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting attributes for Calllog artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex); logger.log(Level.SEVERE, String.format("Error getting attributes for Calllog artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
} }
List<AccountPersonaSearcherData> personaSearchDataList = new ArrayList<>();
// update the view with the call log data // update the view with the call log data
if (callLogViewData != null) { if (callLogViewData != null) {
List<AccountPersonaSearcherData> personaSearchDataList = updateView(callLogViewData); personaSearchDataList.addAll(updateView(callLogViewData));
}
if (!personaSearchDataList.isEmpty()) { if (!personaSearchDataList.isEmpty()) {
currentAccountFetcher = new PersonaAccountFetcher(artifact, personaSearchDataList, this); currentAccountFetcher = new PersonaAccountFetcher(artifact, personaSearchDataList, this);
currentAccountFetcher.execute(); currentAccountFetcher.execute();
} else { } else {
currentAccountFetcher = null; currentAccountFetcher = null;
} }
}
// repaint // repaint
this.revalidate(); this.revalidate();
this.repaint();
} }
/** /**
@ -309,7 +312,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
@ -366,8 +369,6 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
this.setLayout(m_gridBagLayout); this.setLayout(m_gridBagLayout);
this.revalidate(); this.revalidate();
this.repaint();
return dataList; return dataList;
} }
@ -384,7 +385,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 +415,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 +433,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 +445,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 +505,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;
} }

View File

@ -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,7 +399,8 @@ 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();
@ -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.
@ -442,6 +433,9 @@ final class CommunicationArtifactViewerHelper {
personaLabel.setEnabled(false); personaLabel.setEnabled(false);
} }
// restore constraint
constraints.insets = savedInsets;
addLineEndGlue(panel, gridbagLayout, constraints); addLineEndGlue(panel, gridbagLayout, constraints);
return dataList; return dataList;
@ -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());

View File

@ -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));
} }
@ -129,19 +130,15 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
// Reset the panel. // Reset the panel.
resetComponent(); resetComponent();
if (artifact == null) { if (artifact != null) {
return;
}
try { try {
extractArtifactData(artifact); extractArtifactData(artifact);
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting attributes for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex); logger.log(Level.SEVERE, String.format("Error getting attributes for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
return; return;
} }
updateView(); updateView();
}
this.setLayout(this.m_gridBagLayout); this.setLayout(this.m_gridBagLayout);
this.revalidate(); this.revalidate();
this.repaint(); this.repaint();
@ -163,6 +160,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
* Extracts data from the artifact to be displayed in the panel. * Extracts data from the artifact to be displayed in the panel.
* *
* @param artifact Artifact to show. * @param artifact Artifact to show.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
private void extractArtifactData(BlackboardArtifact artifact) throws TskCoreException { private void extractArtifactData(BlackboardArtifact artifact) throws TskCoreException {
@ -245,7 +243,10 @@ 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));
@ -256,6 +257,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 +277,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 +304,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 +318,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 +337,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 +348,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 +363,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 +438,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 +461,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 +476,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 +492,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 +506,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 +548,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;
} }
@ -778,7 +782,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
personaPanel.addAccount(account, Bundle.ContactArtifactViewer_persona_account_justification(), Persona.Confidence.HIGH); personaPanel.addAccount(account, Bundle.ContactArtifactViewer_persona_account_justification(), Persona.Confidence.HIGH);
} }
if(contactName != null && contactUniqueAccountsList.isEmpty()) { if (contactName != null && contactUniqueAccountsList.isEmpty()) {
createPersonaDialog.setStartupPopupMessage(Bundle.ContactArtifactViewer_id_not_found_in_cr(contactName)); createPersonaDialog.setStartupPopupMessage(Bundle.ContactArtifactViewer_id_not_found_in_cr(contactName));
} }

View File

@ -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;
@ -60,8 +66,13 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
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;

View File

@ -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());

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jSourceLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
@ -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()&#xd;&#xa;" 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, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jUsageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
@ -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, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jUnknownLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</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>

View File

@ -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;
@ -56,6 +59,10 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
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<>();
private final List<ContextSourcePanel> contextSourcePanels = new ArrayList<>(); private final List<ContextSourcePanel> contextSourcePanels = 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);
} }

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,21 @@
#Mon Jun 14 12:23:19 UTC 2021
OsAccountDataPanel_administrator_title=\u7ba1\u7406\u8005
OsAccountDataPanel_basic_address=\u4f4f\u6240
OsAccountDataPanel_basic_admin=\u7ba1\u7406\u8005
OsAccountDataPanel_basic_creationDate=\u4f5c\u6210\u65e5
OsAccountDataPanel_basic_fullname=\u6c0f\u540d
OsAccountDataPanel_basic_login=\u30ed\u30b0\u30a4\u30f3
OsAccountDataPanel_basic_title=\u57fa\u672c\u30d7\u30ed\u30d1\u30c6\u30a3
OsAccountDataPanel_basic_type=\u30bf\u30a4\u30d7
OsAccountDataPanel_data_accessed_title=\u524d\u56de\u306e\u30ed\u30b0\u30a4\u30f3
OsAccountDataPanel_host_count_title=\u30ed\u30b0\u30a4\u30f3\u6570
OsAccountDataPanel_host_section_title={0} \u8a73\u7d30
OsAccountDataPanel_realm_address=\u4f4f\u6240
OsAccountDataPanel_realm_confidence=\u4fe1\u983c\u5ea6
OsAccountDataPanel_realm_name=\u540d\u524d
OsAccountDataPanel_realm_scope=\u30b9\u30b3\u30fc\u30d7
OsAccountDataPanel_realm_title=\u5206\u91ce\u30d7\u30ed\u30d1\u30c6\u30a3
OsAccountDataPanel_realm_unknown=\u4e0d\u660e
OsAccountViewer_title=OS\u30a2\u30ab\u30a6\u30f3\u30c8
OsAccountViewer_tooltip=\u9078\u629e\u3057\u305f\u30ce\u30fc\u30c9\u306b\u95a2\u9023\u3059\u308b\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30d3\u30e5\u30fc\u30a2\u3002
TableDataPanel.titleLabel.text=\u79f0\u53f7

View File

@ -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;
@ -62,6 +63,10 @@ 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;
} }

View File

@ -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;
/** /**
@ -97,8 +100,14 @@ 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)));
} }
} }

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
AboutWindowPanel.actVerboseLogging.text=\u8a73\u7d30\u30ed\u30ae\u30f3\u30b0\u3092\u30a2\u30af\u30c6\u30a3\u30d6\u5316 AboutWindowPanel.actVerboseLogging.text=\u8a73\u7d30\u30ed\u30ae\u30f3\u30b0\u3092\u30a2\u30af\u30c6\u30a3\u30d6\u5316
AddExternalViewerRulePanel.browseButton.text=\u53c2\u7167 AddExternalViewerRulePanel.browseButton.text=\u53c2\u7167
AddExternalViewerRulePanel.exePathLabel.text=\u3053\u306e\u30bf\u30a4\u30d7\u307e\u305f\u306f\u62e1\u5f35\u5b50\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u4f7f\u7528\u3059\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u306e\u30d1\u30b9 AddExternalViewerRulePanel.exePathLabel.text=\u3053\u306e\u30bf\u30a4\u30d7\u307e\u305f\u306f\u62e1\u5f35\u5b50\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u4f7f\u7528\u3059\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u306e\u30d1\u30b9
@ -41,12 +41,18 @@ AutopsyOptionsPanel.runtimePanel.border.title=\u30e9\u30f3\u30bf\u30a4\u30e0
AutopsyOptionsPanel.sizingTextPane.text=\u9ad8DPI\u30b7\u30b9\u30c6\u30e0\u3067\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30ca\u30d3\u30b2\u30fc\u30c8\u304c\u96e3\u3057\u3044\u5834\u5408\u306f\u3001\u6b21\u306e\u5909\u66f4\u3092\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002\n\n1.\u30c7\u30b9\u30af\u30c8\u30c3\u30d7\u3001\u30b9\u30bf\u30fc\u30c8\u30e1\u30cb\u30e5\u30fc\u306a\u3069\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30a2\u30a4\u30b3\u30f3\u3092\u53f3\u30af\u30ea\u30c3\u30af\n2.\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u9078\u629e\n3. [\u4e92\u63db\u6027]\u30bf\u30d6\u306b\u79fb\u52d5\n4. [\u9ad8DPI\u8a2d\u5b9a\u306e\u5909\u66f4]\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\n5. [\u9ad8DPI\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\u52d5\u4f5c\u3092\u5909\u66f4]\u3092\u9078\u629e\n6.\u300c\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\u306e\u5b9f\u884c\uff1a\u300d\u30c9\u30ed\u30c3\u30d7\u30c0\u30a6\u30f3\u30dc\u30c3\u30af\u30b9\u3092\u300c\u30b7\u30b9\u30c6\u30e0\u300d\u306b\u5909\u66f4\u3057\u307e\u3059\u3002\n7.Autopsy\u3092\u518d\u5b9f\u884c AutopsyOptionsPanel.sizingTextPane.text=\u9ad8DPI\u30b7\u30b9\u30c6\u30e0\u3067\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30ca\u30d3\u30b2\u30fc\u30c8\u304c\u96e3\u3057\u3044\u5834\u5408\u306f\u3001\u6b21\u306e\u5909\u66f4\u3092\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002\n\n1.\u30c7\u30b9\u30af\u30c8\u30c3\u30d7\u3001\u30b9\u30bf\u30fc\u30c8\u30e1\u30cb\u30e5\u30fc\u306a\u3069\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30a2\u30a4\u30b3\u30f3\u3092\u53f3\u30af\u30ea\u30c3\u30af\n2.\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u9078\u629e\n3. [\u4e92\u63db\u6027]\u30bf\u30d6\u306b\u79fb\u52d5\n4. [\u9ad8DPI\u8a2d\u5b9a\u306e\u5909\u66f4]\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\n5. [\u9ad8DPI\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\u52d5\u4f5c\u3092\u5909\u66f4]\u3092\u9078\u629e\n6.\u300c\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\u306e\u5b9f\u884c\uff1a\u300d\u30c9\u30ed\u30c3\u30d7\u30c0\u30a6\u30f3\u30dc\u30c3\u30af\u30b9\u3092\u300c\u30b7\u30b9\u30c6\u30e0\u300d\u306b\u5909\u66f4\u3057\u307e\u3059\u3002\n7.Autopsy\u3092\u518d\u5b9f\u884c
AutopsyOptionsPanel.solrJVMHeapWarning.text=\u6ce8\: \u3053\u308c\u3092\u3042\u307e\u308a\u306b\u3082\u5927\u304d\u304f\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u5168\u4f53\u306b\u5f71\u97ff\u3059\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002 AutopsyOptionsPanel.solrJVMHeapWarning.text=\u6ce8\: \u3053\u308c\u3092\u3042\u307e\u308a\u306b\u3082\u5927\u304d\u304f\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u5168\u4f53\u306b\u5f71\u97ff\u3059\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002
AutopsyOptionsPanel.specifyLogoRB.text=\u30ed\u30b4\u3092\u6307\u5b9a AutopsyOptionsPanel.specifyLogoRB.text=\u30ed\u30b4\u3092\u6307\u5b9a
AutopsyOptionsPanel.tempCaseRadio.text=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u4e00\u6642\u30d5\u30a9\u30eb\u30c0
AutopsyOptionsPanel.tempCustomRadio.text=\u30ab\u30b9\u30bf\u30e0
AutopsyOptionsPanel.tempDirectoryBrowseButton.text=\u30d6\u30e9\u30a6\u30ba AutopsyOptionsPanel.tempDirectoryBrowseButton.text=\u30d6\u30e9\u30a6\u30ba
AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0 AutopsyOptionsPanel.tempDirectoryPanel.AccessibleContext.accessibleName=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0
AutopsyOptionsPanel.tempDirectoryPanel.border.title=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0 AutopsyOptionsPanel.tempDirectoryPanel.border.title=\u30eb\u30fc\u30c8\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea
AutopsyOptionsPanel.tempDirectoryPanel.name=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0 AutopsyOptionsPanel.tempDirectoryPanel.name=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0
AutopsyOptionsPanel.tempDirectoryWarningLabel.text=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0\u3092\u5909\u66f4\u3059\u308b\u306b\u306f\u30b1\u30fc\u30b9\u3092\u9589\u3058\u3066\u4e0b\u3055\u3044\u3002 AutopsyOptionsPanel.tempDirectoryWarningLabel.text=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0\u3092\u5909\u66f4\u3059\u308b\u306b\u306f\u30b1\u30fc\u30b9\u3092\u9589\u3058\u3066\u4e0b\u3055\u3044\u3002
AutopsyOptionsPanel.tempLocalRadio.text=\u30ed\u30fc\u30ab\u30eb\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea
AutopsyOptionsPanel.tempOnCustomNoPath.text=\u30ab\u30b9\u30bf\u30e0\u30eb\u30fc\u30c8\u306e\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fb\u30d1\u30b9\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002
AutopsyOptionsPanel.totalMemoryLabel.text=\u5408\u8a08\u30b7\u30b9\u30c6\u30e0\u30e1\u30e2\u30ea\u30fc\: AutopsyOptionsPanel.totalMemoryLabel.text=\u5408\u8a08\u30b7\u30b9\u30c6\u30e0\u30e1\u30e2\u30ea\u30fc\:
AutopsyOptionsPanel_storeTempDir_onChoiceError_description=\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u9078\u629e\u306e\u66f4\u65b0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
AutopsyOptionsPanel_storeTempDir_onChoiceError_title=\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u9078\u629e\u306e\u4fdd\u5b58\u30a8\u30e9\u30fc
AutopsyOptionsPanel_storeTempDir_onError_description=\u30b7\u30b9\u30c6\u30e0\u4e00\u6642\u30d5\u30a9\u30eb\u30c0{0}\u3092\u4f5c\u6210\u3059\u308b\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 AutopsyOptionsPanel_storeTempDir_onError_description=\u30b7\u30b9\u30c6\u30e0\u4e00\u6642\u30d5\u30a9\u30eb\u30c0{0}\u3092\u4f5c\u6210\u3059\u308b\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
AutopsyOptionsPanel_storeTempDir_onError_title=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f AutopsyOptionsPanel_storeTempDir_onError_title=\u4e00\u6642\u30d5\u30a9\u30eb\u30c0\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f
AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_description=\u6307\u5b9a\u3055\u308c\u305f\u30d1\u30b9\u5185\u306b\u4e00\u6642\u30d5\u30a9\u30eb\u30c0\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\uff1a{0} AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_description=\u6307\u5b9a\u3055\u308c\u305f\u30d1\u30b9\u5185\u306b\u4e00\u6642\u30d5\u30a9\u30eb\u30c0\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\uff1a{0}
@ -241,6 +247,7 @@ MultiUserSettingsPanel.validationErrMsg.invalidSolr4ServerPort=Solr4\u30b5\u30fc
MultiUserSettingsPanel.validationErrMsg.invalidZkServerHostName=ZooKeeper\u30b5\u30fc\u30d0\u30fc\u306e\u30db\u30b9\u30c8\u540d\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093 MultiUserSettingsPanel.validationErrMsg.invalidZkServerHostName=ZooKeeper\u30b5\u30fc\u30d0\u30fc\u306e\u30db\u30b9\u30c8\u540d\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
MultiUserSettingsPanel.validationErrMsg.invalidZkServerPort=ZooKeeper\u30b5\u30fc\u30d0\u30fc\u306e\u30dd\u30fc\u30c8\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059 MultiUserSettingsPanel.validationErrMsg.invalidZkServerPort=ZooKeeper\u30b5\u30fc\u30d0\u30fc\u306e\u30dd\u30fc\u30c8\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059
MultiUserSettingsPanel.validationErrMsg.solrNotConfigured=Solr8\u3068Solr4\u30b5\u30fc\u30d0\u30fc\u306e\u3044\u305a\u308c\u304b\u3092\u69cb\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059 MultiUserSettingsPanel.validationErrMsg.solrNotConfigured=Solr8\u3068Solr4\u30b5\u30fc\u30d0\u30fc\u306e\u3044\u305a\u308c\u304b\u3092\u69cb\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059
MultiUserSettingsPanel_Close_Case_To_Modify=\u8a2d\u5b9a\u3092\u5909\u66f4\u3059\u308b\u306b\u306f\u30b1\u30fc\u30b9\u3092\u9589\u3058\u3066\u304f\u3060\u3055\u3044
OpenIDE-Module-Name=CoreComponents OpenIDE-Module-Name=CoreComponents
OptionsCategory_Keywords_General=Autopsy\u30aa\u30d7\u30b7\u30e7\u30f3 OptionsCategory_Keywords_General=Autopsy\u30aa\u30d7\u30b7\u30e7\u30f3
OptionsCategory_Keywords_Multi_User_Options=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u8a2d\u5b9a OptionsCategory_Keywords_Multi_User_Options=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u8a2d\u5b9a
@ -267,7 +274,6 @@ ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text=\u30c7\u30fc\u30bf\u30bd\
ViewPreferencesPanel.displayTimeLabel.text=\u6642\u523b\u8868\u793a\u6642\: ViewPreferencesPanel.displayTimeLabel.text=\u6642\u523b\u8868\u793a\u6642\:
ViewPreferencesPanel.fileNameTranslationColumnCheckbox.text=\u7d50\u679c\u30d3\u30e5\u30fc\u30ef\u30fc\u306b\u30d5\u30a1\u30a4\u30eb\u540d\u7ffb\u8a33\u7528\u5217\u3092\u8ffd\u52a0 ViewPreferencesPanel.fileNameTranslationColumnCheckbox.text=\u7d50\u679c\u30d3\u30e5\u30fc\u30ef\u30fc\u306b\u30d5\u30a1\u30a4\u30eb\u540d\u7ffb\u8a33\u7528\u5217\u3092\u8ffd\u52a0
ViewPreferencesPanel.globalSettingsPanel.border.title=\u30b0\u30ed\u30fc\u30d0\u30eb\u8a2d\u5b9a ViewPreferencesPanel.globalSettingsPanel.border.title=\u30b0\u30ed\u30fc\u30d0\u30eb\u8a2d\u5b9a
ViewPreferencesPanel.groupByDataSourceCheckbox.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u5225\u306b\u30b0\u30eb\u30fc\u30d7\u5316
ViewPreferencesPanel.hideKnownFilesLabel.text=\u6b21\u306e\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb(NIST NSRL\u5185\u306e\u30d5\u30a1\u30a4\u30eb)\u3092\u975e\u8868\u793a\u306b\u3059\u308b\: ViewPreferencesPanel.hideKnownFilesLabel.text=\u6b21\u306e\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb(NIST NSRL\u5185\u306e\u30d5\u30a1\u30a4\u30eb)\u3092\u975e\u8868\u793a\u306b\u3059\u308b\:
ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=\u30c4\u30ea\u30fc\u5185\u306e\u30bf\u30b0\u9818\u57df ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=\u30c4\u30ea\u30fc\u5185\u306e\u30bf\u30b0\u9818\u57df
ViewPreferencesPanel.hideOtherUsersTagsLabel.text=\u6b21\u306e\u305d\u306e\u4ed6\u306e\u30e6\u30fc\u30b6\u30fc\u306e\u30bf\u30b0\u3092\u975e\u8868\u793a\u306b\u3059\u308b\: ViewPreferencesPanel.hideOtherUsersTagsLabel.text=\u6b21\u306e\u305d\u306e\u4ed6\u306e\u30e6\u30fc\u30b6\u30fc\u306e\u30bf\u30b0\u3092\u975e\u8868\u793a\u306b\u3059\u308b\:
@ -277,6 +283,8 @@ ViewPreferencesPanel.keepCurrentViewerRadioButton.text=\u540c\u3058\u30d5\u30a1\
ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText=\u305f\u3068\u3048\u3070\u3001JPEG\u9078\u629e\u6642\u306f16\u9032\u30d3\u30e5\u30fc\u306e\u307e\u307e\u306b\u3057\u307e\u3059\u3002 ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText=\u305f\u3068\u3048\u3070\u3001JPEG\u9078\u629e\u6642\u306f16\u9032\u30d3\u30e5\u30fc\u306e\u307e\u307e\u306b\u3057\u307e\u3059\u3002
ViewPreferencesPanel.maxResultsLabel.text=\u30c6\u30fc\u30d6\u30eb\u3067\u8868\u793a\u3059\u308b\u6700\u5927\u7d50\u679c\u6570\: ViewPreferencesPanel.maxResultsLabel.text=\u30c6\u30fc\u30d6\u30eb\u3067\u8868\u793a\u3059\u308b\u6700\u5927\u7d50\u679c\u6570\:
ViewPreferencesPanel.maxResultsLabel.toolTipText=<html>\n\u3053\u306e\u5024\u30920 \u306b\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u3059\u3079\u3066\u306e\u7d50\u679c\u304c\u7d50\u679c\u30c6\u30fc\u30d6\u30eb\u306b\u8868\u793a\u3055\u308c\u307e\u3059\u3002\n<br>\u3053\u306e\u5024\u30920 \u306b\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u7d50\u679c\u6570\u304c\u591a\u3044\u5834\u5408UI\u306e\u5fdc\u7b54\u6027\u304c\u60aa\u304f\u306a\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059 \u3002\n</html> ViewPreferencesPanel.maxResultsLabel.toolTipText=<html>\n\u3053\u306e\u5024\u30920 \u306b\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u3059\u3079\u3066\u306e\u7d50\u679c\u304c\u7d50\u679c\u30c6\u30fc\u30d6\u30eb\u306b\u8868\u793a\u3055\u308c\u307e\u3059\u3002\n<br>\u3053\u306e\u5024\u30920 \u306b\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u7d50\u679c\u6570\u304c\u591a\u3044\u5834\u5408UI\u306e\u5fdc\u7b54\u6027\u304c\u60aa\u304f\u306a\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059 \u3002\n</html>
ViewPreferencesPanel.radioGroupByDataType.text=\u30c7\u30fc\u30bf\u30fb\u30bf\u30a4\u30d7\u3067\u30b0\u30eb\u30fc\u30d7\u5316
ViewPreferencesPanel.radioGroupByPersonHost.text=\u4eba/\u30db\u30b9\u30c8\u3067\u30b0\u30eb\u30fc\u30d7\u5316
ViewPreferencesPanel.scoColumnsCheckbox.text=S(\u30b9\u30b3\u30a2)\u3001C(\u30b3\u30e1\u30f3\u30c8)\u3001O(\u767a\u751f) ViewPreferencesPanel.scoColumnsCheckbox.text=S(\u30b9\u30b3\u30a2)\u3001C(\u30b3\u30e1\u30f3\u30c8)\u3001O(\u767a\u751f)
ViewPreferencesPanel.scoColumnsLabel.text=\u6b21\u306e\u305f\u3081\u306e\u5217\u3092\u8ffd\u52a0\u3057\u306a\u3044\: ViewPreferencesPanel.scoColumnsLabel.text=\u6b21\u306e\u305f\u3081\u306e\u5217\u3092\u8ffd\u52a0\u3057\u306a\u3044\:
ViewPreferencesPanel.scoColumnsWrapAroundText.text=\u975e\u8868\u793a\u306b\u3059\u308b\u3068\u8aad\u8fbc\u307f\u304c\u65e9\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 ViewPreferencesPanel.scoColumnsWrapAroundText.text=\u975e\u8868\u793a\u306b\u3059\u308b\u3068\u8aad\u8fbc\u307f\u304c\u65e9\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002

View File

@ -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";
@ -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,88 +521,60 @@ 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();
Component headerComp = headerRenderer.getTableCellRendererComponent(outline, headerValue, false, false, 0, columnIdx);
width = Math.max(headerComp.getPreferredSize().width + columnPadding, width);
// find the maximum width needed to fit the values for the first 100 rows, at most // get the max of row widths from the first SAMPLE_ROW_NUM rows
for (int row = 0; row < Math.min(100, outline.getRowCount()); row++) { Component comp = null;
TableCellRenderer renderer = outline.getCellRenderer(row, column); int rowCount = outline.getRowCount();
Component comp = outline.prepareRenderer(renderer, row, column); for (int row = 0; row < Math.min(rowCount, SAMPLE_ROW_NUM); row++) {
valuesWidth = Math.max(comp.getPreferredSize().width, valuesWidth); TableCellRenderer renderer = outline.getCellRenderer(row, columnIdx);
comp = outline.prepareRenderer(renderer, row, columnIdx);
width = Math.max(comp.getPreferredSize().width + columnPadding, width);
} }
int headerWidth = metrics.stringWidth(outline.getColumnName(column)); // no higher than maximum column width
valuesWidth += firstColumnPadding; // add extra padding for first column if (width > MAX_COLUMN_WIDTH) {
width = MAX_COLUMN_WIDTH;
int columnWidth = Math.max(valuesWidth, headerWidth);
columnWidth += 2 * margin + padding; // add margin and regular padding
columnWidth = Math.min(columnWidth, columnWidthLimit);
columnWidths.add(columnWidth);
totalColumnWidth += columnWidth;
if (columnWidth == columnWidthLimit) {
cntMaxSizeColumns++;
}
} }
// Figure out how much extra, if any can be given to the columns // if last column, calculate remaining width factoring in the possibility of a scroll bar.
// so that the table is as wide as outlineViewWidth. If cntMaxSizeColumns if (columnIdx == outline.getColumnCount() - 1) {
// is greater than 0 divide the extra space between the columns int rowHeight = comp == null ? MIN_ROW_HEIGHT : comp.getPreferredSize().height;
// that could use more space. Otherwise divide evenly amoung if (headerComp.getPreferredSize().height + rowCount * rowHeight > outlineView.getSize().getHeight()) {
// all columns. availableTableWidth -= SCROLL_BAR_WIDTH;
int extraWidth = 0; }
if (totalColumnWidth < outlineViewWidth) { columnModel.getColumn(columnIdx).setPreferredWidth(Math.max(width, (int) availableTableWidth));
if (cntMaxSizeColumns > 0) {
extraWidth = (int) ((outlineViewWidth - totalColumnWidth) / cntMaxSizeColumns);
} else { } else {
extraWidth = (int) ((outlineViewWidth - totalColumnWidth) / columnWidths.size()); // otherwise set preferred width to width and decrement availableTableWidth accordingly
columnModel.getColumn(columnIdx).setPreferredWidth(width);
availableTableWidth -= width;
} }
} }
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);
}
} }
protected TableColumnModel getColumnModel() { protected TableColumnModel getColumnModel() {
@ -1266,7 +1246,9 @@ 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) {

View File

@ -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

View File

@ -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");
@ -36,6 +36,7 @@ import org.openide.nodes.Node;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -278,6 +279,8 @@ public class Artifacts {
private final RefreshThrottler refreshThrottler = new RefreshThrottler(this); private final RefreshThrottler refreshThrottler = new RefreshThrottler(this);
private final Category category; private final Category category;
private final PropertyChangeListener weakPcl;
/** /**
* Main constructor. * Main constructor.
* *
@ -290,9 +293,8 @@ public class Artifacts {
super(); super();
this.filteringDSObjId = filteringDSObjId; this.filteringDSObjId = filteringDSObjId;
this.category = category; this.category = category;
}
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
String eventType = evt.getPropertyName(); String eventType = evt.getPropertyName();
if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
// case was closed. Remove listeners so that we don't get called with a stale case handle // case was closed. Remove listeners so that we don't get called with a stale case handle
@ -302,9 +304,10 @@ public class Artifacts {
} else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
|| eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) { || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
/** /**
* This is a stop gap measure until a different way of handling * This is a stop gap measure until a different way of
* the closing of cases is worked out. Currently, remote events * handling the closing of cases is worked out. Currently,
* may be received for a case that is already closed. * remote events may be received for a case that is already
* closed.
*/ */
try { try {
Case.getCurrentCaseThrows(); Case.getCurrentCaseThrows();
@ -317,18 +320,23 @@ public class Artifacts {
} }
}; };
@Override weakPcl = WeakListeners.propertyChange(pcl, null);
protected void addNotify() {
refreshThrottler.registerForIngestModuleEvents();
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
} }
@Override @Override
protected void removeNotify() { protected void addNotify() {
super.addNotify();
refreshThrottler.registerForIngestModuleEvents();
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
}
@Override
protected void finalize() throws Throwable {
super.finalize();
refreshThrottler.unregisterEventListener(); refreshThrottler.unregisterEventListener();
IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
typeNodeMap.clear(); typeNodeMap.clear();
} }
@ -625,16 +633,20 @@ public class Artifacts {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void onAdd() { protected void onAdd() {
refreshThrottler.registerForIngestModuleEvents(); refreshThrottler.registerForIngestModuleEvents();
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
} }
@Override @Override
protected void onRemove() { protected void onRemove() {
if(refreshThrottler != null) {
refreshThrottler.unregisterEventListener(); refreshThrottler.unregisterEventListener();
IngestManager.getInstance().removeIngestJobEventListener(pcl); }
IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
} }
@Override @Override

View File

@ -1,6 +1,5 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
*
* Copyright 2018-2021 Basis Technology Corp. * Copyright 2018-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
@ -20,7 +19,6 @@ package org.sleuthkit.autopsy.datamodel;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
@ -32,6 +30,7 @@ import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.openide.nodes.ChildFactory; import org.openide.nodes.ChildFactory;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.WeakListeners;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.CasePreferences; import org.sleuthkit.autopsy.casemodule.CasePreferences;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -83,16 +82,18 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
super.addNotify(); super.addNotify();
Case.addEventTypeSubscriber(EVENTS_OF_INTEREST, pcl); Case.addEventTypeSubscriber(EVENTS_OF_INTEREST, weakPcl);
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
super.removeNotify(); super.finalize();
Case.removeEventTypeSubscriber(EVENTS_OF_INTEREST, pcl); Case.removeEventTypeSubscriber(EVENTS_OF_INTEREST, weakPcl);
} }
/** /**
@ -128,7 +129,7 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
.sorted() .sorted()
.collect(Collectors.toList()); .collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(personManager.getHostsForPerson(null))) { if (CollectionUtils.isNotEmpty(personManager.getHostsWithoutPersons())) {
nodes.add(new PersonGrouping(null)); nodes.add(new PersonGrouping(null));
} }
} else { } else {

View File

@ -122,7 +122,8 @@ public abstract class BaseChildFactory<T extends Content> extends ChildFactory.D
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
super.finalize();
onRemove(); onRemove();
} }

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
AbstractAbstractFileNode.accessTimeColLbl=\u30a2\u30af\u30bb\u30b9\u65e5\u6642 AbstractAbstractFileNode.accessTimeColLbl=\u30a2\u30af\u30bb\u30b9\u65e5\u6642
AbstractAbstractFileNode.attrAddrColLbl=\u5c5e\u6027\u30a2\u30c9\u30ec\u30b9 AbstractAbstractFileNode.attrAddrColLbl=\u5c5e\u6027\u30a2\u30c9\u30ec\u30b9
AbstractAbstractFileNode.changeTimeColLbl=\u30a8\u30f3\u30c8\u30ea\u66f4\u65b0\u65e5\u6642 AbstractAbstractFileNode.changeTimeColLbl=\u30a8\u30f3\u30c8\u30ea\u66f4\u65b0\u65e5\u6642
@ -139,6 +139,7 @@ DataModelActionsFactory.fileInDir.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30f
DataModelActionsFactory.openExtViewer.text=\u5916\u90e8\u30d3\u30e5\u30fc\u30ef\u30fc\u3067\u958b\u304f Ctrl+E DataModelActionsFactory.openExtViewer.text=\u5916\u90e8\u30d3\u30e5\u30fc\u30ef\u30fc\u3067\u958b\u304f Ctrl+E
DataModelActionsFactory.srcFileInDir.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u5185\u306e\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u8868\u793a DataModelActionsFactory.srcFileInDir.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u5185\u306e\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u8868\u793a
DataModelActionsFactory.viewNewWin.text=\u65b0\u3057\u3044\u30a6\u30a3\u30f3\u30c9\u30a6\u3067\u8868\u793a DataModelActionsFactory.viewNewWin.text=\u65b0\u3057\u3044\u30a6\u30a3\u30f3\u30c9\u30a6\u3067\u8868\u793a
DataSourcesHostsNode_name=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
DataSourcesNode.createSheet.name.desc=\u8aac\u660e\u306a\u3057 DataSourcesNode.createSheet.name.desc=\u8aac\u660e\u306a\u3057
DataSourcesNode.createSheet.name.displayName=\u540d\u524d DataSourcesNode.createSheet.name.displayName=\u540d\u524d
DataSourcesNode.createSheet.name.name=\u540d\u524d DataSourcesNode.createSheet.name.name=\u540d\u524d
@ -226,6 +227,11 @@ GetSCOTask.occurrences.multipleProperties=\u3053\u306e\u7d50\u679c\u306b\u8907\u
HashsetHits.createSheet.name.desc=\u8aac\u660e\u306a\u3057 HashsetHits.createSheet.name.desc=\u8aac\u660e\u306a\u3057
HashsetHits.createSheet.name.displayName=\u540d\u524d HashsetHits.createSheet.name.displayName=\u540d\u524d
HashsetHits.createSheet.name.name=\u540d\u524d HashsetHits.createSheet.name.name=\u540d\u524d
HostGroupingNode_unknownHostNode_title=\u672a\u77e5\u306e\u30db\u30b9\u30c8
HostNode_actions_associateWithExisting=\u65e2\u5b58\u306e\u4eba\u3068\u95a2\u9023\u4ed8\u3051\u308b...
HostNode_actions_associateWithNew=\u65b0\u3057\u3044\u4eba\u3068\u95a2\u9023\u4ed8\u3051\u308b...
HostNode_actions_removeFromPerson=\u4eba\u304b\u3089\u524a\u9664\uff08{0}\uff09
HostNode_createSheet_nameProperty=\u540d\u524d
ImageNode.action.runIngestMods.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5b9f\u884c ImageNode.action.runIngestMods.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5b9f\u884c
ImageNode.createSheet.deviceId.desc=\u30a4\u30e1\u30fc\u30b8\u306e\u30c7\u30d0\u30a4\u30b9ID ImageNode.createSheet.deviceId.desc=\u30a4\u30e1\u30fc\u30b8\u306e\u30c7\u30d0\u30a4\u30b9ID
ImageNode.createSheet.deviceId.displayName=\u30c7\u30d0\u30a4\u30b9ID ImageNode.createSheet.deviceId.displayName=\u30c7\u30d0\u30a4\u30b9ID
@ -309,6 +315,23 @@ OpenReportAction.actionPerformed.MissingReportFileMessage=\u30ec\u30dd\u30fc\u30
OpenReportAction.actionPerformed.NoAssociatedEditorMessage=\u3053\u306e\u30bf\u30a4\u30d7\u306e\u30ec\u30dd\u30fc\u30c8\u306b\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30a8\u30c7\u30a3\u30bf\u30fc\u304c\u306a\u3044\u304b\u3001\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304c\u8d77\u52d5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 OpenReportAction.actionPerformed.NoAssociatedEditorMessage=\u3053\u306e\u30bf\u30a4\u30d7\u306e\u30ec\u30dd\u30fc\u30c8\u306b\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30a8\u30c7\u30a3\u30bf\u30fc\u304c\u306a\u3044\u304b\u3001\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304c\u8d77\u52d5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
OpenReportAction.actionPerformed.NoOpenInEditorSupportMessage=\u3053\u306e\u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0(\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0)\u306f\u3053\u306e\u65b9\u6cd5\u3067\u30a8\u30c7\u30a3\u30bf\u30fc\u3067\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f\u3053\u3068\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002 OpenReportAction.actionPerformed.NoOpenInEditorSupportMessage=\u3053\u306e\u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0(\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0)\u306f\u3053\u306e\u65b9\u6cd5\u3067\u30a8\u30c7\u30a3\u30bf\u30fc\u3067\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f\u3053\u3068\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002
OpenReportAction.actionPerformed.ReportFileOpenPermissionDeniedMessage=\u30ec\u30dd\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f\u8a31\u53ef\u304c\u62d2\u5426\u3055\u308c\u307e\u3057\u305f\u3002 OpenReportAction.actionPerformed.ReportFileOpenPermissionDeniedMessage=\u30ec\u30dd\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f\u8a31\u53ef\u304c\u62d2\u5426\u3055\u308c\u307e\u3057\u305f\u3002
OsAccount_listNode_name=OS\u30a2\u30ab\u30a6\u30f3\u30c8
OsAccounts_accountNameProperty_desc=OS\u30a2\u30ab\u30a6\u30f3\u30c8\u540d
OsAccounts_accountNameProperty_displayName=\u540d\u524d
OsAccounts_accountNameProperty_name=\u540d\u524d
OsAccounts_accountRealmNameProperty_desc=OS\u30a2\u30ab\u30a6\u30f3\u30c8\u5206\u91ce\u540d
OsAccounts_accountRealmNameProperty_displayName=\u5206\u91ce\u540d
OsAccounts_accountRealmNameProperty_name=\u5206\u91ce\u540d
OsAccounts_createdTimeProperty_desc=OS\u30a2\u30ab\u30a6\u30f3\u30c8\u4f5c\u6210\u6642\u9593
OsAccounts_createdTimeProperty_displayName=\u4f5c\u6210\u6642\u9593
OsAccounts_createdTimeProperty_name=\u4f5c\u6210\u6642\u9593
OsAccounts_loginNameProperty_desc=OS\u30a2\u30ab\u30a6\u30f3\u30c8\u30ed\u30b0\u30a4\u30f3\u540d
OsAccounts_loginNameProperty_displayName=\u30ed\u30b0\u30a4\u30f3\u540d
OsAccounts_loginNameProperty_name=\u30ed\u30b0\u30a4\u30f3\u540d
PersonGroupingNode_actions_delete=\u4eba\u306e\u524a\u9664
PersonGroupingNode_actions_rename=\u540d\u524d\u3092\u5909\u66f4...
PersonGroupingNode_createSheet_nameProperty=\u540d\u524d
PersonNode_unknownPersonNode_title=\u672a\u77e5\u306e\u4eba\u7269
PoolNode.createSheet.name.desc=\u8aac\u660e\u306a\u3057 PoolNode.createSheet.name.desc=\u8aac\u660e\u306a\u3057
PoolNode.createSheet.name.displayName=\u540d\u524d PoolNode.createSheet.name.displayName=\u540d\u524d
PoolNode.createSheet.name.name=\u540d\u524d PoolNode.createSheet.name.name=\u540d\u524d

View File

@ -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

View File

@ -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();
} }

View File

@ -31,6 +31,7 @@ import org.openide.nodes.Node;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
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.WeakListeners;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -77,14 +78,17 @@ public class DataSourcesNode extends DisplayableItemNode {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
Case.addEventTypeSubscriber(UPDATE_EVTS, pcl); Case.addEventTypeSubscriber(UPDATE_EVTS, weakPcl);
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable{
Case.removeEventTypeSubscriber(UPDATE_EVTS, pcl); Case.removeEventTypeSubscriber(UPDATE_EVTS, weakPcl);
super.finalize();
} }
@Override @Override
@ -122,7 +126,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");

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2012-2020 Basis Technology Corp. * Copyright 2012-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");
@ -37,6 +37,7 @@ 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; import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -314,20 +315,23 @@ public class EmailExtracted implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
emailResults.update(); emailResults.update();
emailResults.addObserver(this); emailResults.addObserver(this);
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable{
IngestManager.getInstance().removeIngestJobEventListener(pcl); super.finalize();
IngestManager.getInstance().removeIngestModuleEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
emailResults.deleteObserver(this); emailResults.deleteObserver(this);
} }

View File

@ -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");
@ -39,6 +39,7 @@ 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; import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -279,20 +280,23 @@ public class HashsetHits implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
hashsetResults.update(); hashsetResults.update();
hashsetResults.addObserver(this); hashsetResults.addObserver(this);
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(pcl); super.finalize();
IngestManager.getInstance().removeIngestModuleEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
hashsetResults.deleteObserver(this); hashsetResults.deleteObserver(this);
} }

View File

@ -94,14 +94,18 @@ public class HostNode extends DisplayableItemNode {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(dataSourceAddedPcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), dataSourceAddedPcl); super.addNotify();
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), weakPcl);
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), dataSourceAddedPcl); super.finalize();
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), weakPcl);
} }
@Override @Override
@ -212,7 +216,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());
} }
/** /**

View File

@ -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());) {
ResultSet deviceIdSet = query.getResultSet();
if (deviceIdSet.next()) {
sheetSet.put(new NodeProperty<>(Bundle.ImageNode_createSheet_deviceId_name(), sheetSet.put(new NodeProperty<>(Bundle.ImageNode_createSheet_deviceId_name(),
Bundle.ImageNode_createSheet_deviceId_displayName(), Bundle.ImageNode_createSheet_deviceId_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;
} }

View File

@ -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");
@ -39,6 +39,7 @@ 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; import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -272,20 +273,23 @@ public class InterestingHits implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
interestingResults.update(); interestingResults.update();
interestingResults.addObserver(this); interestingResults.addObserver(this);
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(pcl); super.finalize();
IngestManager.getInstance().removeIngestModuleEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
interestingResults.deleteObserver(this); interestingResults.deleteObserver(this);
} }

View File

@ -42,6 +42,7 @@ import org.openide.nodes.Node;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -437,7 +438,8 @@ public class KeywordHits implements AutopsyVisitableItem {
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
super.finalize();
keywordResults.deleteObserver(this); keywordResults.deleteObserver(this);
} }
@ -505,21 +507,23 @@ public class KeywordHits implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
keywordResults.update(); keywordResults.update();
super.addNotify(); super.addNotify();
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable{
IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
IngestManager.getInstance().removeIngestModuleEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
super.removeNotify(); super.finalize();
} }
@Override @Override

View File

@ -138,18 +138,21 @@ public final class OsAccounts implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(listener, null);
@Override
protected void finalize() throws Throwable {
super.finalize();
Case.removeEventTypeSubscriber(Collections.singleton(Case.Events.OS_ACCOUNTS_ADDED), weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
}
@Override @Override
protected void addNotify() { protected void addNotify() {
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.OS_ACCOUNTS_ADDED, Case.Events.OS_ACCOUNTS_DELETED), listener); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.OS_ACCOUNTS_ADDED, Case.Events.OS_ACCOUNTS_DELETED), listener);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), listener); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), listener);
} }
@Override
protected void removeNotify() {
Case.removeEventTypeSubscriber(Collections.singleton(Case.Events.OS_ACCOUNTS_ADDED), listener);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), listener);
}
@Override @Override
protected boolean createKeys(List<OsAccount> list) { protected boolean createKeys(List<OsAccount> list) {
if (skCase != null) { if (skCase != null) {

View File

@ -92,6 +92,7 @@ public class PersonNode extends DisplayableItemNode {
*/ */
PersonChildren(Person person) { PersonChildren(Person person) {
this.person = person; this.person = person;
} }
/** /**
@ -112,14 +113,17 @@ public class PersonNode extends DisplayableItemNode {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(hostAddedDeletedPcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
Case.addEventTypeSubscriber(HOST_EVENTS_OF_INTEREST, hostAddedDeletedPcl); Case.addEventTypeSubscriber(HOST_EVENTS_OF_INTEREST, weakPcl);
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
Case.removeEventTypeSubscriber(HOST_EVENTS_OF_INTEREST, hostAddedDeletedPcl); super.finalize();
Case.removeEventTypeSubscriber(HOST_EVENTS_OF_INTEREST, weakPcl);
} }
@Override @Override
@ -203,7 +207,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);

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2019 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");
@ -33,6 +33,7 @@ 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; import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -214,6 +215,8 @@ public class Tags implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
/** /**
* Constructor * Constructor
* *
@ -221,21 +224,21 @@ public class Tags implements AutopsyVisitableItem {
*/ */
TagNameNodeFactory(long objId) { TagNameNodeFactory(long objId) {
this.filteringDSObjId = objId; this.filteringDSObjId = objId;
} }
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, weakPcl);
tagResults.update(); tagResults.update();
tagResults.addObserver(this); tagResults.addObserver(this);
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(pcl); super.finalize();
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, weakPcl);
tagResults.deleteObserver(this); tagResults.deleteObserver(this);
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2019 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");
@ -57,6 +57,7 @@ import org.openide.nodes.NodeOp;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.Utilities; import org.openide.util.Utilities;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -218,8 +219,8 @@ final public class Accounts implements AutopsyVisitableItem {
abstract void handleDataAdded(ModuleDataEvent event); abstract void handleDataAdded(ModuleDataEvent event);
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
super.removeNotify(); super.finalize();
reviewStatusBus.unregister(ObservingChildren.this); reviewStatusBus.unregister(ObservingChildren.this);
} }
@ -416,6 +417,8 @@ final public class Accounts implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Subscribe @Subscribe
@Override @Override
void handleReviewStatusChange(ReviewStatusChangeEvent event) { void handleReviewStatusChange(ReviewStatusChangeEvent event) {
@ -473,18 +476,18 @@ final public class Accounts implements AutopsyVisitableItem {
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
IngestManager.getInstance().removeIngestModuleEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
super.removeNotify(); super.finalize();
} }
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
super.addNotify(); super.addNotify();
refresh(true); refresh(true);
} }
@ -551,20 +554,21 @@ final public class Accounts implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
super.addNotify();
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(pcl); super.finalize();
IngestManager.getInstance().removeIngestModuleEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
super.removeNotify(); Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
} }
@Override @Override
@ -728,6 +732,9 @@ final public class Accounts implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Subscribe @Subscribe
@Override @Override
void handleReviewStatusChange(ReviewStatusChangeEvent event) { void handleReviewStatusChange(ReviewStatusChangeEvent event) {
@ -742,17 +749,18 @@ final public class Accounts implements AutopsyVisitableItem {
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
super.addNotify(); super.addNotify();
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(pcl); super.finalize();
IngestManager.getInstance().removeIngestModuleEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
super.removeNotify(); super.removeNotify();
} }
@ -882,20 +890,22 @@ final public class Accounts implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
super.addNotify(); super.addNotify();
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(pcl); super.finalize();
IngestManager.getInstance().removeIngestModuleEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
super.removeNotify(); Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
} }
@Subscribe @Subscribe
@ -1096,20 +1106,22 @@ final public class Accounts implements AutopsyVisitableItem {
} }
}; };
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
@Override @Override
protected void addNotify() { protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, pcl); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
super.addNotify(); super.addNotify();
} }
@Override @Override
protected void removeNotify() { protected void finalize() throws Throwable{
IngestManager.getInstance().removeIngestJobEventListener(pcl); super.finalize();
IngestManager.getInstance().removeIngestModuleEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); IngestManager.getInstance().removeIngestModuleEventListener(weakPcl);
super.removeNotify(); Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
} }
@Subscribe @Subscribe

View File

@ -0,0 +1,41 @@
#Mon Jun 14 12:23:19 UTC 2021
AddEditHostDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
AddEditHostDialog.inputTextField.text=jTextField1
AddEditHostDialog.nameLabel.text=\u540d\u524d\uff1a
AddEditHostDialog.okButton.text=OK
AddEditHostDialog_addHost_title=\u30db\u30b9\u30c8\u3092\u8ffd\u52a0
AddEditHostDialog_editHost_title=\u30db\u30b9\u30c8\u306e\u7de8\u96c6
AssociateNewPersonAction_menuTitle=\u65b0\u3057\u3044\u4eba...
AssociateNewPersonAction_onError_description=\u30db\u30b9\u30c8{0}\u3092\u65b0\u3057\u3044\u4eba{1}\u306b\u95a2\u9023\u4ed8\u3051\u308b\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
AssociateNewPersonAction_onError_title=\u65b0\u3057\u3044\u4eba\u306e\u95a2\u9023\u4ed8\u3051\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
AssociatePersonAction_onError_description=\u30db\u30b9\u30c8{0}\u3068\u500b\u4eba{1}\u306e\u95a2\u9023\u4ed8\u3051\u3067\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
AssociatePersonAction_onError_title=\u30db\u30b9\u30c8\u3068\u500b\u4eba\u306e\u95a2\u9023\u4ed8\u3051\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
AssociatePersonAction_unknownPerson=\u5931\u540d\u6c0f
AssociatePersonsMenuAction_menuTitle=\u4eba\u3068\u95a2\u9023\u4ed8\u3051\u308b
CTL_OpenHosts=\u30db\u30b9\u30c8\u306e\u7ba1\u7406
HostNameValidator_getValidationMessage_onDuplicate=\u5225\u306e\u30db\u30b9\u30c8\u306f\u3059\u3067\u306b\u540c\u3058\u540d\u524d\u3092\u6301\u3063\u3066\u3044\u307e\u3059\u3002 \u5225\u306e\u540d\u524d\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
HostNameValidator_getValidationMessage_onEmpty=\u30db\u30b9\u30c8\u540d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
HostNameValidator_getValidationMessage_sameAsOriginal=\u3053\u306e\u30db\u30b9\u30c8\u306e\u65b0\u3057\u3044\u540d\u524d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
ManageHostsDialog.closeButton.text=\u9589\u3058\u308b
ManageHostsDialog.deleteButton.text=\u524a\u9664
ManageHostsDialog.editButton.text=\u7de8\u96c6
ManageHostsDialog.hostDescriptionTextArea.text=\u30db\u30b9\u30c8\u306f\u3001\u8907\u6570\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u6301\u3064\u53ef\u80fd\u6027\u306e\u3042\u308b\u500b\u3005\u306e\u30c7\u30d0\u30a4\u30b9\u3092\u8868\u3057\u307e\u3059\u3002
ManageHostsDialog.hostDetailsLabel.text=\u30db\u30b9\u30c8\u306e\u8a73\u7d30
ManageHostsDialog.hostListLabel.text=\u30db\u30b9\u30c8
ManageHostsDialog.hostNameLabel.text=\u30db\u30b9\u30c8\u540d\uff1a
ManageHostsDialog.newButton.text=\u65b0
ManageHostsDialog_title_text=\u30db\u30b9\u30c8\u306e\u7ba1\u7406
MergeHostAction.confirmText={0}\u3092{1}\u306b\u30de\u30fc\u30b8\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f\n\u3053\u308c\u306b\u306fOS\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30de\u30fc\u30b8\u304c\u542b\u307e\u308c\u308b\u5834\u5408\u304c\u3042\u308a\u3001\u5143\u306b\u623b\u3059\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002
MergeHostAction.confirmTitle=\u78ba\u8a8d
MergeHostAction.errorText=\u30db\u30b9\u30c8\u306e\u30de\u30fc\u30b8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\n\u6570\u5206\u5f8c\u306b\u3082\u3046\u4e00\u5ea6\u8a66\u3059\u304b\u3001\u30ed\u30b0\u3067\u8a73\u7d30\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002
MergeHostAction.errorTitle=\u30db\u30b9\u30c8\u306e\u30de\u30fc\u30b8\u30a8\u30e9\u30fc
MergeHostAction.progressIndicatorName=\u30db\u30b9\u30c8\u306e\u30de\u30fc\u30b8
MergeHostAction.progressText={0}\u3092{1}\u306b\u30de\u30fc\u30b8\u3057\u3066\u3044\u307e\u3059...
MergeHostAction_onError_description=\u30db\u30b9\u30c8{0}\u3092\u30db\u30b9\u30c8{1}\u306b\u30de\u30fc\u30b8\u3059\u308b\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
MergeHostAction_onError_title=\u30db\u30b9\u30c8\u306e\u30de\u30fc\u30b8\u30a8\u30e9\u30fc
MergeHostMenuAction_menuTitle=\u4ed6\u306e\u30db\u30b9\u30c8\u306b\u30de\u30fc\u30b8\u3059\u308b
OpenHostsAction_displayName=\u30db\u30b9\u30c8
RemoveParentPersonAction_menuTitle=\u4eba\u304b\u3089\u524a\u9664\uff08{0}\uff09
RemoveParentPersonAction_onError_description=\u30db\u30b9\u30c8\u304b\u3089\u4eba\u3092\u524a\u9664\u3059\u308b\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a{0}\u3002
RemoveParentPersonAction_onError_title=\u500b\u4eba\u304b\u3089\u30db\u30b9\u30c8\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
RemoveParentPersonAction_unknownPerson=\u5931\u540d\u6c0f

View File

@ -0,0 +1,19 @@
#Mon Jun 14 12:23:19 UTC 2021
AddEditPersonDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
AddEditPersonDialog.cancelButton.text_1=\u30ad\u30e3\u30f3\u30bb\u30eb
AddEditPersonDialog.inputTextField.text_1=jTextField1
AddEditPersonDialog.nameLabel.text=\u540d\u524d\uff1a
AddEditPersonDialog.nameLabel.text_1=\u540d\u524d\uff1a
AddEditPersonDialog.okButton.text=OK
AddEditPersonDialog.okButton.text_1=OK
AddEditPersonDialog_addPerson_title=\u4eba\u3092\u8ffd\u52a0
AddEditPersonDialog_editPerson_title=\u4eba\u306e\u7de8\u96c6
DeletePersonAction_menuTitle=\u4eba\u306e\u524a\u9664
DeletePersonAction_onError_description=\u4eba\u306e\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a{0}\u3002
DeletePersonAction_onError_title=\u500b\u4eba\u304b\u3089\u30db\u30b9\u30c8\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
EditPersonAction_menuTitle=\u4eba\u306e\u7de8\u96c6\u3002\u3002\u3002
EditPersonAction_onError_description=\u4eba\u306e\u7de8\u96c6\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a{0}\u3002
EditPersonAction_onError_title=\u4eba\u306e\u7de8\u96c6\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
PersonNameValidator_getValidationMessage_onDuplicate=\u540c\u3058\u540d\u524d\u304c\u65e2\u306b\u5b58\u5728\u3057\u3066\u3044\u307e\u3059\u3002 \u5225\u306e\u540d\u524d\u3092\u9078\u3093\u3067\u304f\u3060\u3055\u3044\u3002
PersonNameValidator_getValidationMessage_onEmpty=\u540d\u524d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
PersonNameValidator_getValidationMessage_sameAsOriginal=\u3053\u306e\u4eba\u306e\u65b0\u3057\u3044\u540d\u524d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002

View File

@ -1,4 +1,3 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
DataSourceUserActivitySummary_getRecentAccounts_calllogMessage=\u901a\u8a71\u8a18\u9332 DataSourceUserActivitySummary_getRecentAccounts_calllogMessage=\u901a\u8a71\u8a18\u9332
DataSourceUserActivitySummary_getRecentAccounts_emailMessage=\u30e1\u30fc\u30eb\u30e1\u30c3\u30bb\u30fc\u30b8 DataSourceUserActivitySummary_getRecentAccounts_emailMessage=\u30e1\u30fc\u30eb\u30e1\u30c3\u30bb\u30fc\u30b8
IngestModuleCheckUtil_recentActivityModuleName=\u6700\u8fd1\u306e\u6d3b\u52d5

View File

@ -1,11 +1,13 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
AnalysisPanel.hashsetHitsLabel.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30d2\u30c3\u30c8 AnalysisPanel.hashsetHitsLabel.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30d2\u30c3\u30c8
AnalysisPanel.interestingItemLabel.text=\u8208\u5473\u6df1\u3044\u30a2\u30a4\u30c6\u30e0\u306e\u30d2\u30c3\u30c8 AnalysisPanel.interestingItemLabel.text=\u8208\u5473\u6df1\u3044\u30a2\u30a4\u30c6\u30e0\u306e\u30d2\u30c3\u30c8
AnalysisPanel.keywordHitsLabel.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u30d2\u30c3\u30c8 AnalysisPanel.keywordHitsLabel.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u30d2\u30c3\u30c8
AnalysisPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8 AnalysisPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8
AnalysisPanel_hashsetHits_tabName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30fb\u30d2\u30c3\u30c8
AnalysisPanel_interestingItemHits_tabName=\u8208\u5473\u6df1\u3044\u30a2\u30a4\u30c6\u30e0\u306e\u30d2\u30c3\u30c8
AnalysisPanel_keyColumn_title=\u540d\u524d AnalysisPanel_keyColumn_title=\u540d\u524d
AnalysisPanel_keywordHits_tabName=\u30ad\u30fc\u30ef\u30fc\u30c9\u30fb\u30d2\u30c3\u30c8
AnalysisPanel_keywordSearchModuleName=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22 AnalysisPanel_keywordSearchModuleName=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22
BaseDataSourceSummaryPanel_defaultNotIngestMessage={0}\u53d6\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u3053\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u306f\u5b9f\u884c\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
BaseDataSourceSummaryPanel_goToArtifact=\u30bd\u30fc\u30b9\u7d50\u679c\u306e\u8868\u793a BaseDataSourceSummaryPanel_goToArtifact=\u30bd\u30fc\u30b9\u7d50\u679c\u306e\u8868\u793a
BaseDataSourceSummaryPanel_goToFile=\u30d5\u30a9\u30eb\u30c0\u30fc\u5185\u306e\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u8868\u793a BaseDataSourceSummaryPanel_goToFile=\u30d5\u30a9\u30eb\u30c0\u30fc\u5185\u306e\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u8868\u793a
CTL_DataSourceSummaryAction=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u6982\u8981 CTL_DataSourceSummaryAction=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u6982\u8981
@ -30,7 +32,21 @@ ContainerPanel.units.kilobytes=\ kB
ContainerPanel.units.megabytes=\ MB ContainerPanel.units.megabytes=\ MB
ContainerPanel.units.petabytes=\ PB ContainerPanel.units.petabytes=\ PB
ContainerPanel.units.terabytes=\ TB ContainerPanel.units.terabytes=\ TB
ContainerPanel_export_acquisitionDetails=\u8aad\u8fbc\u306e\u8a73\u7d30\uff1a
ContainerPanel_export_deviceId=\u30c7\u30d0\u30a4\u30b9ID\uff1a
ContainerPanel_export_displayName=\u8868\u793a\u540d\uff1a
ContainerPanel_export_filePaths=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\uff1a
ContainerPanel_export_imageType=\u753b\u50cf\u30bf\u30a4\u30d7\uff1a
ContainerPanel_export_md5=MD5\:
ContainerPanel_export_originalName=\u540d\u524d\uff1a
ContainerPanel_export_sectorSize=\u30bb\u30af\u30bf\u30fc\u30b5\u30a4\u30ba\uff1a
ContainerPanel_export_sha1=SHA1\:
ContainerPanel_export_sha256=SHA256\:
ContainerPanel_export_size=\u30b5\u30a4\u30ba\uff1a
ContainerPanel_export_timeZone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\uff1a
ContainerPanel_export_unallocatedSize=\u672a\u5272\u308a\u5f53\u3066\u9818\u57df\uff1a
ContainerPanel_setFieldsForNonImageDataSource_na=\u8a72\u5f53\u306a\u3057 ContainerPanel_setFieldsForNonImageDataSource_na=\u8a72\u5f53\u306a\u3057
ContainerPanel_tabName=\u30b3\u30f3\u30c6\u30ca
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=\u3059\u3079\u3066 DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=\u3059\u3079\u3066
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=\u5272\u308a\u5f53\u3066\u6e08\u307f DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=\u5272\u308a\u5f53\u3066\u6e08\u307f
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=\u30ab\u30a6\u30f3\u30c8 DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=\u30ab\u30a6\u30f3\u30c8
@ -63,6 +79,7 @@ DataSourceSummaryNode.viewDataSourceAction.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u
DataSourceSummaryTabbedPane.noDataSourceLabel.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 DataSourceSummaryTabbedPane.noDataSourceLabel.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
DataSourceSummaryTabbedPane_analysisTab_title=\u5206\u6790 DataSourceSummaryTabbedPane_analysisTab_title=\u5206\u6790
DataSourceSummaryTabbedPane_detailsTab_title=\u30b3\u30f3\u30c6\u30ca DataSourceSummaryTabbedPane_detailsTab_title=\u30b3\u30f3\u30c6\u30ca
DataSourceSummaryTabbedPane_exportTab_title=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8
DataSourceSummaryTabbedPane_geolocationTab_title=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3 DataSourceSummaryTabbedPane_geolocationTab_title=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3
DataSourceSummaryTabbedPane_ingestHistoryTab_title=\u53d6\u8fbc\u5c65\u6b74 DataSourceSummaryTabbedPane_ingestHistoryTab_title=\u53d6\u8fbc\u5c65\u6b74
DataSourceSummaryTabbedPane_pastCasesTab_title=\u904e\u53bb\u306e\u30b1\u30fc\u30b9 DataSourceSummaryTabbedPane_pastCasesTab_title=\u904e\u53bb\u306e\u30b1\u30fc\u30b9
@ -70,21 +87,46 @@ DataSourceSummaryTabbedPane_recentFileTab_title=\u6700\u8fd1\u4f7f\u7528\u3057\u
DataSourceSummaryTabbedPane_timelineTab_title=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3 DataSourceSummaryTabbedPane_timelineTab_title=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3
DataSourceSummaryTabbedPane_typesTab_title=\u30bf\u30a4\u30d7 DataSourceSummaryTabbedPane_typesTab_title=\u30bf\u30a4\u30d7
DataSourceSummaryTabbedPane_userActivityTab_title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 DataSourceSummaryTabbedPane_userActivityTab_title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3
ExcelExportAction_exportToXLSX_beginExport=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3092\u958b\u59cb\u3057\u3066\u3044\u307e\u3059...
ExcelExportAction_exportToXLSX_gatheringTabData={0}\u30bf\u30d6\u306e\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u3057\u3066\u3044\u307e\u3059...
ExcelExportAction_exportToXLSX_writingToFile=\u30d5\u30a1\u30a4\u30eb\u3078\u306e\u66f8\u51fa\u3057\u4e2d...
ExcelExportAction_getXLSXPath_directory=DataSourceSummary
ExcelExportAction_moduleName=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u6982\u8981
ExcelExportAction_runXLSXExport_errorMessage=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
ExcelExportAction_runXLSXExport_errorTitle=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
ExcelExportAction_runXLSXExport_progressCancelActionTitle=\u30ad\u30e3\u30f3\u30bb\u30eb...
ExcelExportAction_runXLSXExport_progressCancelTitle=\u30ad\u30e3\u30f3\u30bb\u30eb
ExcelExportAction_runXLSXExport_progressTitle={0}\u3092XLSX\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u3059
ExcelExportDialog.okButton.text=OK
ExcelExportDialog.titleLabel.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u6982\u8981\u306f\u6b21\u306e\u5834\u6240\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3055\u308c\u307e\u3057\u305f\uff1a
ExcelExportDialog_title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u6982\u8981\u304c\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3055\u308c\u307e\u3057\u305f
ExportPanel.xlsxExportButton.text=\u8981\u7d04\u30c7\u30fc\u30bf\u306e\u30a8\u30af\u30b9\u30dd\u30fc\u30c8
ExportPanel.xlsxExportMessage.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30b5\u30de\u30ea\u30fc\u304b\u3089Excel\u30d5\u30a1\u30a4\u30eb\u306b\u30c7\u30fc\u30bf\u3092\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3057\u307e\u3059\u3002
GeolocationPanel.commonViewInGeolocationBtn.text=\u5730\u56f3\u3067\u898b\u308b GeolocationPanel.commonViewInGeolocationBtn.text=\u5730\u56f3\u3067\u898b\u308b
GeolocationPanel.mostCommonLabel.text=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u304b\u3089\u306e\u6700\u3082\u4e00\u822c\u7684\u306a\u90fd\u5e02 GeolocationPanel.mostCommonLabel.text=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u7d50\u679c\u304b\u3089\u6700\u3082\u4e00\u822c\u7684\u306a\u90fd\u5e02
GeolocationPanel.mostRecentLabel.text=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u304b\u3089\u306e\u6700\u8fd1\u306e\u90fd\u5e02 GeolocationPanel.mostRecentLabel.text=\u30b8\u30aa\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u7d50\u679c\u3067\u306e\u6700\u8fd1\u306e\u90fd\u5e02
GeolocationPanel.recentViewInGeolocationBtn.text=\u5730\u56f3\u3067\u898b\u308b GeolocationPanel.recentViewInGeolocationBtn.text=\u5730\u56f3\u3067\u898b\u308b
GeolocationPanel.withinDistanceLabel.text=\u90fd\u5e02\u304b\u3089150km\u4ee5\u4e0a\u96e2\u308c\u305f\u5834\u6240\u306f\u3001\u300c\u4e0d\u660e\u300d\u3068\u3057\u3066\u8868\u793a\u3055\u308c\u307e\u3059 GeolocationPanel.withinDistanceLabel.text=\u90fd\u5e02\u304b\u3089150km\u4ee5\u4e0a\u96e2\u308c\u305f\u5834\u6240\u306f\u3001\u300c\u4e0d\u660e\u300d\u3068\u3057\u3066\u8868\u793a\u3055\u308c\u307e\u3059
GeolocationPanel.withinDistanceLabel1.text=\u90fd\u5e02\u304b\u3089150km\u4ee5\u4e0a\u96e2\u308c\u305f\u5834\u6240\u306f\u3001\u300c\u4e0d\u660e\u300d\u3068\u3057\u3066\u8868\u793a\u3055\u308c\u307e\u3059 GeolocationPanel.withinDistanceLabel1.text=\u90fd\u5e02\u304b\u3089150km\u4ee5\u4e0a\u96e2\u308c\u305f\u5834\u6240\u306f\u3001\u300c\u4e0d\u660e\u300d\u3068\u3057\u3066\u8868\u793a\u3055\u308c\u307e\u3059
GeolocationPanel_cityColumn_title=\u6700\u3082\u8fd1\u3044\u90fd\u5e02 GeolocationPanel_cityColumn_title=\u6700\u3082\u8fd1\u3044\u90fd\u5e02
GeolocationPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8 GeolocationPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8
GeolocationPanel_mostCommon_tabName=\u6700\u3082\u4e00\u822c\u7684\u306a\u90fd\u5e02
GeolocationPanel_mostRecent_tabName=\u6700\u8fd1\u4f7f\u7528\u3055\u308c\u305f\u90fd\u5e02
GeolocationPanel_onNoCrIngest_message=GPX\u30d1\u30fc\u30b5\u30fc\u304c\u5b9f\u884c\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093\u3002 GeolocationPanel_onNoCrIngest_message=GPX\u30d1\u30fc\u30b5\u30fc\u304c\u5b9f\u884c\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093\u3002
GeolocationPanel_unknownRow_title=\u4e0d\u660e GeolocationPanel_unknownRow_title=\u4e0d\u660e
IngestJobExcelExport_endTimeColumn=\u7d42\u4e86\u6642\u9593
IngestJobExcelExport_ingestStatusTimeColumn=\u53d6\u8fbc\u307f\u72b6\u6cc1
IngestJobExcelExport_moduleNameTimeColumn=\u30e2\u30b8\u30e5\u30fc\u30eb\u540d
IngestJobExcelExport_sheetName=\u53d6\u8fbc\u307f\u6b74\u53f2
IngestJobExcelExport_startTimeColumn=\u30b9\u30bf\u30fc\u30c8\u6642\u9593
IngestJobExcelExport_versionColumn=\u30e2\u30b8\u30e5\u30fc\u30eb\u30d0\u30fc\u30b8\u30e7\u30f3
PastCasesPanel.notableFileLabel.text=\u300c\u6ce8\u76ee\u300d\u3068\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\u4e00\u822c\u7684\u306a\u30b1\u30fc\u30b9 PastCasesPanel.notableFileLabel.text=\u300c\u6ce8\u76ee\u300d\u3068\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\u4e00\u822c\u7684\u306a\u30b1\u30fc\u30b9
PastCasesPanel.sameIdLabel.text=\u540c\u3058\u30c7\u30d0\u30a4\u30b9ID\u3092\u6301\u3064\u904e\u53bb\u306e\u30b1\u30fc\u30b9 PastCasesPanel.sameIdLabel.text=\u540c\u3058\u30c7\u30d0\u30a4\u30b9ID\u3092\u6301\u3064\u904e\u53bb\u306e\u30b1\u30fc\u30b9
PastCasesPanel_caseColumn_title=\u30b1\u30fc\u30b9 PastCasesPanel_caseColumn_title=\u30b1\u30fc\u30b9
PastCasesPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8 PastCasesPanel_countColumn_title=\u30ab\u30a6\u30f3\u30c8
PastCasesPanel_notableFileTable_tabName=\u4e00\u822c\u7684\u306b\u6ce8\u76ee\u3059\u3079\u304d\u4e8b\u4f8b
PastCasesPanel_onNoCrIngest_message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u5b9f\u884c\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093\u3002 PastCasesPanel_onNoCrIngest_message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u5b9f\u884c\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093\u3002
PastCasesPanel_sameIdsTable_tabName=\u540c\u3058\u30c7\u30d0\u30a4\u30b9\u3067\u306e\u904e\u53bb\u306e\u30b1\u30fc\u30b9
RecentFilePanel_col_header_domain=\u30c9\u30e1\u30a4\u30f3 RecentFilePanel_col_header_domain=\u30c9\u30e1\u30a4\u30f3
RecentFilePanel_col_header_path=\u30d1\u30b9 RecentFilePanel_col_header_path=\u30d1\u30b9
RecentFilePanel_col_header_sender=\u9001\u4fe1\u8005 RecentFilePanel_col_header_sender=\u9001\u4fe1\u8005
@ -96,21 +138,31 @@ RecentFilesPanel.openDocsLabel.text=\u6700\u8fd1\u958b\u3044\u305f\u30c9\u30ad\u
RecentFilesPanel.rightClickForMoreOptions1.text=\u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u3001\u884c\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044 RecentFilesPanel.rightClickForMoreOptions1.text=\u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u3001\u884c\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044
RecentFilesPanel.rightClickForMoreOptions2.text=\u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u3001\u884c\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044 RecentFilesPanel.rightClickForMoreOptions2.text=\u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u3001\u884c\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044
RecentFilesPanel.rightClickForMoreOptions3.text=\u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u3001\u884c\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044 RecentFilesPanel.rightClickForMoreOptions3.text=\u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u3001\u884c\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044
RecentFilesPanel_attachmentsTable_tabName=\u6700\u8fd1\u306e\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb
RecentFilesPanel_col_head_date=\u65e5\u4ed8 RecentFilesPanel_col_head_date=\u65e5\u4ed8
RecentFilesPanel_docsTable_tabName=\u6700\u8fd1\u958b\u3044\u305f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8
RecentFilesPanel_downloadsTable_tabName=\u6700\u8fd1\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9
SizeRepresentationUtil_units_bytes=\u30d0\u30a4\u30c8 SizeRepresentationUtil_units_bytes=\u30d0\u30a4\u30c8
SizeRepresentationUtil_units_gigabytes=\ GB SizeRepresentationUtil_units_gigabytes=GB
SizeRepresentationUtil_units_kilobytes=\ kB SizeRepresentationUtil_units_kilobytes=KB
SizeRepresentationUtil_units_megabytes=\ MB SizeRepresentationUtil_units_megabytes=MB
SizeRepresentationUtil_units_petabytes=\ PB SizeRepresentationUtil_units_petabytes=PB
SizeRepresentationUtil_units_terabytes=\ TB SizeRepresentationUtil_units_terabytes=TB
TimelinePanel.activityRangeLabel.text=\u6d3b\u52d5\u7bc4\u56f2 TimelinePanel.activityRangeLabel.text=\u6d3b\u52d5\u7bc4\u56f2
TimelinePanel.viewInTimelineBtn.text=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u3067\u8868\u793a TimelinePanel.viewInTimelineBtn.text=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u3067\u8868\u793a
TimelinePanel_earliestLabel_title=\u6700\u53e4 TimelinePanel_earliestLabel_title=\u6700\u53e4
TimelinePanel_getExports_activityRange=\u6d3b\u52d5\u7bc4\u56f2
TimelinePanel_getExports_chartName=\u904e\u53bb30\u65e5\u9593
TimelinePanel_getExports_dateColumnHeader=\u65e5\u4ed8
TimelinePanel_getExports_earliest=\u6700\u53e4\uff1a
TimelinePanel_getExports_latest=\u6700\u8fd1\uff1a
TimelinePanel_getExports_sheetName=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3
TimelinePanel_latestLabel_title=\u6700\u65b0 TimelinePanel_latestLabel_title=\u6700\u65b0
TimlinePanel_last30DaysChart_artifactEvts_title=\u7d50\u679c\u30a4\u30d9\u30f3\u30c8 TimlinePanel_last30DaysChart_artifactEvts_title=\u7d50\u679c\u30a4\u30d9\u30f3\u30c8
TimlinePanel_last30DaysChart_fileEvts_title=\u30d5\u30a1\u30a4\u30eb\u30a4\u30d9\u30f3\u30c8 TimlinePanel_last30DaysChart_fileEvts_title=\u30d5\u30a1\u30a4\u30eb\u30a4\u30d9\u30f3\u30c8
TimlinePanel_last30DaysChart_title=\u904e\u53bb30\u65e5\u9593 TimlinePanel_last30DaysChart_title=\u904e\u53bb30\u65e5\u9593
TypesPanel_artifactsTypesPieChart_title=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30bf\u30a4\u30d7 TypesPanel_artifactsTypesPieChart_title=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30bf\u30a4\u30d7
TypesPanel_excelTabName=\u30bf\u30a4\u30d7
TypesPanel_fileMimeTypesChart_audio_title=\u30aa\u30fc\u30c7\u30a3\u30aa TypesPanel_fileMimeTypesChart_audio_title=\u30aa\u30fc\u30c7\u30a3\u30aa
TypesPanel_fileMimeTypesChart_documents_title=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8 TypesPanel_fileMimeTypesChart_documents_title=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8
TypesPanel_fileMimeTypesChart_executables_title=\u5b9f\u884c\u53ef\u80fd\u30d5\u30a1\u30a4\u30eb TypesPanel_fileMimeTypesChart_executables_title=\u5b9f\u884c\u53ef\u80fd\u30d5\u30a1\u30a4\u30eb
@ -119,6 +171,7 @@ TypesPanel_fileMimeTypesChart_notAnalyzed_title=\u5206\u6790\u3055\u308c\u3066\u
TypesPanel_fileMimeTypesChart_other_title=\u305d\u306e\u4ed6 TypesPanel_fileMimeTypesChart_other_title=\u305d\u306e\u4ed6
TypesPanel_fileMimeTypesChart_title=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7 TypesPanel_fileMimeTypesChart_title=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7
TypesPanel_fileMimeTypesChart_unknown_title=\u4e0d\u660e TypesPanel_fileMimeTypesChart_unknown_title=\u4e0d\u660e
TypesPanel_fileMimeTypesChart_valueLabel=\u30ab\u30a6\u30f3\u30c8
TypesPanel_fileMimeTypesChart_videos_title=\u30d3\u30c7\u30aa TypesPanel_fileMimeTypesChart_videos_title=\u30d3\u30c7\u30aa
TypesPanel_filesByCategoryTable_allocatedRow_title=\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30d5\u30a1\u30a4\u30eb TypesPanel_filesByCategoryTable_allocatedRow_title=\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30d5\u30a1\u30a4\u30eb
TypesPanel_filesByCategoryTable_directoryRow_title=\u30d5\u30a9\u30eb\u30c0 TypesPanel_filesByCategoryTable_directoryRow_title=\u30d5\u30a9\u30eb\u30c0
@ -139,18 +192,23 @@ UserActivityPanel.topDevicesAttachedLabel.text=\u6700\u8fd1\u63a5\u7d9a\u3055\u3
UserActivityPanel.topWebSearchLabel.text=\u6700\u8fd1\u306eWeb\u691c\u7d22 UserActivityPanel.topWebSearchLabel.text=\u6700\u8fd1\u306eWeb\u691c\u7d22
UserActivityPanel_TopAccountTableModel_accountType_header=\u30a2\u30ab\u30f3\u30c8\u30bf\u30a4\u30d7 UserActivityPanel_TopAccountTableModel_accountType_header=\u30a2\u30ab\u30f3\u30c8\u30bf\u30a4\u30d7
UserActivityPanel_TopAccountTableModel_lastAccess_header=\u6700\u7d42\u30a2\u30af\u30bb\u30b9\u65e5 UserActivityPanel_TopAccountTableModel_lastAccess_header=\u6700\u7d42\u30a2\u30af\u30bb\u30b9\u65e5
UserActivityPanel_TopAccountTableModel_tabName=\u6700\u8fd1\u4f7f\u7528\u3055\u308c\u305f\u30a2\u30ab\u30a6\u30f3\u30c8\u30bf\u30a4\u30d7
UserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=\u6700\u7d42\u30a2\u30af\u30bb\u30b9\u65e5 UserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=\u6700\u7d42\u30a2\u30af\u30bb\u30b9\u65e5
UserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=\u30c7\u30d0\u30a4\u30b9ID UserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=\u30c7\u30d0\u30a4\u30b9ID
UserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=\u30e1\u30fc\u30ab\u30fc\u3068\u30e2\u30c7\u30eb UserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=\u30e1\u30fc\u30ab\u30fc\u3068\u30e2\u30c7\u30eb
UserActivityPanel_TopDeviceAttachedTableModel_tabName=\u6700\u8fd1\u63a5\u7d9a\u3055\u308c\u305f\u30c7\u30d0\u30a4\u30b9
UserActivityPanel_TopDomainsTableModel_count_header=\u53c2\u89b3 UserActivityPanel_TopDomainsTableModel_count_header=\u53c2\u89b3
UserActivityPanel_TopDomainsTableModel_domain_header=\u30c9\u30e1\u30a4\u30f3 UserActivityPanel_TopDomainsTableModel_domain_header=\u30c9\u30e1\u30a4\u30f3
UserActivityPanel_TopDomainsTableModel_lastAccess_header=\u6700\u7d42\u30a2\u30af\u30bb\u30b9\u65e5 UserActivityPanel_TopDomainsTableModel_lastAccess_header=\u6700\u7d42\u30a2\u30af\u30bb\u30b9\u65e5
UserActivityPanel_TopDomainsTableModel_tabName=\u6700\u8fd1\u306e\u30c9\u30e1\u30a4\u30f3
UserActivityPanel_TopProgramsTableModel_count_header=\u5b9f\u884c\u6642\u9593 UserActivityPanel_TopProgramsTableModel_count_header=\u5b9f\u884c\u6642\u9593
UserActivityPanel_TopProgramsTableModel_folder_header=\u30d5\u30a9\u30eb\u30c0 UserActivityPanel_TopProgramsTableModel_folder_header=\u30d5\u30a9\u30eb\u30c0
UserActivityPanel_TopProgramsTableModel_lastrun_header=\u524d\u56de\u5b9f\u884c UserActivityPanel_TopProgramsTableModel_lastrun_header=\u524d\u56de\u5b9f\u884c
UserActivityPanel_TopProgramsTableModel_name_header=\u30d7\u30ed\u30b0\u30e9\u30e0 UserActivityPanel_TopProgramsTableModel_name_header=\u30d7\u30ed\u30b0\u30e9\u30e0
UserActivityPanel_TopProgramsTableModel_tabName=\u6700\u8fd1\u306e\u30d7\u30ed\u30b0\u30e9\u30e0
UserActivityPanel_TopWebSearchTableModel_dateAccessed_header=\u30a2\u30af\u30bb\u30b9\u65e5 UserActivityPanel_TopWebSearchTableModel_dateAccessed_header=\u30a2\u30af\u30bb\u30b9\u65e5
UserActivityPanel_TopWebSearchTableModel_searchString_header=\u691c\u7d22\u6587\u5b57\u5217 UserActivityPanel_TopWebSearchTableModel_searchString_header=\u691c\u7d22\u6587\u5b57\u5217
UserActivityPanel_TopWebSearchTableModel_tabName=\u6700\u8fd1\u306eWeb\u691c\u7d22
UserActivityPanel_TopWebSearchTableModel_translatedResult_header=\u7ffb\u8a33\u6e08\u307f UserActivityPanel_TopWebSearchTableModel_translatedResult_header=\u7ffb\u8a33\u6e08\u307f
UserActivityPanel_noDataExists=\u901a\u4fe1\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093 UserActivityPanel_noDataExists=\u901a\u4fe1\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093
UserActivityPanel_tab_title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 UserActivityPanel_tab_title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3

View File

@ -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));
} }
/** /**

View File

@ -1,6 +1,7 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
AbstractLoadableComponent_errorMessage_defaultText=\u7d50\u679c\u306e\u8aad\u8fbc\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 AbstractLoadableComponent_errorMessage_defaultText=\u7d50\u679c\u306e\u8aad\u8fbc\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
AbstractLoadableComponent_loadingMessage_defaultText=\u7d50\u679c\u3092\u8aad\u8fbc\u4e2d... AbstractLoadableComponent_loadingMessage_defaultText=\u7d50\u679c\u3092\u8aad\u8fbc\u4e2d...
AbstractLoadableComponent_noDataExists_defaultText=\u30c7\u30fc\u30bf\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 AbstractLoadableComponent_noDataExists_defaultText=\u30c7\u30fc\u30bf\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
ExcelExport_writeExcel_noSheetName=\u30b7\u30fc\u30c8{0}
IngestRunningLabel_defaultMessage=\u53d6\u8fbc\u307f\u5b9f\u884c\u4e2d\u3067\u3059\u3002 IngestRunningLabel_defaultMessage=\u53d6\u8fbc\u307f\u5b9f\u884c\u4e2d\u3067\u3059\u3002
PieChartPanel_noDataLabel=\u30c7\u30fc\u30bf\u7121\u3057 PieChartPanel_noDataLabel=\u30c7\u30fc\u30bf\u7121\u3057

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
AddExternalViewerRuleDialog.cancelButton.title=\u53d6\u308a\u6d88\u3057 AddExternalViewerRuleDialog.cancelButton.title=\u53d6\u308a\u6d88\u3057
AddExternalViewerRuleDialog.saveButton.title=\u4fdd\u5b58 AddExternalViewerRuleDialog.saveButton.title=\u4fdd\u5b58
AddExternalViewerRuleDialog.title=\u5916\u90e8\u30d3\u30e5\u30fc\u30ef\u30fc\u30eb\u30fc\u30eb AddExternalViewerRuleDialog.title=\u5916\u90e8\u30d3\u30e5\u30fc\u30ef\u30fc\u30eb\u30fc\u30eb

View File

@ -31,6 +31,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import org.apache.commons.lang3.StringUtils;
import org.openide.nodes.AbstractNode; import org.openide.nodes.AbstractNode;
import org.openide.explorer.ExplorerManager; import org.openide.explorer.ExplorerManager;
import org.openide.explorer.view.TreeView; import org.openide.explorer.view.TreeView;
@ -168,55 +169,127 @@ public class ViewContextAction extends AbstractAction {
public void actionPerformed(ActionEvent event) { public void actionPerformed(ActionEvent event) {
EventQueue.invokeLater(() -> { EventQueue.invokeLater(() -> {
/* Content parentContent = getParentContent(this.content);
* Get the parent content for the content to be selected in the
* results view. If the parent content is null, then the specified
* content is a data source, and the parent tree view node is the
* "Data Sources" node. Otherwise, the tree view needs to be
* searched to find the parent treeview node.
*/
Content parentContent = null;
try {
parentContent = content.getParent();
} catch (TskCoreException ex) {
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory());
logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS
return;
}
if ((parentContent != null) if ((parentContent != null) && (parentContent instanceof UnsupportedContent)) {
&& (parentContent instanceof UnsupportedContent)) {
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_unsupportedParent()); MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_unsupportedParent());
logger.log(Level.WARNING, String.format("Could not navigate to unsupported content with id: %d", parentContent.getId())); //NON-NLS logger.log(Level.WARNING, String.format("Could not navigate to unsupported content with id: %d", parentContent.getId())); //NON-NLS
return; return;
} }
/* // Get the "Data Sources" node from the tree view.
* Get the "Data Sources" node from the tree view.
*/
DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance(); DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance();
ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager(); ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager();
Node parentTreeViewNode = null; Node parentTreeViewNode = null;
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { // 'Group by Data Source' view if (parentContent != null) {
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
parentTreeViewNode = getParentNodeGroupedByPersonHost(treeViewExplorerMgr, parentContent);
} else {
parentTreeViewNode = getParentNodeGroupedByDataSource(treeViewExplorerMgr, parentContent);
}
}
// if no node is found, report error and do nothing
if (parentTreeViewNode == null) {
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode());
logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS
return;
}
setNodeSelection(this.content, parentTreeViewNode, treeViewTopComponent, treeViewExplorerMgr);
});
}
/**
* Get the parent content for the content to be selected in the results
* view. If the parent content is null, then the specified content is a data
* source, and the parent tree view node is the "Data Sources" node.
* Otherwise, the tree view needs to be searched to find the parent treeview
* node.
*
* @param content The content whose parent will be returned. If this item is
* a datasource, it will be returned.
*
* @return The content if content is a data source or the parent of this
* content.
*/
private Content getParentContent(Content content) {
try {
return (content instanceof DataSource)
? content
: content.getParent();
} catch (TskCoreException ex) {
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindDirectory());
logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS
return null;
}
}
/**
* Returns the node in the tree related to the parentContent or null if
* can't be found. This method should be used when view is grouped by data
* source.
*
* @param treeViewExplorerMgr The explorer manager.
* @param parentContent The content whose equivalent node will be
* returned if found.
*
* @return The node if found or null.
*/
private Node getParentNodeGroupedByDataSource(ExplorerManager treeViewExplorerMgr, Content parentContent) {
// Classic view
// Start the search at the DataSourcesNode
Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren();
Node rootDsNode = rootChildren == null ? null : rootChildren.findChild(DataSourcesNode.getNameIdentifier());
if (rootDsNode != null) {
for (Node dataSourceLevelNode : getDataSourceLevelNodes(rootDsNode)) {
DataSource dataSource = dataSourceLevelNode.getLookup().lookup(DataSource.class);
if (dataSource != null) {
// the tree view needs to be searched to find the parent treeview node.
Node potentialParentTreeViewNode = findParentNodeInTree(parentContent, dataSourceLevelNode);
if (potentialParentTreeViewNode != null) {
return potentialParentTreeViewNode;
}
}
}
}
return null;
}
/**
* Returns the node in the tree related to the parentContent or null if
* can't be found. This method should be used when view is grouped by
* hosts/persons.
*
* @param treeViewExplorerMgr The explorer manager.
* @param parentContent The content whose equivalent node will be
* returned if found.
*
* @return The node if found or null.
*/
private Node getParentNodeGroupedByPersonHost(ExplorerManager treeViewExplorerMgr, Content parentContent) {
// 'Group by Data Source' view
SleuthkitCase skCase; SleuthkitCase skCase;
String dsname; String dsname;
try { try {
// get the objid/name of the datasource of the selected content. // get the objid/name of the datasource of the selected content.
skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
long contentDSObjid = content.getDataSource().getId(); long contentDSObjid = parentContent.getDataSource().getId();
DataSource datasource = skCase.getDataSource(contentDSObjid); DataSource datasource = skCase.getDataSource(contentDSObjid);
dsname = datasource.getName(); dsname = datasource.getName();
Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren(); Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren();
if (null != parentContent) {
// the tree view needs to be searched to find the parent treeview node. // the tree view needs to be searched to find the parent treeview node.
/* NOTE: we can't do a lookup by data source name here, becase if there /* NOTE: we can't do a lookup by data source name here, becase if there
are multiple data sources with the same name, then "getChildren().findChild(dsname)" are multiple data sources with the same name, then "getChildren().findChild(dsname)"
simply returns the first one that it finds. Instead we have to loop over all simply returns the first one that it finds. Instead we have to loop over all
data sources with that name, and make sure we find the correct one. data sources with that name, and make sure we find the correct one.
*/ */
List<Node> dataSourceLevelNodes = Stream.of(rootChildren.getNodes()) List<Node> dataSourceLevelNodes = Stream.of(rootChildren.getNodes(true))
.flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream()) .flatMap(rootNode -> getDataSourceLevelNodes(rootNode).stream())
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -230,52 +303,28 @@ public class ViewContextAction extends AbstractAction {
Node datasourceGroupingNode = treeNode.getChildren().findChild(DataSourceFilesNode.getNameIdentifier()); Node datasourceGroupingNode = treeNode.getChildren().findChild(DataSourceFilesNode.getNameIdentifier());
// check whether this is the data source we are looking for // check whether this is the data source we are looking for
parentTreeViewNode = findParentNodeInTree(parentContent, datasourceGroupingNode); Node parentTreeViewNode = findParentNodeInTree(parentContent, datasourceGroupingNode);
if (parentTreeViewNode != null) { if (parentTreeViewNode != null) {
// found the data source node // found the data source node
break; return parentTreeViewNode;
} }
} }
} else {
/* If the parent content is null, then the specified
* content is a data source, and the parent tree view node is the
* "Data Sources" node. */
Node datasourceGroupingNode = rootChildren.findChild(dsname);
if (!Objects.isNull(datasourceGroupingNode)) {
Children dsChildren = datasourceGroupingNode.getChildren();
parentTreeViewNode = dsChildren.findChild(DataSourceFilesNode.getNameIdentifier());
}
}
if (parentTreeViewNode == null) {
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode());
logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS
return;
}
} catch (NoCurrentCaseException | TskDataException | TskCoreException ex) { } catch (NoCurrentCaseException | TskDataException | TskCoreException ex) {
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode()); MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode());
logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS
return;
}
} else { // Classic view
// Start the search at the DataSourcesNode
Children rootChildren = treeViewExplorerMgr.getRootContext().getChildren();
Node rootDsNode = rootChildren == null ? null : rootChildren.findChild(DataSourcesNode.getNameIdentifier());
if (rootDsNode != null) {
for (Node dataSourceLevelNode : getDataSourceLevelNodes(rootDsNode)) {
DataSource dataSource = dataSourceLevelNode.getLookup().lookup(DataSource.class);
if (dataSource != null) {
// the tree view needs to be searched to find the parent treeview node.
Node potentialParentTreeViewNode = findParentNodeInTree(parentContent, dataSourceLevelNode);
if (potentialParentTreeViewNode != null) {
parentTreeViewNode = potentialParentTreeViewNode;
break;
}
}
}
}
} }
return null;
}
/**
* Set the node selection in the tree.
* @param content The content to select.
* @param parentTreeViewNode The node that is the parent of the content.
* @param treeViewTopComponent The DirectoryTreeTopComponent.
* @param treeViewExplorerMgr The ExplorerManager.
*/
private void setNodeSelection(Content content, Node parentTreeViewNode, DirectoryTreeTopComponent treeViewTopComponent, ExplorerManager treeViewExplorerMgr) {
/* /*
* Set the child selection info of the parent tree node, then select * Set the child selection info of the parent tree node, then select
* the parent node in the tree view. The results view will retrieve * the parent node in the tree view. The results view will retrieve
@ -314,7 +363,6 @@ public class ViewContextAction extends AbstractAction {
logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS
} }
} }
});
} }
/** /**
@ -322,22 +370,23 @@ public class ViewContextAction extends AbstractAction {
* returns itself. * returns itself.
* *
* @param node The node. * @param node The node.
*
* @return The child nodes that are at the data source level. * @return The child nodes that are at the data source level.
*/ */
private List<Node> getDataSourceLevelNodes(Node node) { private List<Node> getDataSourceLevelNodes(Node node) {
if (node == null) { if (node == null) {
return Collections.emptyList(); return Collections.emptyList();
} else if (node.getLookup().lookup(Host.class) != null || } else if (node.getLookup().lookup(Host.class) != null
node.getLookup().lookup(Person.class) != null || || node.getLookup().lookup(Person.class) != null
DataSourcesNode.getNameIdentifier().equals(node.getLookup().lookup(String.class)) || || DataSourcesNode.getNameIdentifier().equals(node.getLookup().lookup(String.class))
PersonNode.getUnknownPersonId().equals(node.getLookup().lookup(String.class))) { || PersonNode.getUnknownPersonId().equals(node.getLookup().lookup(String.class))) {
Children children = node.getChildren(); Children children = node.getChildren();
Node[] childNodes = children == null ? null : children.getNodes(); Node[] childNodes = children == null ? null : children.getNodes(true);
if (childNodes == null) { if (childNodes == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
return Stream.of(node.getChildren().getNodes()) return Stream.of(node.getChildren().getNodes(true))
.flatMap(parent -> getDataSourceLevelNodes(parent).stream()) .flatMap(parent -> getDataSourceLevelNodes(parent).stream())
.collect(Collectors.toList()); .collect(Collectors.toList());
} else { } else {
@ -351,6 +400,7 @@ public class ViewContextAction extends AbstractAction {
* *
* @param parentContent parent content for the content to be searched for * @param parentContent parent content for the content to be searched for
* @param node Node tree to search * @param node Node tree to search
*
* @return Node object of the matching parent, NULL if not found * @return Node object of the matching parent, NULL if not found
*/ */
private Node findParentNodeInTree(Content parentContent, Node node) { private Node findParentNodeInTree(Content parentContent, Node node) {
@ -377,6 +427,11 @@ public class ViewContextAction extends AbstractAction {
Node dummyRootNode = new DirectoryTreeFilterNode(new AbstractNode(new RootContentChildren(contentBranch)), true); Node dummyRootNode = new DirectoryTreeFilterNode(new AbstractNode(new RootContentChildren(contentBranch)), true);
Children ancestorChildren = dummyRootNode.getChildren(); Children ancestorChildren = dummyRootNode.getChildren();
// if content is the data source provided, return that.
if (ancestorChildren.getNodesCount() == 1 && StringUtils.equals(ancestorChildren.getNodeAt(0).getName(), node.getName())) {
return node;
}
/* /*
* Search the tree for the parent node. Note that this algorithm * Search the tree for the parent node. Note that this algorithm
* simply discards "extra" ancestor nodes not shown in the tree, * simply discards "extra" ancestor nodes not shown in the tree,
@ -387,8 +442,9 @@ public class ViewContextAction extends AbstractAction {
Node parentTreeViewNode = null; Node parentTreeViewNode = null;
for (int i = 0; i < ancestorChildren.getNodesCount(); i++) { for (int i = 0; i < ancestorChildren.getNodesCount(); i++) {
Node ancestorNode = ancestorChildren.getNodeAt(i); Node ancestorNode = ancestorChildren.getNodeAt(i);
for (int j = 0; j < treeNodeChildren.getNodesCount(); j++) { Node[] treeNodeChilds = treeNodeChildren.getNodes(true);
Node treeNode = treeNodeChildren.getNodeAt(j); for (int j = 0; j < treeNodeChilds.length; j++) {
Node treeNode = treeNodeChilds[j];
if (ancestorNode.getName().equals(treeNode.getName())) { if (ancestorNode.getName().equals(treeNode.getName())) {
parentTreeViewNode = treeNode; parentTreeViewNode = treeNode;
treeNodeChildren = treeNode.getChildren(); treeNodeChildren = treeNode.getChildren();

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate={0}{1}\u3001{2}\u306e\u9031 DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate={0}{1}\u3001{2}\u306e\u9031
DiscoveryAttributes.GroupingAttributeType.datasource.displayName=\u30c7\u30fc\u30bf\u5143 DiscoveryAttributes.GroupingAttributeType.datasource.displayName=\u30c7\u30fc\u30bf\u5143
DiscoveryAttributes.GroupingAttributeType.fileType.displayName=\u30d5\u30a1\u30a4\u30eb\u306e\u7a2e\u985e DiscoveryAttributes.GroupingAttributeType.fileType.displayName=\u30d5\u30a1\u30a4\u30eb\u306e\u7a2e\u985e
@ -48,6 +48,7 @@ FileSorter.SortingMethod.fullPath.displayName=\u30d5\u30eb\u30d1\u30b9
FileSorter.SortingMethod.keywordlist.displayName=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u540d FileSorter.SortingMethod.keywordlist.displayName=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u540d
FileSorter.SortingMethod.pageViews.displayName=\u30da\u30fc\u30b8\u30d3\u30e5\u30fc FileSorter.SortingMethod.pageViews.displayName=\u30da\u30fc\u30b8\u30d3\u30e5\u30fc
ResultDomain_getDefaultCategory=\u672a\u5206\u985e ResultDomain_getDefaultCategory=\u672a\u5206\u985e
ResultDomain_noAccountTypes=\u4e0d\u660e
ResultFile.score.interestingResult.description=1\u3064\u4ee5\u4e0a\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u8208\u5473\u6df1\u3044\u7d50\u679c\u304c\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u307e\u3059\u3002 ResultFile.score.interestingResult.description=1\u3064\u4ee5\u4e0a\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u8208\u5473\u6df1\u3044\u7d50\u679c\u304c\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u307e\u3059\u3002
ResultFile.score.notableFile.description=1\u3064\u4ee5\u4e0a\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u6ce8\u76ee\u3059\u3079\u304d\u3082\u306e\u3068\u3057\u3066\u8a8d\u8b58\u3055\u308c\u307e\u3057\u305f\u3002 ResultFile.score.notableFile.description=1\u3064\u4ee5\u4e0a\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u6ce8\u76ee\u3059\u3079\u304d\u3082\u306e\u3068\u3057\u3066\u8a8d\u8b58\u3055\u308c\u307e\u3057\u305f\u3002
ResultFile.score.notableTaggedFile.description=1\u3064\u4ee5\u4e0a\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u6ce8\u76ee\u3059\u3079\u304d\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u3066\u3044\u307e\u3059\u3002 ResultFile.score.notableTaggedFile.description=1\u3064\u4ee5\u4e0a\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u6ce8\u76ee\u3059\u3079\u304d\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u3066\u3044\u307e\u3059\u3002

View File

@ -1,4 +1,5 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
ArtifactMenuMouseAdapter.noFile.text=\u30d5\u30a1\u30a4\u30eb\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
ArtifactMenuMouseAdapter_ExternalViewer_label=\u5916\u90e8\u30d3\u30e5\u30fc\u30a2\u3067\u958b\u304f ArtifactMenuMouseAdapter_ExternalViewer_label=\u5916\u90e8\u30d3\u30e5\u30fc\u30a2\u3067\u958b\u304f
ArtifactMenuMouseAdapter_label=\u30d5\u30a1\u30a4\u30eb\u306e\u62bd\u51fa ArtifactMenuMouseAdapter_label=\u30d5\u30a1\u30a4\u30eb\u306e\u62bd\u51fa
ArtifactTypeFilterPanel.artifactTypeCheckbox.text=\u7d50\u679c\u30bf\u30a4\u30d7\uff1a ArtifactTypeFilterPanel.artifactTypeCheckbox.text=\u7d50\u679c\u30bf\u30a4\u30d7\uff1a
@ -23,7 +24,7 @@ DateFilterPanel.dateRange.text=\u65e5\u4ed8\u7bc4\u56f2\uff08{0}\uff09\uff1a
DateFilterPanel.daysLabel.text=\u6d3b\u52d5\u65e5 DateFilterPanel.daysLabel.text=\u6d3b\u52d5\u65e5
DateFilterPanel.endCheckBox.text=\u7d42\u4e86\uff1a DateFilterPanel.endCheckBox.text=\u7d42\u4e86\uff1a
DateFilterPanel.invalidRange.text=\u7bc4\u56f2\u307e\u305f\u306f\u6700\u5f8c\u3092\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 DateFilterPanel.invalidRange.text=\u7bc4\u56f2\u307e\u305f\u306f\u6700\u5f8c\u3092\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
DateFilterPanel.mostRecentRadioButton.text=\u6700\u5f8c\u306e\u307f\uff1a DateFilterPanel.mostRecentRadioButton.text=\u6700\u7d42\u306e\u307f\uff1a
DateFilterPanel.startAfterEnd.text=\u4e21\u65b9\u304c\u6709\u52b9\u306a\u5834\u5408\u3001\u958b\u59cb\u65e5\u306f\u7d42\u4e86\u65e5\u3088\u308a\u524d\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 DateFilterPanel.startAfterEnd.text=\u4e21\u65b9\u304c\u6709\u52b9\u306a\u5834\u5408\u3001\u958b\u59cb\u65e5\u306f\u7d42\u4e86\u65e5\u3088\u308a\u524d\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
DateFilterPanel.startCheckBox.text=\u30b9\u30bf\u30fc\u30c8\uff1a DateFilterPanel.startCheckBox.text=\u30b9\u30bf\u30fc\u30c8\uff1a
DateFilterPanel.startOrEndNeeded.text=\u7bc4\u56f2\u30d5\u30a3\u30eb\u30bf\u30fc\u3092\u4f7f\u7528\u3059\u308b\u306b\u306f\u3001\u958b\u59cb\u65e5\u307e\u305f\u306f\u7d42\u4e86\u65e5\u3092\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 DateFilterPanel.startOrEndNeeded.text=\u7bc4\u56f2\u30d5\u30a3\u30eb\u30bf\u30fc\u3092\u4f7f\u7528\u3059\u308b\u306b\u306f\u3001\u958b\u59cb\u65e5\u307e\u305f\u306f\u7d42\u4e86\u65e5\u3092\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
@ -63,12 +64,18 @@ DocumentPanel.numberOfImages.noImages=\u753b\u50cf\u306a\u3057
DocumentPanel.numberOfImages.text={0}\u753b\u50cf\u306e1\u3064 DocumentPanel.numberOfImages.text={0}\u753b\u50cf\u306e1\u3064
DocumentWrapper.previewInitialValue=\u30d7\u30ec\u30d3\u30e5\u30fc\u306f\u307e\u3060\u751f\u6210\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 DocumentWrapper.previewInitialValue=\u30d7\u30ec\u30d3\u30e5\u30fc\u306f\u307e\u3060\u751f\u6210\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
DomainDetailsPanel.miniTimelineTitle.text=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3 DomainDetailsPanel.miniTimelineTitle.text=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3
DomainDetailsPanel.otherOccurrencesTab.title=\u305d\u306e\u4ed6\u306e\u767a\u751f
DomainFilterPanel.domainFiltersSplitPane.border.title=\u30b9\u30c6\u30c3\u30d72\uff1a\u8868\u793a\u3059\u308b\u30c9\u30e1\u30a4\u30f3\u306e\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0 DomainFilterPanel.domainFiltersSplitPane.border.title=\u30b9\u30c6\u30c3\u30d72\uff1a\u8868\u793a\u3059\u308b\u30c9\u30e1\u30a4\u30f3\u306e\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0
DomainSummaryPanel.activity.text=\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\uff1a{0}\u304b\u3089{1} DomainSummaryPanel.activity.text=\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\uff1a{0}\u304b\u3089{1}
DomainSummaryPanel.category.text=\u30ab\u30c6\u30b4\u30ea\uff1a
DomainSummaryPanel.downloads.text=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305f\u30d5\u30a1\u30a4\u30eb\uff1a DomainSummaryPanel.downloads.text=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305f\u30d5\u30a1\u30a4\u30eb\uff1a
DomainSummaryPanel.loadingImages.text=\u30b5\u30e0\u30cd\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059... DomainSummaryPanel.loadingImages.text=\u30b5\u30e0\u30cd\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...
DomainSummaryPanel.pages.text=\u904e\u53bb60\u65e5\u9593\u306e\u30da\u30fc\u30b8\u30d3\u30e5\u30fc\uff1a DomainSummaryPanel.no.text=\u3044\u3044\u3048
DomainSummaryPanel.notability.text=\u4ee5\u524d\u306b\u6ce8\u76ee\u3059\u3079\u304d\u306b\u30bf\u30b0\u4ed8\u3051\uff1a
DomainSummaryPanel.pages.text=\u6700\u8fd160\u65e5\u9593\u306e\u30da\u30fc\u30b8\u30d3\u30e5\u30fc\uff1a
DomainSummaryPanel.totalPages.text=\u5168\u30da\u30fc\u30b8\u30d3\u30e5\u30fc\uff1a DomainSummaryPanel.totalPages.text=\u5168\u30da\u30fc\u30b8\u30d3\u30e5\u30fc\uff1a
DomainSummaryPanel.userRole.text=\u30a2\u30ab\u30a6\u30f3\u30c8\u30bf\u30a4\u30d7
DomainSummaryPanel.yes.text=\u306f\u3044
FileDetailsPanel.instancesList.border.title=\u4f8b FileDetailsPanel.instancesList.border.title=\u4f8b
GroupListPanel.groupKeyList.border.title=\u30b0\u30eb\u30fc\u30d7 GroupListPanel.groupKeyList.border.title=\u30b0\u30eb\u30fc\u30d7
GroupsListPanel.noDomainResults.message.text=\u9078\u629e\u3057\u305f\u30d5\u30a3\u30eb\u30bf\u30fc\u3067\u306e\u30c9\u30e1\u30a4\u30f3\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n\n\u30ea\u30de\u30a4\u30f3\u30c0\u30fc\uff1a\n -\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u7d50\u679c\u3092\u691c\u7d22\u3059\u308b\u306b\u306f\u5404\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n -\u904e\u53bb\u306e\u767a\u751f\u3067\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\u307e\u305f\u306f\u30bd\u30fc\u30c8\u3059\u308b\u5834\u5408\u306f\u3001\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5404\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n -iOS\u30a2\u30ca\u30e9\u30a4\u30b6\u30fc\uff08iLEAPP\uff09\u30e2\u30b8\u30e5\u30fc\u30eb\u3092iOS\u30c7\u30d0\u30a4\u30b9\u306e\u30c7\u30fc\u30bf\u3092\u542b\u3080\u5404\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 GroupsListPanel.noDomainResults.message.text=\u9078\u629e\u3057\u305f\u30d5\u30a3\u30eb\u30bf\u30fc\u3067\u306e\u30c9\u30e1\u30a4\u30f3\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n\n\u30ea\u30de\u30a4\u30f3\u30c0\u30fc\uff1a\n -\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u7d50\u679c\u3092\u691c\u7d22\u3059\u308b\u306b\u306f\u5404\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n -\u904e\u53bb\u306e\u767a\u751f\u3067\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\u307e\u305f\u306f\u30bd\u30fc\u30c8\u3059\u308b\u5834\u5408\u306f\u3001\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5404\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n -iOS\u30a2\u30ca\u30e9\u30a4\u30b6\u30fc\uff08iLEAPP\uff09\u30e2\u30b8\u30e5\u30fc\u30eb\u3092iOS\u30c7\u30d0\u30a4\u30b9\u306e\u30c7\u30fc\u30bf\u3092\u542b\u3080\u5404\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:28 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
CTL_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8 CTL_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8
CTL_RunIngestAction=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u5b9f\u884c CTL_RunIngestAction=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u5b9f\u884c
DataSourceIngestCancellationPanel.cancelAllModulesRadioButton.text=\u3059\u3079\u3066\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u53d6\u308a\u6d88\u3059 DataSourceIngestCancellationPanel.cancelAllModulesRadioButton.text=\u3059\u3079\u3066\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u53d6\u308a\u6d88\u3059
@ -7,6 +7,7 @@ DataSourceIngestPipeline.moduleError.title.text={0} \u30a8\u30e9\u30fc
FileIngestCancellationPanel.cancelFileIngestRadioButton.text=\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u307f\u3092\u53d6\u308a\u6d88\u3059 FileIngestCancellationPanel.cancelFileIngestRadioButton.text=\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u307f\u3092\u53d6\u308a\u6d88\u3059
FileIngestCancellationPanel.cancelIngestJobRadioButton.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3068\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u53d6\u308a\u6d88\u3059 FileIngestCancellationPanel.cancelIngestJobRadioButton.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3068\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u53d6\u308a\u6d88\u3059
FileIngestPipeline.moduleError.title.text={0} \u30a8\u30e9\u30fc FileIngestPipeline.moduleError.title.text={0} \u30a8\u30e9\u30fc
FileIngestPipeline_SaveResults_Activity=\u7d50\u679c\u306e\u4fdd\u5b58
HINT_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8\u30a6\u30a3\u30f3\u30c9\u30a6 HINT_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8\u30a6\u30a3\u30f3\u30c9\u30a6
IngestDialog.closeButton.title=\u7d42\u4e86 IngestDialog.closeButton.title=\u7d42\u4e86
IngestDialog.startButton.title=\u958b\u59cb IngestDialog.startButton.title=\u958b\u59cb

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2015-2019 Basis Technology Corp. * Copyright 2015-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.keywordsearchservice; package org.sleuthkit.autopsy.keywordsearchservice;
import com.google.common.annotations.Beta;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import org.sleuthkit.autopsy.casemodule.CaseMetadata; import org.sleuthkit.autopsy.casemodule.CaseMetadata;
@ -106,4 +107,13 @@ public interface KeywordSearchService extends Closeable {
*/ */
void deleteDataSource(Long dataSourceId) throws KeywordSearchServiceException; void deleteDataSource(Long dataSourceId) throws KeywordSearchServiceException;
/**
* A flag to enable or disable OCR on all future text indexing.
*
* @param state Boolean flag to enable/disable OCR. Set to True to enable
* OCR, or False to disable it.
*/
@Beta
void changeOcrState(boolean state);
} }

View File

@ -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;
@ -195,6 +196,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
* performed when running ingest. Will return false if the SevenZipExtractor * performed when running ingest. Will return false if the SevenZipExtractor
@ -789,34 +799,19 @@ 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
//inbox message //inbox message
@ -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 {
@ -1498,9 +1506,16 @@ 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
@ -1594,6 +1610,14 @@ class SevenZipExtractor {
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
* *

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:29 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp\u5b9f\u884c\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp\u5b9f\u884c\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f
ALeappAnalyzerIngestModule.completed=aLeapp\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f ALeappAnalyzerIngestModule.completed=aLeapp\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f
ALeappAnalyzerIngestModule.error.creating.output.dir=aLeapp\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 ALeappAnalyzerIngestModule.error.creating.output.dir=aLeapp\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
@ -16,6 +16,7 @@ ALeappAnalyzerIngestModule.running.aLeapp=aLeapp\u5b9f\u884c\u4e2d
ALeappAnalyzerIngestModule.starting.aLeapp=aLeapp\u306e\u958b\u59cb ALeappAnalyzerIngestModule.starting.aLeapp=aLeapp\u306e\u958b\u59cb
ALeappAnalyzerModuleFactory_moduleDesc=aLEAPP\u3092\u4f7f\u7528\u3057\u3066\u3001Android\u30c7\u30d0\u30a4\u30b9\u306e\u8ad6\u7406\u7684\u306a\u53d6\u5f97\u3092\u5206\u6790\u3057\u307e\u3059\u3002 ALeappAnalyzerModuleFactory_moduleDesc=aLEAPP\u3092\u4f7f\u7528\u3057\u3066\u3001Android\u30c7\u30d0\u30a4\u30b9\u306e\u8ad6\u7406\u7684\u306a\u53d6\u5f97\u3092\u5206\u6790\u3057\u307e\u3059\u3002
ALeappAnalyzerModuleFactory_moduleName=Android\u30a2\u30ca\u30e9\u30a4\u30b6\u30fc\uff08aLEAPP\uff09 ALeappAnalyzerModuleFactory_moduleName=Android\u30a2\u30ca\u30e9\u30a4\u30b6\u30fc\uff08aLEAPP\uff09
AleappAnalyzerIngestModule.not.64.bit.os=aLeapp\u306f32\u30d3\u30c3\u30c8\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0\u3067\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093
ILeappAnalyzerIngestModule.completed=iLeapp\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f ILeappAnalyzerIngestModule.completed=iLeapp\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f
ILeappAnalyzerIngestModule.error.creating.output.dir=iLeapp\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 ILeappAnalyzerIngestModule.error.creating.output.dir=iLeapp\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
ILeappAnalyzerIngestModule.error.ileapp.file.processor.init=ILeappProcessFile\u306e\u521d\u671f\u5316\u306b\u5931\u6557\u3057\u307e\u3057\u305f ILeappAnalyzerIngestModule.error.ileapp.file.processor.init=ILeappProcessFile\u306e\u521d\u671f\u5316\u306b\u5931\u6557\u3057\u307e\u3057\u305f
@ -33,8 +34,10 @@ ILeappAnalyzerIngestModule.running.iLeapp=iLeapp\u5b9f\u884c\u4e2d
ILeappAnalyzerIngestModule.starting.iLeapp=iLeapp\u306e\u958b\u59cb ILeappAnalyzerIngestModule.starting.iLeapp=iLeapp\u306e\u958b\u59cb
ILeappAnalyzerModuleFactory_moduleDesc=iLEAPP\u3092\u4f7f\u7528\u3057\u3066\u3001iOS\u30c7\u30d0\u30a4\u30b9\u306e\u8ad6\u7406\u7684\u306a\u53d6\u5f97\u3092\u5206\u6790\u3057\u307e\u3059\u3002 ILeappAnalyzerModuleFactory_moduleDesc=iLEAPP\u3092\u4f7f\u7528\u3057\u3066\u3001iOS\u30c7\u30d0\u30a4\u30b9\u306e\u8ad6\u7406\u7684\u306a\u53d6\u5f97\u3092\u5206\u6790\u3057\u307e\u3059\u3002
ILeappAnalyzerModuleFactory_moduleName=iOS\u30a2\u30ca\u30e9\u30a4\u30b6\u30fc\uff08iLEAPP\uff09 ILeappAnalyzerModuleFactory_moduleName=iOS\u30a2\u30ca\u30e9\u30a4\u30b6\u30fc\uff08iLEAPP\uff09
IleappAnalyzerIngestModule.not.64.bit.os=iLeapp\u306f32\u30d3\u30c3\u30c8\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0\u3067\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093
LeappFileProcessor.Leapp.cancelled=Leapp\u5b9f\u884c\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f LeappFileProcessor.Leapp.cancelled=Leapp\u5b9f\u884c\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f
LeappFileProcessor.cannot.load.artifact.xml=xml\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3002 LeappFileProcessor.cannot.create.message.relationship=TSK_MESSAGE\u95a2\u4fc2\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3002
LeappFileProcessor.cannot.load.artifact.xml=xml\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30fb\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3002
LeappFileProcessor.cannotBuildXmlParser=XML\u30d1\u30fc\u30b5\u30fc\u3092\u69cb\u7bc9\u3067\u304d\u307e\u305b\u3093\u3002 LeappFileProcessor.cannotBuildXmlParser=XML\u30d1\u30fc\u30b5\u30fc\u3092\u69cb\u7bc9\u3067\u304d\u307e\u305b\u3093\u3002
LeappFileProcessor.completed=Leapp\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f LeappFileProcessor.completed=Leapp\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f
LeappFileProcessor.error.creating.new.artifacts=\u65b0\u3057\u3044\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 LeappFileProcessor.error.creating.new.artifacts=\u65b0\u3057\u3044\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002

View File

@ -0,0 +1,35 @@
#Mon Jun 14 12:23:19 UTC 2021
AddEditCategoryDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
AddEditCategoryDialog.categoryLabel.text=\u30ab\u30c6\u30b4\u30ea\u30fc\uff1a
AddEditCategoryDialog.domainSuffixLabel.text=\u30c9\u30e1\u30a4\u30f3\u30fb\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\uff1a
AddEditCategoryDialog.saveButton.text=\u4fdd\u5168
AddEditCategoryDialog_Add=\u30a8\u30f3\u30c8\u30ea\u3092\u8ffd\u52a0
AddEditCategoryDialog_Edit=\u30a8\u30f3\u30c8\u30ea\u306e\u7de8\u96c6
AddEditCategoryDialog_onValueUpdate_badCategory={0}\u6587\u5b57\u4ee5\u4e0b\u306e\u30ab\u30c6\u30b4\u30ea\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002
AddEditCategoryDialog_onValueUpdate_badSuffix=1\u3064\u4ee5\u4e0a\u306e\u30d4\u30ea\u30aa\u30c9\u3092\u542b\u3080{0}\u6587\u5b57\u4ee5\u4e0b\u306e\u30c9\u30e1\u30a4\u30f3\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002
AddEditCategoryDialog_onValueUpdate_sameCategory=\u3053\u306e\u30c9\u30e1\u30a4\u30f3\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u306e\u65b0\u3057\u3044\u30ab\u30c6\u30b4\u30ea\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
AddEditCategoryDialog_onValueUpdate_suffixRepeat=\u30e6\u30cb\u30fc\u30af\u306e\u30c9\u30e1\u30a4\u30f3\u30fb\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u30fb
WebCategoriesOptionsPanel.categoriesTitle.text=\u30ab\u30c6\u30b4\u30ea\uff1a
WebCategoriesOptionsPanel.deleteEntryButton.text=\u30a8\u30f3\u30c8\u30ea\u3092\u524a\u9664
WebCategoriesOptionsPanel.editEntryButton.text=\u30a8\u30f3\u30c8\u30ea\u306e\u7de8\u96c6
WebCategoriesOptionsPanel.exportSetButton.text=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u30fb\u30bb\u30c3\u30c8
WebCategoriesOptionsPanel.importSetButton.text=\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30bb\u30c3\u30c8
WebCategoriesOptionsPanel.ingestRunningWarning.text=\u53d6\u8fbc\u307f\u306f\u73fe\u5728\u5b9f\u884c\u4e2d\u3067\u3059\u3002 \u4eca\u306f\u7de8\u96c6\u306f\u3067\u304d\u307e\u305b\u3093\u3002
WebCategoriesOptionsPanel.newEntryButton.text=\u65b0\u898f\u30a8\u30f3\u30c8\u30ea\u30fc
WebCategoriesOptionsPanel.panelDescription.text=<html>\u3053\u306e\u6a5f\u80fd\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u306e\u53d6\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u3001\u30c9\u30e1\u30a4\u30f3\u306e\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u306b\u57fa\u3065\u3044\u3066Web\u30b5\u30a4\u30c8\u306e\u30ab\u30b9\u30bf\u30e0\u5206\u985e\u3092\u5b9f\u884c\u3067\u304d\u307e\u3059\u3002</ html>
WebCategoriesOptionsPanel_categoryTable_categoryColumnName=\u30ab\u30c6\u30b4\u30ea\uff1a
WebCategoriesOptionsPanel_categoryTable_suffixColumnName=\u30c9\u30e1\u30a4\u30f3\u30fb\u30b5\u30d5\u30a3\u30c3\u30af\u30b9
WebCategoriesOptionsPanel_exportSetButtonActionPerformed_defaultFileName=\u30ab\u30b9\u30bf\u30e0\u30fb\u30ab\u30c6\u30b4\u30ea\u306e\u30a8\u30af\u30b9\u30dd\u30fc\u30c8
WebCategoriesOptionsPanel_exportSetButtonActionPerformed_duplicateMessage=\u9078\u629e\u3057\u305f\u30d1\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059\u3002 \u30ab\u30c6\u30b4\u30ea\u306f\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3055\u308c\u307e\u305b\u3093\u3002
WebCategoriesOptionsPanel_exportSetButtonActionPerformed_duplicateTitle=\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059
WebCategoriesOptionsPanel_exportSetButtonActionPerformed_errorMessage=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
WebCategoriesOptionsPanel_exportSetButtonActionPerformed_errorTitle=\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u30a8\u30e9\u30fc
WebCategoriesOptionsPanel_importSetButtonActionPerformed_errorMessage=json\u30d5\u30a1\u30a4\u30eb\u306e\u30a4\u30f3\u30dd\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
WebCategoriesOptionsPanel_importSetButtonActionPerformed_errorTitle=\u30a4\u30f3\u30dd\u30fc\u30c8\u30a8\u30e9\u30fc
WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictCancel=\u30ad\u30e3\u30f3\u30bb\u30eb
WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictMessage=\u30c9\u30e1\u30a4\u30f3\u30b5\u30d5\u30a3\u30c3\u30af\u30b9{0}\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059\u3002 \u4f55\u3092\u3057\u307e\u3059\u304b\uff1f
WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictOverwrite=\u4e0a\u66f8\u304d\u3059\u308b
WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictSkip=\u7121\u8996
WebCategoriesOptionsPanel_importSetButtonActionPerformed_onConflictTitle=\u30c9\u30e1\u30a4\u30f3\u30fb\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
WebCategoryOptionsController_keywords=\u30ab\u30b9\u30bf\u30e0Web\u30ab\u30c6\u30b4\u30ea
WebCategoryOptionsController_title=\u30ab\u30b9\u30bf\u30e0Web\u30ab\u30c6\u30b4\u30ea

View File

@ -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));
} }
/** /**

View File

@ -158,6 +158,102 @@ final class AutoIngestAdminActions {
} }
} }
@NbBundle.Messages({"AutoIngestAdminActions.enableOCR.title=Enable OCR For This Case",
"AutoIngestAdminActions.enableOCR.error=Failed to enable OCR for case \"%s\"."})
static final class EnableOCR extends AbstractAction {
private static final long serialVersionUID = 1L;
private final AutoIngestJob job;
EnableOCR(AutoIngestJob job) {
super(Bundle.AutoIngestAdminActions_enableOCR_title());
this.job = job;
}
@Override
public void actionPerformed(ActionEvent e) {
if (job == null) {
return;
}
final AutoIngestDashboardTopComponent tc = (AutoIngestDashboardTopComponent) WindowManager.getDefault().findTopComponent(AutoIngestDashboardTopComponent.PREFERRED_ID);
if (tc == null) {
return;
}
AutoIngestDashboard dashboard = tc.getAutoIngestDashboard();
if (dashboard != null) {
dashboard.getPendingJobsPanel().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
EventQueue.invokeLater(() -> {
try {
dashboard.getMonitor().changeOcrStateForCase(job.getManifest().getCaseName(), true);
dashboard.getPendingJobsPanel().refresh(new AutoIngestNodeRefreshEvents.RefreshCaseEvent(dashboard.getMonitor(), job.getManifest().getCaseName()));
} catch (AutoIngestMonitor.AutoIngestMonitorException ex) {
String errorMessage = String.format(Bundle.AutoIngestAdminActions_enableOCR_error(), job.getManifest().getCaseName());
logger.log(Level.SEVERE, errorMessage, ex);
MessageNotifyUtil.Message.error(errorMessage);
} finally {
dashboard.getPendingJobsPanel().setCursor(Cursor.getDefaultCursor());
}
});
}
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); //To change body of generated methods, choose Tools | Templates.
}
}
@NbBundle.Messages({"AutoIngestAdminActions.disableOCR.title=Disable OCR For This Case",
"AutoIngestAdminActions.disableOCR.error=Failed to disable OCR for case \"%s\"."})
static final class DisableOCR extends AbstractAction {
private static final long serialVersionUID = 1L;
private final AutoIngestJob job;
DisableOCR(AutoIngestJob job) {
super(Bundle.AutoIngestAdminActions_disableOCR_title());
this.job = job;
}
@Override
public void actionPerformed(ActionEvent e) {
if (job == null) {
return;
}
final AutoIngestDashboardTopComponent tc = (AutoIngestDashboardTopComponent) WindowManager.getDefault().findTopComponent(AutoIngestDashboardTopComponent.PREFERRED_ID);
if (tc == null) {
return;
}
AutoIngestDashboard dashboard = tc.getAutoIngestDashboard();
if (dashboard != null) {
dashboard.getPendingJobsPanel().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
EventQueue.invokeLater(() -> {
try {
dashboard.getMonitor().changeOcrStateForCase(job.getManifest().getCaseName(), false);
dashboard.getPendingJobsPanel().refresh(new AutoIngestNodeRefreshEvents.RefreshCaseEvent(dashboard.getMonitor(), job.getManifest().getCaseName()));
} catch (AutoIngestMonitor.AutoIngestMonitorException ex) {
String errorMessage = String.format(Bundle.AutoIngestAdminActions_disableOCR_error(), job.getManifest().getCaseName());
logger.log(Level.SEVERE, errorMessage, ex);
MessageNotifyUtil.Message.error(errorMessage);
} finally {
dashboard.getPendingJobsPanel().setCursor(Cursor.getDefaultCursor());
}
});
}
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); //To change body of generated methods, choose Tools | Templates.
}
}
@NbBundle.Messages({"AutoIngestAdminActions.progressDialogAction.title=Ingest Progress"}) @NbBundle.Messages({"AutoIngestAdminActions.progressDialogAction.title=Ingest Progress"})
static final class ProgressDialogAction extends AbstractAction { static final class ProgressDialogAction extends AbstractAction {

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2015-2018 Basis Technology Corp. * Copyright 2015-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");
@ -122,6 +122,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
private static final int RUNNING_TABLE_COL_PREFERRED_WIDTH = 175; private static final int RUNNING_TABLE_COL_PREFERRED_WIDTH = 175;
private static final int PRIORITY_COLUMN_PREFERRED_WIDTH = 60; private static final int PRIORITY_COLUMN_PREFERRED_WIDTH = 60;
private static final int PRIORITY_COLUMN_MAX_WIDTH = 150; private static final int PRIORITY_COLUMN_MAX_WIDTH = 150;
private static final int OCR_COLUMN_PREFERRED_WIDTH = 50;
private static final int OCR_COLUMN_MAX_WIDTH = 150;
private static final int ACTIVITY_TIME_COL_MIN_WIDTH = 250; private static final int ACTIVITY_TIME_COL_MIN_WIDTH = 250;
private static final int ACTIVITY_TIME_COL_MAX_WIDTH = 450; private static final int ACTIVITY_TIME_COL_MAX_WIDTH = 450;
private static final int TIME_COL_MIN_WIDTH = 30; private static final int TIME_COL_MIN_WIDTH = 30;
@ -133,9 +135,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
private static final int ACTIVITY_COL_MIN_WIDTH = 70; private static final int ACTIVITY_COL_MIN_WIDTH = 70;
private static final int ACTIVITY_COL_MAX_WIDTH = 2000; private static final int ACTIVITY_COL_MAX_WIDTH = 2000;
private static final int ACTIVITY_COL_PREFERRED_WIDTH = 300; private static final int ACTIVITY_COL_PREFERRED_WIDTH = 300;
private static final int STATUS_COL_MIN_WIDTH = 55; private static final int STATUS_COL_MIN_WIDTH = 50;
private static final int STATUS_COL_MAX_WIDTH = 250; private static final int STATUS_COL_MAX_WIDTH = 250;
private static final int STATUS_COL_PREFERRED_WIDTH = 55; private static final int STATUS_COL_PREFERRED_WIDTH = 50;
private static final int COMPLETED_TIME_COL_MIN_WIDTH = 30; private static final int COMPLETED_TIME_COL_MIN_WIDTH = 30;
private static final int COMPLETED_TIME_COL_MAX_WIDTH = 2000; private static final int COMPLETED_TIME_COL_MAX_WIDTH = 2000;
private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280; private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280;
@ -179,7 +181,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
"AutoIngestControlPanel.JobsTableModel.ColumnHeader.Status=Status", "AutoIngestControlPanel.JobsTableModel.ColumnHeader.Status=Status",
"AutoIngestControlPanel.JobsTableModel.ColumnHeader.CaseFolder=Case Folder", "AutoIngestControlPanel.JobsTableModel.ColumnHeader.CaseFolder=Case Folder",
"AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob= Local Job?", "AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob= Local Job?",
"AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath= Manifest File Path" "AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath= Manifest File Path",
"AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR=OCR"
}) })
private enum JobsTableModelColumns { private enum JobsTableModelColumns {
@ -195,7 +198,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
CASE_DIRECTORY_PATH(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.CaseFolder")), CASE_DIRECTORY_PATH(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.CaseFolder")),
IS_LOCAL_JOB(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob")), IS_LOCAL_JOB(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob")),
MANIFEST_FILE_PATH(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath")), MANIFEST_FILE_PATH(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath")),
PRIORITY(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.Priority")); PRIORITY(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.Priority")),
OCR(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR"));
private final String header; private final String header;
private JobsTableModelColumns(String header) { private JobsTableModelColumns(String header) {
@ -219,7 +223,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
CASE_DIRECTORY_PATH.getColumnHeader(), CASE_DIRECTORY_PATH.getColumnHeader(),
IS_LOCAL_JOB.getColumnHeader(), IS_LOCAL_JOB.getColumnHeader(),
MANIFEST_FILE_PATH.getColumnHeader(), MANIFEST_FILE_PATH.getColumnHeader(),
PRIORITY.getColumnHeader()}; PRIORITY.getColumnHeader(),
OCR.getColumnHeader()};
} }
/** /**
@ -407,6 +412,12 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
column.setPreferredWidth(PRIORITY_COLUMN_PREFERRED_WIDTH); column.setPreferredWidth(PRIORITY_COLUMN_PREFERRED_WIDTH);
column.setWidth(PRIORITY_COLUMN_PREFERRED_WIDTH); column.setWidth(PRIORITY_COLUMN_PREFERRED_WIDTH);
column = pendingTable.getColumn(JobsTableModelColumns.OCR.getColumnHeader());
column.setCellRenderer(new OcrIconCellRenderer());
column.setMaxWidth(OCR_COLUMN_MAX_WIDTH);
column.setPreferredWidth(OCR_COLUMN_PREFERRED_WIDTH);
column.setWidth(OCR_COLUMN_PREFERRED_WIDTH);
/** /**
* Allow sorting when a column header is clicked. * Allow sorting when a column header is clicked.
*/ */
@ -457,6 +468,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.IS_LOCAL_JOB.getColumnHeader())); runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.IS_LOCAL_JOB.getColumnHeader()));
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader())); runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader()));
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.PRIORITY.getColumnHeader())); runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.PRIORITY.getColumnHeader()));
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.OCR.getColumnHeader()));
/* /*
* Set up a column to display the cases associated with the jobs. * Set up a column to display the cases associated with the jobs.
*/ */
@ -553,6 +566,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader()));
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.PRIORITY.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.PRIORITY.getColumnHeader()));
/* /*
* Set up a column to display the cases associated with the jobs. * Set up a column to display the cases associated with the jobs.
*/ */
@ -604,6 +618,15 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
column.setPreferredWidth(STATUS_COL_PREFERRED_WIDTH); column.setPreferredWidth(STATUS_COL_PREFERRED_WIDTH);
column.setWidth(STATUS_COL_PREFERRED_WIDTH); column.setWidth(STATUS_COL_PREFERRED_WIDTH);
/*
* Set up a column to display OCR enabled/disabled flag.
*/
column = completedTable.getColumn(JobsTableModelColumns.OCR.getColumnHeader());
column.setCellRenderer(new OcrIconCellRenderer());
column.setMaxWidth(OCR_COLUMN_MAX_WIDTH);
column.setPreferredWidth(OCR_COLUMN_PREFERRED_WIDTH);
column.setWidth(OCR_COLUMN_PREFERRED_WIDTH);
/* /*
* Allow sorting when a column header is clicked. * Allow sorting when a column header is clicked.
*/ */
@ -856,6 +879,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
case JOB_COMPLETED: case JOB_COMPLETED:
case CASE_DELETED: case CASE_DELETED:
case REPROCESS_JOB: case REPROCESS_JOB:
case OCR_STATE_CHANGE:
updateExecutor.submit(new UpdateAllJobsTablesTask()); updateExecutor.submit(new UpdateAllJobsTablesTask());
break; break;
case PAUSED_BY_USER_REQUEST: case PAUSED_BY_USER_REQUEST:
@ -1193,7 +1217,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH
job.getProcessingHostName().equals(LOCAL_HOST_NAME), // IS_LOCAL_JOB job.getProcessingHostName().equals(LOCAL_HOST_NAME), // IS_LOCAL_JOB
job.getManifest().getFilePath(), // MANIFEST_FILE_PATH job.getManifest().getFilePath(), // MANIFEST_FILE_PATH
job.getPriority()}); // PRIORITY job.getPriority(), // PRIORITY
job.getOcrEnabled()}); // OCR FLAG
} }
} catch (Exception ex) { } catch (Exception ex) {
sysLogger.log(Level.SEVERE, "Dashboard error refreshing table", ex); sysLogger.log(Level.SEVERE, "Dashboard error refreshing table", ex);

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2018 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");
@ -46,7 +46,7 @@ import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotProvider;
final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSnapshotProvider, Serializable { final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSnapshotProvider, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final int CURRENT_VERSION = 3; private static final int CURRENT_VERSION = 4;
private static final int DEFAULT_PRIORITY = 0; private static final int DEFAULT_PRIORITY = 0;
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName(); private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
@ -101,6 +101,11 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSn
private List<Snapshot> ingestJobsSnapshot; private List<Snapshot> ingestJobsSnapshot;
private Map<String, Long> moduleRunTimesSnapshot; private Map<String, Long> moduleRunTimesSnapshot;
/*
* Version 4 fields.
*/
private boolean ocrEnabled;
/** /**
* Constructs a new automated ingest job. All job state not specified in the * Constructs a new automated ingest job. All job state not specified in the
* job manifest is set to the default state for a new job. * job manifest is set to the default state for a new job.
@ -194,6 +199,11 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSn
this.ingestJobsSnapshot = Collections.emptyList(); this.ingestJobsSnapshot = Collections.emptyList();
this.moduleRunTimesSnapshot = Collections.emptyMap(); this.moduleRunTimesSnapshot = Collections.emptyMap();
/*
* Version 4 fields
*/
this.ocrEnabled = nodeData.getOcrEnabled();
} catch (Exception ex) { } catch (Exception ex) {
throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex); throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex);
} }
@ -254,6 +264,24 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSn
return this.priority; return this.priority;
} }
/**
* Gets the OCR flag for the job.
*
* @return Flag whether OCR is enabled/disabled.
*/
synchronized boolean getOcrEnabled() {
return this.ocrEnabled;
}
/**
* Sets the OCR enabled/disabled flag for the job.
*
* @param enabled Flag whether OCR is enabled/disabled.
*/
synchronized void setOcrEnabled(boolean enabled) {
this.ocrEnabled = enabled;
}
/** /**
* Sets the processing stage of the job. The start date/time for the stage * Sets the processing stage of the job. The start date/time for the stage
* is set when the stage is set. * is set when the stage is set.

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 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");
@ -31,7 +31,7 @@ import javax.lang.model.type.TypeKind;
*/ */
final class AutoIngestJobNodeData { final class AutoIngestJobNodeData {
private static final int CURRENT_VERSION = 2; private static final int CURRENT_VERSION = 3;
private static final int DEFAULT_PRIORITY = 0; private static final int DEFAULT_PRIORITY = 0;
/* /*
@ -47,7 +47,7 @@ final class AutoIngestJobNodeData {
* data. This avoids the need to continuously enlarge the buffer. Once the * data. This avoids the need to continuously enlarge the buffer. Once the
* buffer has all the necessary data, it will be resized as appropriate. * buffer has all the necessary data, it will be resized as appropriate.
*/ */
private static final int MAX_POSSIBLE_NODE_DATA_SIZE = 131637; private static final int MAX_POSSIBLE_NODE_DATA_SIZE = 131641;
/* /*
* Version 0 fields. * Version 0 fields.
@ -79,6 +79,11 @@ final class AutoIngestJobNodeData {
*/ */
private long dataSourceSize; private long dataSourceSize;
/*
* Version 3 fields.
*/
private boolean ocrEnabled;
/** /**
* Gets the current version of the auto ingest job coordination service node * Gets the current version of the auto ingest job coordination service node
* data. * data.
@ -115,6 +120,7 @@ final class AutoIngestJobNodeData {
setProcessingStageStartDate(job.getProcessingStageStartDate()); setProcessingStageStartDate(job.getProcessingStageStartDate());
setProcessingStageDetails(job.getProcessingStageDetails()); setProcessingStageDetails(job.getProcessingStageDetails());
setDataSourceSize(job.getDataSourceSize()); setDataSourceSize(job.getDataSourceSize());
setOcrEnabled(job.getOcrEnabled());
} }
/** /**
@ -150,6 +156,7 @@ final class AutoIngestJobNodeData {
this.processingStageDetailsDescription = ""; this.processingStageDetailsDescription = "";
this.processingStageDetailsStartDate = 0L; this.processingStageDetailsStartDate = 0L;
this.dataSourceSize = 0L; this.dataSourceSize = 0L;
this.ocrEnabled = false;
/* /*
* Get fields from node data. * Get fields from node data.
@ -193,6 +200,14 @@ final class AutoIngestJobNodeData {
this.dataSourceSize = buffer.getLong(); this.dataSourceSize = buffer.getLong();
} }
if (buffer.hasRemaining()) {
/*
* Get version 3 fields.
*/
int ocrFlag = buffer.getInt();
this.ocrEnabled = (1 == ocrFlag);
}
} catch (BufferUnderflowException ex) { } catch (BufferUnderflowException ex) {
throw new InvalidDataException("Node data is incomplete", ex); throw new InvalidDataException("Node data is incomplete", ex);
} }
@ -235,6 +250,24 @@ final class AutoIngestJobNodeData {
this.priority = priority; this.priority = priority;
} }
/**
* Gets the OCR flag for the job.
*
* @return Flag whether OCR is enabled/disabled.
*/
boolean getOcrEnabled() {
return this.ocrEnabled;
}
/**
* Sets the OCR enabled/disabled flag for the job.
*
* @param enabled Flag whether OCR is enabled/disabled.
*/
void setOcrEnabled(boolean enabled) {
this.ocrEnabled = enabled;
}
/** /**
* Gets the number of times the job has crashed during processing. * Gets the number of times the job has crashed during processing.
* *
@ -567,6 +600,10 @@ final class AutoIngestJobNodeData {
if (this.version >= 2) { if (this.version >= 2) {
buffer.putLong(this.dataSourceSize); buffer.putLong(this.dataSourceSize);
} }
if (this.version >= 3) {
buffer.putInt(this.ocrEnabled ? 1 : 0);
}
} }
// Prepare the array // Prepare the array

View File

@ -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");
@ -57,7 +57,8 @@ final class AutoIngestJobsNode extends AbstractNode {
"AutoIngestJobsNode.jobCreated.text=Job Created", "AutoIngestJobsNode.jobCreated.text=Job Created",
"AutoIngestJobsNode.jobCompleted.text=Job Completed", "AutoIngestJobsNode.jobCompleted.text=Job Completed",
"AutoIngestJobsNode.priority.text=Prioritized", "AutoIngestJobsNode.priority.text=Prioritized",
"AutoIngestJobsNode.status.text=Status" "AutoIngestJobsNode.status.text=Status",
"AutoIngestJobsNode.ocr.text=OCR"
}) })
/** /**
@ -69,7 +70,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;
} }
@ -98,12 +99,14 @@ final class AutoIngestJobsNode extends AbstractNode {
private final Stage jobStage; private final Stage jobStage;
private final List<Snapshot> jobSnapshot; private final List<Snapshot> jobSnapshot;
private final Integer jobPriority; private final Integer jobPriority;
private final Boolean ocrFlag;
AutoIngestJobWrapper(AutoIngestJob job) { AutoIngestJobWrapper(AutoIngestJob job) {
autoIngestJob = job; autoIngestJob = job;
jobStage = job.getProcessingStage(); jobStage = job.getProcessingStage();
jobSnapshot = job.getIngestJobSnapshots(); jobSnapshot = job.getIngestJobSnapshots();
jobPriority = job.getPriority(); jobPriority = job.getPriority();
ocrFlag = job.getOcrEnabled();
} }
AutoIngestJob getJob() { AutoIngestJob getJob() {
@ -123,11 +126,12 @@ final class AutoIngestJobsNode extends AbstractNode {
AutoIngestJob thisJob = this.autoIngestJob; AutoIngestJob thisJob = this.autoIngestJob;
AutoIngestJob otherJob = ((AutoIngestJobWrapper) other).autoIngestJob; AutoIngestJob otherJob = ((AutoIngestJobWrapper) other).autoIngestJob;
// Only equal if the manifest paths and processing stage details are the same. // Only equal if the manifest paths, processing stage details, priority, and OCR flag are the same.
return thisJob.getManifest().getFilePath().equals(otherJob.getManifest().getFilePath()) return thisJob.getManifest().getFilePath().equals(otherJob.getManifest().getFilePath())
&& jobStage.equals(((AutoIngestJobWrapper) other).jobStage) && jobStage.equals(((AutoIngestJobWrapper) other).jobStage)
&& jobSnapshot.equals(((AutoIngestJobWrapper) other).jobSnapshot) && jobSnapshot.equals(((AutoIngestJobWrapper) other).jobSnapshot)
&& jobPriority.equals(((AutoIngestJobWrapper) other).jobPriority); && jobPriority.equals(((AutoIngestJobWrapper) other).jobPriority)
&& ocrFlag.equals(((AutoIngestJobWrapper) other).ocrFlag);
} }
@Override @Override
@ -137,6 +141,7 @@ final class AutoIngestJobsNode extends AbstractNode {
hash = 23 * hash + Objects.hashCode(this.jobStage); hash = 23 * hash + Objects.hashCode(this.jobStage);
hash = 23 * hash + Objects.hashCode(this.jobSnapshot); hash = 23 * hash + Objects.hashCode(this.jobSnapshot);
hash = 23 * hash + Objects.hashCode(this.jobPriority); hash = 23 * hash + Objects.hashCode(this.jobPriority);
hash = 23 * hash + Objects.hashCode(this.ocrFlag);
return hash; return hash;
} }
@ -171,6 +176,10 @@ final class AutoIngestJobsNode extends AbstractNode {
Integer getPriority() { Integer getPriority() {
return autoIngestJob.getPriority(); return autoIngestJob.getPriority();
} }
boolean getOcrEnabled() {
return autoIngestJob.getOcrEnabled();
}
} }
/** /**
@ -327,6 +336,8 @@ final class AutoIngestJobsNode extends AbstractNode {
jobWrapper.getManifest().getDateFileCreated())); jobWrapper.getManifest().getDateFileCreated()));
ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text(), ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text(),
jobWrapper.getPriority())); jobWrapper.getPriority()));
ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text(),
jobWrapper.getOcrEnabled()));
break; break;
case RUNNING_JOB: case RUNNING_JOB:
AutoIngestJob.StageDetails status = jobWrapper.getProcessingStageDetails(); AutoIngestJob.StageDetails status = jobWrapper.getProcessingStageDetails();
@ -344,6 +355,8 @@ final class AutoIngestJobsNode extends AbstractNode {
jobWrapper.getCompletedDate())); jobWrapper.getCompletedDate()));
ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text(), ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text(),
jobWrapper.getErrorsOccurred() ? StatusIconCellRenderer.Status.WARNING : StatusIconCellRenderer.Status.OK)); jobWrapper.getErrorsOccurred() ? StatusIconCellRenderer.Status.WARNING : StatusIconCellRenderer.Status.OK));
ss.put(new NodeProperty<>(Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text(),
jobWrapper.getOcrEnabled()));
break; break;
default: default:
} }
@ -364,6 +377,11 @@ final class AutoIngestJobsNode extends AbstractNode {
PrioritizationAction.DeprioritizeCaseAction deprioritizeCaseAction = new PrioritizationAction.DeprioritizeCaseAction(jobWrapper.getJob()); PrioritizationAction.DeprioritizeCaseAction deprioritizeCaseAction = new PrioritizationAction.DeprioritizeCaseAction(jobWrapper.getJob());
deprioritizeCaseAction.setEnabled(jobWrapper.getPriority() > 0); deprioritizeCaseAction.setEnabled(jobWrapper.getPriority() > 0);
actions.add(deprioritizeCaseAction); actions.add(deprioritizeCaseAction);
actions.add(new AutoIngestAdminActions.EnableOCR(jobWrapper.getJob()));
AutoIngestAdminActions.DisableOCR disableOCRAction = new AutoIngestAdminActions.DisableOCR(jobWrapper.getJob());
disableOCRAction.setEnabled(jobWrapper.getOcrEnabled() == true);
actions.add(disableOCRAction);
break; break;
case RUNNING_JOB: case RUNNING_JOB:
actions.add(new AutoIngestAdminActions.ProgressDialogAction(jobWrapper.getJob())); actions.add(new AutoIngestAdminActions.ProgressDialogAction(jobWrapper.getJob()));

View File

@ -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");
@ -43,6 +43,7 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa
private static final int INITIAL_CASENAME_WIDTH = 170; private static final int INITIAL_CASENAME_WIDTH = 170;
private static final int INITIAL_DATASOURCE_WIDTH = 270; private static final int INITIAL_DATASOURCE_WIDTH = 270;
private static final int INITIAL_PRIORITIZED_WIDTH = 20; private static final int INITIAL_PRIORITIZED_WIDTH = 20;
private static final int INITIAL_OCR_WIDTH = 20;
private static final int INITIAL_STATUS_WIDTH = 20; private static final int INITIAL_STATUS_WIDTH = 20;
private static final int INVALID_INDEX = -1; private static final int INVALID_INDEX = -1;
private final org.openide.explorer.view.OutlineView outlineView; private final org.openide.explorer.view.OutlineView outlineView;
@ -81,12 +82,18 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa
case PENDING_JOB: case PENDING_JOB:
outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(), outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(),
Bundle.AutoIngestJobsNode_jobCreated_text(), Bundle.AutoIngestJobsNode_jobCreated_text(), Bundle.AutoIngestJobsNode_jobCreated_text(), Bundle.AutoIngestJobsNode_jobCreated_text(),
Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text()); Bundle.AutoIngestJobsNode_priority_text(), Bundle.AutoIngestJobsNode_priority_text(),
Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text());
indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_priority_text()); indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_priority_text());
if (indexOfColumn != INVALID_INDEX) { if (indexOfColumn != INVALID_INDEX) {
outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_PRIORITIZED_WIDTH); outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_PRIORITIZED_WIDTH);
outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new PrioritizedIconCellRenderer()); outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new PrioritizedIconCellRenderer());
} }
indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_ocr_text());
if (indexOfColumn != INVALID_INDEX) {
outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_OCR_WIDTH);
outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new OcrIconCellRenderer());
}
break; break;
case RUNNING_JOB: case RUNNING_JOB:
outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(), outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(),
@ -102,7 +109,8 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa
outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(), outlineView.setPropertyColumns(Bundle.AutoIngestJobsNode_dataSource_text(), Bundle.AutoIngestJobsNode_dataSource_text(),
Bundle.AutoIngestJobsNode_jobCreated_text(), Bundle.AutoIngestJobsNode_jobCreated_text(), Bundle.AutoIngestJobsNode_jobCreated_text(), Bundle.AutoIngestJobsNode_jobCreated_text(),
Bundle.AutoIngestJobsNode_jobCompleted_text(), Bundle.AutoIngestJobsNode_jobCompleted_text(), Bundle.AutoIngestJobsNode_jobCompleted_text(), Bundle.AutoIngestJobsNode_jobCompleted_text(),
Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text()); Bundle.AutoIngestJobsNode_status_text(), Bundle.AutoIngestJobsNode_status_text(),
Bundle.AutoIngestJobsNode_ocr_text(), Bundle.AutoIngestJobsNode_ocr_text());
indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_jobCompleted_text()); indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_jobCompleted_text());
if (indexOfColumn != INVALID_INDEX) { if (indexOfColumn != INVALID_INDEX) {
outline.setColumnSorted(indexOfColumn, false, 1); outline.setColumnSorted(indexOfColumn, false, 1);
@ -112,6 +120,11 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa
outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_STATUS_WIDTH); outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_STATUS_WIDTH);
outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new StatusIconCellRenderer()); outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new StatusIconCellRenderer());
} }
indexOfColumn = getColumnIndexByName(Bundle.AutoIngestJobsNode_ocr_text());
if (indexOfColumn != INVALID_INDEX) {
outline.getColumnModel().getColumn(indexOfColumn).setPreferredWidth(INITIAL_OCR_WIDTH);
outline.getColumnModel().getColumn(indexOfColumn).setCellRenderer(new OcrIconCellRenderer());
}
break; break;
default: default:
} }

View File

@ -105,6 +105,7 @@ import org.sleuthkit.autopsy.ingest.IngestModuleError;
import org.sleuthkit.autopsy.ingest.IngestStream; import org.sleuthkit.autopsy.ingest.IngestStream;
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchModuleException; import org.sleuthkit.autopsy.keywordsearch.KeywordSearchModuleException;
import org.sleuthkit.autopsy.keywordsearch.Server; import org.sleuthkit.autopsy.keywordsearch.Server;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
@ -144,7 +145,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
ControlEventType.SHUTDOWN.toString(), ControlEventType.SHUTDOWN.toString(),
ControlEventType.GENERATE_THREAD_DUMP_REQUEST.toString(), ControlEventType.GENERATE_THREAD_DUMP_REQUEST.toString(),
Event.CANCEL_JOB.toString(), Event.CANCEL_JOB.toString(),
Event.REPROCESS_JOB.toString()})); Event.REPROCESS_JOB.toString(),
Event.OCR_STATE_CHANGE.toString()}));
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED); private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED);
private static final long JOB_STATUS_EVENT_INTERVAL_SECONDS = 10; private static final long JOB_STATUS_EVENT_INTERVAL_SECONDS = 10;
private static final String JOB_STATUS_PUBLISHING_THREAD_NAME = "AIM-job-status-event-publisher-%d"; private static final String JOB_STATUS_PUBLISHING_THREAD_NAME = "AIM-job-status-event-publisher-%d";
@ -308,6 +310,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
handleRemoteJobCancelEvent((AutoIngestJobCancelEvent) event); handleRemoteJobCancelEvent((AutoIngestJobCancelEvent) event);
} else if (event instanceof AutoIngestJobReprocessEvent) { } else if (event instanceof AutoIngestJobReprocessEvent) {
handleRemoteJobReprocessEvent((AutoIngestJobReprocessEvent) event); handleRemoteJobReprocessEvent((AutoIngestJobReprocessEvent) event);
} else if (event instanceof AutoIngestOcrStateChangeEvent) {
handleRemoteOcrEvent((AutoIngestOcrStateChangeEvent) event);
} }
} }
} }
@ -466,11 +470,43 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
String hostName = event.getNodeName(); String hostName = event.getNodeName();
hostNamesToLastMsgTime.put(hostName, Instant.now()); hostNamesToLastMsgTime.put(hostName, Instant.now());
// currently the only way to the get latest ZK manifest node contents is to do an input directory scan
scanInputDirsNow(); scanInputDirsNow();
setChanged(); setChanged();
notifyObservers(Event.CASE_PRIORITIZED); notifyObservers(Event.CASE_PRIORITIZED);
} }
/**
* Processes a case OCR enabled/disabled event from another node.
*
* @param event OCR enabled/disabled event from another auto ingest node.
*/
private void handleRemoteOcrEvent(AutoIngestOcrStateChangeEvent event) {
switch (event.getEventType()) {
case OCR_ENABLED:
sysLogger.log(Level.INFO, "Received OCR enabled event for case {0} from user {1} on machine {2}",
new Object[]{event.getCaseName(), event.getUserName(), event.getNodeName()});
break;
case OCR_DISABLED:
sysLogger.log(Level.INFO, "Received OCR disabled event for case {0} from user {1} on machine {2}",
new Object[]{event.getCaseName(), event.getUserName(), event.getNodeName()});
break;
default:
sysLogger.log(Level.WARNING, "Received invalid OCR enabled/disabled event from user {0} on machine {1}",
new Object[]{event.getUserName(), event.getNodeName()});
break;
}
String hostName = event.getNodeName();
hostNamesToLastMsgTime.put(hostName, Instant.now());
// currently the only way to the get latest ZK manifest node contents is to do an input directory scan
scanInputDirsNow();
setChanged();
notifyObservers(Event.OCR_STATE_CHANGE);
}
/** /**
* Processes a case deletion event from another node by triggering an * Processes a case deletion event from another node by triggering an
* immediate input directory scan. * immediate input directory scan.
@ -2057,10 +2093,11 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
} }
iterator.remove(); iterator.remove();
currentJob = job; // create a new job object based on latest ZK node data (i.e. instead of re-using potentially stale local pending AutoIngestJob object).
currentJob = new AutoIngestJob(nodeData);
break; break;
} catch (AutoIngestJobNodeData.InvalidDataException ex) { } catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) {
sysLogger.log(Level.WARNING, String.format("Unable to use node data for %s", manifestPath), ex); sysLogger.log(Level.WARNING, String.format("Unable to use node data for %s", manifestPath), ex);
} }
} }
@ -2215,21 +2252,20 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
* auto ingest job. * auto ingest job.
*/ */
private void attemptJob() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, IOException, JobMetricsCollectionException { private void attemptJob() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, IOException, JobMetricsCollectionException {
updateConfiguration();
if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) {
return;
}
verifyRequiredSevicesAreRunning(); verifyRequiredSevicesAreRunning();
if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) { if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) {
return; return;
} }
Case caseForJob = openCase(); Case caseForJob = openCase();
try { try {
if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) {
return;
}
updateConfiguration();
if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) { if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) {
return; return;
} }
runIngestForJob(caseForJob); runIngestForJob(caseForJob);
} finally { } finally {
try { try {
Case.closeCurrentCase(); Case.closeCurrentCase();
@ -2242,7 +2278,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
/** /**
* Updates the ingest system settings by downloading the latest version * Updates the ingest system settings by downloading the latest version
* of the settings if using shared configuration. * of the settings if using shared configuration. Also updates the OCR
* setting.
* *
* @throws SharedConfigurationException if there is an error downloading * @throws SharedConfigurationException if there is an error downloading
* shared configuration. * shared configuration.
@ -2258,6 +2295,15 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG, Date.from(Instant.now())); currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG, Date.from(Instant.now()));
new SharedConfiguration().downloadConfiguration(); new SharedConfiguration().downloadConfiguration();
} }
// update the OCR enabled/disabled setting
if (currentJob.getOcrEnabled()) {
sysLogger.log(Level.INFO, "Enabling OCR for job {0}", currentJob.getManifest().getFilePath());
} else {
sysLogger.log(Level.INFO, "Disabling OCR for job {0}", currentJob.getManifest().getFilePath());
}
KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
kwsService.changeOcrState(currentJob.getOcrEnabled());
} }
/** /**
@ -3151,7 +3197,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
REPORT_STATE, REPORT_STATE,
CANCEL_JOB, CANCEL_JOB,
REPROCESS_JOB, REPROCESS_JOB,
GENERATE_THREAD_DUMP_RESPONSE GENERATE_THREAD_DUMP_RESPONSE,
OCR_STATE_CHANGE
} }
/** /**

View File

@ -84,7 +84,8 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen
AutoIngestManager.Event.SHUTTING_DOWN.toString(), AutoIngestManager.Event.SHUTTING_DOWN.toString(),
AutoIngestManager.Event.SHUTDOWN.toString(), AutoIngestManager.Event.SHUTDOWN.toString(),
AutoIngestManager.Event.RESUMED.toString(), AutoIngestManager.Event.RESUMED.toString(),
AutoIngestManager.Event.GENERATE_THREAD_DUMP_RESPONSE.toString()})); AutoIngestManager.Event.GENERATE_THREAD_DUMP_RESPONSE.toString(),
AutoIngestManager.Event.OCR_STATE_CHANGE.toString()}));
private final AutopsyEventPublisher eventPublisher; private final AutopsyEventPublisher eventPublisher;
private CoordinationService coordinationService; private CoordinationService coordinationService;
private final ScheduledThreadPoolExecutor coordSvcQueryExecutor; private final ScheduledThreadPoolExecutor coordSvcQueryExecutor;
@ -166,6 +167,8 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen
handleAutoIngestNodeStateEvent((AutoIngestNodeStateEvent) event); handleAutoIngestNodeStateEvent((AutoIngestNodeStateEvent) event);
} else if (event instanceof ThreadDumpResponseEvent) { } else if (event instanceof ThreadDumpResponseEvent) {
handleRemoteThreadDumpResponseEvent((ThreadDumpResponseEvent) event); handleRemoteThreadDumpResponseEvent((ThreadDumpResponseEvent) event);
} else if (event instanceof AutoIngestOcrStateChangeEvent) {
handleOcrStateChangeEvent((AutoIngestOcrStateChangeEvent) event);
} }
} }
@ -228,6 +231,15 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen
} }
} }
/**
* Handles an OCR state change event.
*
* @param event OCR state change event.
*/
private void handleOcrStateChangeEvent(AutoIngestOcrStateChangeEvent event) {
coordSvcQueryExecutor.submit(new StateRefreshTask());
}
/** /**
* Handles an auto ingest job/case prioritization event. * Handles an auto ingest job/case prioritization event.
* *
@ -428,6 +440,51 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen
} }
} }
/**
* Enables OCR for all pending ingest jobs for a specified case.
*
* @param caseName The name of the case to enable OCR.
*
* @throws AutoIngestMonitorException If there is an error enabling OCR for the jobs for the case.
*
*/
void changeOcrStateForCase(final String caseName, final boolean ocrState) throws AutoIngestMonitorException {
List<AutoIngestJob> jobsToPrioritize = new ArrayList<>();
synchronized (jobsLock) {
for (AutoIngestJob pendingJob : getPendingJobs()) {
if (pendingJob.getManifest().getCaseName().equals(caseName)) {
jobsToPrioritize.add(pendingJob);
}
}
if (!jobsToPrioritize.isEmpty()) {
for (AutoIngestJob job : jobsToPrioritize) {
String manifestNodePath = job.getManifest().getFilePath().toString();
try {
AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath));
nodeData.setOcrEnabled(ocrState);
coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath, nodeData.toArray());
} catch (AutoIngestJobNodeData.InvalidDataException | CoordinationServiceException | InterruptedException ex) {
throw new AutoIngestMonitorException("Error enabling OCR for job " + job.toString(), ex);
}
job.setOcrEnabled(ocrState);
/**
* Update job object in pending jobs queue
*/
jobsSnapshot.addOrReplacePendingJob(job);
}
/*
* Publish the OCR enabled event.
*/
new Thread(() -> {
eventPublisher.publishRemotely(new AutoIngestOcrStateChangeEvent(LOCAL_HOST_NAME, caseName,
AutoIngestManager.getSystemUserNameProperty(), ocrState));
}).start();
}
}
}
/** /**
* Removes the priority (set to zero) of all pending ingest jobs for a * Removes the priority (set to zero) of all pending ingest jobs for a
* specified case. * specified case.

View File

@ -69,7 +69,7 @@ class AutoIngestNodeRefreshEvents {
private final String caseName; private final String caseName;
/** /**
* Contructs a RefreshCaseEvent * Constructs a RefreshCaseEvent
* *
* @param monitor The monitor that will provide access to the current state of the jobs lists. * @param monitor The monitor that will provide access to the current state of the jobs lists.
* @param name The name of the case whose nodes should be refreshed. * @param name The name of the case whose nodes should be refreshed.

View File

@ -0,0 +1,99 @@
/*
* 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.experimental.autoingest;
import java.io.Serializable;
import org.sleuthkit.autopsy.events.AutopsyEvent;
/**
* Event published when an automated ingest manager enables or disables OCR on a case.
*/
public final class AutoIngestOcrStateChangeEvent extends AutopsyEvent implements Serializable {
/**
* Possible event types
*/
enum EventType {
OCR_ENABLED,
OCR_DISABLED
}
private static final long serialVersionUID = 1L;
private final String caseName;
private final String nodeName;
private final String userName;
private final EventType eventType;
/**
* Constructs an event published when an automated ingest manager
* enables or disables OCR on a case.
*
* @param caseName The name of the case.
* @param nodeName The host name of the node that enabled/disabled OCR.
* @param userName The logged in user
* @param ocrState Flag whether OCR is enabled/disabled
*/
public AutoIngestOcrStateChangeEvent(String nodeName, String caseName, String userName, boolean ocrState) {
super(AutoIngestManager.Event.OCR_STATE_CHANGE.toString(), null, null);
this.caseName = caseName;
this.nodeName = nodeName;
this.userName = userName;
if (ocrState == true) {
this.eventType = EventType.OCR_ENABLED;
} else {
this.eventType = EventType.OCR_DISABLED;
}
}
/**
* Gets the name of the prioritized case.
*
* @return The case name.
*/
public String getCaseName() {
return caseName;
}
/**
* Gets the host name of the node that prioritized the case.
*
* @return The host name of the node.
*/
public String getNodeName() {
return nodeName;
}
/**
* Gets the user logged in to the node that prioritized the case.
*
* @return The user name
*/
String getUserName() {
return userName;
}
/**
* Gets the type of prioritization
*
* @return The type
*/
EventType getEventType() {
return eventType;
}
}

View File

@ -10,6 +10,10 @@ AinStatusNode.status.title=Status
AinStatusNode.status.unknown=Unknown AinStatusNode.status.unknown=Unknown
AutoIngestAdminActions.cancelJobAction.title=Cancel Job AutoIngestAdminActions.cancelJobAction.title=Cancel Job
AutoIngestAdminActions.cancelModuleAction.title=Cancel Module AutoIngestAdminActions.cancelModuleAction.title=Cancel Module
AutoIngestAdminActions.disableOCR.error=Failed to disable OCR for case "%s".
AutoIngestAdminActions.disableOCR.title=Disable OCR For This Case
AutoIngestAdminActions.enableOCR.error=Failed to enable OCR for case "%s".
AutoIngestAdminActions.enableOCR.title=Enable OCR For This Case
AutoIngestAdminActions.getThreadDump.title=Generate Thread Dump AutoIngestAdminActions.getThreadDump.title=Generate Thread Dump
AutoIngestAdminActions.pause.title=Pause Node AutoIngestAdminActions.pause.title=Pause Node
AutoIngestAdminActions.progressDialogAction.title=Ingest Progress AutoIngestAdminActions.progressDialogAction.title=Ingest Progress
@ -71,6 +75,7 @@ AutoIngestControlPanel.JobsTableModel.ColumnHeader.HostName=Host Name
AutoIngestControlPanel.JobsTableModel.ColumnHeader.ImageFolder=Data Source AutoIngestControlPanel.JobsTableModel.ColumnHeader.ImageFolder=Data Source
AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob=\ Local Job? AutoIngestControlPanel.JobsTableModel.ColumnHeader.LocalJob=\ Local Job?
AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath=\ Manifest File Path AutoIngestControlPanel.JobsTableModel.ColumnHeader.ManifestFilePath=\ Manifest File Path
AutoIngestControlPanel.JobsTableModel.ColumnHeader.OCR=OCR
AutoIngestControlPanel.JobsTableModel.ColumnHeader.Priority=Prioritized AutoIngestControlPanel.JobsTableModel.ColumnHeader.Priority=Prioritized
AutoIngestControlPanel.JobsTableModel.ColumnHeader.Stage=Stage AutoIngestControlPanel.JobsTableModel.ColumnHeader.Stage=Stage
AutoIngestControlPanel.JobsTableModel.ColumnHeader.StageTime=Time in Stage AutoIngestControlPanel.JobsTableModel.ColumnHeader.StageTime=Time in Stage
@ -130,6 +135,7 @@ AutoIngestJobsNode.dataSource.text=Data Source
AutoIngestJobsNode.hostName.text=Host Name AutoIngestJobsNode.hostName.text=Host Name
AutoIngestJobsNode.jobCompleted.text=Job Completed AutoIngestJobsNode.jobCompleted.text=Job Completed
AutoIngestJobsNode.jobCreated.text=Job Created AutoIngestJobsNode.jobCreated.text=Job Created
AutoIngestJobsNode.ocr.text=OCR
AutoIngestJobsNode.prioritized.false=No AutoIngestJobsNode.prioritized.false=No
AutoIngestJobsNode.prioritized.true=Yes AutoIngestJobsNode.prioritized.true=Yes
AutoIngestJobsNode.priority.text=Prioritized AutoIngestJobsNode.priority.text=Prioritized
@ -206,9 +212,7 @@ DeleteCaseTask.progress.parsingManifest=Parsing manifest file {0}...
DeleteCaseTask.progress.releasingManifestLock=Releasing lock on the manifest file {0}... DeleteCaseTask.progress.releasingManifestLock=Releasing lock on the manifest file {0}...
DeleteCaseTask.progress.startMessage=Starting deletion... DeleteCaseTask.progress.startMessage=Starting deletion...
DeleteOrphanCaseNodesAction.progressDisplayName=Cleanup Case Znodes DeleteOrphanCaseNodesAction.progressDisplayName=Cleanup Case Znodes
# {0} - item count
DeleteOrphanCaseNodesDialog.additionalInit.lblNodeCount.text=Znodes found: {0} DeleteOrphanCaseNodesDialog.additionalInit.lblNodeCount.text=Znodes found: {0}
# {0} - item count
DeleteOrphanCaseNodesDialog.additionalInit.znodesTextArea.countMessage=ZNODES FOUND: {0} DeleteOrphanCaseNodesDialog.additionalInit.znodesTextArea.countMessage=ZNODES FOUND: {0}
DeleteOrphanCaseNodesTask.progress.connectingToCoordSvc=Connecting to the coordination service DeleteOrphanCaseNodesTask.progress.connectingToCoordSvc=Connecting to the coordination service
# {0} - node path # {0} - node path
@ -224,6 +228,8 @@ DeleteOrphanManifestNodesTask.progress.gettingManifestNodes=Querying the coordin
DeleteOrphanManifestNodesTask.progress.lookingForOrphanedManifestFileZnodes=Looking for orphaned manifest file znodes DeleteOrphanManifestNodesTask.progress.lookingForOrphanedManifestFileZnodes=Looking for orphaned manifest file znodes
DeleteOrphanManifestNodesTask.progress.startMessage=Starting orphaned manifest file znode cleanup DeleteOrphanManifestNodesTask.progress.startMessage=Starting orphaned manifest file znode cleanup
HINT_CasesDashboardTopComponent=This is an adminstrative dashboard for multi-user cases HINT_CasesDashboardTopComponent=This is an adminstrative dashboard for multi-user cases
OcrIconCellRenderer.disabled.tooltiptext=This job does not have OCR enabled.
OcrIconCellRenderer.enabled.tooltiptext=This job has OCR enabled.
OpenAutoIngestLogAction.deletedLogErrorMsg=The case auto ingest log has been deleted. OpenAutoIngestLogAction.deletedLogErrorMsg=The case auto ingest log has been deleted.
OpenAutoIngestLogAction.logOpenFailedErrorMsg=Failed to open case auto ingest log. See application log for details. OpenAutoIngestLogAction.logOpenFailedErrorMsg=Failed to open case auto ingest log. See application log for details.
OpenAutoIngestLogAction.menuItemText=Open Auto Ingest Log File OpenAutoIngestLogAction.menuItemText=Open Auto Ingest Log File
@ -333,7 +339,7 @@ PrioritizationAction.deprioritizeCaseAction.error=Failed to deprioritize case "%
PrioritizationAction.deprioritizeCaseAction.title=Deprioritize Case PrioritizationAction.deprioritizeCaseAction.title=Deprioritize Case
PrioritizationAction.deprioritizeJobAction.error=Failed to deprioritize job "%s". PrioritizationAction.deprioritizeJobAction.error=Failed to deprioritize job "%s".
PrioritizationAction.deprioritizeJobAction.title=Deprioritize Job PrioritizationAction.deprioritizeJobAction.title=Deprioritize Job
PrioritizationAction.prioritizeCaseAction.error==Failed to prioritize case "%s". PrioritizationAction.prioritizeCaseAction.error=Failed to prioritize case "%s".
PrioritizationAction.prioritizeCaseAction.title=Prioritize Case PrioritizationAction.prioritizeCaseAction.title=Prioritize Case
PrioritizationAction.prioritizeJobAction.error=Failed to prioritize job "%s". PrioritizationAction.prioritizeJobAction.error=Failed to prioritize job "%s".
PrioritizationAction.prioritizeJobAction.title=Prioritize Job PrioritizationAction.prioritizeJobAction.title=Prioritize Job

View File

@ -0,0 +1,72 @@
/*
* 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.experimental.autoingest;
import java.awt.Component;
import java.lang.reflect.InvocationTargetException;
import javax.swing.ImageIcon;
import javax.swing.JTable;
import static javax.swing.SwingConstants.CENTER;
import org.openide.nodes.Node;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.guiutils.GrayableCellRenderer;
import org.sleuthkit.autopsy.datamodel.NodeProperty;
/**
* A JTable and Outline view cell renderer that represents whether OCR is enabled for the job.
*/
class OcrIconCellRenderer extends GrayableCellRenderer {
@Messages({
"OcrIconCellRenderer.enabled.tooltiptext=This job has OCR enabled.",
"OcrIconCellRenderer.disabled.tooltiptext=This job does not have OCR enabled."
})
private static final long serialVersionUID = 1L;
static final ImageIcon checkedIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/experimental/images/tick.png", false));
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setHorizontalAlignment(CENTER);
Object switchValue = null;
if ((value instanceof NodeProperty)) {
//The Outline view has properties in the cell, the value contained in the property is what we want
try {
switchValue = ((Node.Property) value).getValue();
} catch (IllegalAccessException | InvocationTargetException ignored) {
//Unable to get the value from the NodeProperty no Icon will be displayed
}
} else {
//JTables contain the value we want directly in the cell
switchValue = value;
}
if (switchValue instanceof Boolean && (boolean) switchValue == true) {
setIcon(checkedIcon);
setToolTipText(org.openide.util.NbBundle.getMessage(OcrIconCellRenderer.class, "OcrIconCellRenderer.enabled.tooltiptext"));
} else {
setIcon(null);
if (switchValue instanceof Boolean) {
setToolTipText(org.openide.util.NbBundle.getMessage(OcrIconCellRenderer.class, "OcrIconCellRenderer.disabled.tooltiptext"));
}
}
grayCellIfTableNotEnabled(table, isSelected);
return this;
}
}

View File

@ -193,7 +193,7 @@ abstract class PrioritizationAction extends AbstractAction {
* AutoIngestJob is a part of. * AutoIngestJob is a part of.
*/ */
@Messages({"PrioritizationAction.prioritizeCaseAction.title=Prioritize Case", @Messages({"PrioritizationAction.prioritizeCaseAction.title=Prioritize Case",
"PrioritizationAction.prioritizeCaseAction.error==Failed to prioritize case \"%s\"."}) "PrioritizationAction.prioritizeCaseAction.error=Failed to prioritize case \"%s\"."})
static final class PrioritizeCaseAction extends PrioritizationAction { static final class PrioritizeCaseAction extends PrioritizationAction {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -0,0 +1,3 @@
#Mon Jun 14 12:23:19 UTC 2021
MemoryDSInputPanel.deselectAllButton.text=\u5168\u9078\u629e\u3092\u30af\u30ea\u30a2
MemoryDSInputPanel.selectAllButton.text=\u3059\u3079\u3066\u9078\u629e

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:29 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
AbstractFileStringContentStream.getSize.exception.msg=\u6587\u5b57\u5217\u5168\u4f53\u304c\u5909\u63db\u3055\u308c\u308b\u307e\u3067\u3001\u5909\u63db\u3055\u308c\u305f\u6587\u5b57\u5217\u306e\u6587\u5b57\u6570\u306f\u308f\u304b\u308a\u307e\u305b\u3093 AbstractFileStringContentStream.getSize.exception.msg=\u6587\u5b57\u5217\u5168\u4f53\u304c\u5909\u63db\u3055\u308c\u308b\u307e\u3067\u3001\u5909\u63db\u3055\u308c\u305f\u6587\u5b57\u5217\u306e\u6587\u5b57\u6570\u306f\u308f\u304b\u308a\u307e\u305b\u3093
AbstractFileStringContentStream.getSrcInfo.text=\u30d5\u30a1\u30a4\u30eb\:{0} AbstractFileStringContentStream.getSrcInfo.text=\u30d5\u30a1\u30a4\u30eb\:{0}
AbstractFileTikaTextExtract.index.exception.tikaParse.msg=\u4f8b\u5916\: \u6b21\u306e\u30d5\u30a1\u30a4\u30eb\u306eTika\u89e3\u6790\u30bf\u30b9\u30af\u5b9f\u884c\u6642\u306e\u4e88\u671f\u305b\u306c\u4f8b\u5916\: {0}\u3001{1} AbstractFileTikaTextExtract.index.exception.tikaParse.msg=\u4f8b\u5916\: \u6b21\u306e\u30d5\u30a1\u30a4\u30eb\u306eTika\u89e3\u6790\u30bf\u30b9\u30af\u5b9f\u884c\u6642\u306e\u4e88\u671f\u305b\u306c\u4f8b\u5916\: {0}\u3001{1}
@ -47,6 +47,17 @@ DropdownSingleTermSearchPanel.jSaveSearchResults.toolTipText=\u30ad\u30fc\u30ef\
DropdownSingleTermSearchPanel.selected=\u30a2\u30c9\u30db\u30c3\u30af\u691c\u7d22\u30bd\u30fc\u30b9\u30d5\u30a3\u30eb\u30bf\u30fc\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u3059 DropdownSingleTermSearchPanel.selected=\u30a2\u30c9\u30db\u30c3\u30af\u691c\u7d22\u30bd\u30fc\u30b9\u30d5\u30a3\u30eb\u30bf\u30fc\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u3059
DropdownSingleTermSearchPanel.warning.text=\u5883\u754c\u6587\u5b57 ^ \u3068 $ \u304c\u5358\u8a9e\u9818\u57df\u3068\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002[ \\.,] \u306a\u3069\u306e\u660e\u793a\u7684\u306a\u5883\u754c\u6587\u5b57\u30ea\u30b9\u30c8\u3068\u306e\u7f6e\u63db\u3092\n\u691c\u8a0e\u3057\u3066\u304f\u3060\u3055\u3044 DropdownSingleTermSearchPanel.warning.text=\u5883\u754c\u6587\u5b57 ^ \u3068 $ \u304c\u5358\u8a9e\u9818\u57df\u3068\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002[ \\.,] \u306a\u3069\u306e\u660e\u793a\u7684\u306a\u5883\u754c\u6587\u5b57\u30ea\u30b9\u30c8\u3068\u306e\u7f6e\u63db\u3092\n\u691c\u8a0e\u3057\u3066\u304f\u3060\u3055\u3044
DropdownSingleTermSearchPanel.warning.title=\u8b66\u544a DropdownSingleTermSearchPanel.warning.title=\u8b66\u544a
ExtractAllTermsReport.description.text=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u304b\u3089\u3059\u3079\u3066\u306e\u30e6\u30cb\u30fc\u30af\u306e\u5358\u8a9e\u3092\u62bd\u51fa\u3057\u307e\u3059\u3002 \u6ce8\uff1a\u62bd\u51fa\u3055\u308c\u305f\u5358\u8a9e\u306f\u5c0f\u6587\u5b57\u3067\u3059\u3002
ExtractAllTermsReport.error.noOpenCase=\u73fe\u5728\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u306f\u3042\u308a\u307e\u305b\u3093\u3002
ExtractAllTermsReport.export.error=\u30e6\u30cb\u30fc\u30af\u306e\u5358\u8a9e\u306e\u62bd\u51fa\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
ExtractAllTermsReport.exportComplete=\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u62bd\u51fa\u5b8c\u4e86
ExtractAllTermsReport.getName.text=\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u3092\u62bd\u51fa\u3059\u308b
ExtractAllTermsReport.numberExtractedTerms={0}\u7528\u8a9e.\u304c\u62bd\u51fa\u3055\u308c\u307e\u3057\u305f..
ExtractAllTermsReport.search.ingestInProgressBody=<html>\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u53d6\u8fbc\u307f\u306f\u73fe\u5728\u5b9f\u884c\u4e2d\u3067\u3059\u3002<br/>\u5168\u3066\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u767b\u9332\u3055\u308c\u3066\u307e\u305b\u3093\u3001\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u3092\u62bd\u51fa\u3059\u308b\u3068\u4e0d\u5b8c\u5168\u306a\u7d50\u679c\u306b\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<br />\u305d\u308c\u3067\u3082\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u306e\u62bd\u51fa\u3092\u7d9a\u884c\u3057\u307e\u3059\u304b\uff1f</ html>
ExtractAllTermsReport.search.noFilesInIdxMsg=\u307e\u3060\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u30d5\u30a1\u30a4\u30eb\u306f\u3042\u308a\u307e\u305b\u3093\u3002 \u3042\u3068\u3067\u3082\u3046\u4e00\u5ea6\u8a66\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306f{0}\u5206\u3054\u3068\u306b\u66f4\u65b0\u3055\u308c\u307e\u3059\u3002
ExtractAllTermsReport.search.noFilesInIdxMsg2=\u307e\u3060\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u30d5\u30a1\u30a4\u30eb\u306f\u3042\u308a\u307e\u305b\u3093\u3002 \u3042\u3068\u3067\u3082\u3046\u4e00\u5ea6\u8a66\u3057\u3066\u304f\u3060\u3055\u3044\u3002
ExtractAllTermsReport.search.searchIngestInProgressTitle=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u306e\u53d6\u8fbc\u307f\u304c\u9032\u884c\u4e2d
ExtractAllTermsReport.startExport=\u30e6\u30cb\u30fc\u30af\u306a\u5358\u8a9e\u62bd\u51fa\u306e\u958b\u59cb
ExtractedContentPanel.SetMarkup.progress.loading={0} \u306e\u30c6\u30ad\u30b9\u30c8\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059 ExtractedContentPanel.SetMarkup.progress.loading={0} \u306e\u30c6\u30ad\u30b9\u30c8\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059
ExtractedContentPanel.copyMenuItem.text=\u30b3\u30d4\u30fc ExtractedContentPanel.copyMenuItem.text=\u30b3\u30d4\u30fc
ExtractedContentPanel.hitButtonsLabel.text=\u4e00\u81f4\u3059\u308b\u7d50\u679c ExtractedContentPanel.hitButtonsLabel.text=\u4e00\u81f4\u3059\u308b\u7d50\u679c
@ -333,11 +344,12 @@ Server.deleteCore.exception.msg=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3{0}\u306
Server.exceptionMessage.unableToBackupCollection=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3067\u304d\u307e\u305b\u3093 Server.exceptionMessage.unableToBackupCollection=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3067\u304d\u307e\u305b\u3093
Server.exceptionMessage.unableToCreateCollection=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093 Server.exceptionMessage.unableToCreateCollection=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093
Server.exceptionMessage.unableToRestoreCollection=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u5fa9\u5143\u3067\u304d\u307e\u305b\u3093 Server.exceptionMessage.unableToRestoreCollection=Solr\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u5fa9\u5143\u3067\u304d\u307e\u305b\u3093
Server.getAllTerms.error=\u5168\u3066\u306e\u30e6\u30cb\u30fc\u30af\u306aSolr\u7528\u8a9e\u306e\u62bd\u51fa\u306b\u5931\u6557\u3057\u307e\u3057\u305f\uff1a
Server.isRunning.exception.errCheckSolrRunning.msg=Solr\u30b5\u30fc\u30d0\u30fc\u304c\u5b9f\u884c\u4e2d\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f Server.isRunning.exception.errCheckSolrRunning.msg=Solr\u30b5\u30fc\u30d0\u30fc\u304c\u5b9f\u884c\u4e2d\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
Server.isRunning.exception.errCheckSolrRunning.msg2=Solr\u30b5\u30fc\u30d0\u30fc\u304c\u5b9f\u884c\u4e2d\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f Server.isRunning.exception.errCheckSolrRunning.msg2=Solr\u30b5\u30fc\u30d0\u30fc\u304c\u5b9f\u884c\u4e2d\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
Server.openCore.exception.alreadyOpen.msg=\u958b\u3044\u3066\u3044\u308bSolr\u306e\u30b3\u30a2\u304c\u3059\u3067\u306b\u3042\u308a\u307e\u3059\u3002\u6700\u521d\u306b\u30b3\u30a2\u3092\u660e\u793a\u7684\u306b\u9589\u3058\u3066\u304f\u3060\u3055\u3044\u3002 Server.openCore.exception.alreadyOpen.msg=\u958b\u3044\u3066\u3044\u308bSolr\u306e\u30b3\u30a2\u304c\u3059\u3067\u306b\u3042\u308a\u307e\u3059\u3002\u6700\u521d\u306b\u30b3\u30a2\u3092\u660e\u793a\u7684\u306b\u9589\u3058\u3066\u304f\u3060\u3055\u3044\u3002
Server.openCore.exception.cantOpen.msg=\u7d22\u5f15\u3092\u4f5c\u6210\u307e\u305f\u306f\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f Server.openCore.exception.cantOpen.msg=\u7d22\u5f15\u3092\u4f5c\u6210\u307e\u305f\u306f\u958b\u3051\u307e\u305b\u3093\u3067\u3057\u305f
Server.openCore.exception.msg=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30b5\u30fc\u30d3\u30b9\u306f\u307e\u3060\u5b9f\u884c\u3057\u3066\u3044\u307e\u305b\u3093 Server.openCore.exception.msg=\u30ed\u30fc\u30ab\u30eb\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30b5\u30fc\u30d3\u30b9\u306f\u307e\u3060\u5b9f\u884c\u3055\u308c\u3066\u3044\u307e\u305b\u3093
Server.openCore.exception.noIndexDir.msg=\u7d22\u5f15\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u4f5c\u6210\u3067\u304d\u306a\u304b\u3063\u305f\u304b\u3001\u898b\u3064\u304b\u308a\u307e\u305b\u3093 Server.openCore.exception.noIndexDir.msg=\u7d22\u5f15\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u4f5c\u6210\u3067\u304d\u306a\u304b\u3063\u305f\u304b\u3001\u898b\u3064\u304b\u308a\u307e\u305b\u3093
Server.query.exception.msg=\u6b21\u306e\u30af\u30a8\u30ea\u306e\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\: {0} Server.query.exception.msg=\u6b21\u306e\u30af\u30a8\u30ea\u306e\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\: {0}
Server.query2.exception.msg=\u6b21\u306e\u30af\u30a8\u30ea\u306e\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\: {0} Server.query2.exception.msg=\u6b21\u306e\u30af\u30a8\u30ea\u306e\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\: {0}
@ -360,10 +372,12 @@ SolrSearch.checkingForLatestIndex.msg=\u6700\u65b0\u306eSolr\u3068\u30b9\u30ad\u
SolrSearch.complete.msg=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u304c\u6b63\u5e38\u306b\u958b\u304d\u307e\u3057\u305f SolrSearch.complete.msg=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u304c\u6b63\u5e38\u306b\u958b\u304d\u307e\u3057\u305f
SolrSearch.creatingNewIndex.msg=\u65b0\u898f\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u3092\u751f\u6210\u4e2d\u3067\u3059 SolrSearch.creatingNewIndex.msg=\u65b0\u898f\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u3092\u751f\u6210\u4e2d\u3067\u3059
SolrSearch.findingIndexes.msg=\u65e2\u5b58\u306e\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u691c\u7d22\u4e2d\u3067\u3059 SolrSearch.findingIndexes.msg=\u65e2\u5b58\u306e\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u691c\u7d22\u4e2d\u3067\u3059
SolrSearch.futureIndexVersion.msg=\u30b1\u30fc\u30b9\u306e\u30c6\u30ad\u30b9\u30c8\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306fSolr {0}\u7528\u3067\u3059\u3002 \u3053\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306eAutopsy\u306f\u3001Solr {1}\u3068\u4e92\u63db\u6027\u304c\u3042\u308a\u307e\u3059\u3002
SolrSearch.indentifyingIndex.msg=\u4f7f\u7528\u3059\u308b\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u3092\u7279\u5b9a\u4e2d\u3067\u3059 SolrSearch.indentifyingIndex.msg=\u4f7f\u7528\u3059\u308b\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u3092\u7279\u5b9a\u4e2d\u3067\u3059
SolrSearch.lookingForMetadata.msg=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u4e2d\u3067\u3059 SolrSearch.lookingForMetadata.msg=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u4e2d\u3067\u3059
SolrSearch.openCore.msg=\u30c6\u30ad\u30b9\u30c8\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u958b\u304d\u307e\u3059\u3002 \u3053\u308c\u306b\u306f\u6570\u5206\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002 SolrSearch.openCore.msg=\u30c6\u30ad\u30b9\u30c8\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u958b\u304d\u307e\u3059\u3002 \u3053\u308c\u306b\u306f\u6570\u5206\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002
SolrSearch.readingIndexes.msg=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u307f\u4e2d\u3067\u3059 SolrSearch.readingIndexes.msg=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u307f\u4e2d\u3067\u3059
SolrSearch.unableToFindIndex.msg=\u30b1\u30fc\u30b9\u306b\u4f7f\u7528\u3067\u304d\u308b\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
SolrSearchService.ServiceName=Solr\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30b5\u30fc\u30d3\u30b9 SolrSearchService.ServiceName=Solr\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30b5\u30fc\u30d3\u30b9
SolrSearchService.exceptionMessage.failedToDeleteIndexFiles={0} \u306e\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f SolrSearchService.exceptionMessage.failedToDeleteIndexFiles={0} \u306e\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f
SolrSearchService.exceptionMessage.noCurrentSolrCore=IndexMetadata\u306b\u306f\u73fe\u5728\u306eSolr\u306e\u30b3\u30a2\u304c\u542b\u307e\u308c\u3066\u3044\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u30b1\u30fc\u30b9\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f SolrSearchService.exceptionMessage.noCurrentSolrCore=IndexMetadata\u306b\u306f\u73fe\u5728\u306eSolr\u306e\u30b3\u30a2\u304c\u542b\u307e\u308c\u3066\u3044\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u30b1\u30fc\u30b9\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f

View File

@ -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);
} }

View File

@ -462,4 +462,17 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
} }
} }
/**
* A flag to enable or disable OCR on all future text indexing. Also sets the
* the "Limited OCR" functionality accordingly.
*
* @param state Boolean flag to enable/disable OCR. Set to True to enable
* OCR, or False to disable it.
*/
@Override
public void changeOcrState(boolean state) {
KeywordSearchSettings.setOcrOption(state);
KeywordSearchSettings.setLimitedOcrOption(state);
}
} }

View File

@ -1,4 +1,4 @@
#Fri Feb 12 16:56:29 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
Chrome.getBookmark.errMsg.errAnalyzeFile={0}\:\u30d5\u30a1\u30a4\u30eb\:{1}\u3092\u89e3\u6790\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f Chrome.getBookmark.errMsg.errAnalyzeFile={0}\:\u30d5\u30a1\u30a4\u30eb\:{1}\u3092\u89e3\u6790\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
Chrome.getBookmark.errMsg.errAnalyzingFile={0}\:\u30d5\u30a1\u30a4\u30eb\:{1}\u3092\u89e3\u6790\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f Chrome.getBookmark.errMsg.errAnalyzingFile={0}\:\u30d5\u30a1\u30a4\u30eb\:{1}\u3092\u89e3\u6790\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
Chrome.getBookmark.errMsg.errAnalyzingFile3={0}\:\u30d5\u30a1\u30a4\u30eb\:{1}\u3092\u89e3\u6790\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f Chrome.getBookmark.errMsg.errAnalyzingFile3={0}\:\u30d5\u30a1\u30a4\u30eb\:{1}\u3092\u89e3\u6790\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
@ -80,7 +80,7 @@ Firefox.moduleName=FireFox
Firefox.parentModuleName=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 Firefox.parentModuleName=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3
Firefox.parentModuleName.noSpace=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 Firefox.parentModuleName.noSpace=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3
OpenIDE-Module-Display-Category=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb OpenIDE-Module-Display-Category=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb
OpenIDE-Module-Long-Description=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3002\n\n\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u306e\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u304b\u3089\u6709\u7528\u306a\u6700\u8fd1\u306e\u30e6\u30fc\u30b6\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u3092\u62bd\u51fa\u3057\u307e\u3059\u3002\u4f8b\u3048\u3070\uff1a\n\n-\u6700\u8fd1\u958b\u3044\u305f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3001\n-\u30a6\u30a7\u30d6\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\uff08\u8a2a\u308c\u305f\u30b5\u30a4\u30c8\u3001\u4fdd\u5b58\u3055\u308c\u305fCookie\u3001\u30d6\u30c3\u30af\u30de\u30fc\u30af\u3055\u308c\u305f\u30b5\u30a4\u30c8\u3001\u30b5\u30fc\u30c1\u30a8\u30f3\u30b8\u30f3\u30af\u30a8\u30ea\u3001\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\uff09\u3001\n-\u6700\u8fd1\u63a5\u7d9a\u3057\u305f\u30c7\u30d0\u30a4\u30b9\u3001\n-\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u305f\u30d7\u30ed\u30b0\u30e9\u30e0\u3002\n\n\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u73fe\u5728Windows\u306e\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u3057\u304b\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002\n\u30d7\u30e9\u30b0\u30a4\u30f3\u306fWindows\u7248\u306eAutopsy\u3092\u5229\u7528\u3059\u308b\u3068\u5168\u3066\u306e\u6a5f\u80fd\u304c\u4f7f\u3048\u307e\u3059\u3002 OpenIDE-Module-Long-Description=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u53d6\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u3002\n\n\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u3001\u53d6\u8fbc\u307e\u308c\u3066\u3044\u308b\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u3067\u306e\u6700\u8fd1\u306e\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u306b\u95a2\u3059\u308b\u6709\u7528\u306a\u60c5\u5831\u3092\u62bd\u51fa\u3057\u307e\u3059\u3002\n\n-\u6700\u8fd1\u958b\u3044\u305f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3001\n-Web\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\uff08\u30a2\u30af\u30bb\u30b9\u3057\u305f\u30b5\u30a4\u30c8\u3001\u4fdd\u5b58\u3055\u308c\u305fCookie\u3001\u30d6\u30c3\u30af\u30de\u30fc\u30af\u3055\u308c\u305f\u30b5\u30a4\u30c8\u3001\u691c\u7d22\u30a8\u30f3\u30b8\u30f3\u30af\u30a8\u30ea\u3001\u30d5\u30a1\u30a4\u30eb\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\uff09\u3001\n-\u6700\u8fd1\u63a5\u7d9a\u3055\u308c\u305f\u30c7\u30d0\u30a4\u30b9\u3001\n-\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u305f\u30d7\u30ed\u30b0\u30e9\u30e0\u3002\n\n\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306fWindows\u306e\u307f\u306e\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u3059\u3002\nWindows\u30d0\u30fc\u30b8\u30e7\u30f3\u306eAutopsy\u306b\u30c7\u30d7\u30ed\u30a4\u3059\u308b\u3068\u30d7\u30e9\u30b0\u30a4\u30f3\u306f\u5b8c\u5168\u306b\u6a5f\u80fd\u3057\u307e\u3059\u3002
OpenIDE-Module-Name=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3 OpenIDE-Module-Name=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3
OpenIDE-Module-Short-Description=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u30d5\u30a1\u30a4\u30f3\u30c0\u30fc\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb OpenIDE-Module-Short-Description=\u6700\u8fd1\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u30d5\u30a1\u30a4\u30f3\u30c0\u30fc\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb
Progress_Message_Chrome_AutoFill=Chrome\u81ea\u52d5\u5165\u529b\u30d6\u30e9\u30a6\u30b6{0} Progress_Message_Chrome_AutoFill=Chrome\u81ea\u52d5\u5165\u529b\u30d6\u30e9\u30a6\u30b6{0}

View File

@ -597,7 +597,8 @@ final class ChromeCacheExtractor {
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

View File

@ -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;
} }

View File

@ -157,20 +157,16 @@ 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;
} }
} }
} }
}
/** /**
* Checks to see if the data source might be an Android media card or a * Checks to see if the data source might be an Android media card or a

View File

@ -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;

View File

@ -29,7 +29,9 @@ import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader; import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.logging.Level; import java.util.logging.Level;
@ -1062,7 +1064,7 @@ class ExtractRegistry extends Extract {
File regfile = new File(regFilePath); File regfile = new File(regFilePath);
List<BlackboardArtifact> newArtifacts = new ArrayList<>(); List<BlackboardArtifact> newArtifacts = new ArrayList<>();
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(regfile))) { try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(regfile), StandardCharsets.UTF_8))) {
// Read the file in and create a Document and elements // Read the file in and create a Document and elements
String userInfoSection = "User Information"; String userInfoSection = "User Information";
String previousLine = null; String previousLine = null;
@ -1684,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

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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);

View File

@ -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
} }

View File

@ -1,2 +1,2 @@
#Fri Feb 12 16:56:29 UTC 2021 #Mon Jun 14 12:23:19 UTC 2021
bundles.ja.lastupdated=c2a4ececfba59d230d1a263f7124e67f88e8d3e6 bundles.ja.lastupdated=0952403cf485350f4db73ab6426ad5d6eb273e31

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