19 package org.sleuthkit.autopsy.keywordsearch;
21 import java.awt.EventQueue;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.logging.Level;
27 import java.util.regex.Pattern;
28 import java.util.regex.PatternSyntaxException;
29 import javax.swing.JTable;
30 import javax.swing.ListSelectionModel;
31 import javax.swing.event.ListSelectionEvent;
32 import javax.swing.event.ListSelectionListener;
33 import javax.swing.table.AbstractTableModel;
34 import javax.swing.table.TableColumn;
35 import org.netbeans.spi.options.OptionsPanelController;
36 import org.openide.util.NbBundle;
44 class GlobalEditListPanel
extends javax.swing.JPanel implements ListSelectionListener, OptionsPanel {
46 private static final Logger logger = Logger.getLogger(GlobalEditListPanel.class.getName());
47 private static final long serialVersionUID = 1L;
48 private final KeywordTableModel tableModel;
49 private KeywordList currentKeywordList;
54 GlobalEditListPanel() {
55 tableModel =
new KeywordTableModel();
57 customizeComponents();
60 private void customizeComponents() {
61 newKeywordsButton.setToolTipText((NbBundle.getMessage(
this.getClass(),
"KeywordSearchEditListPanel.customizeComponents.addWordToolTip")));
62 deleteWordButton.setToolTipText(NbBundle.getMessage(
this.getClass(),
"KeywordSearchEditListPanel.customizeComponents.removeSelectedMsg"));
64 keywordTable.getParent().setBackground(keywordTable.getBackground());
65 final int width = jScrollPane1.getPreferredSize().width;
66 keywordTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
68 for (
int i = 0; i < keywordTable.getColumnCount(); i++) {
69 column = keywordTable.getColumnModel().getColumn(i);
71 column.setPreferredWidth(((
int) (width * 0.90)));
73 column.setPreferredWidth(((
int) (width * 0.10)));
76 keywordTable.setCellSelectionEnabled(
false);
77 keywordTable.setRowSelectionAllowed(
true);
79 final ListSelectionModel lsm = keywordTable.getSelectionModel();
80 lsm.addListSelectionListener(
new ListSelectionListener() {
82 public void valueChanged(ListSelectionEvent e) {
83 boolean canDelete = !(lsm.isSelectionEmpty() || currentKeywordList.isEditable() || IngestManager.getInstance().isIngestRunning());
84 boolean canEdit = canDelete && (lsm.getMaxSelectionIndex() == lsm.getMinSelectionIndex());
85 deleteWordButton.setEnabled(canDelete);
86 editWordButton.setEnabled(canEdit);
92 IngestManager.getInstance().addIngestJobEventListener(
new PropertyChangeListener() {
94 public void propertyChange(PropertyChangeEvent evt) {
95 Object source = evt.getSource();
96 if (source instanceof String && ((String) source).equals(
"LOCAL")) {
97 EventQueue.invokeLater(() -> {
108 void setButtonStates() {
109 boolean isIngestRunning = IngestManager.getInstance().isIngestRunning();
110 boolean isListSelected = currentKeywordList != null;
113 boolean canEditList = isListSelected && !isIngestRunning;
114 ingestMessagesCheckbox.setEnabled(canEditList);
115 ingestMessagesCheckbox.setSelected(currentKeywordList != null && currentKeywordList.getIngestMessages());
118 boolean canAddWord = canEditList && !currentKeywordList.isEditable();
119 newKeywordsButton.setEnabled(canAddWord);
122 if ((currentKeywordList == null) || (currentKeywordList.getKeywords().isEmpty())) {
123 deleteWordButton.setEnabled(
false);
124 editWordButton.setEnabled(
false);
128 @NbBundle.Messages(
"GlobalEditListPanel.editKeyword.title=Edit Keyword")
135 private boolean addKeywordsAction(String existingKeywords,
boolean isLiteral,
boolean isWholeWord) {
136 String keywordsToRedisplay = existingKeywords;
137 AddKeywordsDialog dialog =
new AddKeywordsDialog();
143 if (!existingKeywords.isEmpty()) {
144 dialog.setTitle(NbBundle.getMessage(GlobalEditListPanel.class,
"GlobalEditListPanel.editKeyword.title"));
146 while (badCount > 0) {
147 dialog.setInitialKeywordList(keywordsToRedisplay, isLiteral, isWholeWord);
153 keywordsToRedisplay =
"";
155 if (!dialog.getKeywords().isEmpty()) {
157 for (String newWord : dialog.getKeywords()) {
158 if (newWord.isEmpty()) {
162 final Keyword keyword =
new Keyword(newWord, !dialog.isKeywordRegex(), dialog.isKeywordExact(), currentKeywordList.getName(), newWord);
163 if (currentKeywordList.hasKeyword(keyword)) {
169 boolean valid =
true;
171 Pattern.compile(newWord);
172 }
catch (PatternSyntaxException ex1) {
174 }
catch (IllegalArgumentException ex2) {
180 keywordsToRedisplay += newWord +
"\n";
186 tableModel.addKeyword(keyword);
189 XmlKeywordSearchList.getCurrent().addList(currentKeywordList);
190 firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
192 if ((badCount > 0) || (dupeCount > 0)) {
198 KeywordSearchUtil.DIALOG_MESSAGE_TYPE level = KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO;
201 summary += NbBundle.getMessage(GlobalEditListPanel.class,
"GlobalEditListPanel.keywordsAddedPlural.text", goodCount) +
"\n";
203 summary += NbBundle.getMessage(GlobalEditListPanel.class,
"GlobalEditListPanel.keywordsAdded.text", goodCount) +
"\n";
208 summary += NbBundle.getMessage(GlobalEditListPanel.class,
"GlobalEditListPanel.keywordDupesSkippedPlural.text", dupeCount) +
"\n";
210 summary += NbBundle.getMessage(GlobalEditListPanel.class,
"GlobalEditListPanel.keywordDupesSkipped.text", dupeCount) +
"\n";
212 level = KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN;
216 summary += NbBundle.getMessage(GlobalEditListPanel.class,
"GlobalEditListPanel.keywordErrorsPlural.text", badCount) +
"\n";
218 summary += NbBundle.getMessage(GlobalEditListPanel.class,
"GlobalEditListPanel.keywordErrors.text", badCount) +
"\n";
220 level = KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR;
222 KeywordSearchUtil.displayDialog(NbBundle.getMessage(
this.getClass(),
"GlobalEditListPanel.addKeywordResults.text"),
227 setFocusOnKeywordTextBox();
229 return (goodCount >= 1 && dupeCount == 0);
238 private void deleteKeywordAction(
int[] selectedKeywords) {
239 tableModel.deleteSelected(selectedKeywords);
240 XmlKeywordSearchList.getCurrent().addList(currentKeywordList);
249 @SuppressWarnings(
"unchecked")
251 private
void initComponents() {
253 listEditorPanel =
new javax.swing.JPanel();
254 jScrollPane1 =
new javax.swing.JScrollPane();
255 keywordTable =
new javax.swing.JTable();
256 ingestMessagesCheckbox =
new javax.swing.JCheckBox();
257 keywordsLabel =
new javax.swing.JLabel();
258 newKeywordsButton =
new javax.swing.JButton();
259 deleteWordButton =
new javax.swing.JButton();
260 editWordButton =
new javax.swing.JButton();
262 setMinimumSize(
new java.awt.Dimension(0, 0));
264 listEditorPanel.setMinimumSize(
new java.awt.Dimension(0, 0));
266 jScrollPane1.setPreferredSize(
new java.awt.Dimension(340, 300));
268 keywordTable.setModel(tableModel);
269 keywordTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
270 keywordTable.setGridColor(
new java.awt.Color(153, 153, 153));
271 keywordTable.setMaximumSize(
new java.awt.Dimension(30000, 30000));
272 keywordTable.getTableHeader().setReorderingAllowed(
false);
273 jScrollPane1.setViewportView(keywordTable);
275 ingestMessagesCheckbox.setSelected(
true);
276 ingestMessagesCheckbox.setText(
org.openide.util.NbBundle.getMessage(GlobalEditListPanel.class,
"KeywordSearchEditListPanel.ingestMessagesCheckbox.text"));
277 ingestMessagesCheckbox.setToolTipText(
org.openide.util.NbBundle.getMessage(GlobalEditListPanel.class,
"KeywordSearchEditListPanel.ingestMessagesCheckbox.toolTipText"));
278 ingestMessagesCheckbox.addActionListener(
new java.awt.event.ActionListener() {
279 public void actionPerformed(java.awt.event.ActionEvent evt) {
280 ingestMessagesCheckboxActionPerformed(evt);
284 keywordsLabel.setText(
org.openide.util.NbBundle.getMessage(GlobalEditListPanel.class,
"KeywordSearchEditListPanel.keywordsLabel.text"));
286 newKeywordsButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/add16.png")));
287 newKeywordsButton.setText(
org.openide.util.NbBundle.getMessage(GlobalEditListPanel.class,
"GlobalEditListPanel.newKeywordsButton.text"));
288 newKeywordsButton.addActionListener(
new java.awt.event.ActionListener() {
289 public void actionPerformed(java.awt.event.ActionEvent evt) {
290 newKeywordsButtonActionPerformed(evt);
294 deleteWordButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/delete16.png")));
295 deleteWordButton.setText(
org.openide.util.NbBundle.getMessage(GlobalEditListPanel.class,
"KeywordSearchEditListPanel.deleteWordButton.text"));
296 deleteWordButton.addActionListener(
new java.awt.event.ActionListener() {
297 public void actionPerformed(java.awt.event.ActionEvent evt) {
298 deleteWordButtonActionPerformed(evt);
302 editWordButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/edit16.png")));
303 editWordButton.setText(
org.openide.util.NbBundle.getMessage(GlobalEditListPanel.class,
"GlobalEditListPanel.editWordButton.text"));
304 editWordButton.addActionListener(
new java.awt.event.ActionListener() {
305 public void actionPerformed(java.awt.event.ActionEvent evt) {
306 editWordButtonActionPerformed(evt);
310 javax.swing.GroupLayout listEditorPanelLayout =
new javax.swing.GroupLayout(listEditorPanel);
311 listEditorPanel.setLayout(listEditorPanelLayout);
312 listEditorPanelLayout.setHorizontalGroup(
313 listEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
314 .addGroup(listEditorPanelLayout.createSequentialGroup()
316 .addGroup(listEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
317 .addGroup(listEditorPanelLayout.createSequentialGroup()
318 .addComponent(keywordsLabel)
319 .addGap(0, 0, Short.MAX_VALUE))
320 .addGroup(listEditorPanelLayout.createSequentialGroup()
322 .addGroup(listEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
323 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 483, Short.MAX_VALUE)
324 .addGroup(listEditorPanelLayout.createSequentialGroup()
325 .addGroup(listEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
326 .addComponent(ingestMessagesCheckbox)
327 .addGroup(listEditorPanelLayout.createSequentialGroup()
328 .addComponent(newKeywordsButton, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
330 .addComponent(editWordButton, javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE)
332 .addComponent(deleteWordButton, javax.swing.GroupLayout.PREFERRED_SIZE, 144, javax.swing.GroupLayout.PREFERRED_SIZE)))
333 .addGap(0, 0, Short.MAX_VALUE)))))
337 listEditorPanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {deleteWordButton, editWordButton, newKeywordsButton});
339 listEditorPanelLayout.setVerticalGroup(
340 listEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
341 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, listEditorPanelLayout.createSequentialGroup()
343 .addComponent(keywordsLabel)
344 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
345 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 257, Short.MAX_VALUE)
346 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
347 .addGroup(listEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
348 .addComponent(deleteWordButton)
349 .addComponent(newKeywordsButton)
350 .addComponent(editWordButton))
351 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
352 .addComponent(ingestMessagesCheckbox)
356 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
357 this.setLayout(layout);
358 layout.setHorizontalGroup(
359 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
360 .addComponent(listEditorPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
362 layout.setVerticalGroup(
363 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
364 .addGroup(layout.createSequentialGroup()
365 .addComponent(listEditorPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
370 private void deleteWordButtonActionPerformed(java.awt.event.ActionEvent evt) {
371 if (KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(
this.getClass(),
"KeywordSearchEditListPanel.removeKwMsg"),
372 NbBundle.getMessage(
this.getClass(),
"KeywordSearchEditListPanel.deleteWordButtonActionPerformed.delConfirmMsg"),
373 KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN)) {
374 deleteKeywordAction(keywordTable.getSelectedRows());
375 firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
379 private void ingestMessagesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
380 currentKeywordList.setIngestMessages(ingestMessagesCheckbox.isSelected());
381 XmlKeywordSearchList updater = XmlKeywordSearchList.getCurrent();
382 updater.addList(currentKeywordList);
383 firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
386 private void newKeywordsButtonActionPerformed(java.awt.event.ActionEvent evt) {
387 addKeywordsAction(
"",
true,
true);
390 private void editWordButtonActionPerformed(java.awt.event.ActionEvent evt) {
391 int[] selectedKeywords = keywordTable.getSelectedRows();
392 if (selectedKeywords.length == 1) {
393 Keyword currentKeyword = currentKeywordList.getKeywords().get(selectedKeywords[0]);
394 if (addKeywordsAction(currentKeyword.getSearchTerm(), currentKeyword.searchTermIsLiteral(), currentKeyword.searchTermIsWholeWord())) {
395 deleteKeywordAction(selectedKeywords);
401 private javax.swing.JButton deleteWordButton;
402 private javax.swing.JButton editWordButton;
403 private javax.swing.JCheckBox ingestMessagesCheckbox;
404 private javax.swing.JScrollPane jScrollPane1;
405 private javax.swing.JTable keywordTable;
406 private javax.swing.JLabel keywordsLabel;
407 private javax.swing.JPanel listEditorPanel;
408 private javax.swing.JButton newKeywordsButton;
412 public void valueChanged(ListSelectionEvent e) {
414 ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
415 currentKeywordList = null;
416 if (!listSelectionModel.isSelectionEmpty()) {
417 XmlKeywordSearchList loader = XmlKeywordSearchList.getCurrent();
418 if (listSelectionModel.getMinSelectionIndex() == listSelectionModel.getMaxSelectionIndex()) {
419 currentKeywordList = loader.getListsL(
false).get(listSelectionModel.getMinSelectionIndex());
427 public void store() {
436 KeywordList getCurrentKeywordList() {
437 return currentKeywordList;
440 void setCurrentKeywordList(KeywordList list) {
441 currentKeywordList = list;
453 return currentKeywordList == null ? 0 : currentKeywordList.getKeywords().size();
458 String colName = null;
462 colName = NbBundle.getMessage(this.getClass(),
"KeywordSearchEditListPanel.kwColName");
465 colName = NbBundle.getMessage(this.getClass(),
"KeywordSearch.typeColLbl");
476 if (currentKeywordList == null) {
479 Keyword word = currentKeywordList.getKeywords().get(rowIndex);
480 switch (columnIndex) {
482 ret = word.getSearchTerm();
485 ret = word.getSearchTermType();
488 logger.log(Level.SEVERE,
"Invalid table column index: {0}", columnIndex);
500 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
508 void addKeyword(Keyword keyword) {
509 if (!currentKeywordList.hasKeyword(keyword)) {
510 currentKeywordList.getKeywords().add(keyword);
512 fireTableDataChanged();
516 fireTableDataChanged();
520 void deleteSelected(
int[] selected) {
521 List<Keyword> words = currentKeywordList.getKeywords();
522 Arrays.sort(selected);
523 for (
int arrayi = selected.length - 1; arrayi >= 0; arrayi--) {
524 words.remove(selected[arrayi]);
533 void setFocusOnKeywordTextBox() {
534 newKeywordsButton.requestFocus();
boolean isCellEditable(int rowIndex, int columnIndex)
void setValueAt(Object aValue, int rowIndex, int columnIndex)
String getColumnName(int column)
Class<?> getColumnClass(int c)
Object getValueAt(int rowIndex, int columnIndex)