mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Merge pull request #2355 from wishdasher/AUT-2107_tag_deletion_options_panel
Added options panel for adding and deleting user tag names
This commit is contained in:
commit
00a905533e
@ -19,8 +19,8 @@
|
||||
package org.sleuthkit.autopsy.actions;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JMenu;
|
||||
@ -87,10 +87,12 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup {
|
||||
|
||||
// Get the current set of tag names.
|
||||
TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
|
||||
List<TagName> tagNames = null;
|
||||
Map<String, TagName> tagNamesMap = null;
|
||||
try {
|
||||
tagNames = tagsManager.getAllTagNames();
|
||||
Collections.sort(tagNames);
|
||||
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
|
||||
}
|
||||
@ -102,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<String, TagName> 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);
|
||||
}
|
||||
@ -114,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();
|
||||
|
||||
@ -143,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
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
|
||||
GetTagNameAndCommentDialog.newTagButton.text=New Tag Name
|
||||
GetTagNameAndCommentDialog.okButton.text=OK
|
||||
GetTagNameAndCommentDialog.commentText.toolTipText=Enter an optional tag comment or leave blank
|
||||
GetTagNameAndCommentDialog.commentText.text=
|
||||
@ -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
|
||||
@ -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
|
||||
CTL_OpenPythonModulesFolderAction=Python Plugins
|
||||
|
@ -28,7 +28,7 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="newTagButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="78" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="48" max="32767" attributes="0"/>
|
||||
<Component id="okButton" linkSize="1" min="-2" pref="67" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
|
@ -21,8 +21,8 @@ package org.sleuthkit.autopsy.actions;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.ActionMap;
|
||||
@ -43,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<String, TagName> tagNames = new HashMap<>();
|
||||
private final Map<String, TagName> tagNamesMap = new TreeMap<>();
|
||||
private TagNameAndComment tagNameAndComment = null;
|
||||
|
||||
public static class TagNameAndComment {
|
||||
@ -114,19 +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<TagName> currentTagNames = null;
|
||||
try {
|
||||
currentTagNames = tagsManager.getAllTagNames();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +199,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))
|
||||
@ -240,7 +242,18 @@ public class GetTagNameAndCommentDialog extends JDialog {
|
||||
}// </editor-fold>//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
|
||||
|
||||
@ -257,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());
|
||||
}
|
||||
|
@ -22,8 +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.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.ActionMap;
|
||||
@ -45,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<String, TagName> tagNames = new HashMap<>();
|
||||
private final Map<String, TagName> tagNamesMap = new TreeMap<>();
|
||||
private TagName tagName = null;
|
||||
|
||||
/**
|
||||
@ -96,22 +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<TagName> currentTagNames = null;
|
||||
try {
|
||||
currentTagNames = tagsManager.getAllTagNames();
|
||||
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<String>(tagNamesMap.keySet())));
|
||||
tagsTable.setTableHeader(null);
|
||||
tagsTable.setCellSelectionEnabled(false);
|
||||
tagsTable.setFocusable(false);
|
||||
@ -122,30 +117,19 @@ 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<TagName> tagNames = new ArrayList<>();
|
||||
private final ArrayList<String> tagDisplayNames = new ArrayList<>();
|
||||
|
||||
TagsTableModel(List<TagName> tagNames) {
|
||||
for (TagName tagName : tagNames) {
|
||||
this.tagNames.add(tagName);
|
||||
TagsTableModel(List<String> tagDisplayNames) {
|
||||
for (String tagDisplayName : tagDisplayNames) {
|
||||
this.tagDisplayNames.add(tagDisplayName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return tagNames.size();
|
||||
return tagDisplayNames.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -160,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,13 +289,13 @@ 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"),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} else {
|
||||
tagName = tagNames.get(tagDisplayName);
|
||||
tagName = tagNamesMap.get(tagDisplayName);
|
||||
if (tagName == null) {
|
||||
try {
|
||||
tagName = Case.getCurrentCase().getServices().getTagsManager().addTagName(tagDisplayName);
|
||||
@ -326,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",
|
||||
|
@ -1,3 +1,5 @@
|
||||
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})
|
||||
TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset
|
||||
@ -7,3 +9,18 @@ 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}
|
||||
TagNamesSettingsPanel.deleteTagNameButton.text=Delete Tag Name
|
||||
TagNamesSettingsPanel.tagNamesListLabel.text=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
|
||||
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
|
||||
|
98
Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.form
Executable file
98
Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.form
Executable file
@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="tagNameTextField" pref="220" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="okButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="newTagNameLabel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="newTagNameLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tagNameTextField" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="50" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="newTagNameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/services/Bundle.properties" key="NewUserTagNameDialog.newTagNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="tagNameTextField">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/services/Bundle.properties" key="NewUserTagNameDialog.tagNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="cancelButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/services/Bundle.properties" key="NewUserTagNameDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="okButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/services/Bundle.properties" key="NewUserTagNameDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
246
Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java
Executable file
246
Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java
Executable file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.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 javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
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);
|
||||
initComponents();
|
||||
this.display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets display settings for the dialog and adds appropriate listeners.
|
||||
*/
|
||||
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 OK button when the text field changes.
|
||||
*/
|
||||
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();
|
||||
|
||||
/*
|
||||
* 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().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);
|
||||
return;
|
||||
}
|
||||
userTagDisplayName = newTagDisplayName;
|
||||
result = BUTTON_PRESSED.OK;
|
||||
} else {
|
||||
result = BUTTON_PRESSED.CANCEL;
|
||||
}
|
||||
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
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//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();
|
||||
}// </editor-fold>//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
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.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_TagNamesOptions",
|
||||
iconBase = "org/sleuthkit/autopsy/casemodule/services/tags-manager.png",
|
||||
keywords = "#OptionsCategory_TagNames",
|
||||
keywordsCategory = "CustomTagNames",
|
||||
position = 8
|
||||
)
|
||||
public final class TagNamesOptionsPanelController extends OptionsPanelController {
|
||||
|
||||
private TagNamesSettingsPanel panel;
|
||||
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) {
|
||||
getPanel().store();
|
||||
changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
@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 TagNamesSettingsPanel getPanel() {
|
||||
if (panel == null) {
|
||||
panel = new TagNamesSettingsPanel();
|
||||
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);
|
||||
}
|
||||
}
|
203
Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form
Executable file
203
Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form
Executable file
@ -0,0 +1,203 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanel1" alignment="0" pref="778" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jPanel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[750, 500]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="jSplitPane1" max="32767" attributes="0"/>
|
||||
<Component id="panelDescriptionLabel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="panelDescriptionLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jSplitPane1" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="panelDescriptionLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/services/Bundle.properties" key="TagNamesSettingsPanel.panelDescriptionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JSplitPane" name="jSplitPane1">
|
||||
<Properties>
|
||||
<Property name="dividerLocation" type="int" value="400"/>
|
||||
<Property name="dividerSize" type="int" value="1"/>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="modifyTagNameListPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="left"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="tagNamesListLabel" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="newTagNameButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="deleteTagNameButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="113" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tagNamesListLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="383" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="newTagNameButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deleteTagNameButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="tagNamesListLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/services/Bundle.properties" key="TagNamesSettingsPanel.tagNamesListLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="tagNamesList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<UserTagName>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="newTagNameButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/add-tag.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/services/Bundle.properties" key="TagNamesSettingsPanel.newTagNameButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newTagNameButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteTagNameButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/delete-tag.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/services/Bundle.properties" key="TagNamesSettingsPanel.deleteTagNameButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteTagNameButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="tagNameAdditionalPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="right"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="356" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="456" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
316
Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java
Executable file
316
Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java
Executable file
@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.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;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
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.
|
||||
*/
|
||||
final 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 DEFAULT_DESCRIPTION = "";
|
||||
private static final String DEFAULT_COLOR_STRING = "NONE";
|
||||
|
||||
private DefaultListModel<UserTagName> tagNamesListModel;
|
||||
private List<UserTagName> tagNames;
|
||||
|
||||
/**
|
||||
* Creates new form TagsManagerOptionsPanel
|
||||
*/
|
||||
TagNamesSettingsPanel() {
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
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<>();
|
||||
newTagNameButton = 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
|
||||
|
||||
jScrollPane1.setViewportView(tagNamesList);
|
||||
|
||||
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) {
|
||||
newTagNameButtonActionPerformed(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(newTagNameButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(deleteTagNameButton)
|
||||
.addGap(0, 113, 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(newTagNameButton)
|
||||
.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))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
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) {
|
||||
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"),
|
||||
NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.title"),
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
} else {
|
||||
tagNames.add(newTagName);
|
||||
updateTagNamesListModel();
|
||||
/*
|
||||
* Set the selection to the tag name that was just added.
|
||||
*/
|
||||
int index = tagNames.indexOf(newTagName);
|
||||
tagNamesList.setSelectedIndex(index);
|
||||
enableButtons();
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}
|
||||
}//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
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
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<UserTagName> 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();
|
||||
Set<UserTagName> tagNameSet = new HashSet<>();
|
||||
tagNameSet.addAll(tagNames);
|
||||
tagNames.clear();
|
||||
tagNames.addAll(tagNameSet);
|
||||
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 options panel.
|
||||
*
|
||||
* Adds all new tag names to the case database for displaying usable tag
|
||||
* names when tagging.
|
||||
*/
|
||||
@Override
|
||||
public void store() {
|
||||
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() {
|
||||
String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY);
|
||||
tagNames.clear();
|
||||
if (null != setting && !setting.isEmpty()) {
|
||||
List<String> 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
@ -1,28 +1,32 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.services;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
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;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
@ -53,7 +57,7 @@ public class TagsManager implements Closeable {
|
||||
* 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) {
|
||||
@ -61,8 +65,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).
|
||||
*
|
||||
@ -77,6 +80,58 @@ public class TagsManager implements Closeable {
|
||||
return caseDb.getAllTagNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 map of String display name to TagName DTO, TagName may be null
|
||||
*/
|
||||
public synchronized Map<String, TagName> getUserTagNamesMap() {
|
||||
lazyLoadExistingTagNames();
|
||||
Map<String, TagName> tagNamesMap = new HashMap<>();
|
||||
String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY);
|
||||
if (null != setting && !setting.isEmpty()) {
|
||||
List<String> tagNameTuples = Arrays.asList(setting.split(";"));
|
||||
for (String tagNameTuple : tagNameTuples) {
|
||||
String[] tagNameAttributes = tagNameTuple.split(",");
|
||||
tagNamesMap.put(tagNameAttributes[0], uniqueTagNames.get(tagNameAttributes[0]));
|
||||
}
|
||||
}
|
||||
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<String, TagName> getPredefinedTagNamesMap() {
|
||||
Map<String, TagName> 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 mapping of the display names of predefined tag names and tag names
|
||||
* that are in use to their TagName 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 Map<String, TagName> getTagNamesInUseMap() throws TskCoreException {
|
||||
List<TagName> tagNames = getTagNamesInUse();
|
||||
Map<String, TagName> tagNamesMap = new HashMap<>();
|
||||
for (TagName tagName : tagNames) {
|
||||
tagNamesMap.put(tagName.getDisplayName(), tagName);
|
||||
}
|
||||
return tagNamesMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all tag names currently in use for tagging content or
|
||||
* artifacts.
|
||||
@ -103,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,21 +222,31 @@ 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. It is also possible a user tag name was never added to the
|
||||
* database.
|
||||
*/
|
||||
if (uniqueTagNames.containsKey(displayName)) {
|
||||
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);
|
||||
|
||||
/*
|
||||
* Add the tag name to the tags settings.
|
||||
*/
|
||||
uniqueTagNames.put(newTagName.getDisplayName(), newTagName);
|
||||
saveTagNamesToTagsSettings();
|
||||
|
||||
addNewTagNameToTagsSettings(newTagName);
|
||||
|
||||
return newTagName;
|
||||
}
|
||||
@ -563,7 +629,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.
|
||||
@ -572,7 +638,6 @@ public class TagsManager implements Closeable {
|
||||
@Override
|
||||
@Deprecated
|
||||
public synchronized void close() throws IOException {
|
||||
saveTagNamesToTagsSettings();
|
||||
caseDb = null;
|
||||
}
|
||||
|
||||
@ -583,10 +648,12 @@ public class TagsManager implements Closeable {
|
||||
private void lazyLoadExistingTagNames() {
|
||||
if (!tagNamesLoaded) {
|
||||
addTagNamesFromCurrentCase();
|
||||
addTagNamesFromTagsSettings();
|
||||
addPredefinedTagNames();
|
||||
saveTagNamesToTagsSettings();
|
||||
addTagNamesFromTagsSettings();
|
||||
tagNamesLoaded = true;
|
||||
} else {
|
||||
// Reload case db tag names in case another user has added some.
|
||||
addTagNamesFromCurrentCase();
|
||||
}
|
||||
}
|
||||
|
||||
@ -621,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -648,24 +710,55 @@ 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 potentially added
|
||||
*/
|
||||
private void saveTagNamesToTagsSettings() {
|
||||
if (!uniqueTagNames.isEmpty()) {
|
||||
StringBuilder setting = new StringBuilder();
|
||||
for (TagName tagName : uniqueTagNames.values()) {
|
||||
if (setting.length() != 0) {
|
||||
setting.append(";");
|
||||
}
|
||||
setting.append(tagName.getDisplayName()).append(",");
|
||||
setting.append(tagName.getDescription()).append(",");
|
||||
setting.append(tagName.getColor().name());
|
||||
void storeNewUserTagNames(List<UserTagName> userTagNames) {
|
||||
lazyLoadExistingTagNames();
|
||||
for (UserTagName utn : userTagNames) {
|
||||
if (!uniqueTagNames.containsKey(utn.getDisplayName())) {
|
||||
uniqueTagNames.put(utn.getDisplayName(), null);
|
||||
}
|
||||
ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
if (setting == null || setting.isEmpty()) {
|
||||
setting = "";
|
||||
} else {
|
||||
setting += ";";
|
||||
}
|
||||
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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
|
86
Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java
Executable file
86
Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java
Executable file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.services;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 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<UserTagName> {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
BIN
Core/src/org/sleuthkit/autopsy/casemodule/services/tags-manager.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/casemodule/services/tags-manager.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
Core/src/org/sleuthkit/autopsy/images/add-tag.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/images/add-tag.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
Core/src/org/sleuthkit/autopsy/images/delete-tag.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/images/delete-tag.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
Core/src/org/sleuthkit/autopsy/images/edit-tag.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/images/edit-tag.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Loading…
x
Reference in New Issue
Block a user