19 package org.sleuthkit.autopsy.corecomponents;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.concurrent.ExecutionException;
27 import java.util.logging.Level;
28 import javax.swing.JMenuItem;
29 import javax.swing.JTextPane;
30 import javax.swing.SwingWorker;
31 import org.openide.nodes.Node;
32 import org.openide.util.Lookup;
33 import org.openide.util.NbBundle;
34 import org.openide.util.lookup.ServiceProvider;
53 @ServiceProvider(service = DataContentViewer.class, position = 3)
58 private final static String ERROR_TEXT = NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.errorText");
60 private int currentPage = 1;
61 private final Object lock =
new Object();
63 SwingWorker<ViewUpdate, Void> currentTask;
67 customizeComponents();
76 @SuppressWarnings(
"unchecked")
78 private
void initComponents() {
80 rightClickMenu =
new javax.swing.JPopupMenu();
81 copyMenuItem =
new javax.swing.JMenuItem();
82 selectAllMenuItem =
new javax.swing.JMenuItem();
83 jPanel1 =
new javax.swing.JPanel();
84 jScrollPane1 =
new javax.swing.JScrollPane();
85 outputViewPane =
new JTextPane(){
86 public boolean getScrollableTracksViewportWidth() {
87 return (getSize().width < 400);
89 totalPageLabel =
new javax.swing.JLabel();
90 ofLabel =
new javax.swing.JLabel();
91 currentPageLabel =
new javax.swing.JLabel();
92 pageLabel =
new javax.swing.JLabel();
93 nextPageButton =
new javax.swing.JButton();
94 pageLabel2 =
new javax.swing.JLabel();
95 prevPageButton =
new javax.swing.JButton();
97 copyMenuItem.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.copyMenuItem.text"));
98 rightClickMenu.add(copyMenuItem);
100 selectAllMenuItem.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.selectAllMenuItem.text"));
101 rightClickMenu.add(selectAllMenuItem);
103 setPreferredSize(
new java.awt.Dimension(622, 424));
105 jPanel1.setPreferredSize(
new java.awt.Dimension(622, 424));
107 outputViewPane.setEditable(
false);
108 outputViewPane.setPreferredSize(
new java.awt.Dimension(700, 400));
109 jScrollPane1.setViewportView(outputViewPane);
111 totalPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.totalPageLabel.text"));
115 currentPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.currentPageLabel.text"));
116 currentPageLabel.setMaximumSize(
new java.awt.Dimension(18, 14));
117 currentPageLabel.setMinimumSize(
new java.awt.Dimension(18, 14));
118 currentPageLabel.setPreferredSize(
new java.awt.Dimension(18, 14));
121 pageLabel.setMaximumSize(
new java.awt.Dimension(33, 14));
122 pageLabel.setMinimumSize(
new java.awt.Dimension(33, 14));
123 pageLabel.setPreferredSize(
new java.awt.Dimension(33, 14));
125 nextPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png")));
126 nextPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.nextPageButton.text"));
127 nextPageButton.setBorderPainted(
false);
128 nextPageButton.setContentAreaFilled(
false);
129 nextPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png")));
130 nextPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
131 nextPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
132 nextPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png")));
133 nextPageButton.addActionListener(
new java.awt.event.ActionListener() {
134 public void actionPerformed(java.awt.event.ActionEvent evt) {
135 nextPageButtonActionPerformed(evt);
140 pageLabel2.setMaximumSize(
new java.awt.Dimension(29, 14));
141 pageLabel2.setMinimumSize(
new java.awt.Dimension(29, 14));
142 pageLabel2.setPreferredSize(
new java.awt.Dimension(29, 14));
144 prevPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back.png")));
145 prevPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.prevPageButton.text"));
146 prevPageButton.setBorderPainted(
false);
147 prevPageButton.setContentAreaFilled(
false);
148 prevPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png")));
149 prevPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
150 prevPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
151 prevPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png")));
152 prevPageButton.addActionListener(
new java.awt.event.ActionListener() {
153 public void actionPerformed(java.awt.event.ActionEvent evt) {
154 prevPageButtonActionPerformed(evt);
158 javax.swing.GroupLayout jPanel1Layout =
new javax.swing.GroupLayout(jPanel1);
159 jPanel1.setLayout(jPanel1Layout);
160 jPanel1Layout.setHorizontalGroup(
161 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
162 .addGroup(jPanel1Layout.createSequentialGroup()
164 .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
165 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
166 .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
167 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
168 .addComponent(ofLabel)
169 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
170 .addComponent(totalPageLabel)
172 .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
173 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
174 .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
176 .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
177 .addContainerGap(366, Short.MAX_VALUE))
178 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 622, Short.MAX_VALUE)
180 jPanel1Layout.setVerticalGroup(
181 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
182 .addGroup(jPanel1Layout.createSequentialGroup()
183 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
184 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
185 .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
186 .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
187 .addComponent(ofLabel)
188 .addComponent(totalPageLabel))
189 .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
190 .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
191 .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
193 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 401, Short.MAX_VALUE))
196 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
197 this.setLayout(layout);
198 layout.setHorizontalGroup(
199 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
200 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
202 layout.setVerticalGroup(
203 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
204 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
209 currentPage = currentPage + 1;
210 currentPageLabel.setText(Integer.toString(currentPage));
215 currentPage = currentPage - 1;
216 currentPageLabel.setText(Integer.toString(currentPage));
237 outputViewPane.setComponentPopupMenu(rightClickMenu);
238 ActionListener actList =
new ActionListener() {
240 public void actionPerformed(ActionEvent e) {
241 JMenuItem jmi = (JMenuItem) e.getSource();
242 if (jmi.equals(copyMenuItem)) {
243 outputViewPane.copy();
244 }
else if (jmi.equals(selectAllMenuItem)) {
245 outputViewPane.selectAll();
249 copyMenuItem.addActionListener(actList);
250 selectAllMenuItem.addActionListener(actList);
260 currentPageLabel.setText(
"");
261 totalPageLabel.setText(
"");
262 outputViewPane.setText(
"");
263 prevPageButton.setEnabled(
false);
264 nextPageButton.setEnabled(
false);
270 if (currentNode == selectedNode) {
273 currentNode = selectedNode;
276 if (selectedNode == null) {
281 Lookup lookup = selectedNode.getLookup();
283 if (content == null) {
292 return NbBundle.getMessage(this.getClass(),
"DataContentViewerArtifact.title");
297 return NbBundle.getMessage(this.getClass(),
"DataContentViewerArtifact.toolTip");
322 if (content != null) {
326 logger.log(Level.WARNING,
"Couldn't get count of BlackboardArtifacts for content", ex);
338 if ((artifact == null)
357 ViewUpdate(
int numberOfPages,
int currentPage, String text) {
358 this.currentPage = currentPage;
359 this.numberOfPages = numberOfPages;
372 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
374 nextPageButton.setEnabled(viewUpdate.currentPage < viewUpdate.numberOfPages);
375 prevPageButton.setEnabled(viewUpdate.currentPage > 1);
376 currentPage = viewUpdate.currentPage;
377 totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages));
378 currentPageLabel.setText(Integer.toString(currentPage));
384 outputViewPane.setText(viewUpdate.text);
385 outputViewPane.moveCaretPosition(0);
387 this.setCursor(null);
396 private synchronized void startNewTask(SwingWorker<ViewUpdate, Void> task) {
397 outputViewPane.setText(WAIT_TEXT);
398 outputViewPane.moveCaretPosition(0);
401 if (currentTask != null) {
404 currentTask.cancel(
false);
409 currentTask.execute();
418 synchronized (lock) {
419 this.artifactContentStrings = artifactStrings;
429 synchronized (lock) {
430 return artifactContentStrings;
444 this.selectedNode = selectedNode;
451 Lookup lookup = selectedNode.getLookup();
455 if (content == null) {
456 return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
461 ArrayList<BlackboardArtifact> artifacts;
465 logger.log(Level.WARNING,
"Couldn't get artifacts", ex);
466 return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
474 ArrayList<ArtifactStringContent> artifactStrings =
new ArrayList<>();
483 if (artifact != null) {
484 index = artifacts.indexOf(artifact);
492 long assocArtifactId = attr.getValueLong();
493 int assocArtifactIndex = -1;
495 if (assocArtifactId == art.getArtifactID()) {
496 assocArtifactIndex = artifacts.indexOf(art);
500 if (assocArtifactIndex >= 0) {
501 index = assocArtifactIndex;
507 logger.log(Level.WARNING,
"Couldn't get associated artifact to display in Content Viewer.", ex);
520 ViewUpdate viewUpdate =
new ViewUpdate(artifactStrings.size(), index + 1, artifactStrings.get(index).getString());
529 setArtifactContentStrings(artifactStrings);
536 if (!isCancelled()) {
539 if (viewUpdate != null) {
540 updateView(viewUpdate);
542 }
catch (InterruptedException | ExecutionException ex) {
543 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
559 this.pageIndex = pageIndex;
566 List<ArtifactStringContent> artifactStrings = getArtifactContentStrings();
571 String artifactString = artifactStringContent.
getString();
579 return new ViewUpdate(artifactStrings.size(), pageIndex, artifactString);
584 if (!isCancelled()) {
587 if (viewUpdate != null) {
588 updateView(viewUpdate);
590 }
catch (InterruptedException | ExecutionException ex) {
591 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
javax.swing.JPopupMenu rightClickMenu
void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JScrollPane jScrollPane1
List< ArtifactStringContent > artifactContentStrings
void setArtifactContentStrings(List< ArtifactStringContent > artifactStrings)
javax.swing.JLabel pageLabel
List< ArtifactStringContent > getArtifactContentStrings()
javax.swing.JTextPane outputViewPane
synchronized void startNewTask(SwingWorker< ViewUpdate, Void > task)
javax.swing.JPanel jPanel1
javax.swing.JButton nextPageButton
void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt)
DataContentViewerArtifact()
ViewUpdate doInBackground()
void updateView(ViewUpdate viewUpdate)
void setNode(Node selectedNode)
static void configureTextPaneAsHtml(JTextPane pane)
long getAllArtifactsCount()
javax.swing.JMenuItem copyMenuItem
javax.swing.JLabel totalPageLabel
javax.swing.JButton prevPageButton
List< BlackboardAttribute > getAttributes()
javax.swing.JMenuItem selectAllMenuItem
ArrayList< BlackboardArtifact > getAllArtifacts()
javax.swing.JLabel pageLabel2
javax.swing.JLabel ofLabel
DataContentViewer createInstance()
synchronized static Logger getLogger(String name)
ViewUpdate doInBackground()
boolean isSupported(Node node)
int isPreferred(Node node)
void customizeComponents()
javax.swing.JLabel currentPageLabel