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 final class MultiUserCasesPanel
extends JPanel{
41 private static final Logger LOGGER = Logger.getLogger(MultiUserCasesPanel.class.getName());
42 private static final long serialVersionUID = 1L;
43 private final JDialog parentDialog;
44 private final CaseBrowser caseBrowserPanel;
50 MultiUserCasesPanel(JDialog parentDialog) {
51 this.parentDialog = parentDialog;
54 caseBrowserPanel =
new CaseBrowser();
55 caseExplorerScrollPane.add(caseBrowserPanel);
56 caseExplorerScrollPane.setViewportView(caseBrowserPanel);
61 caseBrowserPanel.addListSelectionListener((ListSelectionEvent e) -> {
72 caseBrowserPanel.refresh();
80 bnOpen.setEnabled(caseBrowserPanel.isRowSelected());
88 private void openCase(String caseMetadataFilePath) {
89 if (caseMetadataFilePath != null) {
90 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
92 StartupWindowProvider.getInstance().close();
93 if (parentDialog != null) {
94 parentDialog.setVisible(
false);
98 Case.openAsCurrentCase(caseMetadataFilePath);
99 }
catch (CaseActionException ex) {
100 if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
101 LOGGER.log(Level.SEVERE, String.format(
"Error opening case with metadata file path %s", caseMetadataFilePath), ex);
102 MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
104 SwingUtilities.invokeLater(() -> {
106 StartupWindowProvider.getInstance().open();
109 SwingUtilities.invokeLater(() -> {
111 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
122 private static class RowSorter<M
extends DefaultTableModel> extends TableRowSorter<M> {
130 if (!this.getModel().getColumnClass(column).equals(Date.class)) {
131 super.toggleSortOrder(column);
133 ArrayList<
RowSorter.SortKey> sortKeys =
new ArrayList<>(getSortKeys());
134 if (sortKeys.isEmpty() || sortKeys.get(0).getColumn() != column) {
135 sortKeys.add(0,
new RowSorter.SortKey(column, SortOrder.DESCENDING));
136 }
else if (sortKeys.get(0).getSortOrder() == SortOrder.ASCENDING) {
137 sortKeys.removeIf(key -> key.getColumn() == column);
138 sortKeys.add(0,
new RowSorter.SortKey(column, SortOrder.DESCENDING));
140 sortKeys.removeIf(key -> key.getColumn() == column);
141 sortKeys.add(0,
new RowSorter.SortKey(column, SortOrder.ASCENDING));
143 setSortKeys(sortKeys);
153 @SuppressWarnings(
"unchecked")
155 private
void initComponents() {
157 bnOpen =
new javax.swing.JButton();
158 bnOpenSingleUserCase =
new javax.swing.JButton();
159 cancelButton =
new javax.swing.JButton();
160 searchLabel =
new javax.swing.JLabel();
161 caseExplorerScrollPane =
new javax.swing.JScrollPane();
163 setName(
"Completed Cases");
164 setPreferredSize(
new java.awt.Dimension(960, 485));
166 org.openide.awt.Mnemonics.setLocalizedText(bnOpen,
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class,
"MultiUserCasesPanel.bnOpen.text"));
167 bnOpen.setEnabled(
false);
168 bnOpen.setMaximumSize(
new java.awt.Dimension(80, 23));
169 bnOpen.setMinimumSize(
new java.awt.Dimension(80, 23));
170 bnOpen.setPreferredSize(
new java.awt.Dimension(80, 23));
171 bnOpen.addActionListener(
new java.awt.event.ActionListener() {
172 public void actionPerformed(java.awt.event.ActionEvent evt) {
173 bnOpenActionPerformed(evt);
177 org.openide.awt.Mnemonics.setLocalizedText(bnOpenSingleUserCase,
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class,
"MultiUserCasesPanel.bnOpenSingleUserCase.text"));
178 bnOpenSingleUserCase.setMinimumSize(
new java.awt.Dimension(156, 23));
179 bnOpenSingleUserCase.setPreferredSize(
new java.awt.Dimension(156, 23));
180 bnOpenSingleUserCase.addActionListener(
new java.awt.event.ActionListener() {
181 public void actionPerformed(java.awt.event.ActionEvent evt) {
182 bnOpenSingleUserCaseActionPerformed(evt);
186 org.openide.awt.Mnemonics.setLocalizedText(cancelButton,
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class,
"MultiUserCasesPanel.cancelButton.text"));
187 cancelButton.setMaximumSize(
new java.awt.Dimension(80, 23));
188 cancelButton.setMinimumSize(
new java.awt.Dimension(80, 23));
189 cancelButton.setPreferredSize(
new java.awt.Dimension(80, 23));
190 cancelButton.addActionListener(
new java.awt.event.ActionListener() {
191 public void actionPerformed(java.awt.event.ActionEvent evt) {
192 cancelButtonActionPerformed(evt);
196 org.openide.awt.Mnemonics.setLocalizedText(searchLabel,
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class,
"MultiUserCasesPanel.searchLabel.text"));
198 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
199 this.setLayout(layout);
200 layout.setHorizontalGroup(
201 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
202 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
204 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
205 .addComponent(caseExplorerScrollPane)
206 .addGroup(layout.createSequentialGroup()
207 .addComponent(searchLabel)
208 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 120, Short.MAX_VALUE)
209 .addComponent(bnOpenSingleUserCase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
210 .addGap(226, 226, 226)
211 .addComponent(bnOpen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
212 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
213 .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
217 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {bnOpen, cancelButton});
219 layout.setVerticalGroup(
220 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
221 .addGroup(layout.createSequentialGroup()
223 .addComponent(caseExplorerScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 450, javax.swing.GroupLayout.PREFERRED_SIZE)
224 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
225 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
226 .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
227 .addComponent(bnOpen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
228 .addComponent(bnOpenSingleUserCase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
229 .addComponent(searchLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
239 private void bnOpenActionPerformed(java.awt.event.ActionEvent evt) {
240 openCase(caseBrowserPanel.getCasePath());
243 private void bnOpenSingleUserCaseActionPerformed(java.awt.event.ActionEvent evt) {
244 Lookup.getDefault().lookup(CaseOpenAction.class).openCaseSelectionWindow();
247 private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {
248 if (parentDialog != null) {
249 parentDialog.setVisible(
false);
254 private javax.swing.JButton bnOpen;
255 private javax.swing.JButton bnOpenSingleUserCase;
256 private javax.swing.JButton cancelButton;
257 private javax.swing.JScrollPane caseExplorerScrollPane;
258 private javax.swing.JLabel searchLabel;
void toggleSortOrder(int column)