19 package org.sleuthkit.autopsy.contentviewers.artifactviewers;
 
   21 import java.awt.Color;
 
   22 import java.awt.Component;
 
   23 import java.awt.Dimension;
 
   24 import java.awt.GridBagConstraints;
 
   25 import java.awt.GridBagLayout;
 
   26 import java.awt.Insets;
 
   27 import java.awt.Toolkit;
 
   28 import java.awt.datatransfer.StringSelection;
 
   29 import java.awt.event.ActionEvent;
 
   30 import java.awt.event.ActionListener;
 
   31 import java.util.ArrayList;
 
   32 import java.util.Arrays;
 
   33 import java.util.Collections;
 
   34 import java.util.HashMap;
 
   35 import java.util.List;
 
   37 import java.util.logging.Level;
 
   38 import java.util.stream.Collectors;
 
   39 import java.util.stream.Stream;
 
   40 import javax.swing.JLabel;
 
   41 import javax.swing.JMenuItem;
 
   42 import javax.swing.JPopupMenu;
 
   43 import javax.swing.JTextPane;
 
   44 import javax.swing.SwingUtilities;
 
   45 import javax.swing.border.EmptyBorder;
 
   46 import org.apache.commons.lang.StringUtils;
 
   47 import org.apache.commons.lang3.tuple.Pair;
 
   48 import org.openide.util.NbBundle;
 
   49 import org.openide.util.lookup.ServiceProvider;
 
   62 @ServiceProvider(service = ArtifactContentViewer.class)
 
   65     private static final long serialVersionUID = 1L;
 
   68     private final static int MAX_COLS = 4;
 
   69     private final static Insets ZERO_INSETS = 
new java.awt.Insets(0, 0, 0, 0);
 
   71     private final static Insets FIRST_HEADER_INSETS = ZERO_INSETS;
 
   76     private final static double GLUE_WEIGHT_X = 1.0;
 
   77     private final static double TEXT_WEIGHT_X = 0.0;
 
   78     private final static int LABEL_COLUMN = 0;
 
   79     private final static int VALUE_COLUMN = 1;
 
   80     private final static int VALUE_WIDTH = 2;
 
   81     private final static int LABEL_WIDTH = 1;
 
   82     private static final Integer[] DEFAULT_ORDERING = 
new Integer[]{BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),
 
   83         BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
 
   84         BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID(),
 
   85         BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
 
   86         BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),
 
   87         BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID(),
 
   88         BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(),
 
   89         BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS.getTypeID()};
 
   90     private static final List<Integer> TYPES_WITH_DATE_SECTION = Arrays.asList(
new Integer[]{BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()});
 
   91     private final GridBagLayout gridBagLayout = 
new GridBagLayout();
 
   92     private final GridBagConstraints gridBagConstraints = 
new GridBagConstraints();
 
   93     private final Map<Integer, Integer[]> orderingMap = 
new HashMap<>();
 
   94     private final javax.swing.JPanel detailsPanel = 
new javax.swing.JPanel();
 
  103         gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
 
  104         detailsPanel.setLayout(gridBagLayout);
 
  113         orderingMap.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID(), 
new Integer[]{BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),
 
  114             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID(),
 
  115             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
 
  116             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID(),
 
  117             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
 
  118             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()});
 
  119         orderingMap.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID(), 
new Integer[]{BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(),
 
  120             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
 
  121             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
 
  122             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID(),
 
  123             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID(),
 
  124             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()});
 
  125         orderingMap.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID(), 
new Integer[]{BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(),
 
  126             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
 
  127             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
 
  128             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID(),
 
  129             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID(),
 
  130             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()});
 
  131         orderingMap.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID(), 
new Integer[]{BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID(),
 
  132             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
 
  133             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID(),
 
  134             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(),
 
  135             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()});
 
  136         orderingMap.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID(), 
new Integer[]{BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID(),
 
  137             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID(),
 
  138             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
 
  139             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID(),
 
  140             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
 
  141             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(),
 
  142             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()});
 
  143         orderingMap.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID(), 
