/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 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.actions;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.table.AbstractTableModel;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
public class GetTagNameDialog extends JDialog {
private static final long serialVersionUID = 1L;
private static final String TAG_ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS
private final Map<String, TagName> tagNamesMap = new TreeMap<>();
private TagName tagName = null;
/**
* Show the Tag Name Dialog and return the TagName selected by the user. The
* dialog will be centered with the main autopsy window as its owner. To set
* another window as the owner use doDialog(Window) instead.
*
* @return a TagName instance selected by the user, or null if the user
* canceled the dialog.
*/
public static TagName doDialog() {
return doDialog(WindowManager.getDefault().getMainWindow());
}
/**
* Show the Tag Name Dialog and return the TagName selected by the user.
*
* @param owner the window that will be the owner of the dialog. The dialog
* will be centered over this window and will block the rest of
* the application.
*
* @return a TagName instance selected by the user, or null if the user
* canceled the dialog.
*/
public static TagName doDialog(Window owner) {
GetTagNameDialog dialog = new GetTagNameDialog(owner);
dialog.display();
return dialog.tagName;
}
private GetTagNameDialog(Window owner) {
super(owner,
NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.createTag"),
ModalityType.APPLICATION_MODAL);
}
private void display() {
setIconImage(ImageUtilities.loadImage(TAG_ICON_PATH));
initComponents();
// Set up the dialog to close when Esc is pressed.
String cancelName = NbBundle.getMessage(this.getClass(), "GetTagNameDialog.cancelName");
InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName);
ActionMap actionMap = getRootPane().getActionMap();
actionMap.put(cancelName, new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
cancelButtonActionPerformed(e);
}
});
// Get the current set of tag names and hash them for a speedy lookup in
// case the user chooses an existing tag name from the tag names table.
TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
try {
tagNamesMap.putAll(tagsManager.getDisplayNamesToTagNamesMap());
} catch (TskCoreException ex) {
Logger.getLogger(GetTagNameDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
}
// Populate the tag names table.
tagsTable.setModel(new TagsTableModel(new ArrayList<>(tagNamesMap.keySet())));
tagsTable.setTableHeader(null);
tagsTable.setCellSelectionEnabled(false);
tagsTable.setFocusable(false);
tagsTable.setRowHeight(tagsTable.getRowHeight() + 5);
// Center and show the dialog box.
this.setLocationRelativeTo(this.getOwner());
setVisible(true);
}
private class TagsTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private final ArrayList<String> tagDisplayNames = new ArrayList<>();
TagsTableModel(List<String> tagDisplayNames) {
for (String tagDisplayName : tagDisplayNames) {
this.tagDisplayNames.add(tagDisplayName);
}
}
@Override
public int getRowCount() {
return tagDisplayNames.size();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public String getValueAt(int rowIndex, int columnIndex) {
return tagDisplayNames.get(rowIndex);
}
}
/**
* 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.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
cancelButton = new javax.swing.JButton();
okButton = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
tagsTable = new javax.swing.JTable();
preexistingLabel = new javax.swing.JLabel();
newTagPanel = new javax.swing.JPanel();
tagNameLabel = new javax.swing.JLabel();
tagNameField = new javax.swing.JTextField();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
formKeyReleased(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.cancelButton.text")); // NOI18N
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.okButton.text")); // NOI18N
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okButtonActionPerformed(evt);
}
});
jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
tagsTable.setBackground(new java.awt.Color(240, 240, 240));
tagsTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
}
));
tagsTable.setShowHorizontalLines(false);
tagsTable.setShowVerticalLines(false);
tagsTable.setTableHeader(null);
jScrollPane1.setViewportView(tagsTable);
org.openide.awt.Mnemonics.setLocalizedText(preexistingLabel, org.openide.util.NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.preexistingLabel.text")); // NOI18N
newTagPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.newTagPanel.border.title"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(tagNameLabel, org.openide.util.NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.tagNameLabel.text")); // NOI18N
tagNameField.setText(org.openide.util.NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.tagNameField.text")); // NOI18N
tagNameField.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
tagNameFieldKeyReleased(evt);
}
});
javax.swing.GroupLayout newTagPanelLayout = new javax.swing.GroupLayout(newTagPanel);
newTagPanel.setLayout(newTagPanelLayout);
newTagPanelLayout.setHorizontalGroup(
newTagPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(newTagPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(tagNameLabel)
.addGap(36, 36, 36)
.addComponent(tagNameField, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
.addContainerGap())
);
newTagPanelLayout.setVerticalGroup(
newTagPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(newTagPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(newTagPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(tagNameLabel)
.addComponent(tagNameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(164, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 198, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(preexistingLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0, 233, Short.MAX_VALUE)
.addComponent(okButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(cancelButton))
.addComponent(newTagPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(preexistingLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
.addComponent(newTagPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cancelButton)
.addComponent(okButton))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
tagName = null;
dispose();
}//GEN-LAST:event_cancelButtonActionPerformed
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
String tagDisplayName = tagNameField.getText();
if (tagDisplayName.isEmpty()) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"GetTagNameDialog.mustSupplyTtagName.msg"),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.tagNameErr"),
JOptionPane.ERROR_MESSAGE);
} else if (TagsManager.containsIllegalCharacters(tagDisplayName)) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.illegalChars.msg"),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.illegalCharsErr"),
JOptionPane.ERROR_MESSAGE);
} else {
tagName = tagNamesMap.get(tagDisplayName);
if (tagName == null) {
try {
tagName = Case.getCurrentCase().getServices().getTagsManager().addTagName(tagDisplayName);
dispose();
} catch (TskCoreException ex) {
Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, "Error adding " + tagDisplayName + " tag name", ex); //NON-NLS
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"GetTagNameDialog.unableToAddTagNameToCase.msg",
tagDisplayName),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.taggingErr"),
JOptionPane.ERROR_MESSAGE);
tagName = null;
} catch (TagsManager.TagNameAlreadyExistsException ex) {
try {
tagName = Case.getCurrentCase().getServices().getTagsManager().getDisplayNamesToTagNamesMap().get(tagDisplayName);
} catch (TskCoreException ex1) {
Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, tagDisplayName + " exists in database but an error occurred in retrieving it.", ex1); //NON-NLS
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"GetTagNameDialog.tagNameExistsTskCore.msg",
tagDisplayName),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.dupTagErr"),
JOptionPane.ERROR_MESSAGE);
tagName = null;
}
}
} else {
dispose();
}
}
}//GEN-LAST:event_okButtonActionPerformed
private void formKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_formKeyReleased
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
okButtonActionPerformed(null);
}
}//GEN-LAST:event_formKeyReleased
private void tagNameFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tagNameFieldKeyReleased
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
okButtonActionPerformed(null);
}
}//GEN-LAST:event_tagNameFieldKeyReleased
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton cancelButton;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JPanel newTagPanel;
private javax.swing.JButton okButton;
private javax.swing.JLabel preexistingLabel;
private javax.swing.JTextField tagNameField;
private javax.swing.JLabel tagNameLabel;
private javax.swing.JTable tagsTable;
// End of variables declaration//GEN-END:variables
}