19 package org.sleuthkit.autopsy.centralrepository.persona;
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.awt.event.ComponentAdapter;
24 import java.awt.event.ComponentEvent;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.List;
28 import java.util.logging.Level;
29 import javax.swing.JOptionPane;
30 import javax.swing.JTable;
31 import javax.swing.ListSelectionModel;
32 import javax.swing.event.AncestorListener;
33 import javax.swing.event.AncestorEvent;
34 import javax.swing.event.ListSelectionEvent;
35 import javax.swing.event.ListSelectionListener;
36 import javax.swing.table.DefaultTableModel;
37 import org.openide.DialogDisplayer;
38 import org.openide.NotifyDescriptor;
39 import org.openide.util.NbBundle.Messages;
40 import org.openide.windows.RetainLocation;
41 import org.openide.windows.TopComponent;
42 import org.openide.windows.WindowManager;
52 @TopComponent.Description(preferredID =
"PersonasTopComponent", persistenceType = TopComponent.PERSISTENCE_NEVER)
53 @TopComponent.Registration(mode =
"personas", openAtStartup =
false)
54 @RetainLocation(
"personas")
55 @SuppressWarnings(
"PMD.SingularField")
58 private static final long serialVersionUID = 1L;
62 private List<Persona> currentResults = null;
66 "PersonasTopComponent_Name=Personas",
67 "PersonasTopComponent_delete_exception_Title=Delete failure",
68 "PersonasTopComponent_delete_exception_msg=Failed to delete persona.",
69 "PersonasTopComponent_delete_confirmation_Title=Are you sure?",
70 "PersonasTopComponent_delete_confirmation_msg=Are you sure you want to delete this persona?",})
73 setName(Bundle.PersonasTopComponent_Name());
75 searchBtn.addActionListener(
new ActionListener() {
77 public void actionPerformed(ActionEvent e) {
82 editBtn.addActionListener(
new ActionListener() {
84 public void actionPerformed(ActionEvent e) {
90 createBtn.addActionListener(
new ActionListener() {
92 public void actionPerformed(ActionEvent e) {
98 deleteBtn.addActionListener(
new ActionListener() {
100 public void actionPerformed(ActionEvent e) {
101 NotifyDescriptor confirm =
new NotifyDescriptor.Confirmation(
102 Bundle.PersonasTopComponent_delete_confirmation_msg(),
103 Bundle.PersonasTopComponent_delete_confirmation_Title(),
104 NotifyDescriptor.YES_NO_OPTION);
105 DialogDisplayer.getDefault().notify(confirm);
106 if (confirm.getValue().equals(NotifyDescriptor.YES_OPTION)) {
108 if (selectedPersona != null) {
112 logger.log(Level.SEVERE,
"Failed to delete persona: " + selectedPersona.
getName(), ex);
114 Bundle.PersonasTopComponent_delete_exception_msg(),
115 Bundle.PersonasTopComponent_delete_exception_Title(),
116 JOptionPane.ERROR_MESSAGE);
125 resultsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
126 resultsTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
128 public void valueChanged(ListSelectionEvent e) {
129 handleSelectionChange(e);
133 createAccountBtn.addActionListener(
new ActionListener() {
135 public void actionPerformed(ActionEvent e) {
144 addComponentListener(
new ComponentAdapter() {
146 public void componentShown(ComponentEvent e) {
147 resetSearchControls();
148 setKeywordSearchEnabled(
false,
true);
159 public void callback(
Persona persona) {
160 if (persona != null) {
161 searchField.setText(
"");
163 int personaRow = currentResults.indexOf(persona);
164 resultsTable.getSelectionModel().setSelectionInterval(personaRow, personaRow);
165 handleSelectionChange();
167 createBtn.setEnabled(
true);
175 searchField.setText(
"");
176 searchNameRadio.setSelected(
true);
177 searchAccountRadio.setSelected(
false);
188 if (setFilterCb && cbFilterByKeyword.isSelected() != selected) {
189 cbFilterByKeyword.setSelected(selected);
192 searchField.setEnabled(selected);
193 searchNameRadio.setEnabled(selected);
194 searchAccountRadio.setEnabled(selected);
199 void setPersona(
int index) {
200 Persona persona = currentResults.get(index);
201 selectedPersona = persona;
202 editBtn.setEnabled(
true);
203 deleteBtn.setEnabled(
true);
209 final class PersonaFilterTableModel
extends DefaultTableModel {
211 private static final long serialVersionUID = 1L;
213 PersonaFilterTableModel(Object[][] rows, String[] colNames) {
214 super(rows, colNames);
218 public boolean isCellEditable(
int row,
int column) {
224 if (e.getValueIsAdjusting()) {
227 handleSelectionChange();
231 int selectedRow = resultsTable.getSelectedRow();
232 if (selectedRow != -1) {
233 setPersona(resultsTable.getSelectedRow());
236 detailsPanel.clear();
241 Object[][] rows =
new Object[results.size()][2];
243 for (
Persona result : results) {
244 rows[i] =
new Object[]{result.getId(), result.getName()};
247 PersonaFilterTableModel updatedTableModel =
new PersonaFilterTableModel(
249 new String[]{
"ID",
"Name"}
252 resultsTable.setModel(updatedTableModel);
253 currentResults =
new ArrayList<>(results);
256 resultsTable.getColumnModel().getColumn(0).setMaxWidth(100);
257 resultsTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
261 "PersonasTopComponent_search_exception_Title=There was a failure during the search. Try opening a case to fully initialize the central repository database.",
262 "PersonasTopComponent_search_exception_msg=Failed to search personas.",
263 "PersonasTopComponent_noCR_msg=Central Repository is not enabled.",})
267 logger.log(Level.SEVERE,
"Central Repository is not enabled, but execute search was called.");
268 JOptionPane.showMessageDialog(
this,
269 Bundle.PersonasTopComponent_search_exception_Title(),
270 Bundle.PersonasTopComponent_noCR_msg(),
271 JOptionPane.ERROR_MESSAGE);
275 Collection<Persona> results;
277 if (cbFilterByKeyword.isSelected()) {
278 if (searchNameRadio.isSelected()) {
287 logger.log(Level.SEVERE,
"Failed to search personas", ex);
288 JOptionPane.showMessageDialog(
this,
289 Bundle.PersonasTopComponent_search_exception_Title(),
290 Bundle.PersonasTopComponent_search_exception_msg(),
291 JOptionPane.ERROR_MESSAGE);
295 resultsTable.clearSelection();
296 updateResultsTable(results);
297 editBtn.setEnabled(
false);
298 deleteBtn.setEnabled(
false);
303 super.componentOpened();
304 WindowManager.getDefault().setTopComponentFloating(
this,
true);
315 searchButtonGroup =
new javax.swing.ButtonGroup();
316 introTextScrollPane =
new javax.swing.JScrollPane();
317 introText =
new javax.swing.JTextArea();
318 mainSplitPane =
new javax.swing.JSplitPane();
319 searchPanel =
new javax.swing.JPanel();
320 searchField =
new javax.swing.JTextField();
321 searchNameRadio =
new javax.swing.JRadioButton();
322 searchAccountRadio =
new javax.swing.JRadioButton();
323 searchBtn =
new javax.swing.JButton();
324 resultsPane =
new javax.swing.JScrollPane();
325 resultsTable =
new javax.swing.JTable();
326 createAccountBtn =
new javax.swing.JButton();
327 editBtn =
new javax.swing.JButton();
328 deleteBtn =
new javax.swing.JButton();
329 createButtonSeparator =
new javax.swing.JSeparator();
330 createBtn =
new javax.swing.JButton();
331 cbFilterByKeyword =
new javax.swing.JCheckBox();
332 detailsScrollPane =
new javax.swing.JScrollPane();
337 introTextScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
339 introText.setBackground(getBackground());
340 introText.setColumns(20);
341 introText.setLineWrap(
true);
342 introText.setRows(5);
343 introText.setText(
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.introText.text"));
344 introText.setWrapStyleWord(
true);
345 introText.setFocusable(
false);
346 introTextScrollPane.setViewportView(introText);
348 mainSplitPane.setDividerLocation(400);
350 searchField.setText(
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.searchField.text"));
352 searchButtonGroup.add(searchNameRadio);
353 searchNameRadio.setSelected(
true);
354 org.openide.awt.Mnemonics.setLocalizedText(searchNameRadio,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.searchNameRadio.text"));
356 searchButtonGroup.add(searchAccountRadio);
357 org.openide.awt.Mnemonics.setLocalizedText(searchAccountRadio,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.searchAccountRadio.text"));
359 org.openide.awt.Mnemonics.setLocalizedText(searchBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.searchBtn.text"));
361 resultsTable.setToolTipText(
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.resultsTable.toolTipText"));
362 resultsTable.getTableHeader().setReorderingAllowed(
false);
363 resultsPane.setViewportView(resultsTable);
364 if (resultsTable.getColumnModel().getColumnCount() > 0) {
365 resultsTable.getColumnModel().getColumn(0).setMaxWidth(25);
366 resultsTable.getColumnModel().getColumn(0).setHeaderValue(
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.resultsTable.columnModel.title0"));
367 resultsTable.getColumnModel().getColumn(1).setHeaderValue(
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.resultsTable.columnModel.title1"));
370 org.openide.awt.Mnemonics.setLocalizedText(createAccountBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.createAccountBtn.text"));
372 org.openide.awt.Mnemonics.setLocalizedText(editBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.editBtn.text"));
373 editBtn.setEnabled(
false);
375 org.openide.awt.Mnemonics.setLocalizedText(deleteBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.deleteBtn.text"));
376 deleteBtn.setEnabled(
false);
378 org.openide.awt.Mnemonics.setLocalizedText(createBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.createBtn.text"));
380 org.openide.awt.Mnemonics.setLocalizedText(cbFilterByKeyword,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.cbFilterByKeyword.text"));
381 cbFilterByKeyword.addActionListener(
new java.awt.event.ActionListener() {
382 public void actionPerformed(java.awt.event.ActionEvent evt) {
383 cbFilterByKeywordActionPerformed(evt);
387 javax.swing.GroupLayout searchPanelLayout =
new javax.swing.GroupLayout(searchPanel);
388 searchPanel.setLayout(searchPanelLayout);
389 searchPanelLayout.setHorizontalGroup(
390 searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
391 .addGroup(searchPanelLayout.createSequentialGroup()
393 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
394 .addComponent(createButtonSeparator)
395 .addComponent(resultsPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
396 .addComponent(searchField)
397 .addGroup(searchPanelLayout.createSequentialGroup()
398 .addComponent(searchNameRadio)
399 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
400 .addComponent(searchAccountRadio)
401 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
402 .addComponent(searchBtn))
403 .addGroup(searchPanelLayout.createSequentialGroup()
404 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
405 .addComponent(createAccountBtn)
406 .addGroup(searchPanelLayout.createSequentialGroup()
407 .addComponent(createBtn)
408 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
409 .addComponent(editBtn)
410 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
411 .addComponent(deleteBtn))
412 .addComponent(cbFilterByKeyword))
413 .addGap(0, 50, Short.MAX_VALUE)))
416 searchPanelLayout.setVerticalGroup(
417 searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
418 .addGroup(searchPanelLayout.createSequentialGroup()
419 .addComponent(cbFilterByKeyword)
421 .addComponent(searchField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
422 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
423 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
424 .addComponent(searchNameRadio)
425 .addComponent(searchAccountRadio)
426 .addComponent(searchBtn))
427 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
428 .addComponent(resultsPane, javax.swing.GroupLayout.PREFERRED_SIZE, 302, javax.swing.GroupLayout.PREFERRED_SIZE)
429 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
430 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
431 .addComponent(editBtn)
432 .addComponent(createBtn)
433 .addComponent(deleteBtn))
434 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
435 .addComponent(createButtonSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 4, javax.swing.GroupLayout.PREFERRED_SIZE)
436 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
437 .addComponent(createAccountBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
441 mainSplitPane.setLeftComponent(searchPanel);
443 detailsScrollPane.setViewportView(detailsPanel);
445 mainSplitPane.setRightComponent(detailsScrollPane);
447 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
448 this.setLayout(layout);
449 layout.setHorizontalGroup(
450 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
451 .addComponent(introTextScrollPane)
452 .addComponent(mainSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 724, Short.MAX_VALUE)
454 layout.setVerticalGroup(
455 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
456 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
457 .addComponent(introTextScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)
458 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
459 .addComponent(mainSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE))
464 setKeywordSearchEnabled(cbFilterByKeyword.isSelected(),
false);
javax.swing.JRadioButton searchNameRadio
javax.swing.JCheckBox cbFilterByKeyword
javax.swing.JPanel searchPanel
void handleSelectionChange()
void handleSelectionChange(ListSelectionEvent e)
javax.swing.JButton createAccountBtn
javax.swing.JSplitPane mainSplitPane
static Collection< Persona > getPersonaByName(String partialName)
javax.swing.JScrollPane introTextScrollPane
javax.swing.JTextField searchField
javax.swing.JScrollPane resultsPane
void cbFilterByKeywordActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JButton searchBtn
javax.swing.JSeparator createButtonSeparator
javax.swing.JButton editBtn
javax.swing.JScrollPane detailsScrollPane
javax.swing.JTable resultsTable
javax.swing.JButton deleteBtn
void resetSearchControls()
void setKeywordSearchEnabled(boolean selected, boolean setFilterCb)
javax.swing.ButtonGroup searchButtonGroup
javax.swing.JTextArea introText
synchronized static Logger getLogger(String name)
org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel detailsPanel
void updateResultsTable(Collection< Persona > results)
javax.swing.JButton createBtn
static Collection< Persona > getPersonaByAccountIdentifierLike(String partialName)
javax.swing.JRadioButton searchAccountRadio
static boolean isEnabled()