Autopsy 4.22.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-2023 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 */
19package org.sleuthkit.autopsy.keywordsearch;
20
21import java.awt.ComponentOrientation;
22import java.awt.EventQueue;
23import java.awt.Font;
24import java.awt.event.ActionListener;
25import java.awt.event.ItemEvent;
26import java.util.ArrayList;
27import java.util.Arrays;
28import java.util.List;
29import java.util.concurrent.CancellationException;
30import java.util.concurrent.ExecutionException;
31import java.util.logging.Level;
32import javax.swing.SizeRequirements;
33import javax.swing.SwingUtilities;
34import javax.swing.SwingWorker;
35import javax.swing.UIManager;
36import javax.swing.text.Element;
37import javax.swing.text.View;
38import javax.swing.text.ViewFactory;
39import javax.swing.text.html.HTMLEditorKit;
40import javax.swing.text.html.HTMLEditorKit.HTMLFactory;
41import javax.swing.text.html.InlineView;
42import javax.swing.text.html.ParagraphView;
43import javax.swing.text.html.StyleSheet;
44import org.apache.commons.lang3.StringUtils;
45import org.netbeans.api.progress.ProgressHandle;
46import org.openide.util.NbBundle;
47import org.sleuthkit.autopsy.coreutils.EscapeUtil;
48import org.sleuthkit.autopsy.coreutils.Logger;
49import org.sleuthkit.autopsy.coreutils.TextUtil;
50import org.sleuthkit.autopsy.guiutils.WrapLayout;
51
56@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
57class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextPanel {
58
59 private static final Logger logger = Logger.getLogger(ExtractedContentPanel.class.getName());
60
61 // set font as close as possible to default
62 private static final Font DEFAULT_FONT = UIManager.getDefaults().getFont("Label.font");
63
64 private static final long serialVersionUID = 1L;
65 private String contentName;
66 private int curSize;
67
68 private final StyleSheet styleSheet;
69 private final HTMLEditorKit editorKit;
70 private String lastKnownAnchor = null;
71
72 ExtractedContentPanel() {
73 initComponents();
74 additionalInit();
75 hitPreviousButton.setEnabled(false);
76 hitNextButton.setEnabled(false);
77
78 /*
79 * This appears to be an attempt to modify the wrapping behavior of the
80 * extractedTextPane taken form this website:
81 * http://java-sl.com/tip_html_letter_wrap.html.
82 */
83 editorKit = new HTMLEditorKit() {
84 private static final long serialVersionUID = 1L;
85
86 @Override
87 public ViewFactory getViewFactory() {
88
89 return new HTMLFactory() {
90 @Override
91 public View create(Element e) {
92 View v = super.create(e);
93 if (v instanceof InlineView) {
94 return new InlineView(e) {
95 @Override
96 public int getBreakWeight(int axis, float pos, float len) {
97 return GoodBreakWeight;
98 }
99
100 @Override
101 public View breakView(int axis, int p0, float pos, float len) {
102 if (axis == View.X_AXIS) {
103 checkPainter();
104 int p1 = getGlyphPainter().getBoundedPosition(this, p0, pos, len);
105 if (p0 == getStartOffset() && p1 == getEndOffset()) {
106 return this;
107 }
108 return createFragment(p0, p1);
109 }
110 return this;
111 }
112 };
113 } else if (v instanceof ParagraphView) {
114 return new ParagraphView(e) {
115 @Override
116 protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
117 SizeRequirements requirements = r;
118 if (requirements == null) {
119 requirements = new SizeRequirements();
120 }
121 float pref = layoutPool.getPreferredSpan(axis);
122 float min = layoutPool.getMinimumSpan(axis);
123 // Don't include insets, Box.getXXXSpan will include them.
124 requirements.minimum = (int) min;
125 requirements.preferred = Math.max(requirements.minimum, (int) pref);
126 requirements.maximum = Integer.MAX_VALUE;
127 requirements.alignment = 0.5f;
128 return requirements;
129 }
130 };
131 }
132 return v;
133 }
134 };
135 }
136 };
137 // set new style sheet to clear default styles
138 styleSheet = editorKit.getStyleSheet();
139
140 sourceComboBox.addItemListener(itemEvent -> {
141 if (itemEvent.getStateChange() == ItemEvent.SELECTED) {
142 refreshCurrentMarkup();
143 }
144 });
145 extractedTextPane.setComponentPopupMenu(rightClickMenu);
146
147 copyMenuItem.addActionListener(actionEvent -> extractedTextPane.copy());
148 selectAllMenuItem.addActionListener(actionEvent -> extractedTextPane.selectAll());
149
150 // TextZoomPanel could not be directly instantiated in Swing WYSIWYG editor
151 // (because it was package private, couldn't use constructor, etc.)
152 // so it was identified as a JPanel for the WYSIWYG. This function is called for
153 // initial setup so the font size of this panel as well as the font size indicated
154 // in the TextZoomPanel are correct
155 SwingUtilities.invokeLater(() -> {
156 if (zoomPanel instanceof TextZoomPanel)
157 ((TextZoomPanel) this.zoomPanel).resetSize();
158 });
159
160 setSources("", new ArrayList<>());
161 }
162
163
164 private void setStyleSheetSize(StyleSheet styleSheet, int size) {
165 styleSheet.addRule(
166 "body { font-family:\"" + DEFAULT_FONT.getFamily() + "\"; font-size:" + size + "pt; } " +
167 "pre { font-family:\"" + DEFAULT_FONT.getFamily() + "\"; font-size:" + size + "pt; } "
168 );
169 }
170
171
172 @Override
173 public int getTextSize() {
174 return curSize;
175 }
176
177 @Override
178 public void setTextSize(int newSize) {
179 curSize = newSize;
180
181 String curText = extractedTextPane.getText();
182
183 setStyleSheetSize(styleSheet, curSize);
184
185 editorKit.setStyleSheet(styleSheet);
186 extractedTextPane.setEditorKit(editorKit);
187
188 extractedTextPane.setText(curText);
189 if (lastKnownAnchor != null)
190 scrollToAnchor(lastKnownAnchor);
191 }
192
193
194 private void additionalInit() {
195 // use wrap layout for better component wrapping
196 WrapLayout layout = new WrapLayout(0,5);
197 layout.setOppositeAligned(Arrays.asList(textSourcePanel));
198 controlPanel.setLayout(layout);
199 }
200
201
207 @SuppressWarnings("unchecked")
208 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
209 private void initComponents() {
210
211 rightClickMenu = new javax.swing.JPopupMenu();
212 copyMenuItem = new javax.swing.JMenuItem();
213 selectAllMenuItem = new javax.swing.JMenuItem();
214 controlPanel = new javax.swing.JPanel();
215 javax.swing.JPanel pagePanel = new javax.swing.JPanel();
216 pagesLabel = new javax.swing.JLabel();
217 javax.swing.Box.Filler fillerSmall1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
218 pageCurLabel = new javax.swing.JLabel();
219 javax.swing.Box.Filler fillerSmall2 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
220 pageOfLabel = new javax.swing.JLabel();
221 javax.swing.Box.Filler fillerSmall3 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
222 pageTotalLabel = new javax.swing.JLabel();
223 javax.swing.Box.Filler fillerSmall4 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
224 pageButtonsLabel = new javax.swing.JLabel();
225 javax.swing.Box.Filler fillerMed1 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
226 pagePreviousButton = new javax.swing.JButton();
227 pageNextButton = new javax.swing.JButton();
228 javax.swing.Box.Filler fillerSmall6 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
229 jSeparator2 = new javax.swing.JSeparator();
230 javax.swing.JPanel matchesPanel = new javax.swing.JPanel();
231 hitLabel = new javax.swing.JLabel();
232 hitCountLabel = new javax.swing.JLabel();
233 hitOfLabel = new javax.swing.JLabel();
234 hitTotalLabel = new javax.swing.JLabel();
235 hitButtonsLabel = new javax.swing.JLabel();
236 javax.swing.Box.Filler fillerMed2 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
237 hitPreviousButton = new javax.swing.JButton();
238 hitNextButton = new javax.swing.JButton();
239 javax.swing.Box.Filler fillerSmall11 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
240 jSeparator3 = new javax.swing.JSeparator();
241 javax.swing.JPanel zoomPanelWrapper = new javax.swing.JPanel();
242 zoomPanel = new TextZoomPanel(this);
243 javax.swing.Box.Filler fillerSmall14 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
244 jSeparator4 = new javax.swing.JSeparator();
245 textSourcePanel = new javax.swing.JPanel();
246 jLabel1 = new javax.swing.JLabel();
247 javax.swing.Box.Filler fillerSmall12 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
248 sourceComboBox = new javax.swing.JComboBox<>();
249 extractedScrollPane = new javax.swing.JScrollPane();
250 extractedTextPane = new javax.swing.JTextPane();
251
252 copyMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.copyMenuItem.text")); // NOI18N
253 rightClickMenu.add(copyMenuItem);
254
255 selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.selectAllMenuItem.text")); // NOI18N
256 rightClickMenu.add(selectAllMenuItem);
257
258 setMinimumSize(new java.awt.Dimension(250, 0));
259 setPreferredSize(new java.awt.Dimension(250, 58));
260 setLayout(new java.awt.BorderLayout());
261
262 controlPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0));
263
264 pagePanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0));
265
266 pagesLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagesLabel.text")); // NOI18N
267 pagePanel.add(pagesLabel);
268 pagePanel.add(fillerSmall1);
269
270 pageCurLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
271 pageCurLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageCurLabel.text")); // NOI18N
272 pagePanel.add(pageCurLabel);
273 pagePanel.add(fillerSmall2);
274
275 pageOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageOfLabel.text")); // NOI18N
276 pagePanel.add(pageOfLabel);
277 pagePanel.add(fillerSmall3);
278
279 pageTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
280 pageTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageTotalLabel.text")); // NOI18N
281 pagePanel.add(pageTotalLabel);
282 pagePanel.add(fillerSmall4);
283
284 pageButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageButtonsLabel.text")); // NOI18N
285 pagePanel.add(pageButtonsLabel);
286 pagePanel.add(fillerMed1);
287
288 pagePreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N
289 pagePreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.text")); // NOI18N
290 pagePreviousButton.setActionCommand(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.actionCommand")); // NOI18N
291 pagePreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
292 pagePreviousButton.setBorderPainted(false);
293 pagePreviousButton.setContentAreaFilled(false);
294 pagePreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N
295 pagePreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
296 pagePanel.add(pagePreviousButton);
297
298 pageNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N
299 pageNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageNextButton.text")); // NOI18N
300 pageNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
301 pageNextButton.setBorderPainted(false);
302 pageNextButton.setContentAreaFilled(false);
303 pageNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N
304 pageNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
305 pageNextButton.setPreferredSize(new java.awt.Dimension(23, 23));
306 pagePanel.add(pageNextButton);
307 pagePanel.add(fillerSmall6);
308
309 jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL);
310 jSeparator2.setMaximumSize(new java.awt.Dimension(2, 25));
311 jSeparator2.setMinimumSize(new java.awt.Dimension(2, 25));
312 jSeparator2.setPreferredSize(new java.awt.Dimension(2, 25));
313 pagePanel.add(jSeparator2);
314
315 controlPanel.add(pagePanel);
316
317 matchesPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0));
318
319 hitLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.text")); // NOI18N
320 hitLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.toolTipText")); // NOI18N
321 matchesPanel.add(hitLabel);
322
323 hitCountLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
324 hitCountLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitCountLabel.text")); // NOI18N
325 hitCountLabel.setMaximumSize(new java.awt.Dimension(18, 14));
326 hitCountLabel.setMinimumSize(new java.awt.Dimension(18, 14));
327 hitCountLabel.setPreferredSize(new java.awt.Dimension(18, 14));
328 matchesPanel.add(hitCountLabel);
329
330 hitOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitOfLabel.text")); // NOI18N
331 matchesPanel.add(hitOfLabel);
332
333 hitTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
334 hitTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitTotalLabel.text")); // NOI18N
335 hitTotalLabel.setMaximumSize(new java.awt.Dimension(18, 14));
336 hitTotalLabel.setMinimumSize(new java.awt.Dimension(18, 14));
337 hitTotalLabel.setPreferredSize(new java.awt.Dimension(18, 14));
338 matchesPanel.add(hitTotalLabel);
339
340 hitButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitButtonsLabel.text")); // NOI18N
341 matchesPanel.add(hitButtonsLabel);
342 matchesPanel.add(fillerMed2);
343
344 hitPreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N
345 hitPreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitPreviousButton.text")); // NOI18N
346 hitPreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
347 hitPreviousButton.setBorderPainted(false);
348 hitPreviousButton.setContentAreaFilled(false);
349 hitPreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N
350 hitPreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
351 hitPreviousButton.setPreferredSize(new java.awt.Dimension(23, 23));
352 hitPreviousButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_hover.png"))); // NOI18N
353 matchesPanel.add(hitPreviousButton);
354
355 hitNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N
356 hitNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitNextButton.text")); // NOI18N
357 hitNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
358 hitNextButton.setBorderPainted(false);
359 hitNextButton.setContentAreaFilled(false);
360 hitNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N
361 hitNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
362 hitNextButton.setPreferredSize(new java.awt.Dimension(23, 23));
363 hitNextButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_hover.png"))); // NOI18N
364 matchesPanel.add(hitNextButton);
365 matchesPanel.add(fillerSmall11);
366
367 jSeparator3.setOrientation(javax.swing.SwingConstants.VERTICAL);
368 jSeparator3.setMaximumSize(new java.awt.Dimension(2, 25));
369 jSeparator3.setMinimumSize(new java.awt.Dimension(2, 25));
370 jSeparator3.setName(""); // NOI18N
371 jSeparator3.setPreferredSize(new java.awt.Dimension(2, 25));
372 matchesPanel.add(jSeparator3);
373
374 controlPanel.add(matchesPanel);
375
376 zoomPanelWrapper.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0));
377
378 zoomPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0));
379 zoomPanelWrapper.add(zoomPanel);
380 zoomPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.AccessibleContext.accessibleName")); // NOI18N
381
382 zoomPanelWrapper.add(fillerSmall14);
383
384 jSeparator4.setOrientation(javax.swing.SwingConstants.VERTICAL);
385 jSeparator4.setMaximumSize(new java.awt.Dimension(2, 25));
386 jSeparator4.setMinimumSize(new java.awt.Dimension(2, 25));
387 jSeparator4.setName(""); // NOI18N
388 jSeparator4.setPreferredSize(new java.awt.Dimension(2, 25));
389 zoomPanelWrapper.add(jSeparator4);
390
391 controlPanel.add(zoomPanelWrapper);
392
393 textSourcePanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0));
394
395 jLabel1.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.jLabel1.text")); // NOI18N
396 textSourcePanel.add(jLabel1);
397 textSourcePanel.add(fillerSmall12);
398
399 sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel<org.sleuthkit.autopsy.keywordsearch.ExtractedText>());
400 sourceComboBox.setMaximumSize(new java.awt.Dimension(150, 32767));
401 sourceComboBox.setMinimumSize(new java.awt.Dimension(150, 25));
402 sourceComboBox.setPreferredSize(new java.awt.Dimension(150, 25));
403 textSourcePanel.add(sourceComboBox);
404
405 controlPanel.add(textSourcePanel);
406
407 add(controlPanel, java.awt.BorderLayout.NORTH);
408
409 extractedScrollPane.setBackground(new java.awt.Color(255, 255, 255));
410 extractedScrollPane.setPreferredSize(new java.awt.Dimension(640, 29));
411
412 extractedTextPane.setEditable(false);
413 extractedTextPane.setAutoscrolls(false);
414 extractedTextPane.setInheritsPopupMenu(true);
415 extractedTextPane.setMaximumSize(new java.awt.Dimension(2000, 2000));
416 extractedTextPane.setPreferredSize(new java.awt.Dimension(600, 29));
417 extractedScrollPane.setViewportView(extractedTextPane);
418
419 add(extractedScrollPane, java.awt.BorderLayout.CENTER);
420 }// </editor-fold>//GEN-END:initComponents
421 // Variables declaration - do not modify//GEN-BEGIN:variables
422 private javax.swing.JPanel controlPanel;
423 private javax.swing.JMenuItem copyMenuItem;
424 private javax.swing.JScrollPane extractedScrollPane;
425 private javax.swing.JTextPane extractedTextPane;
426 private javax.swing.JLabel hitButtonsLabel;
427 private javax.swing.JLabel hitCountLabel;
428 private javax.swing.JLabel hitLabel;
429 private javax.swing.JButton hitNextButton;
430 private javax.swing.JLabel hitOfLabel;
431 private javax.swing.JButton hitPreviousButton;
432 private javax.swing.JLabel hitTotalLabel;
433 private javax.swing.JLabel jLabel1;
434 private javax.swing.JSeparator jSeparator2;
435 private javax.swing.JSeparator jSeparator3;
436 private javax.swing.JSeparator jSeparator4;
437 private javax.swing.JLabel pageButtonsLabel;
438 private javax.swing.JLabel pageCurLabel;
439 private javax.swing.JButton pageNextButton;
440 private javax.swing.JLabel pageOfLabel;
441 private javax.swing.JButton pagePreviousButton;
442 private javax.swing.JLabel pageTotalLabel;
443 private javax.swing.JLabel pagesLabel;
444 private javax.swing.JPopupMenu rightClickMenu;
445 private javax.swing.JMenuItem selectAllMenuItem;
446 private javax.swing.JComboBox<org.sleuthkit.autopsy.keywordsearch.ExtractedText> sourceComboBox;
447 private javax.swing.JPanel textSourcePanel;
448 private javax.swing.JPanel zoomPanel;
449 // End of variables declaration//GEN-END:variables
450
451 void refreshCurrentMarkup() {
452 setMarkup(getSelectedSource());
453 }
454
463 final void setSources(String contentName, List<ExtractedText> sources) {
464 this.lastKnownAnchor = null;
465 this.contentName = contentName;
466 setPanelText(null, false);
467
468 sourceComboBox.removeAllItems();
469 sources.forEach(sourceComboBox::addItem);
470 if (false == sources.isEmpty()) {
471 sourceComboBox.setEnabled(true);
472 sourceComboBox.setSelectedIndex(0);
473 } else {
474 sourceComboBox.setEnabled(false);
475 }
476 }
477
483 public ExtractedText getSelectedSource() {
484 return (ExtractedText) sourceComboBox.getSelectedItem();
485 }
486
487 private void setPanelText(String text, boolean detectDirection) {
488 String safeText = StringUtils.defaultString(text);
489
490 if (detectDirection) {
491 //detect text direction using first 1024 chars and set it
492 //get first up to 1024 chars, strip <pre> tag and unescape html to get the string on which to detect
493 final int len = safeText.length();
494 final int prefixLen = "<pre>".length(); //NON-NLS
495 if (len > prefixLen) {
496 final int maxOrientChars = Math.min(len, 1024);
497 final String orientDetectText = EscapeUtil.unEscapeHtml(safeText.substring(prefixLen, maxOrientChars));
498 ComponentOrientation direction = TextUtil.getTextDirection(orientDetectText);
499 extractedTextPane.applyComponentOrientation(direction);
500 } else {
501 extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
502 }
503 } else {
504 extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
505 }
506
507 // refresh style
508 setStyleSheetSize(styleSheet, curSize);
509 extractedTextPane.setText(safeText);
510 extractedTextPane.setCaretPosition(0);
511 }
512
513 void scrollToAnchor(String anchor) {
514 lastKnownAnchor = anchor;
515 extractedTextPane.scrollToReference(anchor);
516 }
517
523 void updateCurrentMatchDisplay(int current) {
524 if (current == 0) {
525 hitCountLabel.setText("-");
526 } else {
527 hitCountLabel.setText(Integer.toString(current));
528 }
529 }
530
536 void updateTotaMatcheslDisplay(int total) {
537 if (total == 0) {
538 hitTotalLabel.setText("-");
539 } else {
540 hitTotalLabel.setText(Integer.toString(total));
541 }
542 }
543
549 void updateCurrentPageDisplay(int current) {
550 pageCurLabel.setText(Integer.toString(current));
551 }
552
558 void updateTotalPagesDisplay(int total) {
559 if (total >= 0) {
560 pageTotalLabel.setText(Integer.toString(total));
561 } else {
562 pageTotalLabel.setText("-");
563 }
564 }
565
570 void resetDisplay() {
571 setSources("", new ArrayList<>());
572 hitTotalLabel.setText("-");
573 hitCountLabel.setText("-");
574 pageCurLabel.setText("-");
575 pageTotalLabel.setText("-");
576 }
577
583 void enablePrevMatchControl(boolean enable) {
584 hitPreviousButton.setEnabled(enable);
585 }
586
592 void enableNextMatchControl(boolean enable) {
593 hitNextButton.setEnabled(enable);
594 }
595
596 void addPrevMatchControlListener(ActionListener l) {
597 hitPreviousButton.addActionListener(l);
598 }
599
600 void addNextMatchControlListener(ActionListener l) {
601 hitNextButton.addActionListener(l);
602 }
603
609 void enablePrevPageControl(boolean enable) {
610 pagePreviousButton.setEnabled(enable);
611 }
612
618 void enableNextPageControl(boolean enable) {
619 pageNextButton.setEnabled(enable);
620 }
621
622 void addPrevPageControlListener(ActionListener l) {
623 pagePreviousButton.addActionListener(l);
624 }
625
626 void addNextPageControlListener(ActionListener l) {
627 pageNextButton.addActionListener(l);
628 }
629
630 void addSourceComboControlListener(ActionListener l) {
631 sourceComboBox.addActionListener(l);
632 }
633
639 void updateControls(ExtractedText source) {
640 updatePageControls(source);
641 updateSearchControls(source);
642 }
643
649 void updatePageControls(ExtractedText source) {
650 if (source == null) {
651 enableNextPageControl(false);
652 enablePrevPageControl(false);
653 updateCurrentPageDisplay(0);
654 updateTotalPagesDisplay(0);
655 return;
656 }
657
658 updateCurrentPageDisplay(source.getCurrentPage());
659 int totalPages = source.getNumberPages();
660 updateTotalPagesDisplay(totalPages);
661
662 enableNextPageControl(source.hasNextPage());
663 enablePrevPageControl(source.hasPreviousPage());
664 }
665
671 void updateSearchControls(ExtractedText source) {
672 //setup search controls
673 if (source != null && source.isSearchable()) {
674 updateCurrentMatchDisplay(source.currentItem());
675 updateTotaMatcheslDisplay(source.getNumberHits());
676 enableNextMatchControl(source.hasNextItem() || source.hasNextPage());
677 enablePrevMatchControl(source.hasPreviousItem() || source.hasPreviousPage());
678 } else {
679 enableNextMatchControl(false);
680 enablePrevMatchControl(false);
681 updateCurrentMatchDisplay(0);
682 updateTotaMatcheslDisplay(0);
683 }
684 }
685
691 private void scrollToCurrentHit(final ExtractedText source) {
692 if (source == null || !source.isSearchable()) {
693 return;
694 }
695
696 //scrolling required invokeLater to enqueue in EDT
697 EventQueue.invokeLater(() -> scrollToAnchor(source.getAnchorPrefix() + source.currentItem()));
698
699 }
700
706 @NbBundle.Messages("ExtractedContentPanel.setMarkup.panelTxt=<span style='font-style:italic'>Loading text... Please wait</span>")
707 private void setMarkup(ExtractedText source) {
708 setPanelText(Bundle.ExtractedContentPanel_setMarkup_panelTxt(), false);
709 new SetMarkupWorker(contentName, source).execute();
710 }
711
717 private final class SetMarkupWorker extends SwingWorker<String, Void> {
718
719 private final String contentName;
720
721 private final ExtractedText source;
722
723 private ProgressHandle progress;
724
725 SetMarkupWorker(String contentName, ExtractedText source) {
726 this.contentName = contentName;
727 this.source = source;
728 }
729
730 @Override
731 @NbBundle.Messages({"# {0} - Content name",
732 "ExtractedContentPanel.SetMarkup.progress.loading=Loading text for {0}"})
733 protected String doInBackground() throws Exception {
734 progress = ProgressHandle.createHandle(Bundle.ExtractedContentPanel_SetMarkup_progress_loading(contentName));
735 progress.start();
736 progress.switchToIndeterminate();
737
738 return source.getText();
739 }
740
741 @Override
742 protected void done() {
743 super.done();
744 progress.finish();
745
746 // see if there are any errors
747 try {
748 String markup = get();
749 if (markup != null) {
750 setPanelText(markup, true);
751 } else {
752 setPanelText("", false);
753 }
754 } catch (InterruptedException | CancellationException | ExecutionException ex) {
755 logger.log(Level.SEVERE, "Error getting marked up text", ex); //NON-NLS
756 setPanelText(Bundle.ExtractedText_errorMessage_errorGettingText(), true);
757 }
758
759 updateControls(source);
760 scrollToCurrentHit(source);
761 }
762 }
763}
static String unEscapeHtml(String toUnescape)
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static ComponentOrientation getTextDirection(String text)
Definition TextUtil.java:36

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.