/*
* Autopsy Forensic Browser
*
* Copyright 2013-2014 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.report;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListDataListener;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
final class ReportVisualPanel2 extends JPanel {
private ReportWizardPanel2 wizPanel;
private Map<String, Boolean> tagStates = new LinkedHashMap<>();
private List<String> tags = new ArrayList<>();
ArtifactSelectionDialog dialog = new ArtifactSelectionDialog((JFrame) WindowManager.getDefault().getMainWindow(), true);
private Map<BlackboardArtifact.Type, Boolean> artifactStates = new HashMap<>();
private List<BlackboardArtifact.Type> artifacts = new ArrayList<>();
private TagsListModel tagsModel;
private TagsListRenderer tagsRenderer;
/**
* Creates new form ReportVisualPanel2
*/
public ReportVisualPanel2(ReportWizardPanel2 wizPanel) {
initComponents();
initTags();
initArtifactTypes();
tagsList.setEnabled(false);
selectAllButton.setEnabled(false);
deselectAllButton.setEnabled(false);
allResultsRadioButton.setSelected(true);
this.wizPanel = wizPanel;
this.allResultsRadioButton.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
tagsList.setEnabled(taggedResultsRadioButton.isSelected());
selectAllButton.setEnabled(taggedResultsRadioButton.isSelected());
deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected());
advancedButton.setEnabled(!taggedResultsRadioButton.isSelected());
updateFinishButton();
}
});
this.taggedResultsRadioButton.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
tagsList.setEnabled(taggedResultsRadioButton.isSelected());
selectAllButton.setEnabled(taggedResultsRadioButton.isSelected());
deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected());
advancedButton.setEnabled(!taggedResultsRadioButton.isSelected());
updateFinishButton();
}
});
}
// Initialize the list of Tags
private void initTags() {
List<TagName> tagNamesInUse;
try {
tagNamesInUse = Case.getCurrentCase().getServices().getTagsManager().getTagNamesInUse();
} catch (TskCoreException ex) {
Logger.getLogger(ReportVisualPanel2.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
return;
}
for (TagName tagName : tagNamesInUse) {
tagStates.put(tagName.getDisplayName(), Boolean.FALSE);
}
tags.addAll(tagStates.keySet());
tagsModel = new TagsListModel();
tagsRenderer = new TagsListRenderer();
tagsList.setModel(tagsModel);
tagsList.setCellRenderer(tagsRenderer);
tagsList.setVisibleRowCount(-1);
// Add the ability to enable and disable Tag checkboxes to the list
tagsList.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
int index = tagsList.locationToIndex(evt.getPoint());
if (index < tagsModel.getSize() && index >= 0) {
String value = tagsModel.getElementAt(index);
tagStates.put(value, !tagStates.get(value));
tagsList.repaint();
updateFinishButton();
}
}
});
}
// Initialize the list of Artifacts
@SuppressWarnings("deprecation")
private void initArtifactTypes() {
try {
ArrayList<BlackboardArtifact.Type> doNotReport = new ArrayList<>();
doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getLabel(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getDisplayName()));
doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getLabel(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getDisplayName())); // output is too unstructured for table review
artifacts = Case.getCurrentCase().getSleuthkitCase().getArtifactTypesInUse();
artifacts.removeAll(doNotReport);
artifactStates = new HashMap<>();
for (BlackboardArtifact.Type type : artifacts) {
artifactStates.put(type, Boolean.TRUE);
}
} catch (TskCoreException ex) {
Logger.getLogger(ReportVisualPanel2.class.getName()).log(Level.SEVERE, "Error getting list of artifacts in use: " + ex.getLocalizedMessage(), ex); //NON-NLS
}
}
@Override
public String getName() {
return NbBundle.getMessage(this.getClass(), "ReportVisualPanel2.getName.text");
}
/**
* Gets the enabled/disabled state of all artifacts
*
* @return the enabled/disabled state of all Artifacts
*/
Map<BlackboardArtifact.Type, Boolean> getArtifactStates() {
return artifactStates;
}
/**
* @return the enabled/disabled state of all Tags
*/
Map<String, Boolean> getTagStates() {
return tagStates;
}
private boolean areTagsSelected() {
boolean result = false;
for (Entry<String, Boolean> entry : tagStates.entrySet()) {
if (entry.getValue()) {
result = true;
}
}
return result;
}
private void updateFinishButton() {
if (taggedResultsRadioButton.isSelected()) {
wizPanel.setFinish(areTagsSelected());
} else {
wizPanel.setFinish(true);
}
}
/**
* @return true if the Tags radio button is selected, false otherwise
*/
boolean isTaggedResultsRadioButtonSelected() {
return taggedResultsRadioButton.isSelected();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
optionsButtonGroup = new javax.swing.ButtonGroup();
taggedResultsRadioButton = new javax.swing.JRadioButton();
allResultsRadioButton = new javax.swing.JRadioButton();
dataLabel = new javax.swing.JLabel();
selectAllButton = new javax.swing.JButton();
deselectAllButton = new javax.swing.JButton();
tagsScrollPane = new javax.swing.JScrollPane();
tagsList = new javax.swing.JList<>();
advancedButton = new javax.swing.JButton();
setPreferredSize(new java.awt.Dimension(650, 250));
optionsButtonGroup.add(taggedResultsRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(taggedResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.taggedResultsRadioButton.text")); // NOI18N
optionsButtonGroup.add(allResultsRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(allResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.allResultsRadioButton.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(dataLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.dataLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(selectAllButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.selectAllButton.text")); // NOI18N
selectAllButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
selectAllButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.deselectAllButton.text")); // NOI18N
deselectAllButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
deselectAllButtonActionPerformed(evt);
}
});
tagsList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
tagsList.setLayoutOrientation(javax.swing.JList.VERTICAL_WRAP);
tagsScrollPane.setViewportView(tagsList);
org.openide.awt.Mnemonics.setLocalizedText(advancedButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.advancedButton.text")); // NOI18N
advancedButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
advancedButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21)
.addComponent(tagsScrollPane)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(advancedButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 89, Short.MAX_VALUE)
.addComponent(deselectAllButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(selectAllButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(taggedResultsRadioButton)
.addComponent(dataLabel)
.addComponent(allResultsRadioButton))
.addGap(0, 481, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(dataLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(allResultsRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(taggedResultsRadioButton)
.addGap(7, 7, 7)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(selectAllButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(deselectAllButton)
.addGap(0, 70, Short.MAX_VALUE))
.addComponent(tagsScrollPane))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(advancedButton)
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed
for (String tag : tags) {
tagStates.put(tag, Boolean.TRUE);
}
tagsList.repaint();
wizPanel.setFinish(true);
}//GEN-LAST:event_selectAllButtonActionPerformed
private void deselectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectAllButtonActionPerformed
for (String tag : tags) {
tagStates.put(tag, Boolean.FALSE);
}
tagsList.repaint();
wizPanel.setFinish(false);
}//GEN-LAST:event_deselectAllButtonActionPerformed
private void advancedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_advancedButtonActionPerformed
artifactStates = dialog.display();
}//GEN-LAST:event_advancedButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton advancedButton;
private javax.swing.JRadioButton allResultsRadioButton;
private javax.swing.JLabel dataLabel;
private javax.swing.JButton deselectAllButton;
private javax.swing.ButtonGroup optionsButtonGroup;
private javax.swing.JButton selectAllButton;
private javax.swing.JRadioButton taggedResultsRadioButton;
private javax.swing.JList<String> tagsList;
private javax.swing.JScrollPane tagsScrollPane;
// End of variables declaration//GEN-END:variables
private class TagsListModel implements ListModel<String> {
@Override
public int getSize() {
return tags.size();
}
@Override
public String getElementAt(int index) {
return tags.get(index);
}
@Override
public void addListDataListener(ListDataListener l) {
}
@Override
public void removeListDataListener(ListDataListener l) {
}
}
// Render the Tags as JCheckboxes
private class TagsListRenderer extends JCheckBox implements ListCellRenderer<String> {
@Override
public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, boolean isSelected, boolean cellHasFocus) {
if (value != null) {
setEnabled(list.isEnabled());
setSelected(tagStates.get(value.toString()));
setFont(list.getFont());
setBackground(list.getBackground());
setForeground(list.getForeground());
setText(value.toString());
return this;
}
return new JLabel();
}
}
}