From 231e87187dfc2a1b005e7a413e22d406a5168aa1 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Thu, 8 Dec 2016 09:58:31 -0500 Subject: [PATCH] Add dialog to allow the user to add multiple keywords at a time. --- .../keywordsearch/AddKeywordsDialog.form | 185 +++++++++++ .../keywordsearch/AddKeywordsDialog.java | 314 ++++++++++++++++++ .../autopsy/keywordsearch/Bundle.properties | 22 +- .../keywordsearch/GlobalEditListPanel.form | 30 +- .../keywordsearch/GlobalEditListPanel.java | 172 ++++++---- 5 files changed, 644 insertions(+), 79 deletions(-) create mode 100644 KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AddKeywordsDialog.form create mode 100644 KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AddKeywordsDialog.java diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AddKeywordsDialog.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AddKeywordsDialog.form new file mode 100644 index 0000000000..65cdd9f88d --- /dev/null +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AddKeywordsDialog.form @@ -0,0 +1,185 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AddKeywordsDialog.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AddKeywordsDialog.java new file mode 100644 index 0000000000..0f5d42ca03 --- /dev/null +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AddKeywordsDialog.java @@ -0,0 +1,314 @@ +/* + * 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.keywordsearch; + +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import org.openide.util.NbBundle; +import org.openide.windows.WindowManager; + +/** + * Dialog to add one or more keywords to a list + */ +class AddKeywordsDialog extends javax.swing.JDialog { + + List newKeywords = new ArrayList<>(); + + /** + * Creates new form AddKeywordsDialog. + * Note that this does not display the dialog - call display() after creation. + * @param initialKeywords Keywords to populate the list with + * @param type Starting keyword type + */ + AddKeywordsDialog(){ + super((JFrame) WindowManager.getDefault().getMainWindow(), + NbBundle.getMessage(AddKeywordsDialog.class, "AddKeywordsDialog.addKeywordsTitle.text"), + true); + initComponents(); + + // Set the add button to only be active when there is text in the text area + addButton.setEnabled(false); + keywordTextArea.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() { + enableButtons(); + } + }); + } + + /** + * Display the dialog + */ + void display() { + newKeywords.clear(); + Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); + setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2); + setVisible(true); + } + + /** + * Set the initial contents of the text box. + * Intended to be used to redisplay any keywords that contained errors + * @param initialKeywords + */ + void setInitialKeywordList(String initialKeywords){ + keywordTextArea.setText(initialKeywords); + } + + + private void enableButtons(){ + addButton.setEnabled(! keywordTextArea.getText().isEmpty()); + } + + /** + * Get the list of keywords from the text area + * @return list of keywords + */ + List getKeywords(){ + return newKeywords; + } + + /** + * Get whether the regex option is selected + * @return true if the regex radio button is selected + */ + boolean isKeywordRegex(){ + return regexRadioButton.isSelected(); + } + + /** + * Get whether the exact match option is selected + * @return true if the exact match radio button is selected + */ + boolean isKeywordExact(){ + return exactRadioButton.isSelected(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + keywordTypeButtonGroup = new javax.swing.ButtonGroup(); + exactRadioButton = new javax.swing.JRadioButton(); + substringRadioButton = new javax.swing.JRadioButton(); + regexRadioButton = new javax.swing.JRadioButton(); + jScrollPane1 = new javax.swing.JScrollPane(); + keywordTextArea = new javax.swing.JTextArea(); + enterKeywordsLabel = new javax.swing.JLabel(); + keywordTypeLabel = new javax.swing.JLabel(); + addButton = new javax.swing.JButton(); + cancelButton = new javax.swing.JButton(); + pasteButton = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + keywordTypeButtonGroup.add(exactRadioButton); + exactRadioButton.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(exactRadioButton, org.openide.util.NbBundle.getMessage(AddKeywordsDialog.class, "AddKeywordsDialog.exactRadioButton.text")); // NOI18N + + keywordTypeButtonGroup.add(substringRadioButton); + org.openide.awt.Mnemonics.setLocalizedText(substringRadioButton, org.openide.util.NbBundle.getMessage(AddKeywordsDialog.class, "AddKeywordsDialog.substringRadioButton.text")); // NOI18N + + keywordTypeButtonGroup.add(regexRadioButton); + org.openide.awt.Mnemonics.setLocalizedText(regexRadioButton, org.openide.util.NbBundle.getMessage(AddKeywordsDialog.class, "AddKeywordsDialog.regexRadioButton.text")); // NOI18N + + keywordTextArea.setColumns(20); + keywordTextArea.setRows(5); + keywordTextArea.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + keywordTextAreaMouseClicked(evt); + } + }); + jScrollPane1.setViewportView(keywordTextArea); + + org.openide.awt.Mnemonics.setLocalizedText(enterKeywordsLabel, org.openide.util.NbBundle.getMessage(AddKeywordsDialog.class, "AddKeywordsDialog.enterKeywordsLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(keywordTypeLabel, org.openide.util.NbBundle.getMessage(AddKeywordsDialog.class, "AddKeywordsDialog.keywordTypeLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(AddKeywordsDialog.class, "AddKeywordsDialog.addButton.text")); // NOI18N + addButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(AddKeywordsDialog.class, "AddKeywordsDialog.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(pasteButton, org.openide.util.NbBundle.getMessage(AddKeywordsDialog.class, "AddKeywordsDialog.pasteButton.text")); // NOI18N + pasteButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + pasteButtonActionPerformed(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(enterKeywordsLabel) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(pasteButton)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(keywordTypeLabel) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(substringRadioButton) + .addComponent(exactRadioButton) + .addComponent(regexRadioButton)))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(enterKeywordsLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(keywordTypeLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(exactRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(substringRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(regexRadioButton) + .addGap(194, 194, 194)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 278, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(5, 5, 5))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(addButton) + .addComponent(cancelButton)) + .addComponent(pasteButton)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void pasteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pasteButtonActionPerformed + keywordTextArea.paste(); + }//GEN-LAST:event_pasteButtonActionPerformed + + private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed + // Save the values from the list + newKeywords.addAll(Arrays.asList(keywordTextArea.getText().split("\\r?\\n"))); + + setVisible(false); + dispose(); + }//GEN-LAST:event_addButtonActionPerformed + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed + setVisible(false); + dispose(); + }//GEN-LAST:event_cancelButtonActionPerformed + + private void keywordTextAreaMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_keywordTextAreaMouseClicked + if (SwingUtilities.isRightMouseButton(evt)) { + JPopupMenu popup = new JPopupMenu(); + + JMenuItem cutMenu = new JMenuItem("Cut"); // NON-NLS + cutMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + keywordTextArea.cut(); + } + }); + + JMenuItem copyMenu = new JMenuItem("Copy"); // NON-NLS + copyMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + keywordTextArea.copy(); + } + }); + + JMenuItem pasteMenu = new JMenuItem("Paste"); // NON-NLS + pasteMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + keywordTextArea.paste(); + } + }); + + popup.add(cutMenu); + popup.add(copyMenu); + popup.add(pasteMenu); + popup.show(keywordTextArea, evt.getX(), evt.getY()); + } + }//GEN-LAST:event_keywordTextAreaMouseClicked + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addButton; + private javax.swing.JButton cancelButton; + private javax.swing.JLabel enterKeywordsLabel; + private javax.swing.JRadioButton exactRadioButton; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextArea keywordTextArea; + private javax.swing.ButtonGroup keywordTypeButtonGroup; + private javax.swing.JLabel keywordTypeLabel; + private javax.swing.JButton pasteButton; + private javax.swing.JRadioButton regexRadioButton; + private javax.swing.JRadioButton substringRadioButton; + // End of variables declaration//GEN-END:variables +} diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index 2afdc83e03..43ba62c3c6 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -22,7 +22,7 @@ KeywordSearchEditListPanel.saveListButton.text=Copy List KeywordSearchEditListPanel.addWordField.text= KeywordSearchEditListPanel.addWordButton.text=New keyword KeywordSearchEditListPanel.chRegex.text=Regular Expression -KeywordSearchEditListPanel.deleteWordButton.text=Delete keyword +KeywordSearchEditListPanel.deleteWordButton.text=Delete keywords KeywordSearchEditListPanel.cutMenuItem.text=Cut KeywordSearchEditListPanel.selectAllMenuItem.text=Select All KeywordSearchEditListPanel.pasteMenuItem.text=Paste @@ -30,6 +30,7 @@ KeywordSearchEditListPanel.copyMenuItem.text=Copy KeywordSearchEditListPanel.exportButton.text=Export List KeywordSearchEditListPanel.deleteListButton.text=Delete List KeywordSearchEditListPanel.emptyKeyword.text=Empty keyword +KeywordSearchEditListPanel.errorAddingKeywords.text=Error adding keyword(s) KeywordSearchListsManagementPanel.newListButton.text=New List KeywordSearchListsManagementPanel.importButton.text=Import List KeywordSearchListsViewerPanel.searchAddButton.text=Search @@ -88,7 +89,7 @@ KeywordSearchConfigurationPanel1.customizeComponents.noOwDefaultMsg=Cannot overw KeywordSearchConfigurationPanel1.customizeComponents.kwListExistMsg=Keyword List <{0}> already exists, do you want to replace it? KeywordSearchConfigurationPanel1.customizeComponents.kwListSavedMsg=Keyword List <{0}> saved KeywordSearchEditListPanel.customizeComponents.kwReToolTip=Keyword is a regular expression -KeywordSearchEditListPanel.customizeComponents.addWordToolTip=Add a new word to the keyword search list +KeywordSearchEditListPanel.customizeComponents.addWordToolTip=Add new words to the keyword search list KeywordSearchEditListPanel.customizeComponents.enterNewWordToolTip=Enter a new word or regex to search KeywordSearchEditListPanel.customizeComponents.exportToFile=Export the current keyword list to a file KeywordSearchEditListPanel.customizeComponents.saveCurrentWIthNewNameToolTip=Save the current keyword list with a new name @@ -295,3 +296,20 @@ NewKeywordPanel.exactButton.text=Exact Match NewKeywordPanel.substringButton.text=Substring Match NewKeywordPanel.keywordTextField.text= NewKeywordPanel.newKeywordLabel.text=Enter a new keyword: +AddKeywordsDialog.exactRadioButton.text=Exact Match +AddKeywordsDialog.substringRadioButton.text=Substring Match +AddKeywordsDialog.regexRadioButton.text=Regular Expression +AddKeywordsDialog.keywordTypeLabel.text=Select type for keywords: +AddKeywordsDialog.enterKeywordsLabel.text=Enter keywords (one per line) below: +AddKeywordsDialog.pasteButton.text=Paste From Clipboard +AddKeywordsDialog.addButton.text=OK +AddKeywordsDialog.cancelButton.text=Cancel +AddKeywordsDialog.addKeywordsTitle.text=New keywords +GlobalEditListPanel.newKeywordsButton.text=New keywords +GlobalEditListPanel.addKeywordResults.text=Add keyword results +GlobalEditListPanel.keywordsAdded.text={0} keyword was successfully added. +GlobalEditListPanel.keywordsAddedPlural.text={0} keywords were successfully added. +GlobalEditListPanel.keywordDupesSkipped.text={0} keyword was already in the list. +GlobalEditListPanel.keywordDupesSkippedPlural.text={0} keywords were already in the list. +GlobalEditListPanel.keywordErrors.text={0} keyword could not be parsed. Please review and try again. +GlobalEditListPanel.keywordErrorsPlural.text={0} keywords could not be parsed. Please review and try again. diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalEditListPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalEditListPanel.form index c2e3d6430c..c43b029272 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalEditListPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalEditListPanel.form @@ -168,7 +168,7 @@ - + @@ -180,8 +180,8 @@ - + @@ -189,19 +189,6 @@ - - - - - - - - - - - - - @@ -215,6 +202,19 @@ + + + + + + + + + + + + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalEditListPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalEditListPanel.java index 4b9ea3a7bd..8c8262ecdf 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalEditListPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalEditListPanel.java @@ -42,7 +42,6 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.IngestManager; -import javax.swing.JOptionPane; /** * GlobalEditListPanel widget to manage keywords in lists @@ -64,7 +63,7 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis } private void customizeComponents() { - newWordButton.setToolTipText((NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.addWordToolTip"))); + newKeywordsButton.setToolTipText((NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.addWordToolTip"))); exportButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.exportToFile")); saveListButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.saveCurrentWIthNewNameToolTip")); deleteWordButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.removeSelectedMsg")); @@ -125,7 +124,7 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis // items that need an unlocked list w/out ingest running boolean isListLocked = ((isListSelected == false) || (currentKeywordList.isEditable())); boolean canAddWord = isListSelected && !isIngestRunning && !isListLocked; - newWordButton.setEnabled(canAddWord); + newKeywordsButton.setEnabled(canAddWord); keywordOptionsLabel.setEnabled(canAddWord); keywordOptionsSeparator.setEnabled(canAddWord); deleteListButton.setEnabled(canAddWord); @@ -155,8 +154,8 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis jScrollPane1 = new javax.swing.JScrollPane(); keywordTable = new javax.swing.JTable(); addKeywordPanel = new javax.swing.JPanel(); - newWordButton = new javax.swing.JButton(); deleteWordButton = new javax.swing.JButton(); + newKeywordsButton = new javax.swing.JButton(); ingestMessagesCheckbox = new javax.swing.JCheckBox(); keywordsLabel = new javax.swing.JLabel(); keywordOptionsLabel = new javax.swing.JLabel(); @@ -180,14 +179,6 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis keywordTable.getTableHeader().setReorderingAllowed(false); jScrollPane1.setViewportView(keywordTable); - newWordButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/new16.png"))); // NOI18N - newWordButton.setText(org.openide.util.NbBundle.getMessage(GlobalEditListPanel.class, "KeywordSearchEditListPanel.addWordButton.text")); // NOI18N - newWordButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - newWordButtonActionPerformed(evt); - } - }); - deleteWordButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/delete16.png"))); // NOI18N deleteWordButton.setText(org.openide.util.NbBundle.getMessage(GlobalEditListPanel.class, "KeywordSearchEditListPanel.deleteWordButton.text")); // NOI18N deleteWordButton.addActionListener(new java.awt.event.ActionListener() { @@ -196,12 +187,20 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis } }); + newKeywordsButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/new16.png"))); // NOI18N + newKeywordsButton.setText(org.openide.util.NbBundle.getMessage(GlobalEditListPanel.class, "GlobalEditListPanel.newKeywordsButton.text")); // NOI18N + newKeywordsButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + newKeywordsButtonActionPerformed(evt); + } + }); + javax.swing.GroupLayout addKeywordPanelLayout = new javax.swing.GroupLayout(addKeywordPanel); addKeywordPanel.setLayout(addKeywordPanelLayout); addKeywordPanelLayout.setHorizontalGroup( addKeywordPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(addKeywordPanelLayout.createSequentialGroup() - .addComponent(newWordButton) + .addComponent(newKeywordsButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(deleteWordButton) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) @@ -211,8 +210,8 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis .addGroup(addKeywordPanelLayout.createSequentialGroup() .addGap(0, 0, 0) .addGroup(addKeywordPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(newWordButton) - .addComponent(deleteWordButton)) + .addComponent(deleteWordButton) + .addComponent(newKeywordsButton)) .addGap(72, 72, 72)) ); @@ -333,51 +332,6 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis ); }// //GEN-END:initComponents - private void newWordButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newWordButtonActionPerformed - NewKeywordPanel panel = new NewKeywordPanel(); - - int result = JOptionPane.showConfirmDialog(null, panel, - NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.addKeyword.title"), - JOptionPane.OK_CANCEL_OPTION); - - if (result == JOptionPane.OK_OPTION) { - String newWord = panel.getKeywordText(); - if (newWord.isEmpty()) { - KeywordSearchUtil.displayDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.newKwTitle"), - NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.emptyKeyword.text"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO); - return; - } - final Keyword keyword = new Keyword(newWord, !panel.isKeywordRegex(), panel.isKeywordExact()); - if (currentKeywordList.hasKeyword(keyword)) { - KeywordSearchUtil.displayDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.newKwTitle"), - NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.addWordButtonAction.kwAlreadyExistsMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO); - return; - } - - //check if valid - boolean valid = true; - try { - Pattern.compile(newWord); - } catch (PatternSyntaxException ex1) { - valid = false; - } catch (IllegalArgumentException ex2) { - valid = false; - } - if (!valid) { - KeywordSearchUtil.displayDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.newKwTitle"), - NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.invalidKwMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR); - return; - } - - //add & reset checkbox - tableModel.addKeyword(keyword); - XmlKeywordSearchList.getCurrent().addList(currentKeywordList); - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - setFocusOnKeywordTextBox(); - setButtonStates(); - } - }//GEN-LAST:event_newWordButtonActionPerformed - private void deleteWordButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteWordButtonActionPerformed if (KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.removeKwMsg"), NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.deleteWordButtonActionPerformed.delConfirmMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN)) { @@ -450,6 +404,100 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_deleteListButtonActionPerformed + private void newKeywordsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newKeywordsButtonActionPerformed + String keywordsToRedisplay = ""; + AddKeywordsDialog dialog = new AddKeywordsDialog(); + + int goodCount; + int dupeCount; + int badCount = 1; // Default to 1 so we enter the loop the first time + + while(badCount > 0){ + dialog.setInitialKeywordList(keywordsToRedisplay); + dialog.display(); + + goodCount = 0; + dupeCount = 0; + badCount = 0; + keywordsToRedisplay = ""; + + if(!dialog.getKeywords().isEmpty()){ + + + for(String newWord:dialog.getKeywords()){ + if (newWord.isEmpty()) { + continue; + } + + final Keyword keyword = new Keyword(newWord, !dialog.isKeywordRegex(), dialog.isKeywordExact()); + if (currentKeywordList.hasKeyword(keyword)) { + dupeCount++; + continue; + } + + //check if valid + boolean valid = true; + try { + Pattern.compile(newWord); + } catch (PatternSyntaxException ex1) { + valid = false; + } catch (IllegalArgumentException ex2) { + valid = false; + } + if (!valid) { + + // Invalid keywords will reappear in the UI + keywordsToRedisplay += newWord + "\n"; + badCount++; + continue; + } + + // Add the new keyword + tableModel.addKeyword(keyword); + goodCount++; + } + XmlKeywordSearchList.getCurrent().addList(currentKeywordList); + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + + if((badCount > 0) || (dupeCount > 0)){ + // Display the error counts to the user + // The add keywords dialog will pop up again if any were invalid with any + // invalid entries (valid entries and dupes will disappear) + + String summary = ""; + KeywordSearchUtil.DIALOG_MESSAGE_TYPE level = KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO; + if(goodCount > 0){ + if(goodCount > 1){ + summary += NbBundle.getMessage(GlobalEditListPanel.class, "GlobalEditListPanel.keywordsAddedPlural.text", goodCount) + "\n"; + } else { + summary += NbBundle.getMessage(GlobalEditListPanel.class, "GlobalEditListPanel.keywordsAdded.text", goodCount) + "\n"; + } + } + if(dupeCount > 0){ + if(dupeCount > 1){ + summary += NbBundle.getMessage(GlobalEditListPanel.class, "GlobalEditListPanel.keywordDupesSkippedPlural.text", dupeCount) + "\n"; + } else { + summary += NbBundle.getMessage(GlobalEditListPanel.class, "GlobalEditListPanel.keywordDupesSkipped.text", dupeCount) + "\n"; + } + level = KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN; + } + if(badCount > 0){ + if(badCount > 1){ + summary += NbBundle.getMessage(GlobalEditListPanel.class, "GlobalEditListPanel.keywordErrorsPlural.text", badCount) + "\n"; + } else { + summary += NbBundle.getMessage(GlobalEditListPanel.class, "GlobalEditListPanel.keywordErrors.text", badCount) + "\n"; + } + level = KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR; + } + KeywordSearchUtil.displayDialog(NbBundle.getMessage(this.getClass(), "GlobalEditListPanel.addKeywordResults.text"), + summary, level); + } + } + } + setFocusOnKeywordTextBox(); + setButtonStates(); + }//GEN-LAST:event_newKeywordsButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel addKeywordPanel; private javax.swing.JButton deleteListButton; @@ -464,7 +512,7 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis private javax.swing.JPanel listEditorPanel; private javax.swing.JLabel listOptionsLabel; private javax.swing.JSeparator listOptionsSeparator; - private javax.swing.JButton newWordButton; + private javax.swing.JButton newKeywordsButton; private javax.swing.JButton saveListButton; // End of variables declaration//GEN-END:variables @@ -604,6 +652,6 @@ class GlobalEditListPanel extends javax.swing.JPanel implements ListSelectionLis * Set the keyboard focus to new keyword textbox. */ void setFocusOnKeywordTextBox() { - newWordButton.requestFocus(); + newKeywordsButton.requestFocus(); } }