From 365a5165819b085ae4c0db630f7fb5573955e904 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 23 Aug 2016 10:59:37 -0400 Subject: [PATCH 01/19] Edited TagsManager to include deletion and created TagsManagerPanel --- .../casemodule/services/TagsManager.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index e8d61bdeba..318b4ce75f 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -184,6 +184,28 @@ public class TagsManager implements Closeable { return newTagName; } + + /** + * Deletes a tag name from the tags settings. + * + * @param displayName The display name for the tag name to be deleted. + * + * @throws TagNameDoesNotExistException + * + * @throws TskCoreException + */ + public synchronized void deleteTagName(String displayName) throws TagNameDoesNotExistException, TskCoreException { + if (null == caseDb) { + throw new TskCoreException("Tags manager has been closed"); + } + lazyLoadExistingTagNames(); + if (!uniqueTagNames.containsKey(displayName)) { + throw new TagNameDoesNotExistException(); + } else { + uniqueTagNames.remove(displayName); + saveTagNamesToTagsSettings(); + } + } /** * Tags a content object. @@ -582,7 +604,7 @@ public class TagsManager implements Closeable { */ private void lazyLoadExistingTagNames() { if (!tagNamesLoaded) { - addTagNamesFromCurrentCase(); + //addTagNamesFromCurrentCase(); addTagNamesFromTagsSettings(); addPredefinedTagNames(); saveTagNamesToTagsSettings(); @@ -673,5 +695,12 @@ public class TagsManager implements Closeable { private static final long serialVersionUID = 1L; } + + /** + * Exception thrown if there is an attempt to delete a nonexistent tag name. + */ + public static class TagNameDoesNotExistException extends Exception { + + } } From 395a8da587e73e20cc47793fc1487138eb25f26a Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 23 Aug 2016 15:14:00 -0400 Subject: [PATCH 02/19] Implemented basic methods in TagsManagerPanel --- .../casemodule/services/TagsManagerPanel.form | 224 ++++++++++++ .../casemodule/services/TagsManagerPanel.java | 333 ++++++++++++++++++ 2 files changed, 557 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.form create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.form new file mode 100755 index 0000000000..572b3b37c8 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.form @@ -0,0 +1,224 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.java new file mode 100755 index 0000000000..dc828dec3f --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.java @@ -0,0 +1,333 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.casemodule.services; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.TreeSet; +import java.util.logging.Level; +import javax.swing.DefaultListModel; +import org.netbeans.spi.options.OptionsPanelController; +import org.sleuthkit.autopsy.corecomponents.OptionsPanel; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.ModuleSettings; + +/** + * + * @author smori + */ +public class TagsManagerPanel extends javax.swing.JPanel implements OptionsPanel { + + private static final String TAG_NAME_EMPTY = "Tag name text is empty."; + private static final String TAG_NAME_ALREADY_EXISTS = "Tag name already exists."; + private static final String TAG_NAME_COMMA = "Tag name may not contain commas."; + + private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS + private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS + + private static final String DEFAULT_DESCRIPTION = ""; + private static final String DEFAULT_COLOR_STRING = "NONE"; + + private final DefaultListModel tagNamesListModel; + private final Set tagNames; + + /** + * Creates new form TagsManagerPanel + */ + public TagsManagerPanel() { + tagNamesListModel = new DefaultListModel<>(); + tagNamesList.setModel(tagNamesListModel); + tagNames = new TreeSet<>(); + + initComponents(); + customizeComponents(); + } + + private void customizeComponents() { + addTagNamesFromTagsSettings(); + + } + + private void addTagNamesFromTagsSettings() { + String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); + if ((setting != null) && !setting.isEmpty()) { + List tagNameTuples = Arrays.asList(setting.split(";")); + for (String tagNameTuple : tagNameTuples) { + String[] tagNameAttributes = tagNameTuple.split(","); + CustomTagName tagName = new CustomTagName(tagNameAttributes[0], tagNameAttributes[1], tagNameAttributes[2]); + tagNames.add(tagName); + } + } + } + + private void updateTagNamesListModel() { + tagNamesListModel.clear(); + tagNames.stream().forEach((tagName) -> { + tagNamesListModel.addElement(tagName); + }); + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jSplitPane1 = new javax.swing.JSplitPane(); + jPanel2 = new javax.swing.JPanel(); + tagNamesListLabel = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + tagNamesList = new javax.swing.JList<>(); + userTagNameTextField = new javax.swing.JTextField(); + addTagNameButton = new javax.swing.JButton(); + deleteTagNameButton = new javax.swing.JButton(); + tagNameErrLabel = new javax.swing.JLabel(); + jPanel3 = new javax.swing.JPanel(); + + jPanel1.setPreferredSize(new java.awt.Dimension(750, 500)); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.jLabel1.text")); // NOI18N + + jSplitPane1.setDividerLocation(-100); + jSplitPane1.setDividerSize(1); + + org.openide.awt.Mnemonics.setLocalizedText(tagNamesListLabel, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.tagNamesListLabel.text")); // NOI18N + + jScrollPane1.setViewportView(tagNamesList); + + userTagNameTextField.setText(org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.userTagNameTextField.text")); // NOI18N + + addTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(addTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.addTagNameButton.text")); // NOI18N + addTagNameButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addTagNameButtonActionPerformed(evt); + } + }); + + deleteTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete16.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(deleteTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.deleteTagNameButton.text")); // NOI18N + deleteTagNameButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + deleteTagNameButtonActionPerformed(evt); + } + }); + + tagNameErrLabel.setForeground(new java.awt.Color(255, 0, 0)); + org.openide.awt.Mnemonics.setLocalizedText(tagNameErrLabel, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.tagNameErrLabel.text")); // NOI18N + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(tagNameErrLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jScrollPane1) + .addComponent(tagNamesListLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addComponent(userTagNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 135, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(addTagNameButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(deleteTagNameButton))) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(tagNamesListLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 374, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(userTagNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(addTagNameButton) + .addComponent(deleteTagNameButton)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(tagNameErrLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + jSplitPane1.setLeftComponent(jPanel2); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 330, Short.MAX_VALUE) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 456, Short.MAX_VALUE) + ); + + jSplitPane1.setRightComponent(jPanel3); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jSplitPane1) + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSplitPane1) + .addContainerGap()) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 778, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void addTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTagNameButtonActionPerformed + String newTagName = userTagNameTextField.getText(); + + if (newTagName.isEmpty()) { + tagNameErrLabel.setText(TAG_NAME_EMPTY); + return; + } + if (newTagName.contains(",")) { + tagNameErrLabel.setText(TAG_NAME_COMMA); + return; + } + + CustomTagName tagName = new CustomTagName(newTagName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); + boolean added = tagNames.add(tagName); + if (!added) { + tagNameErrLabel.setText(TAG_NAME_ALREADY_EXISTS); + return; + } + + updateTagNamesListModel(); + userTagNameTextField.setText(""); + tagNameErrLabel.setText(""); + + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_addTagNameButtonActionPerformed + + private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed + CustomTagName tagName = tagNamesList.getSelectedValue(); + tagNames.remove(tagName); + updateTagNamesListModel(); + + if (!tagNamesListModel.isEmpty()) { + tagNamesList.setSelectedIndex(0); + } + + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_deleteTagNameButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addTagNameButton; + private javax.swing.JButton deleteTagNameButton; + private javax.swing.JLabel jLabel1; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JLabel tagNameErrLabel; + private javax.swing.JList tagNamesList; + private javax.swing.JLabel tagNamesListLabel; + private javax.swing.JTextField userTagNameTextField; + // End of variables declaration//GEN-END:variables + + @Override + public void store() { + if (!tagNames.isEmpty()) { + StringBuilder builder = new StringBuilder(); + for (CustomTagName tagName : tagNames) { + if (builder.length() != 0) { + builder.append(";"); + } + builder.append(tagName.toString()); + } + ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, builder.toString()); + } + } + + @Override + public void load() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + /** + * TagName constructor is not public, CustomTagName is for the purposes of + * preserving description and color information that may be in the user tags + * settings files. + */ + private class CustomTagName implements Comparable { + private final String displayName; + private final String description; + private final String colorName; + + private CustomTagName(String displayName, String description, String colorName) { + this.displayName = displayName; + this.description = description; + this.colorName = colorName; + } + + private String getDisplayName() { + return displayName; + } + + @Override + public int compareTo(CustomTagName other) { + return this.getDisplayName().compareTo(other.getDisplayName()); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 83 * hash + Objects.hashCode(this.displayName); + hash = 83 * hash + Objects.hashCode(this.description); + hash = 83 * hash + Objects.hashCode(this.colorName); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CustomTagName)) return false; + CustomTagName thatTagName = (CustomTagName) obj; + return this.getDisplayName().equals(thatTagName.getDisplayName()); + } + + @Override + public String toString() { + return displayName + "," + description + "," + colorName; + } + + } +} From 0c484350ebb025ac3e1db8fe1c90c21ca1626fdb Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 23 Aug 2016 15:24:07 -0400 Subject: [PATCH 03/19] Renamed TagsManagerPanel to TagsManagerOptionsPanel --- ...anel.form => TagsManagerOptionsPanel.form} | 12 +++++----- ...anel.java => TagsManagerOptionsPanel.java} | 22 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{TagsManagerPanel.form => TagsManagerOptionsPanel.form} (91%) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{TagsManagerPanel.java => TagsManagerOptionsPanel.java} (92%) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form similarity index 91% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.form rename to Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form index 572b3b37c8..a0ea7e8def 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form @@ -65,7 +65,7 @@ - + @@ -128,7 +128,7 @@ - + @@ -154,7 +154,7 @@ - + @@ -164,7 +164,7 @@ - + @@ -177,7 +177,7 @@ - + @@ -190,7 +190,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java similarity index 92% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.java rename to Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java index dc828dec3f..19ec12c104 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java @@ -21,7 +21,7 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; * * @author smori */ -public class TagsManagerPanel extends javax.swing.JPanel implements OptionsPanel { +public class TagsManagerOptionsPanel extends javax.swing.JPanel implements OptionsPanel { private static final String TAG_NAME_EMPTY = "Tag name text is empty."; private static final String TAG_NAME_ALREADY_EXISTS = "Tag name already exists."; @@ -39,7 +39,7 @@ public class TagsManagerPanel extends javax.swing.JPanel implements OptionsPanel /** * Creates new form TagsManagerPanel */ - public TagsManagerPanel() { + public TagsManagerOptionsPanel() { tagNamesListModel = new DefaultListModel<>(); tagNamesList.setModel(tagNamesListModel); tagNames = new TreeSet<>(); @@ -96,19 +96,19 @@ public class TagsManagerPanel extends javax.swing.JPanel implements OptionsPanel jPanel1.setPreferredSize(new java.awt.Dimension(750, 500)); - org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.jLabel1.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.jLabel1.text")); // NOI18N jSplitPane1.setDividerLocation(-100); jSplitPane1.setDividerSize(1); - org.openide.awt.Mnemonics.setLocalizedText(tagNamesListLabel, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.tagNamesListLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(tagNamesListLabel, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.tagNamesListLabel.text")); // NOI18N jScrollPane1.setViewportView(tagNamesList); - userTagNameTextField.setText(org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.userTagNameTextField.text")); // NOI18N + userTagNameTextField.setText(org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.userTagNameTextField.text")); // NOI18N addTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(addTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.addTagNameButton.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(addTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.text")); // NOI18N addTagNameButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addTagNameButtonActionPerformed(evt); @@ -116,7 +116,7 @@ public class TagsManagerPanel extends javax.swing.JPanel implements OptionsPanel }); deleteTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete16.png"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(deleteTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.deleteTagNameButton.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(deleteTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.deleteTagNameButton.text")); // NOI18N deleteTagNameButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteTagNameButtonActionPerformed(evt); @@ -124,7 +124,7 @@ public class TagsManagerPanel extends javax.swing.JPanel implements OptionsPanel }); tagNameErrLabel.setForeground(new java.awt.Color(255, 0, 0)); - org.openide.awt.Mnemonics.setLocalizedText(tagNameErrLabel, org.openide.util.NbBundle.getMessage(TagsManagerPanel.class, "TagsManagerPanel.tagNameErrLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(tagNameErrLabel, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.tagNameErrLabel.text")); // NOI18N javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); @@ -284,9 +284,9 @@ public class TagsManagerPanel extends javax.swing.JPanel implements OptionsPanel } /** - * TagName constructor is not public, CustomTagName is for the purposes of - * preserving description and color information that may be in the user tags - * settings files. + * Because TagName constructor is not public, CustomTagName is used in this + * tags managers panel for the purpose of preserving description and color + * information that is tracked by the user tag settings file. */ private class CustomTagName implements Comparable { private final String displayName; From 791135b6d869d9c4a6c66bcb843280918eae79fd Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 23 Aug 2016 17:22:12 -0400 Subject: [PATCH 04/19] Added PanelController, fixed messages and text, fixed mismatching bugs --- .../casemodule/services/Bundle.properties | 11 ++ .../services/TagsManagerOptionsPanel.java | 43 ++++---- .../TagsManagerOptionsPanelController.java | 101 ++++++++++++++++++ 3 files changed, 137 insertions(+), 18 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index 1a3be9454f..cfaaa7bb20 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -1,3 +1,5 @@ +OptionsCategory_Name_TagsManager=Tags Manager +OptionsCategory_Keywords_TagsManager=TagsManager TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} out of content size range (0 - {1}) TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} out of content size range (0 - {1}) TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset @@ -7,3 +9,12 @@ TagsManager.deleteContentTag.noCaseWarning=Failed to publish content tag deleted TagsManager.addBlackboardArtifactTag.noCaseWarning=Failed to publish new blackboard artifact tag event. There is no case open. TagsManager.deleteBlackboardArtifactTag.noCaseWarning=Failed to publish blackboard artifact tag deleted event. There is no case open. Blackboard.unableToIndexArtifact.error.msg=Unable to index blackboard artifact {0} +TagsManagerOptionsPanel.addTagNameButton.empty=Tag name text is empty. +TagsManagerOptionsPanel.addTagNameButton.containComma=Tag name may not contain commas. +TagsManagerOptionsPanel.addTagNameButton.alreadyExists=Tag name already exists. +TagsManagerOptionsPanel.jLabel1.text=Autopsy keeps a list of the tag names you have used in the past. Add more or delete them here. +TagsManagerOptionsPanel.tagNamesListLabel.text=\ +TagsManagerOptionsPanel.userTagNameTextField.text=\ +TagsManagerOptionsPanel.addTagNameButton.text=Add Tag Name +TagsManagerOptionsPanel.deleteTagNameButton.text=Delete Tag Name +TagsManagerOptionsPanel.tagNameErrLabel.text=\ \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java index 19ec12c104..e0c90f8eee 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java @@ -13,6 +13,7 @@ import java.util.TreeSet; import java.util.logging.Level; import javax.swing.DefaultListModel; import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; @@ -23,10 +24,6 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; */ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements OptionsPanel { - private static final String TAG_NAME_EMPTY = "Tag name text is empty."; - private static final String TAG_NAME_ALREADY_EXISTS = "Tag name already exists."; - private static final String TAG_NAME_COMMA = "Tag name may not contain commas."; - private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS @@ -40,17 +37,19 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio * Creates new form TagsManagerPanel */ public TagsManagerOptionsPanel() { + initComponents(); + tagNamesListModel = new DefaultListModel<>(); tagNamesList.setModel(tagNamesListModel); tagNames = new TreeSet<>(); - initComponents(); customizeComponents(); } private void customizeComponents() { addTagNamesFromTagsSettings(); + tagNameErrLabel.setText(""); } private void addTagNamesFromTagsSettings() { @@ -214,18 +213,18 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio String newTagName = userTagNameTextField.getText(); if (newTagName.isEmpty()) { - tagNameErrLabel.setText(TAG_NAME_EMPTY); + tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.empty")); return; } if (newTagName.contains(",")) { - tagNameErrLabel.setText(TAG_NAME_COMMA); + tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.containComma")); return; } CustomTagName tagName = new CustomTagName(newTagName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); boolean added = tagNames.add(tagName); if (!added) { - tagNameErrLabel.setText(TAG_NAME_ALREADY_EXISTS); + tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.alreadyExists")); return; } @@ -238,14 +237,16 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed CustomTagName tagName = tagNamesList.getSelectedValue(); - tagNames.remove(tagName); - updateTagNamesListModel(); - - if (!tagNamesListModel.isEmpty()) { - tagNamesList.setSelectedIndex(0); + if (tagName != null) { + tagNames.remove(tagName); + updateTagNamesListModel(); + + if (!tagNamesListModel.isEmpty()) { + tagNamesList.setSelectedIndex(0); + } + + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } - - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_deleteTagNameButtonActionPerformed @@ -272,7 +273,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio if (builder.length() != 0) { builder.append(";"); } - builder.append(tagName.toString()); + builder.append(tagName.toSettingsFormat()); } ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, builder.toString()); } @@ -280,7 +281,9 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio @Override public void load() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + addTagNamesFromTagsSettings(); + updateTagNamesListModel(); + //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } /** @@ -305,7 +308,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio @Override public int compareTo(CustomTagName other) { - return this.getDisplayName().compareTo(other.getDisplayName()); + return this.getDisplayName().toLowerCase().compareTo(other.getDisplayName().toLowerCase()); } @Override @@ -326,6 +329,10 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio @Override public String toString() { + return displayName; + } + + public String toSettingsFormat() { return displayName + "," + description + "," + colorName; } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java new file mode 100755 index 0000000000..00e461262d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java @@ -0,0 +1,101 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.casemodule.services; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import javax.swing.JComponent; +import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.HelpCtx; +import org.openide.util.Lookup; + +@OptionsPanelController.TopLevelRegistration( + categoryName = "#OptionsCategory_Name_TagsManager", + iconBase = "org/sleuthkit/autopsy/modules/filetypeid/user-defined-file-types-settings.png", + keywords = "#OptionsCategory_Keywords_TagsManager", + keywordsCategory = "TagsManager", + position = 10 +) +public final class TagsManagerOptionsPanelController extends OptionsPanelController { + + private TagsManagerOptionsPanel panel; + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + private boolean changed; + + @Override + public void update() { + getPanel().load(); + changed = false; + } + + @Override + public void applyChanges() { + if (changed) { + getPanel().store(); + changed = false; + } + } + + @Override + public void cancel() { + //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public boolean isValid() { + return true; + //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public boolean isChanged() { + return changed; + } + + @Override + public JComponent getComponent(Lookup lkp) { + return getPanel(); + } + + @Override + public HelpCtx getHelpCtx() { + return null; + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener l) { + pcs.addPropertyChangeListener(l); + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener l) { + pcs.removePropertyChangeListener(l); + } + + private TagsManagerOptionsPanel getPanel() { + if (panel == null) { + panel = new TagsManagerOptionsPanel(); + panel.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(OptionsPanelController.PROP_CHANGED)) { + changed(); + } + } + }); + } + return panel; + } + + void changed() { + if (!changed) { + changed = true; + pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); + } + pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); + } +} From 5faaeb06ef88c181566ff70f548dd3e0e628e8da Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Wed, 24 Aug 2016 14:38:52 -0400 Subject: [PATCH 05/19] Fixed properties file behavior, TODO: deleted tag names not appear in quick tag --- .../casemodule/services/Bundle.properties | 6 +- .../casemodule/services/TagsManager.java | 27 +++++++-- .../services/TagsManagerOptionsPanel.java | 55 +++++++++++-------- .../TagsManagerOptionsPanelController.java | 5 +- 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index cfaaa7bb20..6e35787c25 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -13,8 +13,8 @@ TagsManagerOptionsPanel.addTagNameButton.empty=Tag name text is empty. TagsManagerOptionsPanel.addTagNameButton.containComma=Tag name may not contain commas. TagsManagerOptionsPanel.addTagNameButton.alreadyExists=Tag name already exists. TagsManagerOptionsPanel.jLabel1.text=Autopsy keeps a list of the tag names you have used in the past. Add more or delete them here. -TagsManagerOptionsPanel.tagNamesListLabel.text=\ -TagsManagerOptionsPanel.userTagNameTextField.text=\ +TagsManagerOptionsPanel.tagNamesListLabel.text=Your tag names: +TagsManagerOptionsPanel.userTagNameTextField.text= TagsManagerOptionsPanel.addTagNameButton.text=Add Tag Name TagsManagerOptionsPanel.deleteTagNameButton.text=Delete Tag Name -TagsManagerOptionsPanel.tagNameErrLabel.text=\ \ No newline at end of file +TagsManagerOptionsPanel.tagNameErrLabel.text= \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index 318b4ce75f..e120ca1361 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -180,8 +180,8 @@ public class TagsManager implements Closeable { * Add the tag name to the tags settings. */ uniqueTagNames.put(newTagName.getDisplayName(), newTagName); - saveTagNamesToTagsSettings(); - + addNewTagNameToTagsSettings(newTagName); + return newTagName; } @@ -585,7 +585,7 @@ public class TagsManager implements Closeable { } /** - * Closes the tags manager, saving the avaialble tag names to secondary + * Closes the tags manager, saving the available tag names to secondary * storage. * * @throws IOException If there is a problem closing the tags manager. @@ -594,7 +594,7 @@ public class TagsManager implements Closeable { @Override @Deprecated public synchronized void close() throws IOException { - saveTagNamesToTagsSettings(); + //saveTagNamesToTagsSettings(); caseDb = null; } @@ -604,10 +604,10 @@ public class TagsManager implements Closeable { */ private void lazyLoadExistingTagNames() { if (!tagNamesLoaded) { - //addTagNamesFromCurrentCase(); addTagNamesFromTagsSettings(); addPredefinedTagNames(); saveTagNamesToTagsSettings(); + addTagNamesFromCurrentCase(); tagNamesLoaded = true; } } @@ -687,7 +687,22 @@ public class TagsManager implements Closeable { ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting.toString()); } } - + + /** + * + */ + private void addNewTagNameToTagsSettings(TagName tagName) { + String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); + if (setting == null || setting.isEmpty()) { + setting = ""; + } + else { + setting += ";"; + } + setting += tagName.getDisplayName() + "," + tagName.getDescription() + "," + tagName.getColor().name(); + ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting); + } + /** * Exception thrown if there is an attempt to add a duplicate tag name. */ diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java index e0c90f8eee..a603bb3c12 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java @@ -13,10 +13,13 @@ import java.util.TreeSet; import java.util.logging.Level; import javax.swing.DefaultListModel; import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; +import org.sleuthkit.datamodel.TskCoreException; /** * @@ -31,7 +34,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio private static final String DEFAULT_COLOR_STRING = "NONE"; private final DefaultListModel tagNamesListModel; - private final Set tagNames; + private Set tagNames; /** * Creates new form TagsManagerPanel @@ -41,27 +44,23 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNamesListModel = new DefaultListModel<>(); tagNamesList.setModel(tagNamesListModel); - tagNames = new TreeSet<>(); - - customizeComponents(); - } - - private void customizeComponents() { - addTagNamesFromTagsSettings(); - + tagNames = getTagNamesFromTagsSettings(); + userTagNameTextField.setText(""); tagNameErrLabel.setText(""); } - private void addTagNamesFromTagsSettings() { + private Set getTagNamesFromTagsSettings() { + Set tagNamesFromSettings = new TreeSet<>(); String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); if ((setting != null) && !setting.isEmpty()) { List tagNameTuples = Arrays.asList(setting.split(";")); for (String tagNameTuple : tagNameTuples) { String[] tagNameAttributes = tagNameTuple.split(","); CustomTagName tagName = new CustomTagName(tagNameAttributes[0], tagNameAttributes[1], tagNameAttributes[2]); - tagNames.add(tagName); + tagNamesFromSettings.add(tagName); } } + return tagNamesFromSettings; } private void updateTagNamesListModel() { @@ -222,8 +221,8 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio } CustomTagName tagName = new CustomTagName(newTagName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); - boolean added = tagNames.add(tagName); - if (!added) { + boolean addedToTagNames = tagNames.add(tagName); + if (!addedToTagNames) { tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.alreadyExists")); return; } @@ -237,16 +236,19 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed CustomTagName tagName = tagNamesList.getSelectedValue(); - if (tagName != null) { - tagNames.remove(tagName); - updateTagNamesListModel(); + if (tagName == null) { + tagNameErrLabel.setText("No tag name selected."); + } else { + tagNames.remove(tagName); + updateTagNamesListModel(); + + + if (!tagNamesListModel.isEmpty()) { + tagNamesList.setSelectedIndex(0); + } - if (!tagNamesListModel.isEmpty()) { - tagNamesList.setSelectedIndex(0); + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } - - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - } }//GEN-LAST:event_deleteTagNameButtonActionPerformed @@ -281,9 +283,16 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio @Override public void load() { - addTagNamesFromTagsSettings(); + tagNames = getTagNamesFromTagsSettings(); updateTagNamesListModel(); - //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + if (!tagNamesListModel.isEmpty()) { + tagNamesList.setSelectedIndex(0); + } + tagNameErrLabel.setText(""); + } + + public void cancelChanges() { + tagNames = getTagNamesFromTagsSettings(); } /** diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java index 00e461262d..bb876d82df 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java @@ -42,7 +42,10 @@ public final class TagsManagerOptionsPanelController extends OptionsPanelControl @Override public void cancel() { - //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + if (changed) { + getPanel().cancelChanges(); + changed = false; + } } @Override From c6d8f07ac5338c95c7db0e8602a9c2ec1c8e1bf2 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Wed, 24 Aug 2016 14:52:35 -0400 Subject: [PATCH 06/19] Edited minor space issues --- .../sleuthkit/autopsy/casemodule/services/Bundle.properties | 2 +- .../autopsy/casemodule/services/TagsManagerOptionsPanel.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index 6e35787c25..a40e1e200f 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -10,7 +10,7 @@ TagsManager.addBlackboardArtifactTag.noCaseWarning=Failed to publish new blackbo TagsManager.deleteBlackboardArtifactTag.noCaseWarning=Failed to publish blackboard artifact tag deleted event. There is no case open. Blackboard.unableToIndexArtifact.error.msg=Unable to index blackboard artifact {0} TagsManagerOptionsPanel.addTagNameButton.empty=Tag name text is empty. -TagsManagerOptionsPanel.addTagNameButton.containComma=Tag name may not contain commas. +TagsManagerOptionsPanel.addTagNameButton.containCommaSemicolon=Tag name may not contain commas or semicolons. TagsManagerOptionsPanel.addTagNameButton.alreadyExists=Tag name already exists. TagsManagerOptionsPanel.jLabel1.text=Autopsy keeps a list of the tag names you have used in the past. Add more or delete them here. TagsManagerOptionsPanel.tagNamesListLabel.text=Your tag names: diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java index a603bb3c12..221d5f2a9f 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java @@ -215,8 +215,8 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.empty")); return; } - if (newTagName.contains(",")) { - tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.containComma")); + if (newTagName.contains(",") || newTagName.contains(";")) { + tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.containCommaSemicolon")); return; } @@ -242,7 +242,6 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNames.remove(tagName); updateTagNamesListModel(); - if (!tagNamesListModel.isEmpty()) { tagNamesList.setSelectedIndex(0); } From 452f4f66f87b10dcc6708a268173b6228e2a3880 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Thu, 25 Aug 2016 10:11:53 -0400 Subject: [PATCH 07/19] Some modifications --- .../casemodule/services/TagsManager.java | 30 +++++++- .../services/TagsManagerOptionsPanel.java | 76 +++++++++---------- 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index e120ca1361..413e1b1fe8 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -20,9 +20,13 @@ package org.sleuthkit.autopsy.casemodule.services; import java.io.Closeable; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.logging.Level; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; @@ -74,7 +78,11 @@ public class TagsManager implements Closeable { throw new TskCoreException("Tags manager has been closed"); } lazyLoadExistingTagNames(); - return caseDb.getAllTagNames(); + //return caseDb.getAllTagNames(); + Set tagNameSet = new HashSet<>(); + tagNameSet.addAll(getTagNamesInUse()); + tagNameSet.addAll(getTagNamesForPropertyFile()); + return new ArrayList<>(tagNameSet); } /** @@ -93,6 +101,26 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getTagNamesInUse(); } + + public synchronized List getTagNamesForPropertyFile() throws TskCoreException { + if (null == caseDb) { + throw new TskCoreException("Tags manager has been closed."); + } + lazyLoadExistingTagNames(); + addTagNamesFromTagsSettings(); + List propertyFileTagNames = new ArrayList<>(); + + String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); + if (null != setting && !setting.isEmpty()) { + List tagNameTuples = Arrays.asList(setting.split(";")); + for (String tagNameTuple : tagNameTuples) { + String[] tagNameAttributes = tagNameTuple.split(","); + String displayName = tagNameAttributes[0]; + propertyFileTagNames.add(uniqueTagNames.get(displayName)); + } + } + return propertyFileTagNames; + } /** * Checks whether a tag name with a given display name exists. diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java index 221d5f2a9f..7d47fcbf8a 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java @@ -1,8 +1,8 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ +* To change this license header, choose License Headers in Project Properties. +* To change this template file, choose Tools | Templates +* and open the template in the editor. +*/ package org.sleuthkit.autopsy.casemodule.services; import java.util.Arrays; @@ -26,16 +26,17 @@ import org.sleuthkit.datamodel.TskCoreException; * @author smori */ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements OptionsPanel { - + private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS private static final String DEFAULT_DESCRIPTION = ""; private static final String DEFAULT_COLOR_STRING = "NONE"; - + private final DefaultListModel tagNamesListModel; private Set tagNames; + /** * Creates new form TagsManagerPanel */ @@ -69,7 +70,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNamesListModel.addElement(tagName); }); } - + /** * 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 @@ -207,7 +208,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio .addGap(0, 0, Short.MAX_VALUE)) ); }// //GEN-END:initComponents - + private void addTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTagNameButtonActionPerformed String newTagName = userTagNameTextField.getText(); @@ -226,31 +227,32 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.alreadyExists")); return; } - + updateTagNamesListModel(); + userTagNameTextField.setText(""); tagNameErrLabel.setText(""); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_addTagNameButtonActionPerformed - + private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed CustomTagName tagName = tagNamesList.getSelectedValue(); - if (tagName == null) { - tagNameErrLabel.setText("No tag name selected."); - } else { - tagNames.remove(tagName); - updateTagNamesListModel(); - - if (!tagNamesListModel.isEmpty()) { - tagNamesList.setSelectedIndex(0); - } - - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + if (tagName == null) { + tagNameErrLabel.setText("No tag name selected."); + } else { + tagNames.remove(tagName); + updateTagNamesListModel(); + + if (!tagNamesListModel.isEmpty()) { + tagNamesList.setSelectedIndex(0); } + + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } }//GEN-LAST:event_deleteTagNameButtonActionPerformed - - + + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addTagNameButton; private javax.swing.JButton deleteTagNameButton; @@ -265,21 +267,19 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio private javax.swing.JLabel tagNamesListLabel; private javax.swing.JTextField userTagNameTextField; // End of variables declaration//GEN-END:variables - + @Override public void store() { - if (!tagNames.isEmpty()) { - StringBuilder builder = new StringBuilder(); - for (CustomTagName tagName : tagNames) { - if (builder.length() != 0) { - builder.append(";"); - } - builder.append(tagName.toSettingsFormat()); + StringBuilder builder = new StringBuilder(); + for (CustomTagName tagName : tagNames) { + if (builder.length() != 0) { + builder.append(";"); } - ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, builder.toString()); + builder.append(tagName.toSettingsFormat()); } + ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, builder.toString()); } - + @Override public void load() { tagNames = getTagNamesFromTagsSettings(); @@ -296,7 +296,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio /** * Because TagName constructor is not public, CustomTagName is used in this - * tags managers panel for the purpose of preserving description and color + * tags managers panel for the purpose of preserving description and color * information that is tracked by the user tag settings file. */ private class CustomTagName implements Comparable { @@ -315,9 +315,9 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio } @Override - public int compareTo(CustomTagName other) { - return this.getDisplayName().toLowerCase().compareTo(other.getDisplayName().toLowerCase()); - } + public int compareTo(CustomTagName other) { + return this.getDisplayName().toLowerCase().compareTo(other.getDisplayName().toLowerCase()); + } @Override public int hashCode() { @@ -334,7 +334,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio CustomTagName thatTagName = (CustomTagName) obj; return this.getDisplayName().equals(thatTagName.getDisplayName()); } - + @Override public String toString() { return displayName; From 5de32ba177912ae66725beea8a6a58d96b81d700 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Thu, 25 Aug 2016 15:06:02 -0400 Subject: [PATCH 08/19] Fixed deletion error and readdition error in the tags options panel, changed name of new tag button --- .../autopsy/actions/Bundle.properties | 2 +- .../actions/GetTagNameAndCommentDialog.form | 2 +- .../actions/GetTagNameAndCommentDialog.java | 2 +- .../casemodule/services/Bundle.properties | 4 +- .../casemodule/services/TagsManager.java | 195 +++++++++--------- .../services/TagsManagerOptionsPanel.form | 3 + .../services/TagsManagerOptionsPanel.java | 93 ++++++++- .../TagsManagerOptionsPanelController.java | 22 +- 8 files changed, 205 insertions(+), 118 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties index d9cc839467..71ce8a4504 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties @@ -4,7 +4,7 @@ GetTagNameDialog.okButton.text=OK GetTagNameDialog.preexistingLabel.text=Pre-existing Tags: GetTagNameDialog.newTagPanel.border.title=New Tag GetTagNameDialog.tagNameLabel.text=Tag Name: -GetTagNameAndCommentDialog.newTagButton.text=New Tag +GetTagNameAndCommentDialog.newTagButton.text=New Tag Name GetTagNameAndCommentDialog.okButton.text=OK GetTagNameAndCommentDialog.commentText.toolTipText=Enter an optional tag comment or leave blank GetTagNameAndCommentDialog.commentText.text= diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.form b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.form index 47ff059281..17a9738dbd 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.form +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.form @@ -28,7 +28,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java index eb4dbbab6b..9a82e445e1 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java @@ -197,7 +197,7 @@ public class GetTagNameAndCommentDialog extends JDialog { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(newTagButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 78, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 48, Short.MAX_VALUE) .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(cancelButton)) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index a40e1e200f..638c8a8412 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -1,4 +1,4 @@ -OptionsCategory_Name_TagsManager=Tags Manager +OptionsCategory_Name_TagsManager=My Tags OptionsCategory_Keywords_TagsManager=TagsManager TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} out of content size range (0 - {1}) TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} out of content size range (0 - {1}) @@ -12,7 +12,7 @@ Blackboard.unableToIndexArtifact.error.msg=Unable to index blackboard artifact { TagsManagerOptionsPanel.addTagNameButton.empty=Tag name text is empty. TagsManagerOptionsPanel.addTagNameButton.containCommaSemicolon=Tag name may not contain commas or semicolons. TagsManagerOptionsPanel.addTagNameButton.alreadyExists=Tag name already exists. -TagsManagerOptionsPanel.jLabel1.text=Autopsy keeps a list of the tag names you have used in the past. Add more or delete them here. +TagsManagerOptionsPanel.jLabel1.text=Autopsy keeps a list of the tag names you have created in the past. Add more or delete them here. TagsManagerOptionsPanel.tagNamesListLabel.text=Your tag names: TagsManagerOptionsPanel.userTagNameTextField.text= TagsManagerOptionsPanel.addTagNameButton.text=Add Tag Name diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index 413e1b1fe8..bfb01e577c 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -1,21 +1,21 @@ /* - * Autopsy Forensic Browser - * - * Copyright 2011-2016 Basis Technology Corp. - * Contact: carrier sleuthkit 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. - */ +* Autopsy Forensic Browser +* +* Copyright 2011-2016 Basis Technology Corp. +* Contact: carrier sleuthkit 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.casemodule.services; import java.io.Closeable; @@ -45,29 +45,30 @@ import org.sleuthkit.datamodel.TskCoreException; * of tags applied to content and blackboard artifacts by users. */ public class TagsManager implements Closeable { - + private static final Logger logger = Logger.getLogger(TagsManager.class.getName()); private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS private SleuthkitCase caseDb; private final HashMap uniqueTagNames = new HashMap<>(); private boolean tagNamesLoaded = false; - + /** * Constructs a per case Autopsy service that manages the creation, * updating, and deletion of tags applied to content and blackboard * artifacts by users. - * + * * @param caseDb The case database. */ TagsManager(SleuthkitCase caseDb) { this.caseDb = caseDb; } - + /** * Gets a list of all tag names currently available for tagging content or - * artifacts. - * + * artifacts. Available tag names include tag names currently being used or + * tag names loaded from the properties file. + * * @return A list, possibly empty, of TagName data transfer objects (DTOs). * * @throws TskCoreException If there is an error reading from the case @@ -84,7 +85,7 @@ public class TagsManager implements Closeable { tagNameSet.addAll(getTagNamesForPropertyFile()); return new ArrayList<>(tagNameSet); } - + /** * Gets a list of all tag names currently in use for tagging content or * artifacts. @@ -102,12 +103,14 @@ public class TagsManager implements Closeable { return caseDb.getTagNamesInUse(); } - public synchronized List getTagNamesForPropertyFile() throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed."); - } + /** + * Gets a list of all tag names associated with the ones found in the + * properties file. + * + * @return A list, possibly empty, of TagName data transfer objects (DTOs). + */ + public synchronized List getTagNamesForPropertyFile() { lazyLoadExistingTagNames(); - addTagNamesFromTagsSettings(); List propertyFileTagNames = new ArrayList<>(); String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); @@ -115,13 +118,12 @@ public class TagsManager implements Closeable { List tagNameTuples = Arrays.asList(setting.split(";")); for (String tagNameTuple : tagNameTuples) { String[] tagNameAttributes = tagNameTuple.split(","); - String displayName = tagNameAttributes[0]; - propertyFileTagNames.add(uniqueTagNames.get(displayName)); + propertyFileTagNames.add(uniqueTagNames.get(tagNameAttributes[0])); } } return propertyFileTagNames; } - + /** * Checks whether a tag name with a given display name exists. * @@ -133,7 +135,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return uniqueTagNames.containsKey(tagDisplayName); } - + /** * Adds a new tag name to the current case and to the tags settings. * @@ -153,7 +155,7 @@ public class TagsManager implements Closeable { } return addTagName(displayName, "", TagName.HTML_COLOR.NONE); } - + /** * Adds a new tag name to the current case and to the tags settings. * @@ -174,7 +176,7 @@ public class TagsManager implements Closeable { } return addTagName(displayName, description, TagName.HTML_COLOR.NONE); } - + /** * Adds a new tag name to the current case and to the tags settings. * @@ -195,46 +197,34 @@ public class TagsManager implements Closeable { throw new TskCoreException("Tags manager has been closed"); } lazyLoadExistingTagNames(); + + //The tag name already exists in the database, user either + //1) adding it again by error -> throws TagNameAlreadyExistsException + //2) adding it after it was deleted at some point in the past if (uniqueTagNames.containsKey(displayName)) { - throw new TagNameAlreadyExistsException(); + TagName existingTagName = uniqueTagNames.get(displayName); + long tagNameCount = getContentTagsCountByTagName(existingTagName) + getBlackboardArtifactTagsCountByTagName(existingTagName); + if (tagNameCount > 0) { + throw new TagNameAlreadyExistsException(); + } else { + addNewTagNameToTagsSettings(existingTagName); + } + return existingTagName; } - /* - * Add the tag name to the case. - */ + * Add the tag name to the case. + */ TagName newTagName = caseDb.addTagName(displayName, description, color); - + /* - * Add the tag name to the tags settings. - */ + * Add the tag name to the tags settings. + */ uniqueTagNames.put(newTagName.getDisplayName(), newTagName); addNewTagNameToTagsSettings(newTagName); return newTagName; } - - /** - * Deletes a tag name from the tags settings. - * - * @param displayName The display name for the tag name to be deleted. - * - * @throws TagNameDoesNotExistException - * - * @throws TskCoreException - */ - public synchronized void deleteTagName(String displayName) throws TagNameDoesNotExistException, TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); - if (!uniqueTagNames.containsKey(displayName)) { - throw new TagNameDoesNotExistException(); - } else { - uniqueTagNames.remove(displayName); - saveTagNamesToTagsSettings(); - } - } - + /** * Tags a content object. * @@ -252,7 +242,7 @@ public class TagsManager implements Closeable { } return addContentTag(content, tagName, "", -1, -1); } - + /** * Tags a content object. * @@ -271,7 +261,7 @@ public class TagsManager implements Closeable { } return addContentTag(content, tagName, comment, -1, -1); } - + /** * Tags a content object or a section of a content object. * @@ -295,33 +285,33 @@ public class TagsManager implements Closeable { ContentTag tag; synchronized (this) { lazyLoadExistingTagNames(); - + if (null == comment) { throw new IllegalArgumentException("Passed null comment argument"); } - + if (beginByteOffset >= 0 && endByteOffset >= 1) { if (beginByteOffset > content.getSize() - 1) { throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.beginByteOffsetOOR.msg", beginByteOffset, content.getSize() - 1)); } - + if (endByteOffset > content.getSize() - 1) { throw new IllegalArgumentException( NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endByteOffsetOOR.msg", endByteOffset, content.getSize() - 1)); } - + if (endByteOffset < beginByteOffset) { throw new IllegalArgumentException( NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endLTbegin.msg")); } } - + tag = caseDb.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset); } - + try { Case.getCurrentCase().notifyContentTagAdded(tag); } catch (IllegalStateException ex) { @@ -329,7 +319,7 @@ public class TagsManager implements Closeable { } return tag; } - + /** * Deletes a content tag. * @@ -346,14 +336,14 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); caseDb.deleteContentTag(tag); } - + try { Case.getCurrentCase().notifyContentTagDeleted(tag); } catch (IllegalStateException ex) { logger.log(Level.SEVERE, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteContentTag.noCaseWarning"), ex); } } - + /** * Gets all content tags for the current case. * @@ -369,7 +359,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getAllContentTags(); } - + /** * Gets content tags count by tag name. * @@ -387,7 +377,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getContentTagsCountByTagName(tagName); } - + /** * Gets a content tag by tag id. * @@ -405,7 +395,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getContentTagByID(tagID); } - + /** * Gets content tags by tag name. * @@ -424,7 +414,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getContentTagsByTagName(tagName); } - + /** * Gets content tags count by content. * @@ -443,7 +433,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getContentTagsByContent(content); } - + /** * Tags a blackboard artifact object. * @@ -462,7 +452,7 @@ public class TagsManager implements Closeable { } return addBlackboardArtifactTag(artifact, tagName, ""); } - + /** * Tags a blackboard artifact object. * @@ -488,7 +478,7 @@ public class TagsManager implements Closeable { } tag = caseDb.addBlackboardArtifactTag(artifact, tagName, comment); } - + try { Case.getCurrentCase().notifyBlackBoardArtifactTagAdded(tag); } catch (IllegalStateException ex) { @@ -496,7 +486,7 @@ public class TagsManager implements Closeable { } return tag; } - + /** * Deletes a blackboard artifact tag. * @@ -513,14 +503,14 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); caseDb.deleteBlackboardArtifactTag(tag); } - + try { Case.getCurrentCase().notifyBlackBoardArtifactTagDeleted(tag); } catch (IllegalStateException ex) { logger.log(Level.WARNING, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteBlackboardArtifactTag.noCaseWarning"), ex); } } - + /** * Gets all blackboard artifact tags for the current case. * @@ -536,7 +526,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getAllBlackboardArtifactTags(); } - + /** * Gets blackboard artifact tags count by tag name. * @@ -555,7 +545,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagsCountByTagName(tagName); } - + /** * Gets a blackboard artifact tag by tag id. * @@ -573,7 +563,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagByID(tagID); } - + /** * Gets blackboard artifact tags by tag name. * @@ -592,7 +582,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagsByTagName(tagName); } - + /** * Gets blackboard artifact tags for a particular blackboard artifact. * @@ -611,7 +601,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagsByArtifact(artifact); } - + /** * Closes the tags manager, saving the available tag names to secondary * storage. @@ -625,10 +615,12 @@ public class TagsManager implements Closeable { //saveTagNamesToTagsSettings(); caseDb = null; } - + /** * Populates the tag names collection and the tag names table in the case * database with the existing tag names from all sources. + * + * Tag names from current case are not saved into the settings file. */ private void lazyLoadExistingTagNames() { if (!tagNamesLoaded) { @@ -639,7 +631,7 @@ public class TagsManager implements Closeable { tagNamesLoaded = true; } } - + /** * Adds any tag names that are in the case database to the tag names * collection. @@ -654,7 +646,7 @@ public class TagsManager implements Closeable { Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag types from the current case", ex); //NON-NLS } } - + /** * Adds any tag names that are in the properties file to the tag names * collection and to the case database. The properties file is used to make @@ -665,7 +657,7 @@ public class TagsManager implements Closeable { if (null != setting && !setting.isEmpty()) { // Read the tag name setting and break it into tag name tuples. List tagNameTuples = Arrays.asList(setting.split(";")); - + // Parse each tuple and add the tag names to the current case, one // at a time to gracefully discard any duplicates or corrupt tuples. for (String tagNameTuple : tagNameTuples) { @@ -681,7 +673,7 @@ public class TagsManager implements Closeable { } } } - + /** * Adds the standard tag names to the tag names collection. */ @@ -696,7 +688,7 @@ public class TagsManager implements Closeable { } } } - + /** * Saves the tag names to a properties file. The properties file is used to * make it possible to use tag names across cases. @@ -717,7 +709,8 @@ public class TagsManager implements Closeable { } /** - * + * Adds a new tag name to the settings file, used when user creates a new + * tag name. */ private void addNewTagNameToTagsSettings(TagName tagName) { String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); @@ -727,7 +720,7 @@ public class TagsManager implements Closeable { else { setting += ";"; } - setting += tagName.getDisplayName() + "," + tagName.getDescription() + "," + tagName.getColor().name(); + setting += tagName.getDisplayName() + "," + tagName.getDescription() + "," + tagName.getColor().toString(); ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting); } @@ -735,7 +728,7 @@ public class TagsManager implements Closeable { * Exception thrown if there is an attempt to add a duplicate tag name. */ public static class TagNameAlreadyExistsException extends Exception { - + private static final long serialVersionUID = 1L; } @@ -745,5 +738,5 @@ public class TagsManager implements Closeable { public static class TagNameDoesNotExistException extends Exception { } - + } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form index a0ea7e8def..1565b9671c 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form @@ -157,6 +157,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java index 7d47fcbf8a..a8881657d7 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java @@ -5,6 +5,7 @@ */ package org.sleuthkit.autopsy.casemodule.services; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -22,8 +23,10 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.datamodel.TskCoreException; /** - * - * @author smori + * A panel to allow the user to create new tag names or to delete tag names that + * user has created in the past. List of user tag names is maintained in a + * properties file, able to be used across cases. + * Potentially room to add other tag name options in the future. */ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements OptionsPanel { @@ -35,10 +38,11 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio private final DefaultListModel tagNamesListModel; private Set tagNames; + private List newDisplayNames; /** - * Creates new form TagsManagerPanel + * Creates new form TagsManagerOptionsPanel */ public TagsManagerOptionsPanel() { initComponents(); @@ -46,10 +50,17 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNamesListModel = new DefaultListModel<>(); tagNamesList.setModel(tagNamesListModel); tagNames = getTagNamesFromTagsSettings(); + newDisplayNames = new ArrayList(); + userTagNameTextField.setText(""); tagNameErrLabel.setText(""); } + /** + * Gets tag names from properties file. + * + * @return A set, possibly empty, of CustomTagName objects + */ private Set getTagNamesFromTagsSettings() { Set tagNamesFromSettings = new TreeSet<>(); String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); @@ -64,6 +75,9 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio return tagNamesFromSettings; } + /** + * Updates the tag names model for the tag names list component. + */ private void updateTagNamesListModel() { tagNamesListModel.clear(); tagNames.stream().forEach((tagName) -> { @@ -105,6 +119,11 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio jScrollPane1.setViewportView(tagNamesList); userTagNameTextField.setText(org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.userTagNameTextField.text")); // NOI18N + userTagNameTextField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + userTagNameTextFieldActionPerformed(evt); + } + }); addTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(addTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.text")); // NOI18N @@ -209,20 +228,28 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio ); }// //GEN-END:initComponents + /** + * Adds a new tag name to the tag names list component without necessarily + * saving the changes. + * + * @param evt ActionEvent generated by clicking the Add Tag Name button + */ private void addTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTagNameButtonActionPerformed - String newTagName = userTagNameTextField.getText(); + String newDisplayName = userTagNameTextField.getText(); - if (newTagName.isEmpty()) { + if (newDisplayName.isEmpty()) { tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.empty")); return; } - if (newTagName.contains(",") || newTagName.contains(";")) { + if (newDisplayName.contains(",") || newDisplayName.contains(";")) { tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.containCommaSemicolon")); return; } - CustomTagName tagName = new CustomTagName(newTagName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); + CustomTagName tagName = new CustomTagName(newDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); + boolean addedToTagNames = tagNames.add(tagName); + if (!addedToTagNames) { tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.alreadyExists")); return; @@ -230,12 +257,19 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio updateTagNamesListModel(); + newDisplayNames.add(newDisplayName); userTagNameTextField.setText(""); tagNameErrLabel.setText(""); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_addTagNameButtonActionPerformed + /** + * Deletes a tag name from the tag names list component without saving the + * changes. + * + * @param evt ActionEvent generated by clicking the Delete Tag Name button + */ private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed CustomTagName tagName = tagNamesList.getSelectedValue(); if (tagName == null) { @@ -251,6 +285,15 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } }//GEN-LAST:event_deleteTagNameButtonActionPerformed + + /** + * Activates addTagNameButtonActionPerformed instead of the OptionsPanel OK + * button when the userTagNameTextField experiences an action. + * @param evt ActionEvent + */ + private void userTagNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_userTagNameTextFieldActionPerformed + addTagNameButtonActionPerformed(evt); + }//GEN-LAST:event_userTagNameTextFieldActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables @@ -268,8 +311,25 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio private javax.swing.JTextField userTagNameTextField; // End of variables declaration//GEN-END:variables + /** + * Stores tag name changes in the properties file, called when OK or Apply + * is selected in the OptionsPanel. + * + * Adds all new tag names to the case database for use. + */ @Override public void store() { + for (String displayName : newDisplayNames) { + try { + Case.getCurrentCase().getServices().getTagsManager().addTagName(displayName); + } catch (TagsManager.TagNameAlreadyExistsException ex) { + //Do nothing, this is just to update the database + } catch (TskCoreException ex) { + Logger.getLogger(TagsManagerOptionsPanel.class.getName()).log(Level.SEVERE, "Error adding " + displayName + " tag name", ex); + } + } + newDisplayNames = new ArrayList<>(); + StringBuilder builder = new StringBuilder(); for (CustomTagName tagName : tagNames) { if (builder.length() != 0) { @@ -280,6 +340,10 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, builder.toString()); } + /** + * Updates the tag names list component with tag names from the properties + * file. + */ @Override public void load() { tagNames = getTagNamesFromTagsSettings(); @@ -290,14 +354,19 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNameErrLabel.setText(""); } + /** + * Discards changes made to the tag names list component if Cancel button is + * selected in the OptionsPanel. + */ public void cancelChanges() { tagNames = getTagNamesFromTagsSettings(); + newDisplayNames = new ArrayList<>(); } /** - * Because TagName constructor is not public, CustomTagName is used in this - * tags managers panel for the purpose of preserving description and color - * information that is tracked by the user tag settings file. + * Because the DTO TagName constructor should not be called outside of its + * class package, CustomTagName is used in this tags managers panel for the + * purpose of tracking the description and color of each tag name. */ private class CustomTagName implements Comparable { private final String displayName; @@ -340,6 +409,10 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio return displayName; } + /** + * @return A String with of the tag name in the format that is used by + * the properties file. + */ public String toSettingsFormat() { return displayName + "," + description + "," + colorName; } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java index bb876d82df..111daaeb68 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java @@ -18,7 +18,7 @@ import org.openide.util.Lookup; iconBase = "org/sleuthkit/autopsy/modules/filetypeid/user-defined-file-types-settings.png", keywords = "#OptionsCategory_Keywords_TagsManager", keywordsCategory = "TagsManager", - position = 10 + position = 8 ) public final class TagsManagerOptionsPanelController extends OptionsPanelController { @@ -26,12 +26,20 @@ public final class TagsManagerOptionsPanelController extends OptionsPanelControl private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private boolean changed; + /** + * Component should load its data here. + */ @Override public void update() { getPanel().load(); changed = false; } + /** + * This method is called when both the Ok and Apply buttons are pressed. It + * applies to any of the panels that have been opened in the process of + * using the options pane. + */ @Override public void applyChanges() { if (changed) { @@ -40,6 +48,11 @@ public final class TagsManagerOptionsPanelController extends OptionsPanelControl } } + /** + * This method is called when the Cancel button is pressed. It applies to + * any of the panels that have been opened in the process of using the + * options pane. + */ @Override public void cancel() { if (changed) { @@ -51,9 +64,14 @@ public final class TagsManagerOptionsPanelController extends OptionsPanelControl @Override public boolean isValid() { return true; - //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } + /** + * Used to determine whether any changes have been made to this controller's + * panel. + * + * @return Whether or not a change has been made. + */ @Override public boolean isChanged() { return changed; From 5cc160c2d5a6ad376085f9350f804d346997a935 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Thu, 25 Aug 2016 15:26:51 -0400 Subject: [PATCH 09/19] Removed unused import --- .../autopsy/casemodule/services/TagsManagerOptionsPanel.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java index a8881657d7..37bec75390 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java @@ -14,7 +14,6 @@ import java.util.TreeSet; import java.util.logging.Level; import javax.swing.DefaultListModel; import org.netbeans.spi.options.OptionsPanelController; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; From d06aab353254bb4619e3411dfda4995a85cd0ff2 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Thu, 25 Aug 2016 15:29:19 -0400 Subject: [PATCH 10/19] Removed another unused import --- .../org/sleuthkit/autopsy/casemodule/services/TagsManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index bfb01e577c..e838e24c7b 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -22,7 +22,6 @@ import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; From ac1b28ebe30ae2ce18643a8cb4268c8f5707403e Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Fri, 26 Aug 2016 10:13:28 -0400 Subject: [PATCH 11/19] Disallowed commas and semicolons as potential characters in tag names --- .../autopsy/actions/Bundle.properties | 2 +- .../autopsy/actions/GetTagNameDialog.java | 13 +-------- .../casemodule/services/Bundle.properties | 2 +- .../casemodule/services/TagsManager.java | 28 +++++++++++++++++-- .../services/TagsManagerOptionsPanel.java | 13 +++++---- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties index 71ce8a4504..ba828aed5d 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties @@ -42,7 +42,7 @@ GetTagNameDialog.createTag=Create Tag GetTagNameDialog.cancelName=Cancel GetTagNameDialog.mustSupplyTtagName.msg=Must supply a tag name to continue. GetTagNameDialog.tagNameErr=Tag Name -GetTagNameDialog.illegalChars.msg=The tag name contains illegal characters.\nCannot contain any of the following symbols\: \\ \: * ? " < > | +GetTagNameDialog.illegalChars.msg=The tag name contains illegal characters.\nCannot contain any of the following symbols\: \\ \: * ? " < > | , ; GetTagNameDialog.illegalCharsErr=Illegal Characters GetTagNameDialog.unableToAddTagNameToCase.msg=Unable to add the {0} tag name to the case. GetTagNameDialog.taggingErr=Tagging Error diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java index b24f69d757..9f6f23282f 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java @@ -122,17 +122,6 @@ public class GetTagNameDialog extends JDialog { setVisible(true); } - private boolean containsIllegalCharacters(String content) { - return (content.contains("\\") - || content.contains(":") - || content.contains("*") - || content.contains("?") - || content.contains("\"") - || content.contains("<") - || content.contains(">") - || content.contains("|")); - } - private class TagsTableModel extends AbstractTableModel { private final ArrayList tagNames = new ArrayList<>(); @@ -305,7 +294,7 @@ public class GetTagNameDialog extends JDialog { "GetTagNameDialog.mustSupplyTtagName.msg"), NbBundle.getMessage(this.getClass(), "GetTagNameDialog.tagNameErr"), JOptionPane.ERROR_MESSAGE); - } else if (containsIllegalCharacters(tagDisplayName)) { + } else if (TagsManager.containsIllegalCharacters(tagDisplayName)) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(), "GetTagNameDialog.illegalChars.msg"), NbBundle.getMessage(this.getClass(), "GetTagNameDialog.illegalCharsErr"), diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index 638c8a8412..a7425bfa0d 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -10,7 +10,7 @@ TagsManager.addBlackboardArtifactTag.noCaseWarning=Failed to publish new blackbo TagsManager.deleteBlackboardArtifactTag.noCaseWarning=Failed to publish blackboard artifact tag deleted event. There is no case open. Blackboard.unableToIndexArtifact.error.msg=Unable to index blackboard artifact {0} TagsManagerOptionsPanel.addTagNameButton.empty=Tag name text is empty. -TagsManagerOptionsPanel.addTagNameButton.containCommaSemicolon=Tag name may not contain commas or semicolons. +TagsManagerOptionsPanel.addTagNameButton.containInvalidCharacter=Tag name may not contain any of the following symbols\: \\ \: * ? " < > | , ; TagsManagerOptionsPanel.addTagNameButton.alreadyExists=Tag name already exists. TagsManagerOptionsPanel.jLabel1.text=Autopsy keeps a list of the tag names you have created in the past. Add more or delete them here. TagsManagerOptionsPanel.tagNamesListLabel.text=Your tag names: diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index e838e24c7b..6848f5cb0a 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -143,7 +143,7 @@ public class TagsManager implements Closeable { * @return A TagName data transfer object (DTO) representing the new tag * name. * - * @throws TagNameAlreadyExistsException If the tag name would be a + * @throws TagNameAlreadyExistsException If the tag name would be a * duplicate. * @throws TskCoreException If there is an error adding the tag * to the case database. @@ -164,7 +164,7 @@ public class TagsManager implements Closeable { * @return A TagName data transfer object (DTO) representing the new tag * name. * - * @throws TagNameAlreadyExistsException If the tag name would be a + * @throws TagNameAlreadyExistsException If the tag name would be a * duplicate. * @throws TskCoreException If there is an error adding the tag * to the case database. @@ -186,7 +186,7 @@ public class TagsManager implements Closeable { * @return A TagName data transfer object (DTO) representing the new tag * name. * - * @throws TagNameAlreadyExistsException If the tag name would be a + * @throws TagNameAlreadyExistsException If the tag name would be a * duplicate. * @throws TskCoreException If there is an error adding the tag * to the case database. @@ -195,6 +195,7 @@ public class TagsManager implements Closeable { if (null == caseDb) { throw new TskCoreException("Tags manager has been closed"); } + lazyLoadExistingTagNames(); //The tag name already exists in the database, user either @@ -723,6 +724,26 @@ public class TagsManager implements Closeable { ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting); } + /** + * Returns true if the tag display name contains an illegal character. Used + * after a tag display name is retrieved from user input. + * + * @param content Display name of the tag being added. + * @return boolean indicating whether the name has an invalid character. + */ + public static boolean containsIllegalCharacters(String content) { + return (content.contains("\\") + || content.contains(":") + || content.contains("*") + || content.contains("?") + || content.contains("\"") + || content.contains("<") + || content.contains(">") + || content.contains("|") + || content.contains(",") + || content.contains(";")); + } + /** * Exception thrown if there is an attempt to add a duplicate tag name. */ @@ -733,6 +754,7 @@ public class TagsManager implements Closeable { /** * Exception thrown if there is an attempt to delete a nonexistent tag name. + * Unused for current implementation of tag name deletion. */ public static class TagNameDoesNotExistException extends Exception { diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java index 37bec75390..f63059e85e 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java @@ -14,6 +14,7 @@ import java.util.TreeSet; import java.util.logging.Level; import javax.swing.DefaultListModel; import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; @@ -49,7 +50,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNamesListModel = new DefaultListModel<>(); tagNamesList.setModel(tagNamesListModel); tagNames = getTagNamesFromTagsSettings(); - newDisplayNames = new ArrayList(); + newDisplayNames = new ArrayList<>(); userTagNameTextField.setText(""); tagNameErrLabel.setText(""); @@ -240,8 +241,8 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.empty")); return; } - if (newDisplayName.contains(",") || newDisplayName.contains(";")) { - tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.containCommaSemicolon")); + if (TagsManager.containsIllegalCharacters(newDisplayName)) { + tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.containInvalidCharacter")); return; } @@ -281,6 +282,8 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio tagNamesList.setSelectedIndex(0); } + newDisplayNames.remove(tagName.getDisplayName()); + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } }//GEN-LAST:event_deleteTagNameButtonActionPerformed @@ -409,8 +412,8 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio } /** - * @return A String with of the tag name in the format that is used by - * the properties file. + * @return A string representation of the tag name in the format that is + * used by the properties file. */ public String toSettingsFormat() { return displayName + "," + description + "," + colorName; From bbd68e3f0efb4bbf3664da7d4ada584b8c4f9614 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Fri, 2 Sep 2016 13:04:05 -0400 Subject: [PATCH 12/19] Added appropriate icon images and reverted a public method change --- .../autopsy/actions/AddTagAction.java | 2 +- .../actions/GetTagNameAndCommentDialog.java | 2 +- .../autopsy/actions/GetTagNameDialog.java | 2 +- .../casemodule/services/TagsManager.java | 27 ++++++++++++++---- .../services/TagsManagerOptionsPanel.form | 4 +-- .../services/TagsManagerOptionsPanel.java | 10 +++++-- .../TagsManagerOptionsPanelController.java | 2 +- .../casemodule/services/tags-manager.png | Bin 0 -> 1215 bytes .../org/sleuthkit/autopsy/images/add-tag.png | Bin 0 -> 1658 bytes .../sleuthkit/autopsy/images/delete-tag.png | Bin 0 -> 1698 bytes .../org/sleuthkit/autopsy/images/edit-tag.png | Bin 0 -> 1755 bytes 11 files changed, 34 insertions(+), 15 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/tags-manager.png create mode 100755 Core/src/org/sleuthkit/autopsy/images/add-tag.png create mode 100755 Core/src/org/sleuthkit/autopsy/images/delete-tag.png create mode 100755 Core/src/org/sleuthkit/autopsy/images/edit-tag.png diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java index 7f4f813495..7db5a5e0ee 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java @@ -89,7 +89,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); List tagNames = null; try { - tagNames = tagsManager.getAllTagNames(); + tagNames = tagsManager.getAllTagNamesForDisplay(); Collections.sort(tagNames); } catch (TskCoreException ex) { Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java index 9a82e445e1..19b32e3905 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java @@ -117,7 +117,7 @@ public class GetTagNameAndCommentDialog extends JDialog { TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); List currentTagNames = null; try { - currentTagNames = tagsManager.getAllTagNames(); + currentTagNames = tagsManager.getAllTagNamesForDisplay(); } catch (TskCoreException ex) { Logger.getLogger(GetTagNameAndCommentDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java index 9f6f23282f..fd8634e123 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java @@ -98,7 +98,7 @@ public class GetTagNameDialog extends JDialog { TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); List currentTagNames = null; try { - currentTagNames = tagsManager.getAllTagNames(); + currentTagNames = tagsManager.getAllTagNamesForDisplay(); } catch (TskCoreException ex) { Logger.getLogger(GetTagNameDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index 6848f5cb0a..fcd7b051bd 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -62,12 +62,11 @@ public class TagsManager implements Closeable { TagsManager(SleuthkitCase caseDb) { this.caseDb = caseDb; } - + /** * Gets a list of all tag names currently available for tagging content or - * artifacts. Available tag names include tag names currently being used or - * tag names loaded from the properties file. - * + * artifacts. + * * @return A list, possibly empty, of TagName data transfer objects (DTOs). * * @throws TskCoreException If there is an error reading from the case @@ -78,7 +77,23 @@ public class TagsManager implements Closeable { throw new TskCoreException("Tags manager has been closed"); } lazyLoadExistingTagNames(); - //return caseDb.getAllTagNames(); + return caseDb.getAllTagNames(); + } + + /** + * Gets a list of all tag names currently being used or tag names loaded + * from the properties file. + * + * @return A list, possibly empty, of TagName data transfer objects (DTOs). + * + * @throws TskCoreException If there is an error reading from the case + * database. + */ + public synchronized List getAllTagNamesForDisplay() throws TskCoreException { + if (null == caseDb) { + throw new TskCoreException("Tags manager has been closed"); + } + lazyLoadExistingTagNames(); Set tagNameSet = new HashSet<>(); tagNameSet.addAll(getTagNamesInUse()); tagNameSet.addAll(getTagNamesForPropertyFile()); @@ -108,7 +123,7 @@ public class TagsManager implements Closeable { * * @return A list, possibly empty, of TagName data transfer objects (DTOs). */ - public synchronized List getTagNamesForPropertyFile() { + private synchronized List getTagNamesForPropertyFile() { lazyLoadExistingTagNames(); List propertyFileTagNames = new ArrayList<>(); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form index 1565b9671c..fc35b992fe 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form @@ -164,7 +164,7 @@ - + @@ -177,7 +177,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java index f63059e85e..17343d9690 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java @@ -14,7 +14,6 @@ import java.util.TreeSet; import java.util.logging.Level; import javax.swing.DefaultListModel; import org.netbeans.spi.options.OptionsPanelController; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; @@ -33,6 +32,8 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS + private static final String TAG_BOOKMARK = "Bookmark"; + private static final String DEFAULT_DESCRIPTION = ""; private static final String DEFAULT_COLOR_STRING = "NONE"; @@ -71,7 +72,10 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio CustomTagName tagName = new CustomTagName(tagNameAttributes[0], tagNameAttributes[1], tagNameAttributes[2]); tagNamesFromSettings.add(tagName); } + } else { + tagNamesFromSettings.add(new CustomTagName(TAG_BOOKMARK, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING)); } + return tagNamesFromSettings; } @@ -125,7 +129,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio } }); - addTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N + addTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(addTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.text")); // NOI18N addTagNameButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -133,7 +137,7 @@ public class TagsManagerOptionsPanel extends javax.swing.JPanel implements Optio } }); - deleteTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete16.png"))); // NOI18N + deleteTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete-tag.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(deleteTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.deleteTagNameButton.text")); // NOI18N deleteTagNameButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java index 111daaeb68..18c15f9c46 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java @@ -15,7 +15,7 @@ import org.openide.util.Lookup; @OptionsPanelController.TopLevelRegistration( categoryName = "#OptionsCategory_Name_TagsManager", - iconBase = "org/sleuthkit/autopsy/modules/filetypeid/user-defined-file-types-settings.png", + iconBase = "org/sleuthkit/autopsy/casemodule/services/tags-manager.png", keywords = "#OptionsCategory_Keywords_TagsManager", keywordsCategory = "TagsManager", position = 8 diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/tags-manager.png b/Core/src/org/sleuthkit/autopsy/casemodule/services/tags-manager.png new file mode 100755 index 0000000000000000000000000000000000000000..b782cfe010a80106eb4915832d74e7a18aaceeab GIT binary patch literal 1215 zcmV;w1VH5w5QqH~So^w9m=eg&e=Rpbt0`xr1z<*4Y zl@##%pLvn8>S`)qy_zJQjwDG^es(;n5ls90(&59`4gW=bX;qc{(*Yb~c0~4-OP!r3 zIl?T6O^O)s&Y?r^h9aQVY!ww$f~ds-hv7$#ob(~83iRgv`}Ehthg5?|HQDW?yn0On zR+g2Kt-L%DSb^IwA3Zwc^Z9~3{5sG$XJ*K3u}I@HGcpxp zeSHJ}Jb5Avdt|@CV4%0#+FCIB9-?qJ>L}J=YZ-p6zyIs``T5`pmn7`mrlh3Mrq*B!G3XtL74GkTi#&Nm?o`*M z%gM>f_`o=Q%hS{8jorK3Ww>5{OLaxG1n&2*`|0f2FD4#8j(fJp6Oq1R1--s&*N5o2 z4bR6km1HsShM&)!>vc{{s5)fWGBPsgwVgXVaCu7$JXSy>!rm}^{`}`or&HD0&TS^( z8+PpY2-lk7kpkAU=f7OI(Bl{%7lu8u-<+9AuWsM|F@}!;KB^YVIYE!pF(d%+#v2ze zb~_x7CB;M{5oWWQnzn5_s0GgXz=Tg!ZwLoo&V~s6=!UIZKgmV8M1pLlv=)nn)?+-+ z<9ah0m~+8$Y|=D*C6Vxu0A2(|0VC5l*S1Uq?Hv``M}N+VLRR+FCh dzvur7FaRGqTh2a`r+)wd002ovPDHLkV1oB1R%rkL literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/images/add-tag.png b/Core/src/org/sleuthkit/autopsy/images/add-tag.png new file mode 100755 index 0000000000000000000000000000000000000000..e60e692bacf25a4168180602ae858586113dea8f GIT binary patch literal 1658 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ za0`Jj+tIX_n~5oC^DMQ#CujeSKy zVsdtBi9%9pdS;%jl7fPQl0s&Rtx~wDuYqrYb81GWM^#a3aFt(3a#eP+Wr~u$9hXgo z6;N|-YDuC(MQ%=Bu~mhw64*>DAR8pCucQE0Qj%?}1aWkPZ-9bxeo?A|iJqZuvVpOQ zf{B@)k-3qjxtWeaaAJvqS7M%mk-37AfdP;(vNANZGBE@?1`L$!xPY`xQA(Oskc%7C zP9V=#DWjyMz)D}gyu4hm+*mKaC|%#s($Z4jz)0W7NEfI=x41H|B(Xv_uUHvk2+SOp z)Z*l#%mQ$5fy_-z$}cUkRZ;?31P4&hB^JOf$}5Hj9xxd7D-sLz4fPE4;U)t$+5iQu zz!8yO6q28xV}~WqY(P3u6d`Oy=udS?EJ?KkhKGf&fswAEd5D3Lm9d$XiD?v)euyG8 z?Y{XbnQ4_s+KqLMOhODTtqcsTOpKt~krY9-+vtM=0x4j?p$_sBnz#ai082@RhgU&q zQ4Tm-Qj+ykb5e6t^Gb?=VP=RLW+};5Y57IDi6wTKxryni`UQFEHu?xbyzYaz8kj7A z$x`D0-@5LI7SBsl$YuZpw;nD$jBzc1r(0 z`=*gw|NGtVr+0q0Ra}}PbNmFGr^#$z#ic6uLRMdO*`;s3g2?h_U_Abl4y+!Bsu{taER+U8> zO{-R=zdrp`$Wh?H_gamvrl6H9mraZ(|5j&YIQ($J(;~^+Z^ib#Km6I|Ns*-p7i-3> zHm{{cl^z@utt{ew_upThC}Ao^tJ>Q)f4%3+>q?3(0-4rcTp3%V zk~T&t@Hnqn)m3B1?|ZqxLWY5%-p`Z4Vfp2qxA_b*fAM>Q8^GU7_%CS>ASThKk-vC*Cpk u^WNE^Y1e%8c}mC3KmP^S-9BlzWWTkgZ*Gc0WgW2mXYh3Ob6Mw<&;$U8UH+v2 literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/images/delete-tag.png b/Core/src/org/sleuthkit/autopsy/images/delete-tag.png new file mode 100755 index 0000000000000000000000000000000000000000..25edd1ab6bb33c22b5275bc245cb90e81e2712f9 GIT binary patch literal 1698 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ za0`Jj+tIX_n~5oC^DMQ#CujeSKy zVsdtBi9%9pdS;%jl7fPQl0s&Rtx~wDuYqrYb81GWM^#a3aFt(3a#eP+Wr~u$9hXgo z6;N|-YDuC(MQ%=Bu~mhw64*>DAR8pCucQE0Qj%?}1aWkPZ-9bxeo?A|iJqZuvVpOQ zf{B@)k-3qjxtWeaaAJvqS7M%mk-37AfdP;(vNANZGBE@?1`L$!xPY`xQA(Oskc%7C zP9V=#DWjyMz)D}gyu4hm+*mKaC|%#s($Z4jz)0W7NEfI=x41H|B(Xv_uUHvk2+SOp z)Z*l#%mQ$5fy_-z$}cUkRZ;?31P4&hB^JOf$}5Hj9xxd7D-sLz4fPE4;U)t$+5iQu zz!8yO6q28xV}~WqY(P3u6d`Oy=udS?EJ?KkhKGf&fswAEd5D3Lm9d$XiD?v)euyG8 z?Y{XbnQ4_s+KqLMOhODTtqcsTOpKt~krY9-+vtM=0x4j?p$_sBnz#ai082@RhgU&q zQ4Tm-Qj+ykb5e6t^Gb?=VP=RLW+};5Y57IDi6wTKxryni`UQFEHu?xbyzYaz8kj7A z$xkBVZ1|p4AzCwQby<%WR99S_^P#VD3Y^zVQ{R?Zo6Y9ke6y!)_u0RHZSUrZH@qzQ_3o>|lXvg@7#I@_Bm}yT zT3A~%Cv1(Hc>Z~zjJv$z?`KIHGcru1fW~E+&E|Uj>Xlc2e}C5Y+pDg>X8-uTc!SEu zn>iL%R$Pn9tz^Sii|%`$94WRfH+c0`r^(fm8F%d47iKj#%|hnUZ@YQV1v_0jjz4x; z9H?_T$!`AT*I!qJXdTR#Nai^6^y$)1KW%Qm6+8cV#@V!rdBc0kz_BhF(DM=ETd{rF+=;lNRA28X?I({pdTC<$`4 zGU-2i>*Zthft{ftYVEQREmyPIs&f68&D*cndDz(4)Li=)e>E%A+}vEM*KN|0{Q^3k zRaI4!_IYgxUw%1IZ~Ee&o=x-P&noD67CD{WuVVKrU-f0oq`9(86N-u literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/images/edit-tag.png b/Core/src/org/sleuthkit/autopsy/images/edit-tag.png new file mode 100755 index 0000000000000000000000000000000000000000..4bc2a7ec131d3bd0bcc982feb699d9c8b8e194d6 GIT binary patch literal 1755 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ za0`JjxV%QuQiw3m9zdD+&^mvr|hHl2X$%^K6wA z6cm&cGE;1o!cBb*d<&dYGcrA@ic*8C{6dnevXd=Slr%ES=p7%)(>;{wt)MJZ`kK`w4kJAph~rHqo20xNy} z^73-Ma$~*xqI7*jOG`_A10#JSBVC{h-Qvo;lEez#ykcdDAuw}XQj3#|G7CyF^Yauy z<|ZcPmzLNnDS<441E}W`3*Z*z6+;6L7>xQAi3R$GdItJ%lYts-fPz-eMX8A;`9&f5 z`8jqF@4ICdrIzOxWfvXKNJY6lDt3ta;vT|@H_10ySAGbO1mn?toDDS~RZ(FX+tQow*i9poo8aY6x>k_->8 zg3_WKaI~Z(>!;?V=BDPA6a&M|5H-wFlC9G6i*gf7>@sr`(^K^e^3rYe5rTN#2XQqp zSpbuzK0IB*oDPplnlKRIP7~uHhSJg!jsqEwfF*_~sBi!$T2OWf$;?etkVo^j2MnSp^x+|$J|#G<8brF1H2?wEP-?o#iAOP#;}>-pEPEmJerI7L9D(=cGogaRE6lL;>pTs^$K&-xxZ ztGaV%KKounx25_r=Z-(zbN*+=`EN<-v9PySpXf2+Y#O5k58IL;&28JZnecL+o#}HdDL>zTZ=C<{-@j*FdG~IepTGar z43jMzHx{n`Yrq~YwC}xeuiNpp^78V=5UvxEm2(^oeNo8 zffCnCJ6)8{oIfwze|%%^?7Z!#Z{C#5&d%P>$gniXb7e@^#f+BMyDa*eU++>8;!N5o z!SJ$V*8TVKkLyesY<`9unmvMvMsi#KT+S*|p8{RWB Date: Fri, 23 Sep 2016 15:47:47 -0400 Subject: [PATCH 13/19] Changed user interface, kept bookmark tag always, renamed files --- .../casemodule/services/Bundle.properties | 23 +- .../services/NewUserTagNameDialog.form | 98 ++++ .../services/NewUserTagNameDialog.java | 197 ++++++++ ...va => TagNamesOptionsPanelController.java} | 18 +- ...sPanel.form => TagNamesSettingsPanel.form} | 59 +-- .../services/TagNamesSettingsPanel.java | 293 ++++++++++++ .../casemodule/services/TagsManager.java | 107 ++--- .../services/TagsManagerOptionsPanel.java | 427 ------------------ .../casemodule/services/UserTagName.java | 72 +++ 9 files changed, 745 insertions(+), 549 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.form create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java rename Core/src/org/sleuthkit/autopsy/casemodule/services/{TagsManagerOptionsPanelController.java => TagNamesOptionsPanelController.java} (85%) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{TagsManagerOptionsPanel.form => TagNamesSettingsPanel.form} (75%) create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java delete mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index a7425bfa0d..226b661523 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -1,5 +1,5 @@ -OptionsCategory_Name_TagsManager=My Tags -OptionsCategory_Keywords_TagsManager=TagsManager +OptionsCategory_Name_TagNamesOptions=My Tag Names +OptionsCategory_TagNames=TagNames TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} out of content size range (0 - {1}) TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} out of content size range (0 - {1}) TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset @@ -12,9 +12,16 @@ Blackboard.unableToIndexArtifact.error.msg=Unable to index blackboard artifact { TagsManagerOptionsPanel.addTagNameButton.empty=Tag name text is empty. TagsManagerOptionsPanel.addTagNameButton.containInvalidCharacter=Tag name may not contain any of the following symbols\: \\ \: * ? " < > | , ; TagsManagerOptionsPanel.addTagNameButton.alreadyExists=Tag name already exists. -TagsManagerOptionsPanel.jLabel1.text=Autopsy keeps a list of the tag names you have created in the past. Add more or delete them here. -TagsManagerOptionsPanel.tagNamesListLabel.text=Your tag names: -TagsManagerOptionsPanel.userTagNameTextField.text= -TagsManagerOptionsPanel.addTagNameButton.text=Add Tag Name -TagsManagerOptionsPanel.deleteTagNameButton.text=Delete Tag Name -TagsManagerOptionsPanel.tagNameErrLabel.text= \ No newline at end of file +TagNamesSettingsPanel.deleteTagNameButton.text=Delete Tag Name +TagNamesSettingsPanel.addTagNameButton.text=Add Tag Name +TagNamesSettingsPanel.tagNamesListLabel.text=Your tag names: +NewUserTagNameDialog.tagNameTextField.text= +NewUserTagNameDialog.newTagNameLabel.text=New Tag Name: +NewUserTagNameDialog.okButton.text=OK +NewUserTagNameDialog.cancelButton.text=Cancel +NewUserTagNameDialog.title.text=New Tag Name +NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.message=Tag name may not contain any of the following symbols\: \\ \: * ? " < > | , ; +NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.title=Invalid character in tag name +TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.message=The tag name already exists in your settings +TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.title=Tag name already exists +TagNamesSettingsPanel.panelDescriptionLabel.text=Autopsy keeps a list of the tag names you have created in the past. Add more or delete them here. diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.form new file mode 100755 index 0000000000..26ab153c27 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.form @@ -0,0 +1,98 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java new file mode 100755 index 0000000000..c39be3dd07 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java @@ -0,0 +1,197 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.casemodule.services; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import org.openide.util.NbBundle; + +public class NewUserTagNameDialog extends javax.swing.JDialog { + + private String userTagDisplayName; + private BUTTON_PRESSED result; + + enum BUTTON_PRESSED { + OK, CANCEL; + } + + NewUserTagNameDialog() { + super(new JFrame(NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.title.text")), + NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.title.text"), true); + initComponents(); + String test = ""; + this.display(); + } + + private void display() { + setLayout(new BorderLayout()); + + // Center the dialog + Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); + int width = this.getSize().width; + int height = this.getSize().height; + setLocation((screenDimension.width - width) / 2, (screenDimension.height - height) / 2); + + // Add a handler for when the dialog window is closed directly + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + doButtonAction(false); + } + }); + + // Add a listener to enable the save button + tagNameTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + fire(); + } + @Override + public void removeUpdate(DocumentEvent e) { + fire(); + } + @Override + public void insertUpdate(DocumentEvent e) { + fire(); + } + private void fire() { + enableOkButton(); + } + }); + + enableOkButton(); + + // Show the dialog + setResizable(false); + setVisible(true); + + } + + private void doButtonAction(boolean okPressed) { + if (okPressed) { + String newTagDisplayName = tagNameTextField.getText(); + if (TagsManager.containsIllegalCharacters(newTagDisplayName)) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.message"), + NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.title"), + JOptionPane.ERROR_MESSAGE); + } else { + userTagDisplayName = newTagDisplayName; + result = BUTTON_PRESSED.OK; + setVisible(false); + } + } else { + result = BUTTON_PRESSED.CANCEL; + setVisible(false); + } + } + + String getTagName() { + return userTagDisplayName; + } + + BUTTON_PRESSED getResult() { + return result; + } + + private void enableOkButton() { + okButton.setEnabled(!tagNameTextField.getText().isEmpty()); + getRootPane().setDefaultButton(okButton); + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + newTagNameLabel = new javax.swing.JLabel(); + tagNameTextField = new javax.swing.JTextField(); + cancelButton = new javax.swing.JButton(); + okButton = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + org.openide.awt.Mnemonics.setLocalizedText(newTagNameLabel, org.openide.util.NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.newTagNameLabel.text")); // NOI18N + + tagNameTextField.setText(org.openide.util.NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.tagNameTextField.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.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(NewUserTagNameDialog.class, "NewUserTagNameDialog.okButton.text")); // NOI18N + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + + 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(tagNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 220, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(okButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton)) + .addComponent(newTagNameLabel, 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() + .addComponent(newTagNameLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(tagNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(50, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cancelButton) + .addComponent(okButton)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed + doButtonAction(true); + }//GEN-LAST:event_okButtonActionPerformed + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed + doButtonAction(false); + }//GEN-LAST:event_cancelButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton cancelButton; + private javax.swing.JLabel newTagNameLabel; + private javax.swing.JButton okButton; + private javax.swing.JTextField tagNameTextField; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java similarity index 85% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java rename to Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java index 18c15f9c46..6f6cb53412 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java @@ -14,15 +14,15 @@ import org.openide.util.HelpCtx; import org.openide.util.Lookup; @OptionsPanelController.TopLevelRegistration( - categoryName = "#OptionsCategory_Name_TagsManager", + categoryName = "#OptionsCategory_Name_TagNamesOptions", iconBase = "org/sleuthkit/autopsy/casemodule/services/tags-manager.png", - keywords = "#OptionsCategory_Keywords_TagsManager", - keywordsCategory = "TagsManager", + keywords = "#OptionsCategory_TagNames", + keywordsCategory = "CustomTagNames", position = 8 ) -public final class TagsManagerOptionsPanelController extends OptionsPanelController { +public final class TagNamesOptionsPanelController extends OptionsPanelController { - private TagsManagerOptionsPanel panel; + private TagNamesSettingsPanel panel; private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private boolean changed; @@ -55,10 +55,6 @@ public final class TagsManagerOptionsPanelController extends OptionsPanelControl */ @Override public void cancel() { - if (changed) { - getPanel().cancelChanges(); - changed = false; - } } @Override @@ -97,9 +93,9 @@ public final class TagsManagerOptionsPanelController extends OptionsPanelControl pcs.removePropertyChangeListener(l); } - private TagsManagerOptionsPanel getPanel() { + private TagNamesSettingsPanel getPanel() { if (panel == null) { - panel = new TagsManagerOptionsPanel(); + panel = new TagNamesSettingsPanel(); panel.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form similarity index 75% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form rename to Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form index fc35b992fe..59cac6e9bc 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form @@ -43,7 +43,7 @@ - +
@@ -53,7 +53,7 @@ - + @@ -62,22 +62,22 @@ - + - + - + - + @@ -90,16 +90,14 @@ - - - - - + + + @@ -111,15 +109,13 @@ - + - - @@ -128,7 +124,7 @@ - + @@ -145,29 +141,22 @@ + + + - + - - - - - - - - - - - + @@ -180,26 +169,16 @@ - + - - - - - - - - - - - + @@ -209,7 +188,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java new file mode 100755 index 0000000000..08fb8ea4e3 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java @@ -0,0 +1,293 @@ +/* +* To change this license header, choose License Headers in Project Properties. +* To change this template file, choose Tools | Templates +* and open the template in the editor. + */ +package org.sleuthkit.autopsy.casemodule.services; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import javax.swing.DefaultListModel; +import javax.swing.JOptionPane; +import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.corecomponents.OptionsPanel; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.ModuleSettings; + +/** + * A panel to allow the user to create new tag names or to delete tag names that + * user has created in the past. List of user tag names is maintained in a + * properties file, able to be used across cases. Potentially room to add other + * tag name options in the future. + */ +public class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsPanel { + + private static final Logger logger = Logger.getLogger(TagNamesSettingsPanel.class.getName()); + + private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS + private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS + + private static final String TAG_BOOKMARK = "Bookmark"; + + private static final String DEFAULT_DESCRIPTION = ""; + private static final String DEFAULT_COLOR_STRING = "NONE"; + + private DefaultListModel tagNamesListModel; + private List tagNames; + + /** + * Creates new form TagsManagerOptionsPanel + */ + public TagNamesSettingsPanel() { + initComponents(); + customizeComponents(); + } + + private void customizeComponents() { + tagNamesListModel = new DefaultListModel<>(); + tagNamesList.setModel(tagNamesListModel); + tagNames = new ArrayList<>(); + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + panelDescriptionLabel = new javax.swing.JLabel(); + jSplitPane1 = new javax.swing.JSplitPane(); + modifyTagNameListPanel = new javax.swing.JPanel(); + tagNamesListLabel = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + tagNamesList = new javax.swing.JList<>(); + addTagNameButton = new javax.swing.JButton(); + deleteTagNameButton = new javax.swing.JButton(); + tagNameAdditionalPanel = new javax.swing.JPanel(); + + jPanel1.setPreferredSize(new java.awt.Dimension(750, 500)); + + org.openide.awt.Mnemonics.setLocalizedText(panelDescriptionLabel, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.panelDescriptionLabel.text")); // NOI18N + + jSplitPane1.setDividerLocation(400); + jSplitPane1.setDividerSize(1); + + org.openide.awt.Mnemonics.setLocalizedText(tagNamesListLabel, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.tagNamesListLabel.text")); // NOI18N + + tagNamesList.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + tagNamesListMouseClicked(evt); + } + }); + jScrollPane1.setViewportView(tagNamesList); + + addTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(addTagNameButton, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.addTagNameButton.text")); // NOI18N + addTagNameButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addTagNameButtonActionPerformed(evt); + } + }); + + deleteTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete-tag.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(deleteTagNameButton, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.deleteTagNameButton.text")); // NOI18N + deleteTagNameButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + deleteTagNameButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout modifyTagNameListPanelLayout = new javax.swing.GroupLayout(modifyTagNameListPanel); + modifyTagNameListPanel.setLayout(modifyTagNameListPanelLayout); + modifyTagNameListPanelLayout.setHorizontalGroup( + modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(modifyTagNameListPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(tagNamesListLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(modifyTagNameListPanelLayout.createSequentialGroup() + .addComponent(addTagNameButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(deleteTagNameButton) + .addGap(0, 115, Short.MAX_VALUE)) + .addComponent(jScrollPane1)) + .addContainerGap()) + ); + modifyTagNameListPanelLayout.setVerticalGroup( + modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(modifyTagNameListPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(tagNamesListLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(addTagNameButton) + .addComponent(deleteTagNameButton)) + .addContainerGap()) + ); + + jSplitPane1.setLeftComponent(modifyTagNameListPanel); + + javax.swing.GroupLayout tagNameAdditionalPanelLayout = new javax.swing.GroupLayout(tagNameAdditionalPanel); + tagNameAdditionalPanel.setLayout(tagNameAdditionalPanelLayout); + tagNameAdditionalPanelLayout.setHorizontalGroup( + tagNameAdditionalPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 356, Short.MAX_VALUE) + ); + tagNameAdditionalPanelLayout.setVerticalGroup( + tagNameAdditionalPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 456, Short.MAX_VALUE) + ); + + jSplitPane1.setRightComponent(tagNameAdditionalPanel); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jSplitPane1) + .addComponent(panelDescriptionLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(panelDescriptionLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSplitPane1) + .addContainerGap()) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 778, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void addTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTagNameButtonActionPerformed + NewUserTagNameDialog dialog = new NewUserTagNameDialog(); + NewUserTagNameDialog.BUTTON_PRESSED result = dialog.getResult(); + if (result == NewUserTagNameDialog.BUTTON_PRESSED.OK) { + String newTagDisplayName = dialog.getTagName(); + UserTagName newTagName = new UserTagName(newTagDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); + if (tagNames.contains(newTagName)) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.message"), + NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.title"), + JOptionPane.ERROR_MESSAGE); + } else { + tagNames.add(newTagName); + updateTagNamesListModel(); + tagNamesList.setSelectedIndex(tagNames.size() - 1); + enableButtons(); + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + } + }//GEN-LAST:event_addTagNameButtonActionPerformed + + private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed + UserTagName tagName = tagNamesList.getSelectedValue(); + tagNames.remove(tagName); + updateTagNamesListModel(); + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_deleteTagNameButtonActionPerformed + + private void tagNamesListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tagNamesListMouseClicked + enableButtons(); + }//GEN-LAST:event_tagNamesListMouseClicked + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addTagNameButton; + private javax.swing.JButton deleteTagNameButton; + private javax.swing.JPanel jPanel1; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JPanel modifyTagNameListPanel; + private javax.swing.JLabel panelDescriptionLabel; + private javax.swing.JPanel tagNameAdditionalPanel; + private javax.swing.JList tagNamesList; + private javax.swing.JLabel tagNamesListLabel; + // End of variables declaration//GEN-END:variables + + /** + * Updates the tag names model for the tag names list component. + */ + private void updateTagNamesListModel() { + tagNamesListModel.clear(); + Collections.sort(tagNames); + for (UserTagName tagName : tagNames) { + tagNamesListModel.addElement(tagName); + } + } + + /** + * Stores tag name changes in the properties file, called when OK or Apply + * is selected in the OptionsPanel. + * + * Adds all new tag names to the case database for use. + */ + @Override + public void store() { + //Case.getCurrentCase().getServices().getTagsManager().saveUserTagNames(tagNames); + StringBuilder setting = new StringBuilder(); + for (UserTagName tagName : tagNames) { + if (setting.length() != 0) { + setting.append(";"); + } + setting.append(tagName.toSettingsFormat()); + } + ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting.toString()); + if (Case.isCaseOpen()) { + Case.getCurrentCase().getServices().getTagsManager().storeNewUserTagNames(tagNames); + } + } + + /** + * Updates the tag names list component with tag names from the properties + * file. + */ + @Override + public void load() { + //tagNames = Case.getCurrentCase().getServices().getTagsManager().getUserTagNames(); + String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); + tagNames.clear(); + if (null != setting && !setting.isEmpty()) { + List tagNameTuples = Arrays.asList(setting.split(";")); + for (String tagNameTuple : tagNameTuples) { + String[] tagNameAttributes = tagNameTuple.split(","); + tagNames.add(new UserTagName(tagNameAttributes[0], tagNameAttributes[1], tagNameAttributes[2])); + } + } + updateTagNamesListModel(); + enableButtons(); + } + + private void enableButtons() { + boolean ruleIsSelected = tagNamesList.getSelectedIndex() != -1; + deleteTagNameButton.setEnabled(ruleIsSelected); + } + + +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index fcd7b051bd..ed4b58eb98 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -95,8 +95,18 @@ public class TagsManager implements Closeable { } lazyLoadExistingTagNames(); Set tagNameSet = new HashSet<>(); + // Add bookmark tag and other tag names that are in use + tagNameSet.add(uniqueTagNames.get(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"))); tagNameSet.addAll(getTagNamesInUse()); - tagNameSet.addAll(getTagNamesForPropertyFile()); + // Add any tag names defined by the user + String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); + if (null != setting && !setting.isEmpty()) { + List tagNameTuples = Arrays.asList(setting.split(";")); + for (String tagNameTuple : tagNameTuples) { + String[] tagNameAttributes = tagNameTuple.split(","); + tagNameSet.add(uniqueTagNames.get(tagNameAttributes[0])); + } + } return new ArrayList<>(tagNameSet); } @@ -117,27 +127,6 @@ public class TagsManager implements Closeable { return caseDb.getTagNamesInUse(); } - /** - * Gets a list of all tag names associated with the ones found in the - * properties file. - * - * @return A list, possibly empty, of TagName data transfer objects (DTOs). - */ - private synchronized List getTagNamesForPropertyFile() { - lazyLoadExistingTagNames(); - List propertyFileTagNames = new ArrayList<>(); - - String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); - if (null != setting && !setting.isEmpty()) { - List tagNameTuples = Arrays.asList(setting.split(";")); - for (String tagNameTuple : tagNameTuples) { - String[] tagNameAttributes = tagNameTuple.split(","); - propertyFileTagNames.add(uniqueTagNames.get(tagNameAttributes[0])); - } - } - return propertyFileTagNames; - } - /** * Checks whether a tag name with a given display name exists. * @@ -213,30 +202,32 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); - //The tag name already exists in the database, user either - //1) adding it again by error -> throws TagNameAlreadyExistsException - //2) adding it after it was deleted at some point in the past + /** + * It is possible user is trying to add back a tag after having deleted + * it. + */ if (uniqueTagNames.containsKey(displayName)) { TagName existingTagName = uniqueTagNames.get(displayName); - long tagNameCount = getContentTagsCountByTagName(existingTagName) + getBlackboardArtifactTagsCountByTagName(existingTagName); - if (tagNameCount > 0) { - throw new TagNameAlreadyExistsException(); - } else { + long count = getContentTagsCountByTagName(existingTagName) + getBlackboardArtifactTagsCountByTagName(existingTagName); + if (count == 0) { addNewTagNameToTagsSettings(existingTagName); + return existingTagName; + } else { + throw new TagNameAlreadyExistsException(); } - return existingTagName; } + /* - * Add the tag name to the case. - */ + * Add the tag name to the case. + */ TagName newTagName = caseDb.addTagName(displayName, description, color); + uniqueTagNames.put(newTagName.getDisplayName(), newTagName); /* - * Add the tag name to the tags settings. - */ - uniqueTagNames.put(newTagName.getDisplayName(), newTagName); + * Add the tag name to the tags settings. + */ addNewTagNameToTagsSettings(newTagName); - + return newTagName; } @@ -634,15 +625,12 @@ public class TagsManager implements Closeable { /** * Populates the tag names collection and the tag names table in the case * database with the existing tag names from all sources. - * - * Tag names from current case are not saved into the settings file. */ private void lazyLoadExistingTagNames() { if (!tagNamesLoaded) { - addTagNamesFromTagsSettings(); - addPredefinedTagNames(); - saveTagNamesToTagsSettings(); addTagNamesFromCurrentCase(); + addPredefinedTagNames(); + addTagNamesFromTagsSettings(); tagNamesLoaded = true; } } @@ -683,7 +671,7 @@ public class TagsManager implements Closeable { uniqueTagNames.put(tagName.getDisplayName(), tagName); } catch (TskCoreException ex) { Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + tagNameAttributes[0], ex); //NON-NLS - } + } } } } @@ -703,23 +691,24 @@ public class TagsManager implements Closeable { } } } - + /** - * Saves the tag names to a properties file. The properties file is used to - * make it possible to use tag names across cases. + * Adds any user defined tag name to the case db and also to uniqueTagNames, + * to allow user tag names to be displayed while tagging. + * + * @param userTagNames a List of UserTagName objects to be added */ - private void saveTagNamesToTagsSettings() { - if (!uniqueTagNames.isEmpty()) { - StringBuilder setting = new StringBuilder(); - for (TagName tagName : uniqueTagNames.values()) { - if (setting.length() != 0) { - setting.append(";"); + void storeNewUserTagNames(List userTagNames) { + lazyLoadExistingTagNames(); + for (UserTagName utn : userTagNames) { + if (!uniqueTagNames.containsKey(utn.getDisplayName())) { + try { + TagName tagName = caseDb.addTagName(utn.getDisplayName(), utn.getDescription(), TagName.HTML_COLOR.getColorByName(utn.getColorName())); + uniqueTagNames.put(tagName.getDisplayName(), tagName); + } catch (TskCoreException ex) { + Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + utn.getDisplayName(), ex); //NON-NLS } - setting.append(tagName.getDisplayName()).append(","); - setting.append(tagName.getDescription()).append(","); - setting.append(tagName.getColor().name()); } - ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting.toString()); } } @@ -767,12 +756,4 @@ public class TagsManager implements Closeable { private static final long serialVersionUID = 1L; } - /** - * Exception thrown if there is an attempt to delete a nonexistent tag name. - * Unused for current implementation of tag name deletion. - */ - public static class TagNameDoesNotExistException extends Exception { - - } - } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java deleted file mode 100755 index 17343d9690..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManagerOptionsPanel.java +++ /dev/null @@ -1,427 +0,0 @@ -/* -* To change this license header, choose License Headers in Project Properties. -* To change this template file, choose Tools | Templates -* and open the template in the editor. -*/ -package org.sleuthkit.autopsy.casemodule.services; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.TreeSet; -import java.util.logging.Level; -import javax.swing.DefaultListModel; -import org.netbeans.spi.options.OptionsPanelController; -import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.corecomponents.OptionsPanel; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.ModuleSettings; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * A panel to allow the user to create new tag names or to delete tag names that - * user has created in the past. List of user tag names is maintained in a - * properties file, able to be used across cases. - * Potentially room to add other tag name options in the future. - */ -public class TagsManagerOptionsPanel extends javax.swing.JPanel implements OptionsPanel { - - private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS - private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS - - private static final String TAG_BOOKMARK = "Bookmark"; - - private static final String DEFAULT_DESCRIPTION = ""; - private static final String DEFAULT_COLOR_STRING = "NONE"; - - private final DefaultListModel tagNamesListModel; - private Set tagNames; - private List newDisplayNames; - - - /** - * Creates new form TagsManagerOptionsPanel - */ - public TagsManagerOptionsPanel() { - initComponents(); - - tagNamesListModel = new DefaultListModel<>(); - tagNamesList.setModel(tagNamesListModel); - tagNames = getTagNamesFromTagsSettings(); - newDisplayNames = new ArrayList<>(); - - userTagNameTextField.setText(""); - tagNameErrLabel.setText(""); - } - - /** - * Gets tag names from properties file. - * - * @return A set, possibly empty, of CustomTagName objects - */ - private Set getTagNamesFromTagsSettings() { - Set tagNamesFromSettings = new TreeSet<>(); - String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); - if ((setting != null) && !setting.isEmpty()) { - List tagNameTuples = Arrays.asList(setting.split(";")); - for (String tagNameTuple : tagNameTuples) { - String[] tagNameAttributes = tagNameTuple.split(","); - CustomTagName tagName = new CustomTagName(tagNameAttributes[0], tagNameAttributes[1], tagNameAttributes[2]); - tagNamesFromSettings.add(tagName); - } - } else { - tagNamesFromSettings.add(new CustomTagName(TAG_BOOKMARK, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING)); - } - - return tagNamesFromSettings; - } - - /** - * Updates the tag names model for the tag names list component. - */ - private void updateTagNamesListModel() { - tagNamesListModel.clear(); - tagNames.stream().forEach((tagName) -> { - tagNamesListModel.addElement(tagName); - }); - } - - /** - * 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") - // //GEN-BEGIN:initComponents - private void initComponents() { - - jPanel1 = new javax.swing.JPanel(); - jLabel1 = new javax.swing.JLabel(); - jSplitPane1 = new javax.swing.JSplitPane(); - jPanel2 = new javax.swing.JPanel(); - tagNamesListLabel = new javax.swing.JLabel(); - jScrollPane1 = new javax.swing.JScrollPane(); - tagNamesList = new javax.swing.JList<>(); - userTagNameTextField = new javax.swing.JTextField(); - addTagNameButton = new javax.swing.JButton(); - deleteTagNameButton = new javax.swing.JButton(); - tagNameErrLabel = new javax.swing.JLabel(); - jPanel3 = new javax.swing.JPanel(); - - jPanel1.setPreferredSize(new java.awt.Dimension(750, 500)); - - org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.jLabel1.text")); // NOI18N - - jSplitPane1.setDividerLocation(-100); - jSplitPane1.setDividerSize(1); - - org.openide.awt.Mnemonics.setLocalizedText(tagNamesListLabel, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.tagNamesListLabel.text")); // NOI18N - - jScrollPane1.setViewportView(tagNamesList); - - userTagNameTextField.setText(org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.userTagNameTextField.text")); // NOI18N - userTagNameTextField.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - userTagNameTextFieldActionPerformed(evt); - } - }); - - addTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(addTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.text")); // NOI18N - addTagNameButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - addTagNameButtonActionPerformed(evt); - } - }); - - deleteTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete-tag.png"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(deleteTagNameButton, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.deleteTagNameButton.text")); // NOI18N - deleteTagNameButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - deleteTagNameButtonActionPerformed(evt); - } - }); - - tagNameErrLabel.setForeground(new java.awt.Color(255, 0, 0)); - org.openide.awt.Mnemonics.setLocalizedText(tagNameErrLabel, org.openide.util.NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.tagNameErrLabel.text")); // NOI18N - - javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(tagNameErrLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane1) - .addComponent(tagNamesListLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addComponent(userTagNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 135, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(addTagNameButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(deleteTagNameButton))) - .addContainerGap()) - ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(tagNamesListLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 374, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(userTagNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(addTagNameButton) - .addComponent(deleteTagNameButton)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(tagNameErrLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - ); - - jSplitPane1.setLeftComponent(jPanel2); - - javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); - jPanel3.setLayout(jPanel3Layout); - jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 330, Short.MAX_VALUE) - ); - jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 456, Short.MAX_VALUE) - ); - - jSplitPane1.setRightComponent(jPanel3); - - javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jSplitPane1) - .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) - ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSplitPane1) - .addContainerGap()) - ); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 778, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - ); - }// //GEN-END:initComponents - - /** - * Adds a new tag name to the tag names list component without necessarily - * saving the changes. - * - * @param evt ActionEvent generated by clicking the Add Tag Name button - */ - private void addTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTagNameButtonActionPerformed - String newDisplayName = userTagNameTextField.getText(); - - if (newDisplayName.isEmpty()) { - tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.empty")); - return; - } - if (TagsManager.containsIllegalCharacters(newDisplayName)) { - tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.containInvalidCharacter")); - return; - } - - CustomTagName tagName = new CustomTagName(newDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); - - boolean addedToTagNames = tagNames.add(tagName); - - if (!addedToTagNames) { - tagNameErrLabel.setText(NbBundle.getMessage(TagsManagerOptionsPanel.class, "TagsManagerOptionsPanel.addTagNameButton.alreadyExists")); - return; - } - - updateTagNamesListModel(); - - newDisplayNames.add(newDisplayName); - userTagNameTextField.setText(""); - tagNameErrLabel.setText(""); - - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_addTagNameButtonActionPerformed - - /** - * Deletes a tag name from the tag names list component without saving the - * changes. - * - * @param evt ActionEvent generated by clicking the Delete Tag Name button - */ - private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed - CustomTagName tagName = tagNamesList.getSelectedValue(); - if (tagName == null) { - tagNameErrLabel.setText("No tag name selected."); - } else { - tagNames.remove(tagName); - updateTagNamesListModel(); - - if (!tagNamesListModel.isEmpty()) { - tagNamesList.setSelectedIndex(0); - } - - newDisplayNames.remove(tagName.getDisplayName()); - - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - } - }//GEN-LAST:event_deleteTagNameButtonActionPerformed - - /** - * Activates addTagNameButtonActionPerformed instead of the OptionsPanel OK - * button when the userTagNameTextField experiences an action. - * @param evt ActionEvent - */ - private void userTagNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_userTagNameTextFieldActionPerformed - addTagNameButtonActionPerformed(evt); - }//GEN-LAST:event_userTagNameTextFieldActionPerformed - - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton addTagNameButton; - private javax.swing.JButton deleteTagNameButton; - private javax.swing.JLabel jLabel1; - private javax.swing.JPanel jPanel1; - private javax.swing.JPanel jPanel2; - private javax.swing.JPanel jPanel3; - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JSplitPane jSplitPane1; - private javax.swing.JLabel tagNameErrLabel; - private javax.swing.JList tagNamesList; - private javax.swing.JLabel tagNamesListLabel; - private javax.swing.JTextField userTagNameTextField; - // End of variables declaration//GEN-END:variables - - /** - * Stores tag name changes in the properties file, called when OK or Apply - * is selected in the OptionsPanel. - * - * Adds all new tag names to the case database for use. - */ - @Override - public void store() { - for (String displayName : newDisplayNames) { - try { - Case.getCurrentCase().getServices().getTagsManager().addTagName(displayName); - } catch (TagsManager.TagNameAlreadyExistsException ex) { - //Do nothing, this is just to update the database - } catch (TskCoreException ex) { - Logger.getLogger(TagsManagerOptionsPanel.class.getName()).log(Level.SEVERE, "Error adding " + displayName + " tag name", ex); - } - } - newDisplayNames = new ArrayList<>(); - - StringBuilder builder = new StringBuilder(); - for (CustomTagName tagName : tagNames) { - if (builder.length() != 0) { - builder.append(";"); - } - builder.append(tagName.toSettingsFormat()); - } - ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, builder.toString()); - } - - /** - * Updates the tag names list component with tag names from the properties - * file. - */ - @Override - public void load() { - tagNames = getTagNamesFromTagsSettings(); - updateTagNamesListModel(); - if (!tagNamesListModel.isEmpty()) { - tagNamesList.setSelectedIndex(0); - } - tagNameErrLabel.setText(""); - } - - /** - * Discards changes made to the tag names list component if Cancel button is - * selected in the OptionsPanel. - */ - public void cancelChanges() { - tagNames = getTagNamesFromTagsSettings(); - newDisplayNames = new ArrayList<>(); - } - - /** - * Because the DTO TagName constructor should not be called outside of its - * class package, CustomTagName is used in this tags managers panel for the - * purpose of tracking the description and color of each tag name. - */ - private class CustomTagName implements Comparable { - private final String displayName; - private final String description; - private final String colorName; - - private CustomTagName(String displayName, String description, String colorName) { - this.displayName = displayName; - this.description = description; - this.colorName = colorName; - } - - private String getDisplayName() { - return displayName; - } - - @Override - public int compareTo(CustomTagName other) { - return this.getDisplayName().toLowerCase().compareTo(other.getDisplayName().toLowerCase()); - } - - @Override - public int hashCode() { - int hash = 7; - hash = 83 * hash + Objects.hashCode(this.displayName); - hash = 83 * hash + Objects.hashCode(this.description); - hash = 83 * hash + Objects.hashCode(this.colorName); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof CustomTagName)) return false; - CustomTagName thatTagName = (CustomTagName) obj; - return this.getDisplayName().equals(thatTagName.getDisplayName()); - } - - @Override - public String toString() { - return displayName; - } - - /** - * @return A string representation of the tag name in the format that is - * used by the properties file. - */ - public String toSettingsFormat() { - return displayName + "," + description + "," + colorName; - } - - } -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java new file mode 100755 index 0000000000..d70f9d38af --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java @@ -0,0 +1,72 @@ +/* +* To change this license header, choose License Headers in Project Properties. +* To change this template file, choose Tools | Templates +* and open the template in the editor. +*/ +package org.sleuthkit.autopsy.casemodule.services; + +import java.util.Objects; + +/** + * Because the DTO TagName constructor should not be called outside of its + * class package, CustomTagName is used in this tags managers panel for the + * purpose of tracking the description and color of each tag name. + */ +class UserTagName implements Comparable { + + private final String displayName; + private final String description; + private final String colorName; + + UserTagName(String displayName, String description, String colorName) { + this.displayName = displayName; + this.description = description; + this.colorName = colorName; + } + + String getDisplayName() { + return displayName; + } + + String getDescription() { + return description; + } + + String getColorName() { + return colorName; + } + + @Override + public int compareTo(UserTagName other) { + return this.getDisplayName().toLowerCase().compareTo(other.getDisplayName().toLowerCase()); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 83 * hash + Objects.hashCode(this.displayName); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof UserTagName)) { + return false; + } + UserTagName thatTagName = (UserTagName) obj; + return this.getDisplayName().equals(thatTagName.getDisplayName()); + } + + @Override + public String toString() { + return displayName; + } + + /** + * @return A string representation of the tag name in the format that is + * used by the properties file. + */ + public String toSettingsFormat() { + return displayName + "," + description + "," + colorName; + } +} From 807d3c0017642d4c9fed49cb50b9a96b2cb26403 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Fri, 23 Sep 2016 16:07:23 -0400 Subject: [PATCH 14/19] Cleaned up formatting, comments, and imports --- .../services/NewUserTagNameDialog.java | 90 ++++++++++++++----- .../TagNamesOptionsPanelController.java | 21 ++++- .../services/TagNamesSettingsPanel.java | 56 +++++++----- .../casemodule/services/TagsManager.java | 80 ++++++++--------- .../casemodule/services/UserTagName.java | 48 ++++++---- 5 files changed, 191 insertions(+), 104 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java index c39be3dd07..778ae3886d 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. +* Autopsy Forensic Browser +* +* Copyright 2011-2016 Basis Technology Corp. +* Contact: carrier sleuthkit 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.casemodule.services; @@ -10,7 +23,6 @@ import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.beans.PropertyChangeEvent; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.event.DocumentEvent; @@ -18,14 +30,17 @@ import javax.swing.event.DocumentListener; import org.openide.util.NbBundle; public class NewUserTagNameDialog extends javax.swing.JDialog { - + private String userTagDisplayName; private BUTTON_PRESSED result; - + enum BUTTON_PRESSED { OK, CANCEL; } - + + /** + * Creates a new NewUserTagNameDialog dialog. + */ NewUserTagNameDialog() { super(new JFrame(NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.title.text")), NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.title.text"), true); @@ -33,25 +48,34 @@ public class NewUserTagNameDialog extends javax.swing.JDialog { String test = ""; this.display(); } - + + /** + * Sets display settings for the dialog and adds appropriate listeners. + */ private void display() { setLayout(new BorderLayout()); - - // Center the dialog + + /* + * Center the dialog + */ Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); int width = this.getSize().width; int height = this.getSize().height; setLocation((screenDimension.width - width) / 2, (screenDimension.height - height) / 2); - - // Add a handler for when the dialog window is closed directly + + /* + * Add a handler for when the dialog window is closed directly. + */ this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { doButtonAction(false); } }); - - // Add a listener to enable the save button + + /* + * Add a listener to enable the save button when the text field changes. + */ tagNameTextField.getDocument().addDocumentListener(new DocumentListener() { @Override public void changedUpdate(DocumentEvent e) { @@ -69,15 +93,20 @@ public class NewUserTagNameDialog extends javax.swing.JDialog { enableOkButton(); } }); - + enableOkButton(); - - // Show the dialog + + /* + * Used to show the dialog. + */ setResizable(false); setVisible(true); - } - + + /** + * Called when a button is pressed or when the dialog is closed. + * @param okPressed whether the OK button was pressed. + */ private void doButtonAction(boolean okPressed) { if (okPressed) { String newTagDisplayName = tagNameTextField.getText(); @@ -96,20 +125,35 @@ public class NewUserTagNameDialog extends javax.swing.JDialog { setVisible(false); } } - + + /** + * Returns the tag name entered by the user. + * + * @return a new user tag name + */ String getTagName() { return userTagDisplayName; } - + + /** + * Returns information about which button was pressed. + * + * @return BUTTON_PRESSED (OK, CANCEL) + */ BUTTON_PRESSED getResult() { return result; } - + + /** + * Enable the OK button if the tag name text field is not empty. + * Sets the enter button as default, so user can press enter to activate + * an okButton press and add the tag name. + */ private void enableOkButton() { okButton.setEnabled(!tagNameTextField.getText().isEmpty()); getRootPane().setDefaultButton(okButton); } - + /** * 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 diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java index 6f6cb53412..20c478d966 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java @@ -1,8 +1,21 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ +* Autopsy Forensic Browser +* +* Copyright 2011-2016 Basis Technology Corp. +* Contact: carrier sleuthkit 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.casemodule.services; import java.beans.PropertyChangeEvent; diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java index 08fb8ea4e3..e0da98adb6 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java @@ -1,15 +1,27 @@ /* -* To change this license header, choose License Headers in Project Properties. -* To change this template file, choose Tools | Templates -* and open the template in the editor. - */ +* Autopsy Forensic Browser +* +* Copyright 2011-2016 Basis Technology Corp. +* Contact: carrier sleuthkit 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.casemodule.services; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Objects; import javax.swing.DefaultListModel; import javax.swing.JOptionPane; import org.netbeans.spi.options.OptionsPanelController; @@ -32,8 +44,6 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS - private static final String TAG_BOOKMARK = "Bookmark"; - private static final String DEFAULT_DESCRIPTION = ""; private static final String DEFAULT_COLOR_STRING = "NONE"; @@ -185,13 +195,16 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options .addGap(0, 0, Short.MAX_VALUE)) ); }// //GEN-END:initComponents - + private void addTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTagNameButtonActionPerformed NewUserTagNameDialog dialog = new NewUserTagNameDialog(); NewUserTagNameDialog.BUTTON_PRESSED result = dialog.getResult(); if (result == NewUserTagNameDialog.BUTTON_PRESSED.OK) { String newTagDisplayName = dialog.getTagName(); UserTagName newTagName = new UserTagName(newTagDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); + /* + * If tag name already exists, don't add the tag name. + */ if (tagNames.contains(newTagName)) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.message"), @@ -200,13 +213,16 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options } else { tagNames.add(newTagName); updateTagNamesListModel(); + /* + * Set the selection to the tag name that was just added. + */ tagNamesList.setSelectedIndex(tagNames.size() - 1); enableButtons(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } } }//GEN-LAST:event_addTagNameButtonActionPerformed - + private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed UserTagName tagName = tagNamesList.getSelectedValue(); tagNames.remove(tagName); @@ -236,7 +252,6 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options */ private void updateTagNamesListModel() { tagNamesListModel.clear(); - Collections.sort(tagNames); for (UserTagName tagName : tagNames) { tagNamesListModel.addElement(tagName); } @@ -244,13 +259,13 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options /** * Stores tag name changes in the properties file, called when OK or Apply - * is selected in the OptionsPanel. + * is selected in the options panel. * - * Adds all new tag names to the case database for use. + * Adds all new tag names to the case database for displaying usable tag + * names when tagging. */ @Override public void store() { - //Case.getCurrentCase().getServices().getTagsManager().saveUserTagNames(tagNames); StringBuilder setting = new StringBuilder(); for (UserTagName tagName : tagNames) { if (setting.length() != 0) { @@ -263,31 +278,32 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options Case.getCurrentCase().getServices().getTagsManager().storeNewUserTagNames(tagNames); } } - + /** * Updates the tag names list component with tag names from the properties * file. */ @Override public void load() { - //tagNames = Case.getCurrentCase().getServices().getTagsManager().getUserTagNames(); String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); tagNames.clear(); if (null != setting && !setting.isEmpty()) { List tagNameTuples = Arrays.asList(setting.split(";")); for (String tagNameTuple : tagNameTuples) { String[] tagNameAttributes = tagNameTuple.split(","); - tagNames.add(new UserTagName(tagNameAttributes[0], tagNameAttributes[1], tagNameAttributes[2])); - } + tagNames.add(new UserTagName(tagNameAttributes[0], tagNameAttributes[1], tagNameAttributes[2])); } + } + Collections.sort(tagNames); updateTagNamesListModel(); enableButtons(); } - + + /** + * Only enable delete button when there is a tag name selected in the list. + */ private void enableButtons() { boolean ruleIsSelected = tagNamesList.getSelectedIndex() != -1; deleteTagNameButton.setEnabled(ruleIsSelected); } - - } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index ed4b58eb98..5727fde423 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -44,14 +44,14 @@ import org.sleuthkit.datamodel.TskCoreException; * of tags applied to content and blackboard artifacts by users. */ public class TagsManager implements Closeable { - + private static final Logger logger = Logger.getLogger(TagsManager.class.getName()); private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS private SleuthkitCase caseDb; private final HashMap uniqueTagNames = new HashMap<>(); private boolean tagNamesLoaded = false; - + /** * Constructs a per case Autopsy service that manages the creation, * updating, and deletion of tags applied to content and blackboard @@ -79,7 +79,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getAllTagNames(); } - + /** * Gets a list of all tag names currently being used or tag names loaded * from the properties file. @@ -109,7 +109,7 @@ public class TagsManager implements Closeable { } return new ArrayList<>(tagNameSet); } - + /** * Gets a list of all tag names currently in use for tagging content or * artifacts. @@ -126,7 +126,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getTagNamesInUse(); } - + /** * Checks whether a tag name with a given display name exists. * @@ -138,7 +138,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return uniqueTagNames.containsKey(tagDisplayName); } - + /** * Adds a new tag name to the current case and to the tags settings. * @@ -158,7 +158,7 @@ public class TagsManager implements Closeable { } return addTagName(displayName, "", TagName.HTML_COLOR.NONE); } - + /** * Adds a new tag name to the current case and to the tags settings. * @@ -179,7 +179,7 @@ public class TagsManager implements Closeable { } return addTagName(displayName, description, TagName.HTML_COLOR.NONE); } - + /** * Adds a new tag name to the current case and to the tags settings. * @@ -199,10 +199,10 @@ public class TagsManager implements Closeable { if (null == caseDb) { throw new TskCoreException("Tags manager has been closed"); } - + lazyLoadExistingTagNames(); - - /** + + /* * It is possible user is trying to add back a tag after having deleted * it. */ @@ -222,7 +222,7 @@ public class TagsManager implements Closeable { */ TagName newTagName = caseDb.addTagName(displayName, description, color); uniqueTagNames.put(newTagName.getDisplayName(), newTagName); - + /* * Add the tag name to the tags settings. */ @@ -230,7 +230,7 @@ public class TagsManager implements Closeable { return newTagName; } - + /** * Tags a content object. * @@ -248,7 +248,7 @@ public class TagsManager implements Closeable { } return addContentTag(content, tagName, "", -1, -1); } - + /** * Tags a content object. * @@ -267,7 +267,7 @@ public class TagsManager implements Closeable { } return addContentTag(content, tagName, comment, -1, -1); } - + /** * Tags a content object or a section of a content object. * @@ -325,7 +325,7 @@ public class TagsManager implements Closeable { } return tag; } - + /** * Deletes a content tag. * @@ -349,7 +349,7 @@ public class TagsManager implements Closeable { logger.log(Level.SEVERE, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteContentTag.noCaseWarning"), ex); } } - + /** * Gets all content tags for the current case. * @@ -365,7 +365,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getAllContentTags(); } - + /** * Gets content tags count by tag name. * @@ -383,7 +383,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getContentTagsCountByTagName(tagName); } - + /** * Gets a content tag by tag id. * @@ -401,7 +401,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getContentTagByID(tagID); } - + /** * Gets content tags by tag name. * @@ -420,7 +420,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getContentTagsByTagName(tagName); } - + /** * Gets content tags count by content. * @@ -439,7 +439,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getContentTagsByContent(content); } - + /** * Tags a blackboard artifact object. * @@ -458,7 +458,7 @@ public class TagsManager implements Closeable { } return addBlackboardArtifactTag(artifact, tagName, ""); } - + /** * Tags a blackboard artifact object. * @@ -484,7 +484,7 @@ public class TagsManager implements Closeable { } tag = caseDb.addBlackboardArtifactTag(artifact, tagName, comment); } - + try { Case.getCurrentCase().notifyBlackBoardArtifactTagAdded(tag); } catch (IllegalStateException ex) { @@ -492,7 +492,7 @@ public class TagsManager implements Closeable { } return tag; } - + /** * Deletes a blackboard artifact tag. * @@ -516,7 +516,7 @@ public class TagsManager implements Closeable { logger.log(Level.WARNING, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteBlackboardArtifactTag.noCaseWarning"), ex); } } - + /** * Gets all blackboard artifact tags for the current case. * @@ -532,7 +532,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getAllBlackboardArtifactTags(); } - + /** * Gets blackboard artifact tags count by tag name. * @@ -551,7 +551,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagsCountByTagName(tagName); } - + /** * Gets a blackboard artifact tag by tag id. * @@ -569,7 +569,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagByID(tagID); } - + /** * Gets blackboard artifact tags by tag name. * @@ -588,7 +588,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagsByTagName(tagName); } - + /** * Gets blackboard artifact tags for a particular blackboard artifact. * @@ -607,7 +607,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagsByArtifact(artifact); } - + /** * Closes the tags manager, saving the available tag names to secondary * storage. @@ -621,7 +621,7 @@ public class TagsManager implements Closeable { //saveTagNamesToTagsSettings(); caseDb = null; } - + /** * Populates the tag names collection and the tag names table in the case * database with the existing tag names from all sources. @@ -634,7 +634,7 @@ public class TagsManager implements Closeable { tagNamesLoaded = true; } } - + /** * Adds any tag names that are in the case database to the tag names * collection. @@ -649,7 +649,7 @@ public class TagsManager implements Closeable { Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag types from the current case", ex); //NON-NLS } } - + /** * Adds any tag names that are in the properties file to the tag names * collection and to the case database. The properties file is used to make @@ -676,7 +676,7 @@ public class TagsManager implements Closeable { } } } - + /** * Adds the standard tag names to the tag names collection. */ @@ -696,7 +696,7 @@ public class TagsManager implements Closeable { * Adds any user defined tag name to the case db and also to uniqueTagNames, * to allow user tag names to be displayed while tagging. * - * @param userTagNames a List of UserTagName objects to be added + * @param userTagNames a List of UserTagName objects to be potentially added */ void storeNewUserTagNames(List userTagNames) { lazyLoadExistingTagNames(); @@ -711,7 +711,7 @@ public class TagsManager implements Closeable { } } } - + /** * Adds a new tag name to the settings file, used when user creates a new * tag name. @@ -727,7 +727,7 @@ public class TagsManager implements Closeable { setting += tagName.getDisplayName() + "," + tagName.getDescription() + "," + tagName.getColor().toString(); ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting); } - + /** * Returns true if the tag display name contains an illegal character. Used * after a tag display name is retrieved from user input. @@ -747,7 +747,7 @@ public class TagsManager implements Closeable { || content.contains(",") || content.contains(";")); } - + /** * Exception thrown if there is an attempt to add a duplicate tag name. */ @@ -755,5 +755,5 @@ public class TagsManager implements Closeable { private static final long serialVersionUID = 1L; } - + } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java index d70f9d38af..c761665c08 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java @@ -1,53 +1,67 @@ /* -* To change this license header, choose License Headers in Project Properties. -* To change this template file, choose Tools | Templates -* and open the template in the editor. +* Autopsy Forensic Browser +* +* Copyright 2011-2016 Basis Technology Corp. +* Contact: carrier sleuthkit 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.casemodule.services; import java.util.Objects; /** - * Because the DTO TagName constructor should not be called outside of its - * class package, CustomTagName is used in this tags managers panel for the - * purpose of tracking the description and color of each tag name. + * Because the DTO TagName constructor can not be called outside of its class + * package, UserTagName is used to keep track of user tag names while + * preserving properties that will potentially be implemented in the future + * (tag name description and tag name color). */ class UserTagName implements Comparable { - + private final String displayName; private final String description; private final String colorName; - + UserTagName(String displayName, String description, String colorName) { this.displayName = displayName; this.description = description; this.colorName = colorName; } - + String getDisplayName() { return displayName; } - + String getDescription() { return description; } - + String getColorName() { return colorName; } - + @Override public int compareTo(UserTagName other) { return this.getDisplayName().toLowerCase().compareTo(other.getDisplayName().toLowerCase()); } - + @Override public int hashCode() { int hash = 7; hash = 83 * hash + Objects.hashCode(this.displayName); return hash; } - + @Override public boolean equals(Object obj) { if (!(obj instanceof UserTagName)) { @@ -56,15 +70,15 @@ class UserTagName implements Comparable { UserTagName thatTagName = (UserTagName) obj; return this.getDisplayName().equals(thatTagName.getDisplayName()); } - + @Override public String toString() { return displayName; } - + /** * @return A string representation of the tag name in the format that is - * used by the properties file. + * used by the properties file. */ public String toSettingsFormat() { return displayName + "," + description + "," + colorName; From e7a5f59081ddf25d3f7951bcf9a25e1a81a82f25 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 27 Sep 2016 09:44:04 -0400 Subject: [PATCH 15/19] Modified button behavior and text, disallowed empty tags --- .../casemodule/services/Bundle.properties | 4 +- .../services/NewUserTagNameDialog.java | 21 ++++++---- .../services/TagNamesSettingsPanel.form | 12 +++--- .../services/TagNamesSettingsPanel.java | 30 +++++++------- .../casemodule/services/TagsManager.java | 40 +++++++++---------- 5 files changed, 57 insertions(+), 50 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index 226b661523..c117fe5186 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -13,7 +13,6 @@ TagsManagerOptionsPanel.addTagNameButton.empty=Tag name text is empty. TagsManagerOptionsPanel.addTagNameButton.containInvalidCharacter=Tag name may not contain any of the following symbols\: \\ \: * ? " < > | , ; TagsManagerOptionsPanel.addTagNameButton.alreadyExists=Tag name already exists. TagNamesSettingsPanel.deleteTagNameButton.text=Delete Tag Name -TagNamesSettingsPanel.addTagNameButton.text=Add Tag Name TagNamesSettingsPanel.tagNamesListLabel.text=Your tag names: NewUserTagNameDialog.tagNameTextField.text= NewUserTagNameDialog.newTagNameLabel.text=New Tag Name: @@ -24,4 +23,7 @@ NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.message=Tag name may n NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.title=Invalid character in tag name TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.message=The tag name already exists in your settings TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.title=Tag name already exists +NewUserTagNameDialog.JOptionPane.tagNameEmpty.message=The tag name cannot be empty +NewUserTagNameDialog.JOptionPane.tagNameEmpty.title=Empty tag name TagNamesSettingsPanel.panelDescriptionLabel.text=Autopsy keeps a list of the tag names you have created in the past. Add more or delete them here. +TagNamesSettingsPanel.newTagNameButton.text=New Tag Name diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java index 778ae3886d..12fc8cb22b 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java @@ -45,7 +45,6 @@ public class NewUserTagNameDialog extends javax.swing.JDialog { super(new JFrame(NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.title.text")), NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.title.text"), true); initComponents(); - String test = ""; this.display(); } @@ -74,7 +73,7 @@ public class NewUserTagNameDialog extends javax.swing.JDialog { }); /* - * Add a listener to enable the save button when the text field changes. + * Add a listener to enable the OK button when the text field changes. */ tagNameTextField.getDocument().addDocumentListener(new DocumentListener() { @Override @@ -109,21 +108,27 @@ public class NewUserTagNameDialog extends javax.swing.JDialog { */ private void doButtonAction(boolean okPressed) { if (okPressed) { - String newTagDisplayName = tagNameTextField.getText(); + String newTagDisplayName = tagNameTextField.getText().trim(); + if (newTagDisplayName.isEmpty()) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameEmpty.message"), + NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameEmpty.title"), + JOptionPane.ERROR_MESSAGE); + return; + } if (TagsManager.containsIllegalCharacters(newTagDisplayName)) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.message"), NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.title"), JOptionPane.ERROR_MESSAGE); - } else { - userTagDisplayName = newTagDisplayName; - result = BUTTON_PRESSED.OK; - setVisible(false); + return; } + userTagDisplayName = newTagDisplayName; + result = BUTTON_PRESSED.OK; } else { result = BUTTON_PRESSED.CANCEL; - setVisible(false); } + setVisible(false); } /** diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form index 59cac6e9bc..3e71ffdeeb 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form @@ -92,10 +92,10 @@ - + - + @@ -112,7 +112,7 @@ - + @@ -150,17 +150,17 @@ - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java index e0da98adb6..576b375b5d 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java @@ -80,7 +80,7 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options tagNamesListLabel = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); tagNamesList = new javax.swing.JList<>(); - addTagNameButton = new javax.swing.JButton(); + newTagNameButton = new javax.swing.JButton(); deleteTagNameButton = new javax.swing.JButton(); tagNameAdditionalPanel = new javax.swing.JPanel(); @@ -100,11 +100,11 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options }); jScrollPane1.setViewportView(tagNamesList); - addTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(addTagNameButton, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.addTagNameButton.text")); // NOI18N - addTagNameButton.addActionListener(new java.awt.event.ActionListener() { + newTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(newTagNameButton, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.newTagNameButton.text")); // NOI18N + newTagNameButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - addTagNameButtonActionPerformed(evt); + newTagNameButtonActionPerformed(evt); } }); @@ -125,10 +125,10 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options .addGroup(modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(tagNamesListLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(modifyTagNameListPanelLayout.createSequentialGroup() - .addComponent(addTagNameButton) + .addComponent(newTagNameButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(deleteTagNameButton) - .addGap(0, 115, Short.MAX_VALUE)) + .addGap(0, 113, Short.MAX_VALUE)) .addComponent(jScrollPane1)) .addContainerGap()) ); @@ -141,7 +141,7 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(addTagNameButton) + .addComponent(newTagNameButton) .addComponent(deleteTagNameButton)) .addContainerGap()) ); @@ -196,7 +196,7 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options ); }// //GEN-END:initComponents - private void addTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTagNameButtonActionPerformed + private void newTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTagNameButtonActionPerformed NewUserTagNameDialog dialog = new NewUserTagNameDialog(); NewUserTagNameDialog.BUTTON_PRESSED result = dialog.getResult(); if (result == NewUserTagNameDialog.BUTTON_PRESSED.OK) { @@ -209,24 +209,26 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options JOptionPane.showMessageDialog(null, NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.message"), NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.title"), - JOptionPane.ERROR_MESSAGE); + JOptionPane.INFORMATION_MESSAGE); } else { tagNames.add(newTagName); updateTagNamesListModel(); /* * Set the selection to the tag name that was just added. */ - tagNamesList.setSelectedIndex(tagNames.size() - 1); + int index = tagNames.indexOf(newTagName); + tagNamesList.setSelectedIndex(index); enableButtons(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } } - }//GEN-LAST:event_addTagNameButtonActionPerformed + }//GEN-LAST:event_newTagNameButtonActionPerformed private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed UserTagName tagName = tagNamesList.getSelectedValue(); tagNames.remove(tagName); updateTagNamesListModel(); + enableButtons(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_deleteTagNameButtonActionPerformed @@ -235,12 +237,12 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options }//GEN-LAST:event_tagNamesListMouseClicked // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton addTagNameButton; private javax.swing.JButton deleteTagNameButton; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSplitPane jSplitPane1; private javax.swing.JPanel modifyTagNameListPanel; + private javax.swing.JButton newTagNameButton; private javax.swing.JLabel panelDescriptionLabel; private javax.swing.JPanel tagNameAdditionalPanel; private javax.swing.JList tagNamesList; @@ -252,6 +254,7 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options */ private void updateTagNamesListModel() { tagNamesListModel.clear(); + Collections.sort(tagNames); for (UserTagName tagName : tagNames) { tagNamesListModel.addElement(tagName); } @@ -294,7 +297,6 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options tagNames.add(new UserTagName(tagNameAttributes[0], tagNameAttributes[1], tagNameAttributes[2])); } } - Collections.sort(tagNames); updateTagNamesListModel(); enableButtons(); } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index 5727fde423..e2b3fd6ab1 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -15,7 +15,7 @@ * 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.casemodule.services; import java.io.Closeable; @@ -83,7 +83,7 @@ public class TagsManager implements Closeable { /** * Gets a list of all tag names currently being used or tag names loaded * from the properties file. - * + * * @return A list, possibly empty, of TagName data transfer objects (DTOs). * * @throws TskCoreException If there is an error reading from the case @@ -147,7 +147,7 @@ public class TagsManager implements Closeable { * @return A TagName data transfer object (DTO) representing the new tag * name. * - * @throws TagNameAlreadyExistsException If the tag name would be a + * @throws TagNameAlreadyExistsException If the tag name would be a * duplicate. * @throws TskCoreException If there is an error adding the tag * to the case database. @@ -168,7 +168,7 @@ public class TagsManager implements Closeable { * @return A TagName data transfer object (DTO) representing the new tag * name. * - * @throws TagNameAlreadyExistsException If the tag name would be a + * @throws TagNameAlreadyExistsException If the tag name would be a * duplicate. * @throws TskCoreException If there is an error adding the tag * to the case database. @@ -190,7 +190,7 @@ public class TagsManager implements Closeable { * @return A TagName data transfer object (DTO) representing the new tag * name. * - * @throws TagNameAlreadyExistsException If the tag name would be a + * @throws TagNameAlreadyExistsException If the tag name would be a * duplicate. * @throws TskCoreException If there is an error adding the tag * to the case database. @@ -291,33 +291,33 @@ public class TagsManager implements Closeable { ContentTag tag; synchronized (this) { lazyLoadExistingTagNames(); - + if (null == comment) { throw new IllegalArgumentException("Passed null comment argument"); } - + if (beginByteOffset >= 0 && endByteOffset >= 1) { if (beginByteOffset > content.getSize() - 1) { throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.beginByteOffsetOOR.msg", beginByteOffset, content.getSize() - 1)); } - + if (endByteOffset > content.getSize() - 1) { throw new IllegalArgumentException( NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endByteOffsetOOR.msg", endByteOffset, content.getSize() - 1)); } - + if (endByteOffset < beginByteOffset) { throw new IllegalArgumentException( NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endLTbegin.msg")); } } - + tag = caseDb.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset); } - + try { Case.getCurrentCase().notifyContentTagAdded(tag); } catch (IllegalStateException ex) { @@ -342,7 +342,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); caseDb.deleteContentTag(tag); } - + try { Case.getCurrentCase().notifyContentTagDeleted(tag); } catch (IllegalStateException ex) { @@ -509,7 +509,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); caseDb.deleteBlackboardArtifactTag(tag); } - + try { Case.getCurrentCase().notifyBlackBoardArtifactTagDeleted(tag); } catch (IllegalStateException ex) { @@ -618,7 +618,6 @@ public class TagsManager implements Closeable { @Override @Deprecated public synchronized void close() throws IOException { - //saveTagNamesToTagsSettings(); caseDb = null; } @@ -660,7 +659,7 @@ public class TagsManager implements Closeable { if (null != setting && !setting.isEmpty()) { // Read the tag name setting and break it into tag name tuples. List tagNameTuples = Arrays.asList(setting.split(";")); - + // Parse each tuple and add the tag names to the current case, one // at a time to gracefully discard any duplicates or corrupt tuples. for (String tagNameTuple : tagNameTuples) { @@ -671,7 +670,7 @@ public class TagsManager implements Closeable { uniqueTagNames.put(tagName.getDisplayName(), tagName); } catch (TskCoreException ex) { Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + tagNameAttributes[0], ex); //NON-NLS - } + } } } } @@ -695,7 +694,7 @@ public class TagsManager implements Closeable { /** * Adds any user defined tag name to the case db and also to uniqueTagNames, * to allow user tag names to be displayed while tagging. - * + * * @param userTagNames a List of UserTagName objects to be potentially added */ void storeNewUserTagNames(List userTagNames) { @@ -720,8 +719,7 @@ public class TagsManager implements Closeable { String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); if (setting == null || setting.isEmpty()) { setting = ""; - } - else { + } else { setting += ";"; } setting += tagName.getDisplayName() + "," + tagName.getDescription() + "," + tagName.getColor().toString(); @@ -731,7 +729,7 @@ public class TagsManager implements Closeable { /** * Returns true if the tag display name contains an illegal character. Used * after a tag display name is retrieved from user input. - * + * * @param content Display name of the tag being added. * @return boolean indicating whether the name has an invalid character. */ @@ -752,7 +750,7 @@ public class TagsManager implements Closeable { * Exception thrown if there is an attempt to add a duplicate tag name. */ public static class TagNameAlreadyExistsException extends Exception { - + private static final long serialVersionUID = 1L; } From a32b95943f5b997c0a722025dd71774954ededd2 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 27 Sep 2016 11:17:31 -0400 Subject: [PATCH 16/19] Made TagsManager methods more general, moved tag name display logic to TagsManager clients --- .../autopsy/actions/AddTagAction.java | 11 ++++-- .../actions/GetTagNameAndCommentDialog.java | 9 ++++- .../autopsy/actions/GetTagNameDialog.java | 8 ++++- .../services/TagNamesSettingsPanel.form | 1 + .../services/TagNamesSettingsPanel.java | 7 ++++ .../casemodule/services/TagsManager.java | 36 +++++++++---------- 6 files changed, 50 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java index 7db5a5e0ee..2729e5e6ff 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java @@ -19,8 +19,12 @@ package org.sleuthkit.autopsy.actions; import java.awt.event.ActionEvent; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.TreeSet; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.JMenu; @@ -89,8 +93,11 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); List tagNames = null; try { - tagNames = tagsManager.getAllTagNamesForDisplay(); - Collections.sort(tagNames); + Set tagNamesSet = new TreeSet<>(); + tagNamesSet.addAll(tagsManager.getUserTagNames()); + tagNamesSet.addAll(tagsManager.getTagNamesInUse()); + tagNamesSet.addAll(tagsManager.getPredefinedTagNames()); + tagNames = new ArrayList(tagNamesSet); } catch (TskCoreException ex) { Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java index 19b32e3905..9d9dbaa7c2 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java @@ -21,8 +21,11 @@ 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.HashMap; import java.util.List; +import java.util.Set; +import java.util.TreeSet; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.ActionMap; @@ -117,7 +120,11 @@ public class GetTagNameAndCommentDialog extends JDialog { TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); List currentTagNames = null; try { - currentTagNames = tagsManager.getAllTagNamesForDisplay(); + Set tagNamesSet = new TreeSet<>(); + tagNamesSet.addAll(tagsManager.getUserTagNames()); + tagNamesSet.addAll(tagsManager.getTagNamesInUse()); + tagNamesSet.addAll(tagsManager.getPredefinedTagNames()); + currentTagNames = new ArrayList(tagNamesSet); } catch (TskCoreException ex) { Logger.getLogger(GetTagNameAndCommentDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java index fd8634e123..f055469fef 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java @@ -24,6 +24,8 @@ import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Set; +import java.util.TreeSet; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.ActionMap; @@ -98,7 +100,11 @@ public class GetTagNameDialog extends JDialog { TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); List currentTagNames = null; try { - currentTagNames = tagsManager.getAllTagNamesForDisplay(); + Set tagNamesSet = new TreeSet<>(); + tagNamesSet.addAll(tagsManager.getUserTagNames()); + tagNamesSet.addAll(tagsManager.getTagNamesInUse()); + tagNamesSet.addAll(tagsManager.getPredefinedTagNames()); + currentTagNames = new ArrayList(tagNamesSet); } catch (TskCoreException ex) { Logger.getLogger(GetTagNameDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form index 3e71ffdeeb..2ebeee3142 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form @@ -143,6 +143,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java index 576b375b5d..9905869ae5 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java @@ -97,6 +97,9 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options public void mouseClicked(java.awt.event.MouseEvent evt) { tagNamesListMouseClicked(evt); } + public void mousePressed(java.awt.event.MouseEvent evt) { + tagNamesListMousePressed(evt); + } }); jScrollPane1.setViewportView(tagNamesList); @@ -236,6 +239,10 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options enableButtons(); }//GEN-LAST:event_tagNamesListMouseClicked + private void tagNamesListMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tagNamesListMousePressed + enableButtons(); + }//GEN-LAST:event_tagNamesListMousePressed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton deleteTagNameButton; private javax.swing.JPanel jPanel1; diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index e2b3fd6ab1..3d29b17ebb 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -64,8 +64,7 @@ public class TagsManager implements Closeable { } /** - * Gets a list of all tag names currently available for tagging content or - * artifacts. + * Gets a list of all tag names currently in the case database. * * @return A list, possibly empty, of TagName data transfer objects (DTOs). * @@ -81,33 +80,34 @@ public class TagsManager implements Closeable { } /** - * Gets a list of all tag names currently being used or tag names loaded - * from the properties file. + * Gets a list of all user tag names from the preference file. * * @return A list, possibly empty, of TagName data transfer objects (DTOs). - * - * @throws TskCoreException If there is an error reading from the case - * database. */ - public synchronized List getAllTagNamesForDisplay() throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } + public synchronized List getUserTagNames() { lazyLoadExistingTagNames(); - Set tagNameSet = new HashSet<>(); - // Add bookmark tag and other tag names that are in use - tagNameSet.add(uniqueTagNames.get(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"))); - tagNameSet.addAll(getTagNamesInUse()); - // Add any tag names defined by the user + List tagNameList = new ArrayList<>(); String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); if (null != setting && !setting.isEmpty()) { List tagNameTuples = Arrays.asList(setting.split(";")); for (String tagNameTuple : tagNameTuples) { String[] tagNameAttributes = tagNameTuple.split(","); - tagNameSet.add(uniqueTagNames.get(tagNameAttributes[0])); + tagNameList.add(uniqueTagNames.get(tagNameAttributes[0])); } } - return new ArrayList<>(tagNameSet); + return tagNameList; + } + + /** + * Gets a list of all predefined tag names. + * + * @return A list of TagName data transfer objects (DTOs). + */ + public synchronized List getPredefinedTagNames() { + lazyLoadExistingTagNames(); + List tagNameList = new ArrayList<>(); + tagNameList.add(uniqueTagNames.get(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"))); + return tagNameList; } /** From cdcd0fa45e17eb57427284a193bbb0d9e41af855 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 27 Sep 2016 15:19:44 -0400 Subject: [PATCH 17/19] Updated TagsManager for multiuser loading, changed some UI text --- Core/src/org/sleuthkit/autopsy/actions/Bundle.properties | 4 ++-- .../sleuthkit/autopsy/casemodule/services/Bundle.properties | 4 ++-- .../autopsy/casemodule/services/NewUserTagNameDialog.java | 2 +- .../autopsy/casemodule/services/TagNamesSettingsPanel.java | 4 ++-- .../sleuthkit/autopsy/casemodule/services/TagsManager.java | 3 +++ 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties index ba828aed5d..d964d91fc7 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties @@ -1,7 +1,7 @@ GetTagNameDialog.tagNameField.text= GetTagNameDialog.cancelButton.text=Cancel GetTagNameDialog.okButton.text=OK -GetTagNameDialog.preexistingLabel.text=Pre-existing Tags: +GetTagNameDialog.preexistingLabel.text=Pre-existing Tag Names: GetTagNameDialog.newTagPanel.border.title=New Tag GetTagNameDialog.tagNameLabel.text=Tag Name: GetTagNameAndCommentDialog.newTagButton.text=New Tag Name @@ -58,4 +58,4 @@ OpenOutputFolder.CouldNotOpenOutputFolder=Could not open output folder ShowIngestProgressSnapshotAction.actionName.text=Get Ingest Progress Snapshot OpenPythonModulesFolderAction.actionName.text=Python Plugins OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python plugins folder not found: {0} -CTL_OpenPythonModulesFolderAction=Python Plugins \ No newline at end of file +CTL_OpenPythonModulesFolderAction=Python Plugins diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index c117fe5186..8fbcb50595 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -1,4 +1,4 @@ -OptionsCategory_Name_TagNamesOptions=My Tag Names +OptionsCategory_Name_TagNamesOptions=Tags OptionsCategory_TagNames=TagNames TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} out of content size range (0 - {1}) TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} out of content size range (0 - {1}) @@ -13,7 +13,7 @@ TagsManagerOptionsPanel.addTagNameButton.empty=Tag name text is empty. TagsManagerOptionsPanel.addTagNameButton.containInvalidCharacter=Tag name may not contain any of the following symbols\: \\ \: * ? " < > | , ; TagsManagerOptionsPanel.addTagNameButton.alreadyExists=Tag name already exists. TagNamesSettingsPanel.deleteTagNameButton.text=Delete Tag Name -TagNamesSettingsPanel.tagNamesListLabel.text=Your tag names: +TagNamesSettingsPanel.tagNamesListLabel.text=Tag names: NewUserTagNameDialog.tagNameTextField.text= NewUserTagNameDialog.newTagNameLabel.text=New Tag Name: NewUserTagNameDialog.okButton.text=OK diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java index 12fc8cb22b..bd04678ba9 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java @@ -29,7 +29,7 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.openide.util.NbBundle; -public class NewUserTagNameDialog extends javax.swing.JDialog { +class NewUserTagNameDialog extends javax.swing.JDialog { private String userTagDisplayName; private BUTTON_PRESSED result; diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java index 9905869ae5..051e8e9549 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java @@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; * properties file, able to be used across cases. Potentially room to add other * tag name options in the future. */ -public class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsPanel { +final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsPanel { private static final Logger logger = Logger.getLogger(TagNamesSettingsPanel.class.getName()); @@ -53,7 +53,7 @@ public class TagNamesSettingsPanel extends javax.swing.JPanel implements Options /** * Creates new form TagsManagerOptionsPanel */ - public TagNamesSettingsPanel() { + TagNamesSettingsPanel() { initComponents(); customizeComponents(); } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index 3d29b17ebb..9cd7a72183 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -631,6 +631,9 @@ public class TagsManager implements Closeable { addPredefinedTagNames(); addTagNamesFromTagsSettings(); tagNamesLoaded = true; + } else { + // Reload case db tag names in case another user has added some. + addTagNamesFromCurrentCase(); } } From ba4640648c2d4087083b0384683fc58b4fa3f226 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 27 Sep 2016 15:30:57 -0400 Subject: [PATCH 18/19] Updated listener method for list selection --- .../services/TagNamesSettingsPanel.form | 4 --- .../services/TagNamesSettingsPanel.java | 26 +++++++------------ 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form index 2ebeee3142..4412f20274 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form @@ -141,10 +141,6 @@ - - - - diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java index 051e8e9549..d6f4953824 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java @@ -24,6 +24,8 @@ import java.util.Collections; import java.util.List; import javax.swing.DefaultListModel; import javax.swing.JOptionPane; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; @@ -57,11 +59,17 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP initComponents(); customizeComponents(); } - + private void customizeComponents() { tagNamesListModel = new DefaultListModel<>(); tagNamesList.setModel(tagNamesListModel); tagNames = new ArrayList<>(); + tagNamesList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + enableButtons(); + } + }); } /** @@ -93,14 +101,6 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP org.openide.awt.Mnemonics.setLocalizedText(tagNamesListLabel, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.tagNamesListLabel.text")); // NOI18N - tagNamesList.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseClicked(java.awt.event.MouseEvent evt) { - tagNamesListMouseClicked(evt); - } - public void mousePressed(java.awt.event.MouseEvent evt) { - tagNamesListMousePressed(evt); - } - }); jScrollPane1.setViewportView(tagNamesList); newTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N @@ -235,14 +235,6 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_deleteTagNameButtonActionPerformed - private void tagNamesListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tagNamesListMouseClicked - enableButtons(); - }//GEN-LAST:event_tagNamesListMouseClicked - - private void tagNamesListMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tagNamesListMousePressed - enableButtons(); - }//GEN-LAST:event_tagNamesListMousePressed - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton deleteTagNameButton; private javax.swing.JPanel jPanel1; From b7f227b76ccb8b17874bf0e04524a82d6016bc68 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Wed, 28 Sep 2016 15:09:28 -0400 Subject: [PATCH 19/19] Updated implementation to not automatically add user tag names --- .../autopsy/actions/AddTagAction.java | 54 +++++++---- .../actions/GetTagNameAndCommentDialog.java | 42 +++++---- .../autopsy/actions/GetTagNameDialog.java | 41 +++----- .../casemodule/services/Bundle.properties | 3 - .../services/TagNamesSettingsPanel.java | 6 ++ .../casemodule/services/TagsManager.java | 94 ++++++++++--------- 6 files changed, 134 insertions(+), 106 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java index 2729e5e6ff..3d394e9215 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java @@ -19,12 +19,8 @@ package org.sleuthkit.autopsy.actions; import java.awt.event.ActionEvent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; +import java.util.Map; +import java.util.TreeMap; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.JMenu; @@ -91,13 +87,12 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { // Get the current set of tag names. TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); - List tagNames = null; + Map tagNamesMap = null; try { - Set tagNamesSet = new TreeSet<>(); - tagNamesSet.addAll(tagsManager.getUserTagNames()); - tagNamesSet.addAll(tagsManager.getTagNamesInUse()); - tagNamesSet.addAll(tagsManager.getPredefinedTagNames()); - tagNames = new ArrayList(tagNamesSet); + tagNamesMap = new TreeMap<>(); + tagNamesMap.putAll(tagsManager.getUserTagNamesMap()); + tagNamesMap.putAll(tagsManager.getPredefinedTagNamesMap()); + tagNamesMap.putAll(tagsManager.getTagNamesInUseMap()); } catch (TskCoreException ex) { Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } @@ -109,11 +104,11 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { // Each tag name in the current set of tags gets its own menu item in // the "Quick Tags" sub-menu. Selecting one of these menu items adds // a tag with the associated tag name. - if (null != tagNames && !tagNames.isEmpty()) { - for (final TagName tagName : tagNames) { - JMenuItem tagNameItem = new JMenuItem(tagName.getDisplayName()); + if (null != tagNamesMap && !tagNamesMap.isEmpty()) { + for (Map.Entry entry : tagNamesMap.entrySet()) { + JMenuItem tagNameItem = new JMenuItem(entry.getKey()); tagNameItem.addActionListener((ActionEvent e) -> { - addTag(tagName, NO_COMMENT); + getAndAddTag(entry.getKey(), entry.getValue(), NO_COMMENT); }); quickTagMenu.add(tagNameItem); } @@ -121,7 +116,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { JMenuItem empty = new JMenuItem(NbBundle.getMessage(this.getClass(), "AddTagAction.noTags")); empty.setEnabled(false); quickTagMenu.add(empty); - } + } quickTagMenu.addSeparator(); @@ -150,5 +145,30 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { }); add(tagAndCommentItem); } + + /** + * Method to add to the action listener for each menu item. Allows a tag + * display name to be added to the menu with an action listener without + * having to instantiate a TagName object for it. + * When the method is called, the TagName object is created here if it + * doesn't already exist. + * + * @param tagDisplayName display name for the tag name + * @param tagName TagName object associated with the tag name, + * may be null + * @param comment comment for the content or artifact tag + */ + private void getAndAddTag(String tagDisplayName, TagName tagName, String comment) { + if (tagName == null) { + try { + tagName = Case.getCurrentCase().getServices().getTagsManager().addTagName(tagDisplayName); + } catch (TagsManager.TagNameAlreadyExistsException ex) { + Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, tagDisplayName + " already exists in database.", ex); //NON-NLS + } catch (TskCoreException ex) { + Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, "Error adding " + tagDisplayName + " tag name", ex); //NON-NLS + } + } + addTag(tagName, comment); + } } } diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java index 9d9dbaa7c2..fa2b1b1593 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java @@ -21,11 +21,8 @@ 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.HashMap; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; +import java.util.Map; +import java.util.TreeMap; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.ActionMap; @@ -46,7 +43,7 @@ public class GetTagNameAndCommentDialog extends JDialog { private static final long serialVersionUID = 1L; private static final String NO_TAG_NAMES_MESSAGE = NbBundle.getMessage(GetTagNameAndCommentDialog.class, "GetTagNameAndCommentDialog.noTags"); - private final HashMap tagNames = new HashMap<>(); + private final Map tagNamesMap = new TreeMap<>(); private TagNameAndComment tagNameAndComment = null; public static class TagNameAndComment { @@ -117,23 +114,21 @@ public class GetTagNameAndCommentDialog extends JDialog { // Populate the combo box with the available tag names and save the // tag name DTOs to be enable to return the one the user selects. + // Tag name DTOs may be null (user tag names that have not been used do + // not exist in the database). TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); - List currentTagNames = null; try { - Set tagNamesSet = new TreeSet<>(); - tagNamesSet.addAll(tagsManager.getUserTagNames()); - tagNamesSet.addAll(tagsManager.getTagNamesInUse()); - tagNamesSet.addAll(tagsManager.getPredefinedTagNames()); - currentTagNames = new ArrayList(tagNamesSet); + tagNamesMap.putAll(tagsManager.getUserTagNamesMap()); + tagNamesMap.putAll(tagsManager.getPredefinedTagNamesMap()); + tagNamesMap.putAll(tagsManager.getTagNamesInUseMap()); } catch (TskCoreException ex) { Logger.getLogger(GetTagNameAndCommentDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } - if (null != currentTagNames && currentTagNames.isEmpty()) { + if (null != tagNamesMap && tagNamesMap.isEmpty()) { tagCombo.addItem(NO_TAG_NAMES_MESSAGE); } else { - for (TagName tagName : currentTagNames) { - tagNames.put(tagName.getDisplayName(), tagName); - tagCombo.addItem(tagName.getDisplayName()); + for (String tagDisplayName : tagNamesMap.keySet()) { + tagCombo.addItem(tagDisplayName); } } @@ -247,7 +242,18 @@ public class GetTagNameAndCommentDialog extends JDialog { }// //GEN-END:initComponents private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed - tagNameAndComment = new TagNameAndComment(tagNames.get((String) tagCombo.getSelectedItem()), commentText.getText()); + String tagDisplayName = (String) tagCombo.getSelectedItem(); + TagName tagNameFromCombo = tagNamesMap.get(tagDisplayName); + if (tagNameFromCombo == null) { + try { + tagNameFromCombo = Case.getCurrentCase().getServices().getTagsManager().addTagName(tagDisplayName); + } catch (TagsManager.TagNameAlreadyExistsException ex) { + Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, tagDisplayName + " already exists in database.", ex); //NON-NLS + } catch (TskCoreException ex) { + Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, "Error adding " + tagDisplayName + " tag name", ex); //NON-NLS + } + } + tagNameAndComment = new TagNameAndComment(tagNameFromCombo, commentText.getText()); dispose(); }//GEN-LAST:event_okButtonActionPerformed @@ -264,7 +270,7 @@ public class GetTagNameAndCommentDialog extends JDialog { private void newTagButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTagButtonActionPerformed TagName newTagName = GetTagNameDialog.doDialog(this); if (newTagName != null) { - tagNames.put(newTagName.getDisplayName(), newTagName); + tagNamesMap.put(newTagName.getDisplayName(), newTagName); tagCombo.addItem(newTagName.getDisplayName()); tagCombo.setSelectedItem(newTagName.getDisplayName()); } diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java index f055469fef..5386af785a 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java @@ -22,10 +22,9 @@ import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Set; -import java.util.TreeSet; +import java.util.Map; +import java.util.TreeMap; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.ActionMap; @@ -47,7 +46,7 @@ import org.sleuthkit.datamodel.TskCoreException; public class GetTagNameDialog extends JDialog { private static final String TAG_ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS - private final HashMap tagNames = new HashMap<>(); + private final Map tagNamesMap = new TreeMap<>(); private TagName tagName = null; /** @@ -98,26 +97,16 @@ public class GetTagNameDialog extends JDialog { // 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(); - List currentTagNames = null; try { - Set tagNamesSet = new TreeSet<>(); - tagNamesSet.addAll(tagsManager.getUserTagNames()); - tagNamesSet.addAll(tagsManager.getTagNamesInUse()); - tagNamesSet.addAll(tagsManager.getPredefinedTagNames()); - currentTagNames = new ArrayList(tagNamesSet); + tagNamesMap.putAll(tagsManager.getUserTagNamesMap()); + tagNamesMap.putAll(tagsManager.getPredefinedTagNamesMap()); + tagNamesMap.putAll(tagsManager.getTagNamesInUseMap()); } catch (TskCoreException ex) { Logger.getLogger(GetTagNameDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } - if (null != currentTagNames) { - for (TagName name : currentTagNames) { - this.tagNames.put(name.getDisplayName(), name); - } - } else { - currentTagNames = new ArrayList<>(); - } // Populate the tag names table. - tagsTable.setModel(new TagsTableModel(currentTagNames)); + tagsTable.setModel(new TagsTableModel(new ArrayList(tagNamesMap.keySet()))); tagsTable.setTableHeader(null); tagsTable.setCellSelectionEnabled(false); tagsTable.setFocusable(false); @@ -130,17 +119,17 @@ public class GetTagNameDialog extends JDialog { private class TagsTableModel extends AbstractTableModel { - private final ArrayList tagNames = new ArrayList<>(); + private final ArrayList tagDisplayNames = new ArrayList<>(); - TagsTableModel(List tagNames) { - for (TagName tagName : tagNames) { - this.tagNames.add(tagName); + TagsTableModel(List tagDisplayNames) { + for (String tagDisplayName : tagDisplayNames) { + this.tagDisplayNames.add(tagDisplayName); } } @Override public int getRowCount() { - return tagNames.size(); + return tagDisplayNames.size(); } @Override @@ -155,7 +144,7 @@ public class GetTagNameDialog extends JDialog { @Override public String getValueAt(int rowIndex, int columnIndex) { - return tagNames.get(rowIndex).getDisplayName(); + return tagDisplayNames.get(rowIndex); } } @@ -306,7 +295,7 @@ public class GetTagNameDialog extends JDialog { NbBundle.getMessage(this.getClass(), "GetTagNameDialog.illegalCharsErr"), JOptionPane.ERROR_MESSAGE); } else { - tagName = tagNames.get(tagDisplayName); + tagName = tagNamesMap.get(tagDisplayName); if (tagName == null) { try { tagName = Case.getCurrentCase().getServices().getTagsManager().addTagName(tagDisplayName); @@ -321,7 +310,7 @@ public class GetTagNameDialog extends JDialog { JOptionPane.ERROR_MESSAGE); tagName = null; } catch (TagsManager.TagNameAlreadyExistsException ex) { - Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, "Error adding " + tagDisplayName + " tag name", ex); //NON-NLS + Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, tagDisplayName + " already exists in database.", ex); //NON-NLS JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(), "GetTagNameDialog.tagNameAlreadyDef.msg", diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index 8fbcb50595..ed80e8696e 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -9,9 +9,6 @@ TagsManager.deleteContentTag.noCaseWarning=Failed to publish content tag deleted TagsManager.addBlackboardArtifactTag.noCaseWarning=Failed to publish new blackboard artifact tag event. There is no case open. TagsManager.deleteBlackboardArtifactTag.noCaseWarning=Failed to publish blackboard artifact tag deleted event. There is no case open. Blackboard.unableToIndexArtifact.error.msg=Unable to index blackboard artifact {0} -TagsManagerOptionsPanel.addTagNameButton.empty=Tag name text is empty. -TagsManagerOptionsPanel.addTagNameButton.containInvalidCharacter=Tag name may not contain any of the following symbols\: \\ \: * ? " < > | , ; -TagsManagerOptionsPanel.addTagNameButton.alreadyExists=Tag name already exists. TagNamesSettingsPanel.deleteTagNameButton.text=Delete Tag Name TagNamesSettingsPanel.tagNamesListLabel.text=Tag names: NewUserTagNameDialog.tagNameTextField.text= diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java index d6f4953824..91a24e7ad2 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java @@ -21,7 +21,9 @@ package org.sleuthkit.autopsy.casemodule.services; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.swing.DefaultListModel; import javax.swing.JOptionPane; import javax.swing.event.ListSelectionEvent; @@ -253,6 +255,10 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP */ private void updateTagNamesListModel() { tagNamesListModel.clear(); + Set tagNameSet = new HashSet<>(); + tagNameSet.addAll(tagNames); + tagNames.clear(); + tagNames.addAll(tagNameSet); Collections.sort(tagNames); for (UserTagName tagName : tagNames) { tagNamesListModel.addElement(tagName); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index 9cd7a72183..7798d3cf3a 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.logging.Level; import org.openide.util.NbBundle; @@ -80,34 +81,55 @@ public class TagsManager implements Closeable { } /** - * Gets a list of all user tag names from the preference file. + * Gets a mapping of user tag name display names to TagName DTOs if they + * have been added to the database. Otherwise, the display name maps to + * null. * - * @return A list, possibly empty, of TagName data transfer objects (DTOs). + * @return A map of String display name to TagName DTO, TagName may be null */ - public synchronized List getUserTagNames() { + public synchronized Map getUserTagNamesMap() { lazyLoadExistingTagNames(); - List tagNameList = new ArrayList<>(); + Map tagNamesMap = new HashMap<>(); String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); if (null != setting && !setting.isEmpty()) { List tagNameTuples = Arrays.asList(setting.split(";")); for (String tagNameTuple : tagNameTuples) { String[] tagNameAttributes = tagNameTuple.split(","); - tagNameList.add(uniqueTagNames.get(tagNameAttributes[0])); + tagNamesMap.put(tagNameAttributes[0], uniqueTagNames.get(tagNameAttributes[0])); } } - return tagNameList; + return tagNamesMap; + } + + /** + * Gets a mapping of predefined tag names to their TagName DTOs. Currently + * only for the bookmark tag. + * + * @return A map of String display name to TagName DTO + */ + public synchronized Map getPredefinedTagNamesMap() { + Map tagNamesMap = new HashMap<>(); + TagName bookmarkTagName = uniqueTagNames.get(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text")); + tagNamesMap.put(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"), bookmarkTagName); + return tagNamesMap; } /** - * Gets a list of all predefined tag names. + * Gets a mapping of the display names of predefined tag names and tag names + * that are in use to their TagName DTOs. * - * @return A list of TagName data transfer objects (DTOs). + * @return A map of String display name to TagName DTO + * + * @throws TskCoreException If there is an error reading from the case + * database. */ - public synchronized List getPredefinedTagNames() { - lazyLoadExistingTagNames(); - List tagNameList = new ArrayList<>(); - tagNameList.add(uniqueTagNames.get(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"))); - return tagNameList; + public synchronized Map getTagNamesInUseMap() throws TskCoreException { + List tagNames = getTagNamesInUse(); + Map tagNamesMap = new HashMap<>(); + for (TagName tagName : tagNames) { + tagNamesMap.put(tagName.getDisplayName(), tagName); + } + return tagNamesMap; } /** @@ -136,7 +158,8 @@ public class TagsManager implements Closeable { */ public synchronized boolean tagNameExists(String tagDisplayName) { lazyLoadExistingTagNames(); - return uniqueTagNames.containsKey(tagDisplayName); + return uniqueTagNames.containsKey(tagDisplayName) && + (uniqueTagNames.get(tagDisplayName) != null); } /** @@ -201,31 +224,28 @@ public class TagsManager implements Closeable { } lazyLoadExistingTagNames(); - + /* * It is possible user is trying to add back a tag after having deleted - * it. + * it. It is also possible a user tag name was never added to the + * database. */ if (uniqueTagNames.containsKey(displayName)) { - TagName existingTagName = uniqueTagNames.get(displayName); - long count = getContentTagsCountByTagName(existingTagName) + getBlackboardArtifactTagsCountByTagName(existingTagName); - if (count == 0) { - addNewTagNameToTagsSettings(existingTagName); - return existingTagName; - } else { - throw new TagNameAlreadyExistsException(); + if (uniqueTagNames.get(displayName) != null) { + TagName existingTagName = uniqueTagNames.get(displayName); + long count = getContentTagsCountByTagName(existingTagName) + getBlackboardArtifactTagsCountByTagName(existingTagName); + if (count == 0) { + addNewTagNameToTagsSettings(existingTagName); + return existingTagName; + } else { + throw new TagNameAlreadyExistsException(); + } } } - - /* - * Add the tag name to the case. - */ + TagName newTagName = caseDb.addTagName(displayName, description, color); uniqueTagNames.put(newTagName.getDisplayName(), newTagName); - /* - * Add the tag name to the tags settings. - */ addNewTagNameToTagsSettings(newTagName); return newTagName; @@ -668,12 +688,7 @@ public class TagsManager implements Closeable { for (String tagNameTuple : tagNameTuples) { String[] tagNameAttributes = tagNameTuple.split(","); if (!uniqueTagNames.containsKey(tagNameAttributes[0])) { - try { - TagName tagName = caseDb.addTagName(tagNameAttributes[0], tagNameAttributes[1], TagName.HTML_COLOR.getColorByName(tagNameAttributes[2])); - uniqueTagNames.put(tagName.getDisplayName(), tagName); - } catch (TskCoreException ex) { - Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + tagNameAttributes[0], ex); //NON-NLS - } + uniqueTagNames.put(tagNameAttributes[0], null); } } } @@ -704,12 +719,7 @@ public class TagsManager implements Closeable { lazyLoadExistingTagNames(); for (UserTagName utn : userTagNames) { if (!uniqueTagNames.containsKey(utn.getDisplayName())) { - try { - TagName tagName = caseDb.addTagName(utn.getDisplayName(), utn.getDescription(), TagName.HTML_COLOR.getColorByName(utn.getColorName())); - uniqueTagNames.put(tagName.getDisplayName(), tagName); - } catch (TskCoreException ex) { - Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + utn.getDisplayName(), ex); //NON-NLS - } + uniqueTagNames.put(utn.getDisplayName(), null); } } }