19 package org.sleuthkit.autopsy.centralrepository.persona;
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.List;
26 import java.util.logging.Level;
27 import javax.swing.JOptionPane;
28 import javax.swing.JTable;
29 import javax.swing.ListSelectionModel;
30 import javax.swing.event.ListSelectionEvent;
31 import javax.swing.event.ListSelectionListener;
32 import javax.swing.table.DefaultTableModel;
33 import org.openide.DialogDisplayer;
34 import org.openide.NotifyDescriptor;
35 import org.openide.util.NbBundle.Messages;
36 import org.openide.windows.RetainLocation;
37 import org.openide.windows.TopComponent;
38 import org.openide.windows.WindowManager;
47 @TopComponent.Description(preferredID =
"PersonasTopComponent", persistenceType = TopComponent.PERSISTENCE_NEVER)
48 @TopComponent.Registration(mode =
"personas", openAtStartup =
false)
49 @RetainLocation(
"personas")
50 @SuppressWarnings(
"PMD.SingularField")
53 private static final long serialVersionUID = 1L;
57 private List<Persona> currentResults = null;
61 "PersonasTopComponent_Name=Personas",
62 "PersonasTopComponent_delete_exception_Title=Delete failure",
63 "PersonasTopComponent_delete_exception_msg=Failed to delete persona.",
64 "PersonasTopComponent_delete_confirmation_Title=Are you sure?",
65 "PersonasTopComponent_delete_confirmation_msg=Are you sure you want to delete this persona?",
69 setName(Bundle.PersonasTopComponent_Name());
72 searchBtn.addActionListener(
new ActionListener() {
74 public void actionPerformed(ActionEvent e) {
79 editBtn.addActionListener(
new ActionListener() {
81 public void actionPerformed(ActionEvent e) {
87 createBtn.addActionListener(
new ActionListener() {
89 public void actionPerformed(ActionEvent e) {
95 deleteBtn.addActionListener(
new ActionListener() {
97 public void actionPerformed(ActionEvent e) {
98 NotifyDescriptor confirm =
new NotifyDescriptor.Confirmation(
99 Bundle.PersonasTopComponent_delete_confirmation_msg(),
100 Bundle.PersonasTopComponent_delete_confirmation_Title(),
101 NotifyDescriptor.YES_NO_OPTION);
102 DialogDisplayer.getDefault().notify(confirm);
103 if (confirm.getValue().equals(NotifyDescriptor.YES_OPTION)) {
105 if (selectedPersona != null) {
109 logger.log(Level.SEVERE,
"Failed to delete persona: " + selectedPersona.
getName(), ex);
111 Bundle.PersonasTopComponent_delete_exception_msg(),
112 Bundle.PersonasTopComponent_delete_exception_Title(),
113 JOptionPane.ERROR_MESSAGE);
122 resultsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
123 resultsTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
125 public void valueChanged(ListSelectionEvent e) {
126 handleSelectionChange(e);
130 searchNameRadio.addActionListener((ActionEvent e) -> {
131 searchField.setText(
"");
134 searchAccountRadio.addActionListener((ActionEvent e) -> {
135 searchField.setText(
"");
138 createAccountBtn.addActionListener(
new ActionListener() {
140 public void actionPerformed(ActionEvent e) {
152 public void callback(
Persona persona) {
153 if (persona != null) {
154 searchField.setText(
"");
156 int personaRow = currentResults.indexOf(persona);
157 resultsTable.getSelectionModel().setSelectionInterval(personaRow, personaRow);
158 handleSelectionChange();
160 createBtn.setEnabled(
true);
164 void setPersona(
int index) {
165 Persona persona = currentResults.get(index);
166 selectedPersona = persona;
167 editBtn.setEnabled(
true);
168 deleteBtn.setEnabled(
true);
174 final class PersonaFilterTableModel
extends DefaultTableModel {
176 private static final long serialVersionUID = 1L;
178 PersonaFilterTableModel(Object[][] rows, String[] colNames) {
179 super(rows, colNames);
183 public boolean isCellEditable(
int row,
int column) {
189 if (e.getValueIsAdjusting()) {
192 handleSelectionChange();
196 int selectedRow = resultsTable.getSelectedRow();
197 if (selectedRow != -1) {
198 setPersona(resultsTable.getSelectedRow());
201 detailsPanel.clear();
206 Object[][] rows =
new Object[results.size()][2];
208 for (
Persona result : results) {
209 rows[i] =
new Object[]{result.getId(), result.getName()};
212 PersonaFilterTableModel updatedTableModel =
new PersonaFilterTableModel(
214 new String[]{
"ID",
"Name"}
217 resultsTable.setModel(updatedTableModel);
218 currentResults =
new ArrayList<>(results);
221 resultsTable.getColumnModel().getColumn(0).setMaxWidth(100);
222 resultsTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
226 "PersonasTopComponent_search_exception_Title=Search failure",
227 "PersonasTopComponent_search_exception_msg=Failed to search personas.",})
229 Collection<Persona> results;
231 if (searchNameRadio.isSelected()) {
237 logger.log(Level.SEVERE,
"Failed to search personas", ex);
238 JOptionPane.showMessageDialog(
this,
239 Bundle.PersonasTopComponent_search_exception_Title(),
240 Bundle.PersonasTopComponent_search_exception_msg(),
241 JOptionPane.ERROR_MESSAGE);
245 resultsTable.clearSelection();
246 updateResultsTable(results);
247 editBtn.setEnabled(
false);
248 deleteBtn.setEnabled(
false);
253 super.componentOpened();
254 WindowManager.getDefault().setTopComponentFloating(
this,
true);
265 searchButtonGroup =
new javax.swing.ButtonGroup();
266 mainSplitPane =
new javax.swing.JSplitPane();
267 searchPanel =
new javax.swing.JPanel();
268 searchField =
new javax.swing.JTextField();
269 searchNameRadio =
new javax.swing.JRadioButton();
270 searchAccountRadio =
new javax.swing.JRadioButton();
271 searchBtn =
new javax.swing.JButton();
272 resultsPane =
new javax.swing.JScrollPane();
273 resultsTable =
new javax.swing.JTable();
274 createAccountBtn =
new javax.swing.JButton();
275 editBtn =
new javax.swing.JButton();
276 deleteBtn =
new javax.swing.JButton();
277 createButtonSeparator =
new javax.swing.JSeparator();
278 createBtn =
new javax.swing.JButton();
279 detailsScrollPane =
new javax.swing.JScrollPane();
284 mainSplitPane.setDividerLocation(400);
286 searchField.setText(
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.searchField.text"));
288 searchButtonGroup.add(searchNameRadio);
289 searchNameRadio.setSelected(
true);
290 org.openide.awt.Mnemonics.setLocalizedText(searchNameRadio,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.searchNameRadio.text"));
292 searchButtonGroup.add(searchAccountRadio);
293 org.openide.awt.Mnemonics.setLocalizedText(searchAccountRadio,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.searchAccountRadio.text"));
295 org.openide.awt.Mnemonics.setLocalizedText(searchBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.searchBtn.text"));
297 resultsTable.setToolTipText(
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.resultsTable.toolTipText"));
298 resultsTable.getTableHeader().setReorderingAllowed(
false);
299 resultsPane.setViewportView(resultsTable);
300 if (resultsTable.getColumnModel().getColumnCount() > 0) {
301 resultsTable.getColumnModel().getColumn(0).setMaxWidth(25);
302 resultsTable.getColumnModel().getColumn(0).setHeaderValue(
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.resultsTable.columnModel.title0"));
303 resultsTable.getColumnModel().getColumn(1).setHeaderValue(
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.resultsTable.columnModel.title1"));
306 org.openide.awt.Mnemonics.setLocalizedText(createAccountBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.createAccountBtn.text"));
308 org.openide.awt.Mnemonics.setLocalizedText(editBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.editBtn.text"));
309 editBtn.setEnabled(
false);
311 org.openide.awt.Mnemonics.setLocalizedText(deleteBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.deleteBtn.text"));
312 deleteBtn.setEnabled(
false);
314 org.openide.awt.Mnemonics.setLocalizedText(createBtn,
org.openide.util.NbBundle.getMessage(
PersonasTopComponent.class,
"PersonasTopComponent.createBtn.text"));
316 javax.swing.GroupLayout searchPanelLayout =
new javax.swing.GroupLayout(searchPanel);
317 searchPanel.setLayout(searchPanelLayout);
318 searchPanelLayout.setHorizontalGroup(
319 searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
320 .addGroup(searchPanelLayout.createSequentialGroup()
322 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
323 .addComponent(createButtonSeparator)
324 .addComponent(resultsPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
325 .addComponent(searchField)
326 .addGroup(searchPanelLayout.createSequentialGroup()
327 .addComponent(searchNameRadio)
328 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
329 .addComponent(searchAccountRadio)
330 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
331 .addComponent(searchBtn))
332 .addGroup(searchPanelLayout.createSequentialGroup()
333 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
334 .addComponent(createAccountBtn)
335 .addGroup(searchPanelLayout.createSequentialGroup()
336 .addComponent(createBtn)
337 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
338 .addComponent(editBtn)
339 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
340 .addComponent(deleteBtn)))
341 .addGap(0, 0, Short.MAX_VALUE)))
344 searchPanelLayout.setVerticalGroup(
345 searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
346 .addGroup(searchPanelLayout.createSequentialGroup()
348 .addComponent(searchField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
349 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
350 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
351 .addComponent(searchNameRadio)
352 .addComponent(searchAccountRadio)
353 .addComponent(searchBtn))
354 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
355 .addComponent(resultsPane, javax.swing.GroupLayout.DEFAULT_SIZE, 258, Short.MAX_VALUE)
356 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
357 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
358 .addComponent(editBtn)
359 .addComponent(createBtn)
360 .addComponent(deleteBtn))
361 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
362 .addComponent(createButtonSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 4, javax.swing.GroupLayout.PREFERRED_SIZE)
363 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
364 .addComponent(createAccountBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
368 mainSplitPane.setLeftComponent(searchPanel);
370 detailsScrollPane.setViewportView(detailsPanel);
372 mainSplitPane.setRightComponent(detailsScrollPane);
374 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
375 this.setLayout(layout);
376 layout.setHorizontalGroup(
377 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
378 .addComponent(mainSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 816, Short.MAX_VALUE)
380 layout.setVerticalGroup(
381 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
382 .addComponent(mainSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 428, Short.MAX_VALUE)
javax.swing.JRadioButton searchNameRadio
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.JTextField searchField
javax.swing.JScrollPane resultsPane
javax.swing.JButton searchBtn
javax.swing.JSeparator createButtonSeparator
javax.swing.JButton editBtn
javax.swing.JScrollPane detailsScrollPane
javax.swing.JTable resultsTable
javax.swing.JButton deleteBtn
javax.swing.ButtonGroup searchButtonGroup
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