20 package org.sleuthkit.autopsy.corecomponents;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.concurrent.ExecutionException;
28 import java.util.logging.Level;
29 import javax.swing.JMenuItem;
30 import javax.swing.JTextPane;
31 import javax.swing.SwingWorker;
32 import org.openide.nodes.Node;
33 import org.openide.util.Lookup;
34 import org.openide.util.NbBundle;
35 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();
248 copyMenuItem.addActionListener(actList);
249 selectAllMenuItem.addActionListener(actList);
259 currentPageLabel.setText(
"");
260 totalPageLabel.setText(
"");
261 outputViewPane.setText(
"");
262 prevPageButton.setEnabled(
false);
263 nextPageButton.setEnabled(
false);
269 if (currentNode == selectedNode) {
272 currentNode = selectedNode;
275 if (selectedNode == null) {
280 Lookup lookup = selectedNode.getLookup();
282 if (content == null) {
291 return NbBundle.getMessage(this.getClass(),
"DataContentViewerArtifact.title");
296 return NbBundle.getMessage(this.getClass(),
"DataContentViewerArtifact.toolTip");
321 if(content != null) {
326 logger.log(Level.WARNING,
"Couldn't get count of BlackboardArtifacts for content", ex);
338 if ((artifact == null) ||
356 ViewUpdate(
int numberOfPages,
int currentPage, String text) {
357 this.currentPage = currentPage;
358 this.numberOfPages = numberOfPages;
368 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
370 nextPageButton.setEnabled(viewUpdate.currentPage < viewUpdate.numberOfPages);
371 prevPageButton.setEnabled(viewUpdate.currentPage > 1);
372 currentPage = viewUpdate.currentPage;
373 totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages));
374 currentPageLabel.setText(Integer.toString(currentPage));
380 outputViewPane.setText(viewUpdate.text);
381 outputViewPane.moveCaretPosition(0);
383 this.setCursor(null);
390 private synchronized void startNewTask(SwingWorker<ViewUpdate, Void> task) {
391 outputViewPane.setText(WAIT_TEXT);
392 outputViewPane.moveCaretPosition(0);
395 if (currentTask != null) {
398 currentTask.cancel(
false);
403 currentTask.execute();
411 synchronized (lock) {
412 this.artifactContentStrings = artifactStrings;
421 synchronized (lock) {
422 return artifactContentStrings;
434 this.selectedNode = selectedNode;
441 Lookup lookup = selectedNode.getLookup();
445 if (content == null) {
446 return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
451 ArrayList<BlackboardArtifact> artifacts;
456 logger.log(Level.WARNING,
"Couldn't get artifacts", ex);
457 return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
465 ArrayList<ArtifactStringContent> artifactStrings =
new ArrayList<>();
474 if (artifact != null) {
475 index = artifacts.indexOf(artifact);
483 long assocArtifactId = attr.getValueLong();
484 int assocArtifactIndex = -1;
486 if (assocArtifactId == art.getArtifactID()) {
487 assocArtifactIndex = artifacts.indexOf(art);
491 if (assocArtifactIndex >= 0) {
492 index = assocArtifactIndex;
499 logger.log(Level.WARNING,
"Couldn't get associated artifact to display in Content Viewer.", ex);
512 ViewUpdate viewUpdate =
new ViewUpdate(artifactStrings.size(), index + 1, artifactStrings.get(index).getString());
521 setArtifactContentStrings(artifactStrings);
528 if (!isCancelled()) {
531 if (viewUpdate != null) {
532 updateView(viewUpdate);
535 catch (InterruptedException | ExecutionException ex) {
536 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
550 this.pageIndex = pageIndex;
557 List<ArtifactStringContent> artifactStrings = getArtifactContentStrings();
562 String artifactString = artifactStringContent.
getString();
570 return new ViewUpdate(artifactStrings.size(), pageIndex, artifactString);
575 if (!isCancelled()) {
578 if (viewUpdate != null) {
579 updateView(viewUpdate);
582 catch (InterruptedException | ExecutionException ex) {
583 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()
ViewUpdate doInBackground()
boolean isSupported(Node node)
static Logger getLogger(String name)
int isPreferred(Node node)
void customizeComponents()
javax.swing.JLabel currentPageLabel