Autopsy  4.9.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractedContentPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2018 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.keywordsearch;
20 
21 import java.awt.ComponentOrientation;
22 import java.awt.EventQueue;
23 import java.awt.event.ActionListener;
24 import java.awt.event.ItemEvent;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.concurrent.CancellationException;
28 import java.util.concurrent.ExecutionException;
29 import java.util.logging.Level;
30 import javax.swing.SizeRequirements;
31 import javax.swing.SwingWorker;
32 import javax.swing.text.Element;
33 import javax.swing.text.View;
34 import javax.swing.text.ViewFactory;
35 import javax.swing.text.html.HTMLEditorKit;
36 import javax.swing.text.html.HTMLEditorKit.HTMLFactory;
37 import javax.swing.text.html.InlineView;
38 import javax.swing.text.html.ParagraphView;
39 import org.apache.commons.lang3.StringUtils;
40 import org.netbeans.api.progress.ProgressHandle;
41 import org.openide.util.NbBundle;
45 
50 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
51 class ExtractedContentPanel extends javax.swing.JPanel {
52 
53  private static final Logger logger = Logger.getLogger(ExtractedContentPanel.class.getName());
54  private String contentName;
55 
56  ExtractedContentPanel() {
57  initComponents();
58  setSources("", new ArrayList<>());
59  hitPreviousButton.setEnabled(false);
60  hitNextButton.setEnabled(false);
61 
62  /*
63  * This appears to be an attempt to modify the wrapping behavior of the
64  * extractedTextPane taken form this website:
65  * http://java-sl.com/tip_html_letter_wrap.html.
66  */
67  HTMLEditorKit editorKit = new HTMLEditorKit() {
68  @Override
69  public ViewFactory getViewFactory() {
70 
71  return new HTMLFactory() {
72  @Override
73  public View create(Element e) {
74  View v = super.create(e);
75  if (v instanceof InlineView) {
76  return new InlineView(e) {
77  @Override
78  public int getBreakWeight(int axis, float pos, float len) {
79  return GoodBreakWeight;
80  }
81 
82  @Override
83  public View breakView(int axis, int p0, float pos, float len) {
84  if (axis == View.X_AXIS) {
85  checkPainter();
86  int p1 = getGlyphPainter().getBoundedPosition(this, p0, pos, len);
87  if (p0 == getStartOffset() && p1 == getEndOffset()) {
88  return this;
89  }
90  return createFragment(p0, p1);
91  }
92  return this;
93  }
94  };
95  } else if (v instanceof ParagraphView) {
96  return new ParagraphView(e) {
97  @Override
98  protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
99  if (r == null) {
100  r = new SizeRequirements();
101  }
102  float pref = layoutPool.getPreferredSpan(axis);
103  float min = layoutPool.getMinimumSpan(axis);
104  // Don't include insets, Box.getXXXSpan will include them.
105  r.minimum = (int) min;
106  r.preferred = Math.max(r.minimum, (int) pref);
107  r.maximum = Integer.MAX_VALUE;
108  r.alignment = 0.5f;
109  return r;
110  }
111  };
112  }
113  return v;
114  }
115  };
116  }
117  };
118  /*
119  * set font size manually in an effort to get fonts in this panel to
120  * look similar to what is in the 'String View' content viewer.
121  */
122  editorKit.getStyleSheet().addRule("body {font-size: 8.5px;}"); //NON-NLS
123  extractedTextPane.setEditorKit(editorKit);
124 
125  sourceComboBox.addItemListener(itemEvent -> {
126  if (itemEvent.getStateChange() == ItemEvent.SELECTED) {
127  refreshCurrentMarkup();
128  }
129  });
130  extractedTextPane.setComponentPopupMenu(rightClickMenu);
131  copyMenuItem.addActionListener(actionEvent -> extractedTextPane.copy());
132  selectAllMenuItem.addActionListener(actionEvent -> extractedTextPane.selectAll());
133  }
134 
140  @SuppressWarnings("unchecked")
141  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
142  private void initComponents() {
143 
144  rightClickMenu = new javax.swing.JPopupMenu();
145  copyMenuItem = new javax.swing.JMenuItem();
146  selectAllMenuItem = new javax.swing.JMenuItem();
147  jScrollPane1 = new javax.swing.JScrollPane();
148  extractedTextPane = new javax.swing.JTextPane();
149  jScrollPane2 = new javax.swing.JScrollPane();
150  jPanel1 = new javax.swing.JPanel();
151  sourceComboBox = new javax.swing.JComboBox<>();
152  jLabel1 = new javax.swing.JLabel();
153  pageOfLabel = new javax.swing.JLabel();
154  pageButtonsLabel = new javax.swing.JLabel();
155  pageTotalLabel = new javax.swing.JLabel();
156  pagesLabel = new javax.swing.JLabel();
157  pageNextButton = new javax.swing.JButton();
158  pagePreviousButton = new javax.swing.JButton();
159  pageCurLabel = new javax.swing.JLabel();
160  jSeparator1 = new javax.swing.JSeparator();
161  hitLabel = new javax.swing.JLabel();
162  hitButtonsLabel = new javax.swing.JLabel();
163  hitNextButton = new javax.swing.JButton();
164  hitOfLabel = new javax.swing.JLabel();
165  hitTotalLabel = new javax.swing.JLabel();
166  hitPreviousButton = new javax.swing.JButton();
167  hitCountLabel = new javax.swing.JLabel();
168  jSeparator2 = new javax.swing.JSeparator();
169 
170  copyMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.copyMenuItem.text")); // NOI18N
171  rightClickMenu.add(copyMenuItem);
172 
173  selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.selectAllMenuItem.text")); // NOI18N
174  rightClickMenu.add(selectAllMenuItem);
175 
176  setPreferredSize(new java.awt.Dimension(100, 58));
177 
178  jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
179  jScrollPane1.setPreferredSize(new java.awt.Dimension(640, 29));
180 
181  extractedTextPane.setEditable(false);
182  extractedTextPane.setAutoscrolls(false);
183  extractedTextPane.setInheritsPopupMenu(true);
184  extractedTextPane.setMaximumSize(new java.awt.Dimension(2000, 2000));
185  extractedTextPane.setPreferredSize(new java.awt.Dimension(600, 29));
186  jScrollPane1.setViewportView(extractedTextPane);
187 
188  jScrollPane2.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
189  jScrollPane2.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
190  jScrollPane2.setPreferredSize(new java.awt.Dimension(600, 100));
191 
192  jPanel1.setMinimumSize(new java.awt.Dimension(0, 0));
193  jPanel1.setPreferredSize(new java.awt.Dimension(600, 81));
194 
195  sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel<org.sleuthkit.autopsy.keywordsearch.IndexedText>());
196  sourceComboBox.setMaximumSize(new java.awt.Dimension(150, 32767));
197  sourceComboBox.setMinimumSize(new java.awt.Dimension(150, 20));
198  sourceComboBox.setPreferredSize(new java.awt.Dimension(150, 20));
199 
200  jLabel1.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.jLabel1.text")); // NOI18N
201 
202  pageOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageOfLabel.text")); // NOI18N
203 
204  pageButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageButtonsLabel.text")); // NOI18N
205 
206  pageTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
207  pageTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageTotalLabel.text")); // NOI18N
208 
209  pagesLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagesLabel.text")); // NOI18N
210 
211  pageNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N
212  pageNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageNextButton.text")); // NOI18N
213  pageNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
214  pageNextButton.setBorderPainted(false);
215  pageNextButton.setContentAreaFilled(false);
216  pageNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N
217  pageNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
218  pageNextButton.setPreferredSize(new java.awt.Dimension(23, 23));
219 
220  pagePreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N
221  pagePreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.text")); // NOI18N
222  pagePreviousButton.setActionCommand(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.actionCommand")); // NOI18N
223  pagePreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
224  pagePreviousButton.setBorderPainted(false);
225  pagePreviousButton.setContentAreaFilled(false);
226  pagePreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N
227  pagePreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
228 
229  pageCurLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
230  pageCurLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageCurLabel.text")); // NOI18N
231 
232  jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
233 
234  hitLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.text")); // NOI18N
235  hitLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.toolTipText")); // NOI18N
236 
237  hitButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitButtonsLabel.text")); // NOI18N
238 
239  hitNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N
240  hitNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitNextButton.text")); // NOI18N
241  hitNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
242  hitNextButton.setBorderPainted(false);
243  hitNextButton.setContentAreaFilled(false);
244  hitNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N
245  hitNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
246  hitNextButton.setPreferredSize(new java.awt.Dimension(23, 23));
247  hitNextButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_hover.png"))); // NOI18N
248 
249  hitOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitOfLabel.text")); // NOI18N
250 
251  hitTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
252  hitTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitTotalLabel.text")); // NOI18N
253  hitTotalLabel.setMaximumSize(new java.awt.Dimension(18, 14));
254  hitTotalLabel.setMinimumSize(new java.awt.Dimension(18, 14));
255  hitTotalLabel.setPreferredSize(new java.awt.Dimension(18, 14));
256 
257  hitPreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N
258  hitPreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitPreviousButton.text")); // NOI18N
259  hitPreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
260  hitPreviousButton.setBorderPainted(false);
261  hitPreviousButton.setContentAreaFilled(false);
262  hitPreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N
263  hitPreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
264  hitPreviousButton.setPreferredSize(new java.awt.Dimension(23, 23));
265  hitPreviousButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_hover.png"))); // NOI18N
266 
267  hitCountLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
268  hitCountLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitCountLabel.text")); // NOI18N
269  hitCountLabel.setMaximumSize(new java.awt.Dimension(18, 14));
270  hitCountLabel.setMinimumSize(new java.awt.Dimension(18, 14));
271  hitCountLabel.setPreferredSize(new java.awt.Dimension(18, 14));
272 
273  jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL);
274 
275  javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
276  jPanel1.setLayout(jPanel1Layout);
277  jPanel1Layout.setHorizontalGroup(
278  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
279  .addGap(0, 600, Short.MAX_VALUE)
280  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
281  .addGroup(jPanel1Layout.createSequentialGroup()
282  .addContainerGap()
283  .addComponent(hitLabel)
284  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
285  .addComponent(hitCountLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
286  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
287  .addComponent(hitOfLabel)
288  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
289  .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
290  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
291  .addComponent(hitButtonsLabel)
292  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
293  .addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
294  .addGap(0, 0, 0)
295  .addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
296  .addGap(18, 18, 18)
297  .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
298  .addGap(18, 18, 18)
299  .addComponent(pagesLabel)
300  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
301  .addComponent(pageCurLabel)
302  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
303  .addComponent(pageOfLabel)
304  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
305  .addComponent(pageTotalLabel)
306  .addGap(18, 18, 18)
307  .addComponent(pageButtonsLabel)
308  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
309  .addComponent(pagePreviousButton)
310  .addGap(0, 0, 0)
311  .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
312  .addGap(18, 18, 18)
313  .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
314  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
315  .addComponent(jLabel1)
316  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
317  .addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
318  .addContainerGap()))
319  );
320  jPanel1Layout.setVerticalGroup(
321  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
322  .addGap(0, 81, Short.MAX_VALUE)
323  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
324  .addGroup(jPanel1Layout.createSequentialGroup()
325  .addContainerGap()
326  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
327  .addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
328  .addComponent(jLabel1)
329  .addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
330  .addComponent(pageButtonsLabel)
331  .addComponent(pagePreviousButton)
332  .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
333  .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
334  .addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
335  .addComponent(pagesLabel)
336  .addComponent(hitLabel)
337  .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
338  .addComponent(pageCurLabel)
339  .addComponent(pageOfLabel)
340  .addComponent(hitCountLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
341  .addComponent(pageTotalLabel)
342  .addComponent(hitOfLabel)
343  .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
344  .addComponent(hitButtonsLabel))
345  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
346  );
347 
348  jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator1, jSeparator2, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox});
349 
350  jScrollPane2.setViewportView(jPanel1);
351 
352  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
353  this.setLayout(layout);
354  layout.setHorizontalGroup(
355  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
356  .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE)
357  .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE)
358  );
359  layout.setVerticalGroup(
360  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
361  .addGroup(layout.createSequentialGroup()
362  .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)
363  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
364  .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE))
365  );
366  }// </editor-fold>//GEN-END:initComponents
367  // Variables declaration - do not modify//GEN-BEGIN:variables
368  private javax.swing.JMenuItem copyMenuItem;
369  private javax.swing.JTextPane extractedTextPane;
370  private javax.swing.JLabel hitButtonsLabel;
371  private javax.swing.JLabel hitCountLabel;
372  private javax.swing.JLabel hitLabel;
373  private javax.swing.JButton hitNextButton;
374  private javax.swing.JLabel hitOfLabel;
375  private javax.swing.JButton hitPreviousButton;
376  private javax.swing.JLabel hitTotalLabel;
377  private javax.swing.JLabel jLabel1;
378  private javax.swing.JPanel jPanel1;
379  private javax.swing.JScrollPane jScrollPane1;
380  private javax.swing.JScrollPane jScrollPane2;
381  private javax.swing.JSeparator jSeparator1;
382  private javax.swing.JSeparator jSeparator2;
383  private javax.swing.JLabel pageButtonsLabel;
384  private javax.swing.JLabel pageCurLabel;
385  private javax.swing.JButton pageNextButton;
386  private javax.swing.JLabel pageOfLabel;
387  private javax.swing.JButton pagePreviousButton;
388  private javax.swing.JLabel pageTotalLabel;
389  private javax.swing.JLabel pagesLabel;
390  private javax.swing.JPopupMenu rightClickMenu;
391  private javax.swing.JMenuItem selectAllMenuItem;
392  private javax.swing.JComboBox<org.sleuthkit.autopsy.keywordsearch.IndexedText> sourceComboBox;
393  // End of variables declaration//GEN-END:variables
394 
395  void refreshCurrentMarkup() {
396  setMarkup(getSelectedSource());
397  }
398 
407  void setSources(String contentName, List<IndexedText> sources) {
408  this.contentName = contentName;
409  setPanelText(null, false);
410 
411  sourceComboBox.removeAllItems();
412  sources.forEach(sourceComboBox::addItem);
413  if (false == sources.isEmpty()) {
414  sourceComboBox.setSelectedIndex(0);
415  }
416  }
417 
423  public IndexedText getSelectedSource() {
424  return (IndexedText) sourceComboBox.getSelectedItem();
425  }
426 
427  private void setPanelText(String text, boolean detectDirection) {
428  text = StringUtils.defaultString(text);
429 
430  if (detectDirection) {
431  //detect text direction using first 1024 chars and set it
432  //get first up to 1024 chars, strip <pre> tag and unescape html to get the string on which to detect
433  final int len = text.length();
434  final int prefixLen = "<pre>".length(); //NON-NLS
435  if (len > prefixLen) {
436  final int maxOrientChars = Math.min(len, 1024);
437  final String orientDetectText = EscapeUtil.unEscapeHtml(text.substring(prefixLen, maxOrientChars));
438  ComponentOrientation direction = TextUtil.getTextDirection(orientDetectText);
439  //logger.log(Level.INFO, "ORIENTATION LEFT TO RIGHT: " + direction.isLeftToRight());
440  extractedTextPane.applyComponentOrientation(direction);
441  } else {
442  extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
443  }
444  } else {
445  extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
446  }
447 
448  extractedTextPane.setText(text);
449  extractedTextPane.setCaretPosition(0);
450  }
451 
452  void scrollToAnchor(String anchor) {
453  extractedTextPane.scrollToReference(anchor);
454  }
455 
460  void updateCurrentMatchDisplay(int current) {
461  if (current == 0) {
462  hitCountLabel.setText("-");
463  } else {
464  hitCountLabel.setText(Integer.toString(current));
465  }
466  }
467 
472  void updateTotaMatcheslDisplay(int total) {
473  if (total == 0) {
474  hitTotalLabel.setText("-");
475  } else {
476  hitTotalLabel.setText(Integer.toString(total));
477  }
478  }
479 
484  void updateCurrentPageDisplay(int current) {
485  pageCurLabel.setText(Integer.toString(current));
486  }
487 
492  void updateTotalPageslDisplay(int total) {
493  pageTotalLabel.setText(Integer.toString(total));
494  }
495 
500  void resetDisplay() {
501  setSources("", new ArrayList<>());
502  hitTotalLabel.setText("-");
503  hitCountLabel.setText("-");
504  pageCurLabel.setText("-");
505  pageTotalLabel.setText("-");
506  }
507 
513  void enablePrevMatchControl(boolean enable) {
514  hitPreviousButton.setEnabled(enable);
515  }
516 
522  void enableNextMatchControl(boolean enable) {
523  hitNextButton.setEnabled(enable);
524  }
525 
526  void addPrevMatchControlListener(ActionListener l) {
527  hitPreviousButton.addActionListener(l);
528  }
529 
530  void addNextMatchControlListener(ActionListener l) {
531  hitNextButton.addActionListener(l);
532  }
533 
539  void enablePrevPageControl(boolean enable) {
540  pagePreviousButton.setEnabled(enable);
541  }
542 
548  void enableNextPageControl(boolean enable) {
549  pageNextButton.setEnabled(enable);
550  }
551 
552  void addPrevPageControlListener(ActionListener l) {
553  pagePreviousButton.addActionListener(l);
554  }
555 
556  void addNextPageControlListener(ActionListener l) {
557  pageNextButton.addActionListener(l);
558  }
559 
560  void addSourceComboControlListener(ActionListener l) {
561  sourceComboBox.addActionListener(l);
562  }
563 
569  void updateControls(IndexedText source) {
570  updatePageControls(source);
571  updateSearchControls(source);
572  }
573 
579  void updatePageControls(IndexedText source) {
580  if (source == null) {
581  enableNextPageControl(false);
582  enablePrevPageControl(false);
583  updateCurrentPageDisplay(0);
584  updateTotalPageslDisplay(0);
585  return;
586  }
587 
588  updateCurrentPageDisplay(source.getCurrentPage());
589  int totalPages = source.getNumberPages();
590  updateTotalPageslDisplay(totalPages);
591 
592  if (totalPages == 1) {
593  enableNextPageControl(false);
594  enablePrevPageControl(false);
595  } else {
596  enableNextPageControl(source.hasNextPage());
597  enablePrevPageControl(source.hasPreviousPage());
598  }
599  }
600 
606  void updateSearchControls(IndexedText source) {
607  //setup search controls
608  if (source != null && source.isSearchable()) {
609  updateCurrentMatchDisplay(source.currentItem());
610  updateTotaMatcheslDisplay(source.getNumberHits());
611  enableNextMatchControl(source.hasNextItem() || source.hasNextPage());
612  enablePrevMatchControl(source.hasPreviousItem() || source.hasPreviousPage());
613  } else {
614  enableNextMatchControl(false);
615  enablePrevMatchControl(false);
616  updateCurrentMatchDisplay(0);
617  updateTotaMatcheslDisplay(0);
618  }
619  }
620 
626  private void scrollToCurrentHit(final IndexedText source) {
627  if (source == null || !source.isSearchable()) {
628  return;
629  }
630 
631  //scrolling required invokeLater to enqueue in EDT
632  EventQueue.invokeLater(() -> scrollToAnchor(source.getAnchorPrefix() + source.currentItem()));
633 
634  }
635 
641  @NbBundle.Messages("ExtractedContentPanel.setMarkup.panelTxt=<span style='font-style:italic'>Loading text... Please wait</span>")
642  private void setMarkup(IndexedText source) {
643  setPanelText(Bundle.ExtractedContentPanel_setMarkup_panelTxt(), false);
644  new SetMarkupWorker(contentName, source).execute();
645  }
646 
652  private final class SetMarkupWorker extends SwingWorker<String, Void> {
653 
654  private final String contentName;
655 
656  private final IndexedText source;
657 
658  private ProgressHandle progress;
659 
660  SetMarkupWorker(String contentName, IndexedText source) {
661  this.contentName = contentName;
662  this.source = source;
663  }
664 
665  @Override
666  @NbBundle.Messages({"# {0} - Content name",
667  "ExtractedContentPanel.SetMarkup.progress.loading=Loading text for {0}"})
668  protected String doInBackground() throws Exception {
669  progress = ProgressHandle.createHandle(Bundle.ExtractedContentPanel_SetMarkup_progress_loading(contentName));
670  progress.start();
671  progress.switchToIndeterminate();
672 
673  return source.getText();
674  }
675 
676  @Override
677  protected void done() {
678  super.done();
679  progress.finish();
680 
681  // see if there are any errors
682  try {
683  String markup = get();
684  if (markup != null) {
685  setPanelText(markup, true);
686  } else {
687  setPanelText("", false);
688  }
689 
690  } catch (InterruptedException | CancellationException | ExecutionException ex) {
691  logger.log(Level.SEVERE, "Error getting marked up text", ex); //NON-NLS
692  setPanelText(Bundle.IndexedText_errorMessage_errorGettingText(), true);
693  }
694 
695  updateControls(source);
696 
697  scrollToCurrentHit(source);
698  }
699  }
700 }

Copyright © 2012-2018 Basis Technology. Generated on: Tue Dec 18 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.