new Integer[]{BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(),
 
  144             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
 
  145             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),
 
  146             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(),
 
  147             BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()});
 
  151     @NbBundle.Messages({
"GeneralPurposeArtifactViewer.unknown.text=Unknown"})
 
  155         if (artifact != null) {
 
  156             String dataSourceName = Bundle.GeneralPurposeArtifactViewer_unknown_text();
 
  157             String sourceFileName = Bundle.GeneralPurposeArtifactViewer_unknown_text();
 
  158             Map<Integer, List<BlackboardAttribute>> attributeMap = 
new HashMap<>();
 
  161                 for (BlackboardAttribute bba : artifact.getAttributes()) {
 
  162                     List<BlackboardAttribute> attrList = attributeMap.get(bba.getAttributeType().getTypeID());
 
  163                     if (attrList == null) {
 
  164                         attrList = 
new ArrayList<>();
 
  167                     attributeMap.put(bba.getAttributeType().getTypeID(), attrList);
 
  169                 dataSourceName = artifact.getDataSource().getName();
 
  170                 sourceFileName = artifact.getParent().getUniquePath();
 
  171             } 
catch (TskCoreException ex) {
 
  172                 logger.log(Level.WARNING, 
"Unable to get attributes for artifact " + artifact.getArtifactID(), ex);
 
  174             updateView(artifact, attributeMap, dataSourceName, sourceFileName);
 
  176         detailsScrollPane.setViewportView(detailsPanel);
 
  177         detailsScrollPane.revalidate();
 
  185     private 
void resetComponent() {
 
  187         detailsPanel.removeAll();
 
  188         detailsPanel.setLayout(gridBagLayout);
 
  189         detailsPanel.revalidate();
 
  190         gridBagConstraints.gridy = 0;
 
  191         gridBagConstraints.gridx = LABEL_COLUMN;
 
  192         gridBagConstraints.weighty = 0.0;
 
  193         gridBagConstraints.weightx = TEXT_WEIGHT_X;    
 
  194         gridBagConstraints.fill = GridBagConstraints.NONE;
 
  195         gridBagConstraints.insets = ZERO_INSETS;
 
  201         return (artifact != null)
 
  202                 && (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()
 
  203                 || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()
 
  204                 || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()
 
  205                 || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()
 
  206                 || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
 
  207                 || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID()
 
  208                 || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_ACCOUNT_TYPE.getTypeID()
 
  209                 || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()
 
  210                 || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL.getTypeID());
 
  213     @NbBundle.Messages({
"GeneralPurposeArtifactViewer.details.attrHeader=Details",
 
  214         "GeneralPurposeArtifactViewer.details.sourceHeader=Source",
 
  215         "GeneralPurposeArtifactViewer.details.dataSource=Data Source",
 
  216         "GeneralPurposeArtifactViewer.details.file=File",
 
  217         "GeneralPurposeArtifactViewer.details.datesHeader=Dates"})
 
  223     @SuppressWarnings(
"unchecked")
 
  227         detailsScrollPane = 
new javax.swing.JScrollPane();
 
  229         detailsScrollPane.setPreferredSize(
new java.awt.Dimension(300, 0));
 
  231         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  232         this.setLayout(layout);
 
  233         layout.setHorizontalGroup(
 
  234             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  235             .addComponent(detailsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  237         layout.setVerticalGroup(
 
  238             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  239             .addGroup(layout.createSequentialGroup()
 
  240                 .addComponent(detailsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  255     @NbBundle.Messages({
"GeneralPurposeArtifactViewer.dates.created=Created",
 
  256         "GeneralPurposeArtifactViewer.dates.start=Start",
 
  257         "GeneralPurposeArtifactViewer.dates.end=End",
 
  258         "GeneralPurposeArtifactViewer.dates.time=Time",
 
  259         "GeneralPurposeArtifactViewer.term.label=Term",
 
  260         "GeneralPurposeArtifactViewer.details.otherHeader=Other",
 
  261         "GeneralPurposeArtifactViewer.noFile.text= (no longer exists)"})
 
  263     private void updateView(BlackboardArtifact artifact, Map<Integer, List<BlackboardAttribute>> attributeMap, String dataSourceName, String sourceFilePath) {
 
  264         final Integer artifactTypeId = artifact.getArtifactTypeID();
 
  265         if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) {
 
  266             JTextPane firstTextPane = addDetailsHeader(artifactTypeId);
 
  267             Integer[] orderingArray = orderingMap.get(artifactTypeId);
 
  268             if (orderingArray == null) {
 
  269                 orderingArray = DEFAULT_ORDERING;
 
  271             for (Integer attrId : orderingArray) {
 
  272                 List<BlackboardAttribute> attrList = attributeMap.remove(attrId);
 
  273                 if (attrList != null) {
 
  274                     for (BlackboardAttribute bba : attrList) {
 
  275                         if (bba.getAttributeType().getTypeName().startsWith(
"TSK_DATETIME")) {
 
  276                             if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
 
  281                         } 
else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID() && artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
 
  282                             addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString());
 
  283                         } 
else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()) {
 
  284                             String displayString = bba.getDisplayString();
 
  285                             if (!attributeMap.containsKey(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID())) {
 
  286                                 displayString += Bundle.GeneralPurposeArtifactViewer_noFile_text();
 
  288                             addNameValueRow(bba.getAttributeType().getDisplayName(), displayString);
 
  290                             addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
 
  295             if (TYPES_WITH_DATE_SECTION.contains(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID())) {
 
  296                 boolean headerAdded = 
false;
 
  297                 headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_created(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()), headerAdded);
 
  298                 headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_start(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()), headerAdded);
 
  299                 headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_end(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()), headerAdded);
 
  300                 addDates(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getDisplayName(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()), headerAdded);
 
  302             if (!attributeMap.keySet().isEmpty()) {
 
  303                 addHeader(Bundle.GeneralPurposeArtifactViewer_details_otherHeader());
 
  304                 for (
int key : attributeMap.keySet()) {
 
  305                     for (BlackboardAttribute bba : attributeMap.get(key)) {
 
  306                         if (bba.getAttributeType().getTypeName().startsWith(
"TSK_DATETIME")) {
 
  309                             addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
 
  314             addHeader(Bundle.GeneralPurposeArtifactViewer_details_sourceHeader());
 
  315             addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_dataSource(), dataSourceName);
 
  316             addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_file(), sourceFilePath);
 
  319             if (firstTextPane != null) {
 
  320                 firstTextPane.setCaretPosition(0);
 
  323         detailsPanel.revalidate();
 
  336     private boolean addDates(String label, List<BlackboardAttribute> attrList, 
boolean headerExists) {
 
  337         boolean headerAdded = headerExists;
 
  338         if (attrList != null) {
 
  340                 addHeader(Bundle.GeneralPurposeArtifactViewer_details_datesHeader());
 
  343             String labelToUse = label;
 
  344             for (BlackboardAttribute bba : attrList) {
 
  345                 if (StringUtils.isBlank(label)) {
 
  346                     labelToUse = bba.getAttributeType().getDisplayName();
 
  348                 addNameValueRow(labelToUse, bba.getDisplayString());
 
  359     @NbBundle.Messages({
"GeneralPurposeArtifactViewer.details.bookmarkHeader=Bookmark Details",
 
  360         "GeneralPurposeArtifactViewer.details.historyHeader=Visit Details",
 
  361         "GeneralPurposeArtifactViewer.details.downloadHeader=Downloaded File",
 
  362         "GeneralPurposeArtifactViewer.details.searchHeader=Web Search",
 
  363         "GeneralPurposeArtifactViewer.details.cachedHeader=Cached File",
 
  364         "GeneralPurposeArtifactViewer.details.cookieHeader=Cookie Details",})
 
  367         if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
 
  368             header = Bundle.GeneralPurposeArtifactViewer_details_historyHeader();
 
  369         } 
else if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
 
  370             header = Bundle.GeneralPurposeArtifactViewer_details_bookmarkHeader();
 
  371         } 
else if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID()) {
 
  372             header = Bundle.GeneralPurposeArtifactViewer_details_cachedHeader();
 
  373         } 
else if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
 
  374             header = Bundle.GeneralPurposeArtifactViewer_details_cookieHeader();
 
  375         } 
else if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
 
  376             header = Bundle.GeneralPurposeArtifactViewer_details_downloadHeader();
 
  377         } 
else if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
 
  378             header = Bundle.GeneralPurposeArtifactViewer_details_searchHeader();
 
  380             header = Bundle.GeneralPurposeArtifactViewer_details_attrHeader();
 
  382         return addHeader(header);
 
  393     private JTextPane addHeader(String headerString) {
 
  395         javax.swing.JTextPane headingLabel = 
new javax.swing.JTextPane();
 
  396         headingLabel.setOpaque(
false);
 
  397         headingLabel.setFocusable(
false);
 
  398         headingLabel.setEditable(
false);
 
  401         gridBagConstraints.insets = (gridBagConstraints.gridy == 0) 
 
  402                 ? FIRST_HEADER_INSETS
 
  405         gridBagConstraints.gridy++;
 
  406         gridBagConstraints.gridx = LABEL_COLUMN;;
 
  408         gridBagConstraints.gridwidth = MAX_COLS;
 
  410         headingLabel.setText(headerString);
 
  413         headingLabel.setMargin(ZERO_INSETS);
 
  415         addToPanel(headingLabel);
 
  417         gridBagConstraints.gridwidth = LABEL_WIDTH;
 
  420         gridBagConstraints.insets = ZERO_INSETS;
 
  432         addKeyAtCol(keyString);
 
  433         return addValueAtCol(valueString);
 
  442         gridBagConstraints.gridx = MAX_COLS;
 
  443         gridBagConstraints.weightx = GLUE_WEIGHT_X; 
 
  444         gridBagConstraints.fill = GridBagConstraints.BOTH;
 
  445         javax.swing.Box.Filler horizontalFiller = 
new javax.swing.Box.Filler(
new Dimension(0, 0), 
new Dimension(0, 0), 
new Dimension(32767, 0));
 
  447         addToPanel(horizontalFiller);
 
  449         gridBagConstraints.fill = GridBagConstraints.NONE;
 
  450         gridBagConstraints.weightx = TEXT_WEIGHT_X;
 
  458         gridBagConstraints.weighty = 1.0; 
 
  459         gridBagConstraints.fill = GridBagConstraints.VERTICAL;
 
  460         javax.swing.Box.Filler vertFiller = 
new javax.swing.Box.Filler(
new Dimension(0, 0), 
new Dimension(0, 0), 
new Dimension(0, 32767));
 
  462         addToPanel(vertFiller);
 
  474         javax.swing.JLabel keyLabel = 
new javax.swing.JLabel();
 
  475         keyLabel.setFocusable(
false);
 
  476         gridBagConstraints.gridy++;
 
  477         gridBagConstraints.insets = KEY_COLUMN_INSETS;
 
  478         gridBagConstraints.gridx = LABEL_COLUMN;
 
  479         gridBagConstraints.gridwidth = LABEL_WIDTH;
 
  481         keyLabel.setText(keyString + 
": ");
 
  483         addToPanel(keyLabel);
 
  488         detailsPanel.add(comp, gridBagConstraints);
 
  489         detailsPanel.revalidate();
 
  501         JTextPane valueField = 
new JTextPane();
 
  502         valueField.setFocusable(
false);
 
  503         valueField.setEditable(
false);
 
  504         valueField.setOpaque(
false);
 
  505         valueField.setMargin(ZERO_INSETS);
 
  506         gridBagConstraints.gridx = VALUE_COLUMN;
 
  507         gridBagConstraints.insets = VALUE_COLUMN_INSETS;
 
  508         GridBagConstraints cloneConstraints = (GridBagConstraints) gridBagConstraints.clone();
 
  510         cloneConstraints.gridwidth = VALUE_WIDTH;
 
  511         cloneConstraints.fill = GridBagConstraints.BOTH;
 
  513         valueField.setText(valueString);
 
  515         valueField.addMouseListener(
new java.awt.event.MouseAdapter() {
 
  517             public void mouseClicked(java.awt.event.MouseEvent evt) {
 
  518                 valueLabelMouseClicked(evt, valueField);
 
  522         detailsPanel.add(valueField, cloneConstraints);
 
  537         "GeneralPurposeArtifactViewer_menuitem_copy=Copy" 
  540         if (SwingUtilities.isRightMouseButton(evt)) {
 
  541             JPopupMenu popup = 
new JPopupMenu();
 
  542             JMenuItem copyMenu = 
new JMenuItem(Bundle.CommunicationArtifactViewerHelper_menuitem_copy()); 
 
  543             copyMenu.addActionListener(
new ActionListener() {
 
  545                 public void actionPerformed(ActionEvent e) {
 
  546                     Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
new StringSelection(valueLabel.getText()), null);
 
  550             popup.show(valueLabel, evt.getX(), evt.getY());
 
void setArtifact(BlackboardArtifact artifact)
 
void updateView(BlackboardArtifact artifact, Map< Integer, List< BlackboardAttribute >> attributeMap, String dataSourceName, String sourceFilePath)
 
static Integer getLineSpacing()
 
JTextPane addNameValueRow(String keyString, String valueString)
 
static String getFormattedTime(long epochTime)
 
void addToPanel(Component comp)
 
static Insets getPanelInsets()
 
void valueLabelMouseClicked(java.awt.event.MouseEvent evt, JTextPane valueLabel)
 
static Integer getSectionIndent()
 
boolean addDates(String label, List< BlackboardAttribute > attrList, boolean headerExists)
 
JTextPane addValueAtCol(String valueString)
 
boolean isSupported(BlackboardArtifact artifact)
 
static Font getHeaderFont()
 
javax.swing.JScrollPane detailsScrollPane
 
JTextPane addDetailsHeader(int artifactTypeId)
 
static int getColumnSpacing()
 
static Integer getSectionSpacing()
 
synchronized static Logger getLogger(String name)
 
JLabel addKeyAtCol(String keyString)