19 package org.sleuthkit.autopsy.casemodule;
21 import java.awt.Cursor;
22 import java.util.ArrayList;
23 import java.util.Date;
24 import java.util.logging.Level;
25 import javax.swing.JDialog;
26 import javax.swing.JPanel;
27 import javax.swing.SortOrder;
28 import javax.swing.SwingUtilities;
29 import javax.swing.event.ListSelectionEvent;
30 import javax.swing.table.DefaultTableModel;
31 import javax.swing.table.TableRowSorter;
32 import org.openide.util.Lookup;
39 @SuppressWarnings(
"PMD.SingularField")
40 final class MultiUserCasesPanel extends JPanel{
42 private static final Logger logger = Logger.getLogger(MultiUserCasesPanel.class.getName());
43 private static final long serialVersionUID = 1L;
44 private final JDialog parentDialog;
45 private final CaseBrowser caseBrowserPanel;
51 MultiUserCasesPanel(JDialog parentDialog) {
52 this.parentDialog = parentDialog;
55 caseBrowserPanel =
new CaseBrowser();
56 caseExplorerScrollPane.add(caseBrowserPanel);
57 caseExplorerScrollPane.setViewportView(caseBrowserPanel);
62 caseBrowserPanel.addListSelectionListener((ListSelectionEvent e) -> {
73 caseBrowserPanel.refresh();
81 bnOpen.setEnabled(caseBrowserPanel.isRowSelected());
89 private void openCase(String caseMetadataFilePath) {
90 if (caseMetadataFilePath != null) {
91 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
93 StartupWindowProvider.getInstance().close();
94 if (parentDialog != null) {
95 parentDialog.setVisible(
false);
99 Case.openAsCurrentCase(caseMetadataFilePath);
100 }
catch (CaseActionException ex) {
101 if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
102 logger.log(Level.SEVERE, String.format(
"Error opening case with metadata file path %s", caseMetadataFilePath), ex);
103 MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
105 SwingUtilities.invokeLater(() -> {
107 StartupWindowProvider.getInstance().open();
110 SwingUtilities.invokeLater(() -> {
112 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
123 private static class RowSorter<M
extends DefaultTableModel> extends TableRowSorter<M> {
131 if (!this.getModel().getColumnClass(column).equals(Date.class)) {
132 super.toggleSortOrder(column);
134 ArrayList<
RowSorter.SortKey> sortKeys =
new ArrayList<>(getSortKeys());
135 if (sortKeys.isEmpty() || sortKeys.get(0).getColumn() != column) {
136 sortKeys.add(0,
new RowSorter.SortKey(column, SortOrder.DESCENDING));
137 }
else if (sortKeys.get(0).getSortOrder() == SortOrder.ASCENDING) {
138 sortKeys.removeIf(key -> key.getColumn() == column);
139 sortKeys.add(0,
new RowSorter.SortKey(column, SortOrder.DESCENDING));
141 sortKeys.removeIf(key -> key.getColumn() == column);
142 sortKeys.add(0,
new RowSorter.SortKey(column, SortOrder.ASCENDING));
144 setSortKeys(sortKeys);
154 @SuppressWarnings(
"unchecked")
156 private
void initComponents() {
158 bnOpen =
new javax.swing.JButton();
159 bnOpenSingleUserCase =
new javax.swing.JButton();
160 cancelButton =
new javax.swing.JButton();
161 searchLabel =
new javax.swing.JLabel();
162 caseExplorerScrollPane =
new javax.swing.JScrollPane();
164 setName(
"Completed Cases");
165 setPreferredSize(
new java.awt.Dimension(960, 485));
167 org.openide.awt.Mnemonics.setLocalizedText(bnOpen,
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class,
"MultiUserCasesPanel.bnOpen.text"));
168 bnOpen.setEnabled(
false);
169 bnOpen.setMaximumSize(
new java.awt.Dimension(80, 23));
170 bnOpen.setMinimumSize(
new java.awt.Dimension(80, 23));
171 bnOpen.setPreferredSize(
new java.awt.Dimension(80, 23));
172 bnOpen.addActionListener(
new java.awt.event.ActionListener() {
173 public void actionPerformed(java.awt.event.ActionEvent evt) {
174 bnOpenActionPerformed(evt);
178 org.openide.awt.Mnemonics.setLocalizedText(bnOpenSingleUserCase,
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class,
"MultiUserCasesPanel.bnOpenSingleUserCase.text"));
179 bnOpenSingleUserCase.setMinimumSize(
new java.awt.Dimension(156, 23));
180 bnOpenSingleUserCase.setPreferredSize(
new java.awt.Dimension(156, 23));
181 bnOpenSingleUserCase.addActionListener(
new java.awt.event.ActionListener() {
182 public void actionPerformed(java.awt.event.ActionEvent evt) {
183 bnOpenSingleUserCaseActionPerformed(evt);
187 org.openide.awt.Mnemonics.setLocalizedText(cancelButton,
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class,
"MultiUserCasesPanel.cancelButton.text"));
188 cancelButton.setMaximumSize(
new java.awt.Dimension(80, 23));
189 cancelButton.setMinimumSize(
new java.awt.Dimension(80, 23));
190 cancelButton.setPreferredSize(
new java.awt.Dimension(80, 23));
191 cancelButton.addActionListener(
new java.awt.event.ActionListener() {
192 public void actionPerformed(java.awt.event.ActionEvent evt) {
193 cancelButtonActionPerformed(evt);
197 org.openide.awt.Mnemonics.setLocalizedText(searchLabel,
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class,
"MultiUserCasesPanel.searchLabel.text"));
199 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
200 this.setLayout(layout);
201 layout.setHorizontalGroup(
202 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
203 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
205 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
206 .addComponent(caseExplorerScrollPane)
207 .addGroup(layout.createSequentialGroup()
208 .addComponent(searchLabel)
209 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
210 .addComponent(bnOpenSingleUserCase, javax.swing.GroupLayout.PREFERRED_SIZE, 192, javax.swing.GroupLayout.PREFERRED_SIZE)
211 .addGap(190, 190, 190)
212 .addComponent(bnOpen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
213 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
214 .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
218 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {bnOpen, cancelButton});
220 layout.setVerticalGroup(
221 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
222 .addGroup(layout.createSequentialGroup()
224 .addComponent(caseExplorerScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 450, javax.swing.GroupLayout.PREFERRED_SIZE)
225 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
226 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
227 .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
228 .addComponent(bnOpen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
229 .addComponent(bnOpenSingleUserCase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
230 .addComponent(searchLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
240 private void bnOpenActionPerformed(java.awt.event.ActionEvent evt) {
241 openCase(caseBrowserPanel.getCasePath());
244 private void bnOpenSingleUserCaseActionPerformed(java.awt.event.ActionEvent evt) {
245 Lookup.getDefault().lookup(CaseOpenAction.class).openCaseSelectionWindow();
248 private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {
249 if (parentDialog != null) {
250 parentDialog.setVisible(
false);
255 private javax.swing.JButton bnOpen;
256 private javax.swing.JButton bnOpenSingleUserCase;
257 private javax.swing.JButton cancelButton;
258 private javax.swing.JScrollPane caseExplorerScrollPane;
259 private javax.swing.JLabel searchLabel;
void toggleSortOrder(int column)