19 package org.sleuthkit.autopsy.keywordsearch;
 
   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;
 
   50 @SuppressWarnings(
"PMD.SingularField") 
 
   51 class ExtractedContentPanel extends javax.swing.JPanel {
 
   53     private static final Logger logger = Logger.getLogger(ExtractedContentPanel.class.getName());
 
   54     private static final long serialVersionUID = 1L;
 
   55     private String contentName;
 
   57     ExtractedContentPanel() {
 
   59         setSources(
"", 
new ArrayList<>());
 
   60         hitPreviousButton.setEnabled(
false);
 
   61         hitNextButton.setEnabled(
false);
 
   68         HTMLEditorKit editorKit = 
new HTMLEditorKit() {
 
   69             private static final long serialVersionUID = 1L;
 
   72             public ViewFactory getViewFactory() {
 
   74                 return new HTMLFactory() {
 
   76                     public View create(Element e) {
 
   77                         View v = super.create(e);
 
   78                         if (v instanceof InlineView) {
 
   79                             return new InlineView(e) {
 
   81                                 public int getBreakWeight(
int axis, 
float pos, 
float len) {
 
   82                                     return GoodBreakWeight;
 
   86                                 public View breakView(
int axis, 
int p0, 
float pos, 
float len) {
 
   87                                     if (axis == View.X_AXIS) {
 
   89                                         int p1 = getGlyphPainter().getBoundedPosition(
this, p0, pos, len);
 
   90                                         if (p0 == getStartOffset() && p1 == getEndOffset()) {
 
   93                                         return createFragment(p0, p1);
 
   98                         } 
else if (v instanceof ParagraphView) {
 
   99                             return new ParagraphView(e) {
 
  101                                 protected SizeRequirements calculateMinorAxisRequirements(
int axis, SizeRequirements r) {
 
  102                                     SizeRequirements requirements = r;
 
  103                                     if (requirements == null) {
 
  104                                         requirements = 
new SizeRequirements();
 
  106                                     float pref = layoutPool.getPreferredSpan(axis);
 
  107                                     float min = layoutPool.getMinimumSpan(axis);
 
  109                                     requirements.minimum = (int) min;
 
  110                                     requirements.preferred = Math.max(requirements.minimum, (
int) pref);
 
  111                                     requirements.maximum = Integer.MAX_VALUE;
 
  112                                     requirements.alignment = 0.5f;
 
  126         editorKit.getStyleSheet().addRule(
"body {font-size: 8.5px;}"); 
 
  127         extractedTextPane.setEditorKit(editorKit);
 
  129         sourceComboBox.addItemListener(itemEvent -> {
 
  130             if (itemEvent.getStateChange() == ItemEvent.SELECTED) {
 
  131                 refreshCurrentMarkup();
 
  134         extractedTextPane.setComponentPopupMenu(rightClickMenu);
 
  135         copyMenuItem.addActionListener(actionEvent -> extractedTextPane.copy());
 
  136         selectAllMenuItem.addActionListener(actionEvent -> extractedTextPane.selectAll());
 
  144     @SuppressWarnings(
"unchecked")
 
  146     private 
void initComponents() {
 
  148         rightClickMenu = 
new javax.swing.JPopupMenu();
 
  149         copyMenuItem = 
new javax.swing.JMenuItem();
 
  150         selectAllMenuItem = 
new javax.swing.JMenuItem();
 
  151         extractedScrollPane = 
new javax.swing.JScrollPane();
 
  152         extractedTextPane = 
new javax.swing.JTextPane();
 
  153         controlScrollPane = 
new javax.swing.JScrollPane();
 
  154         controlPanel = 
new javax.swing.JPanel();
 
  155         sourceComboBox = 
new javax.swing.JComboBox<>();
 
  156         jLabel1 = 
new javax.swing.JLabel();
 
  157         pageOfLabel = 
new javax.swing.JLabel();
 
  158         pageButtonsLabel = 
new javax.swing.JLabel();
 
  159         pageTotalLabel = 
new javax.swing.JLabel();
 
  160         pagesLabel = 
new javax.swing.JLabel();
 
  161         pageNextButton = 
new javax.swing.JButton();
 
  162         pagePreviousButton = 
new javax.swing.JButton();
 
  163         pageCurLabel = 
new javax.swing.JLabel();
 
  164         jSeparator1 = 
new javax.swing.JSeparator();
 
  165         hitLabel = 
new javax.swing.JLabel();
 
  166         hitButtonsLabel = 
new javax.swing.JLabel();
 
  167         hitNextButton = 
new javax.swing.JButton();
 
  168         hitOfLabel = 
new javax.swing.JLabel();
 
  169         hitTotalLabel = 
new javax.swing.JLabel();
 
  170         hitPreviousButton = 
new javax.swing.JButton();
 
  171         hitCountLabel = 
new javax.swing.JLabel();
 
  172         jSeparator2 = 
new javax.swing.JSeparator();
 
  174         copyMenuItem.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.copyMenuItem.text")); 
 
  175         rightClickMenu.add(copyMenuItem);
 
  177         selectAllMenuItem.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.selectAllMenuItem.text")); 
 
  178         rightClickMenu.add(selectAllMenuItem);
 
  180         setPreferredSize(
new java.awt.Dimension(100, 58));
 
  182         extractedScrollPane.setBackground(
new java.awt.Color(255, 255, 255));
 
  183         extractedScrollPane.setPreferredSize(
new java.awt.Dimension(640, 29));
 
  185         extractedTextPane.setEditable(
false);
 
  186         extractedTextPane.setAutoscrolls(
false);
 
  187         extractedTextPane.setInheritsPopupMenu(
true);
 
  188         extractedTextPane.setMaximumSize(
new java.awt.Dimension(2000, 2000));
 
  189         extractedTextPane.setPreferredSize(
new java.awt.Dimension(600, 29));
 
  190         extractedScrollPane.setViewportView(extractedTextPane);
 
  192         controlScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
 
  193         controlScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
 
  194         controlScrollPane.setPreferredSize(
new java.awt.Dimension(600, 100));
 
  196         controlPanel.setMinimumSize(
new java.awt.Dimension(0, 0));
 
  197         controlPanel.setPreferredSize(
new java.awt.Dimension(600, 81));
 
  200         sourceComboBox.setMaximumSize(
new java.awt.Dimension(150, 32767));
 
  201         sourceComboBox.setMinimumSize(
new java.awt.Dimension(150, 20));
 
  202         sourceComboBox.setPreferredSize(
new java.awt.Dimension(150, 20));
 
  204         jLabel1.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.jLabel1.text")); 
 
  206         pageOfLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.pageOfLabel.text")); 
 
  208         pageButtonsLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.pageButtonsLabel.text")); 
 
  210         pageTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
 
  211         pageTotalLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.pageTotalLabel.text")); 
 
  213         pagesLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.pagesLabel.text")); 
 
  215         pageNextButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); 
 
  216         pageNextButton.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.pageNextButton.text")); 
 
  217         pageNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
 
  218         pageNextButton.setBorderPainted(
false);
 
  219         pageNextButton.setContentAreaFilled(
false);
 
  220         pageNextButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); 
 
  221         pageNextButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
 
  222         pageNextButton.setPreferredSize(
new java.awt.Dimension(23, 23));
 
  224         pagePreviousButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); 
 
  225         pagePreviousButton.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.pagePreviousButton.text")); 
 
  226         pagePreviousButton.setActionCommand(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.pagePreviousButton.actionCommand")); 
 
  227         pagePreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
 
  228         pagePreviousButton.setBorderPainted(
false);
 
  229         pagePreviousButton.setContentAreaFilled(
false);
 
  230         pagePreviousButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); 
 
  231         pagePreviousButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
 
  233         pageCurLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
 
  234         pageCurLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.pageCurLabel.text")); 
 
  236         jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
 
  238         hitLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.hitLabel.text")); 
 
  239         hitLabel.setToolTipText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.hitLabel.toolTipText")); 
 
  241         hitButtonsLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.hitButtonsLabel.text")); 
 
  243         hitNextButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); 
 
  244         hitNextButton.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.hitNextButton.text")); 
 
  245         hitNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
 
  246         hitNextButton.setBorderPainted(
false);
 
  247         hitNextButton.setContentAreaFilled(
false);
 
  248         hitNextButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); 
 
  249         hitNextButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
 
  250         hitNextButton.setPreferredSize(
new java.awt.Dimension(23, 23));
 
  251         hitNextButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_hover.png"))); 
 
  253         hitOfLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.hitOfLabel.text")); 
 
  255         hitTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
 
  256         hitTotalLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.hitTotalLabel.text")); 
 
  257         hitTotalLabel.setMaximumSize(
new java.awt.Dimension(18, 14));
 
  258         hitTotalLabel.setMinimumSize(
new java.awt.Dimension(18, 14));
 
  259         hitTotalLabel.setPreferredSize(
new java.awt.Dimension(18, 14));
 
  261         hitPreviousButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); 
 
  262         hitPreviousButton.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.hitPreviousButton.text")); 
 
  263         hitPreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
 
  264         hitPreviousButton.setBorderPainted(
false);
 
  265         hitPreviousButton.setContentAreaFilled(
false);
 
  266         hitPreviousButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); 
 
  267         hitPreviousButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
 
  268         hitPreviousButton.setPreferredSize(
new java.awt.Dimension(23, 23));
 
  269         hitPreviousButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/keywordsearch/btn_step_back_hover.png"))); 
 
  271         hitCountLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
 
  272         hitCountLabel.setText(
org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, 
"ExtractedContentPanel.hitCountLabel.text")); 
 
  273         hitCountLabel.setMaximumSize(
new java.awt.Dimension(18, 14));
 
  274         hitCountLabel.setMinimumSize(
new java.awt.Dimension(18, 14));
 
  275         hitCountLabel.setPreferredSize(
new java.awt.Dimension(18, 14));
 
  277         jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL);
 
  279         javax.swing.GroupLayout controlPanelLayout = 
new javax.swing.GroupLayout(controlPanel);
 
  280         controlPanel.setLayout(controlPanelLayout);
 
  281         controlPanelLayout.setHorizontalGroup(
 
  282             controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  283             .addGroup(controlPanelLayout.createSequentialGroup()
 
  285                 .addComponent(hitLabel)
 
  286                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  287                 .addComponent(hitCountLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  288                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  289                 .addComponent(hitOfLabel)
 
  290                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  291                 .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  292                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  293                 .addComponent(hitButtonsLabel)
 
  294                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  295                 .addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  297                 .addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  299                 .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  301                 .addComponent(pagesLabel)
 
  302                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  303                 .addComponent(pageCurLabel)
 
  304                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  305                 .addComponent(pageOfLabel)
 
  306                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  307                 .addComponent(pageTotalLabel)
 
  309                 .addComponent(pageButtonsLabel)
 
  310                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  311                 .addComponent(pagePreviousButton)
 
  313                 .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  315                 .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  316                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  317                 .addComponent(jLabel1)
 
  318                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  319                 .addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  322         controlPanelLayout.setVerticalGroup(
 
  323             controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  324             .addGroup(controlPanelLayout.createSequentialGroup()
 
  325                 .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
 
  326                     .addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  327                     .addComponent(jLabel1)
 
  328                     .addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  329                     .addComponent(pageButtonsLabel)
 
  330                     .addComponent(pagePreviousButton)
 
  331                     .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  332                     .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  333                     .addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  334                     .addComponent(pagesLabel)
 
  335                     .addComponent(hitLabel)
 
  336                     .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  337                     .addComponent(pageCurLabel)
 
  338                     .addComponent(pageOfLabel)
 
  339                     .addComponent(hitCountLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  340                     .addComponent(pageTotalLabel)
 
  341                     .addComponent(hitOfLabel)
 
  342                     .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  343                     .addComponent(hitButtonsLabel))
 
  347         controlPanelLayout.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         controlScrollPane.setViewportView(controlPanel);
 
  351         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  352         this.setLayout(layout);
 
  353         layout.setHorizontalGroup(
 
  354             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  355             .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE)
 
  356             .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE)
 
  358         layout.setVerticalGroup(
 
  359             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  360             .addGroup(layout.createSequentialGroup()
 
  361                 .addComponent(controlScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  362                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  363                 .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE))
 
  367     private javax.swing.JPanel controlPanel;
 
  368     private javax.swing.JScrollPane controlScrollPane;
 
  369     private javax.swing.JMenuItem copyMenuItem;
 
  370     private javax.swing.JScrollPane extractedScrollPane;
 
  371     private javax.swing.JTextPane extractedTextPane;
 
  372     private javax.swing.JLabel hitButtonsLabel;
 
  373     private javax.swing.JLabel hitCountLabel;
 
  374     private javax.swing.JLabel hitLabel;
 
  375     private javax.swing.JButton hitNextButton;
 
  376     private javax.swing.JLabel hitOfLabel;
 
  377     private javax.swing.JButton hitPreviousButton;
 
  378     private javax.swing.JLabel hitTotalLabel;
 
  379     private javax.swing.JLabel jLabel1;
 
  380     private javax.swing.JSeparator jSeparator1;
 
  381     private javax.swing.JSeparator jSeparator2;
 
  382     private javax.swing.JLabel pageButtonsLabel;
 
  383     private javax.swing.JLabel pageCurLabel;
 
  384     private javax.swing.JButton pageNextButton;
 
  385     private javax.swing.JLabel pageOfLabel;
 
  386     private javax.swing.JButton pagePreviousButton;
 
  387     private javax.swing.JLabel pageTotalLabel;
 
  388     private javax.swing.JLabel pagesLabel;
 
  389     private javax.swing.JPopupMenu rightClickMenu;
 
  390     private javax.swing.JMenuItem selectAllMenuItem;
 
  394     void refreshCurrentMarkup() {
 
  395         setMarkup(getSelectedSource());
 
  406     final void setSources(String contentName, List<IndexedText> sources) {
 
  407         this.contentName = contentName;
 
  408         setPanelText(null, 
false);
 
  410         sourceComboBox.removeAllItems();
 
  411         sources.forEach(sourceComboBox::addItem);
 
  412         if (
false == sources.isEmpty()) {
 
  413             sourceComboBox.setEnabled(
true);
 
  414             sourceComboBox.setSelectedIndex(0);
 
  416             sourceComboBox.setEnabled(
false);
 
  425     public IndexedText getSelectedSource() {
 
  426         return (IndexedText) sourceComboBox.getSelectedItem();
 
  429     private void setPanelText(String text, 
boolean detectDirection) {
 
  430         String safeText = StringUtils.defaultString(text);
 
  432         if (detectDirection) {
 
  435             final int len = safeText.length();
 
  436             final int prefixLen = 
"<pre>".length(); 
 
  437             if (len > prefixLen) {
 
  438                 final int maxOrientChars = Math.min(len, 1024);
 
  439                 final String orientDetectText = EscapeUtil.unEscapeHtml(safeText.substring(prefixLen, maxOrientChars));
 
  440                 ComponentOrientation direction = TextUtil.getTextDirection(orientDetectText);
 
  441                 extractedTextPane.applyComponentOrientation(direction);
 
  443                 extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
 
  446             extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
 
  449         extractedTextPane.setText(safeText);
 
  450         extractedTextPane.setCaretPosition(0);
 
  453     void scrollToAnchor(String anchor) {
 
  454         extractedTextPane.scrollToReference(anchor);
 
  462     void updateCurrentMatchDisplay(
int current) {
 
  464             hitCountLabel.setText(
"-");
 
  466             hitCountLabel.setText(Integer.toString(current));
 
  475     void updateTotaMatcheslDisplay(
int total) {
 
  477             hitTotalLabel.setText(
"-");
 
  479             hitTotalLabel.setText(Integer.toString(total));
 
  488     void updateCurrentPageDisplay(
int current) {
 
  489         pageCurLabel.setText(Integer.toString(current));
 
  497     void updateTotalPagesDisplay(
int total) {
 
  498         pageTotalLabel.setText(Integer.toString(total));
 
  505     void resetDisplay() {
 
  506         setSources(
"", 
new ArrayList<>());
 
  507         hitTotalLabel.setText(
"-");
 
  508         hitCountLabel.setText(
"-");
 
  509         pageCurLabel.setText(
"-");
 
  510         pageTotalLabel.setText(
"-");
 
  518     void enablePrevMatchControl(
boolean enable) {
 
  519         hitPreviousButton.setEnabled(enable);
 
  527     void enableNextMatchControl(
boolean enable) {
 
  528         hitNextButton.setEnabled(enable);
 
  531     void addPrevMatchControlListener(ActionListener l) {
 
  532         hitPreviousButton.addActionListener(l);
 
  535     void addNextMatchControlListener(ActionListener l) {
 
  536         hitNextButton.addActionListener(l);
 
  544     void enablePrevPageControl(
boolean enable) {
 
  545         pagePreviousButton.setEnabled(enable);
 
  553     void enableNextPageControl(
boolean enable) {
 
  554         pageNextButton.setEnabled(enable);
 
  557     void addPrevPageControlListener(ActionListener l) {
 
  558         pagePreviousButton.addActionListener(l);
 
  561     void addNextPageControlListener(ActionListener l) {
 
  562         pageNextButton.addActionListener(l);
 
  565     void addSourceComboControlListener(ActionListener l) {
 
  566         sourceComboBox.addActionListener(l);
 
  574     void updateControls(IndexedText source) {
 
  575         updatePageControls(source);
 
  576         updateSearchControls(source);
 
  584     void updatePageControls(IndexedText source) {
 
  585         if (source == null) {
 
  586             enableNextPageControl(
false);
 
  587             enablePrevPageControl(
false);
 
  588             updateCurrentPageDisplay(0);
 
  589             updateTotalPagesDisplay(0);
 
  593         updateCurrentPageDisplay(source.getCurrentPage());
 
  594         int totalPages = source.getNumberPages();
 
  595         updateTotalPagesDisplay(totalPages);
 
  597         if (totalPages < 2) {
 
  598             enableNextPageControl(
false);
 
  599             enablePrevPageControl(
false);
 
  601             enableNextPageControl(source.hasNextPage());
 
  602             enablePrevPageControl(source.hasPreviousPage());
 
  611     void updateSearchControls(IndexedText source) {
 
  613         if (source != null && source.isSearchable()) {
 
  614             updateCurrentMatchDisplay(source.currentItem());
 
  615             updateTotaMatcheslDisplay(source.getNumberHits());
 
  616             enableNextMatchControl(source.hasNextItem() || source.hasNextPage());
 
  617             enablePrevMatchControl(source.hasPreviousItem() || source.hasPreviousPage());
 
  619             enableNextMatchControl(
false);
 
  620             enablePrevMatchControl(
false);
 
  621             updateCurrentMatchDisplay(0);
 
  622             updateTotaMatcheslDisplay(0);
 
  631     private void scrollToCurrentHit(
final IndexedText source) {
 
  632         if (source == null || !source.isSearchable()) {
 
  637         EventQueue.invokeLater(() -> scrollToAnchor(source.getAnchorPrefix() + source.currentItem()));
 
  646     @NbBundle.Messages(
"ExtractedContentPanel.setMarkup.panelTxt=<span style='font-style:italic'>Loading text... Please wait</span>")
 
  647     private void setMarkup(IndexedText source) {
 
  648         setPanelText(Bundle.ExtractedContentPanel_setMarkup_panelTxt(), 
false);
 
  649         new SetMarkupWorker(contentName, source).execute();
 
  666             this.contentName = contentName;
 
  667             this.source = source;
 
  671         @NbBundle.Messages({
"# {0} - Content name",
 
  672             "ExtractedContentPanel.SetMarkup.progress.loading=Loading text for {0}"})
 
  674             progress = ProgressHandle.createHandle(Bundle.ExtractedContentPanel_SetMarkup_progress_loading(contentName));
 
  676             progress.switchToIndeterminate();
 
  678             return source.getText();
 
  688                 String markup = 
get();
 
  689                 if (markup != null) {
 
  690                     setPanelText(markup, 
true);
 
  692                     setPanelText(
"", 
false);
 
  694             } 
catch (InterruptedException | CancellationException | ExecutionException ex) {
 
  695                 logger.log(Level.SEVERE, 
"Error getting marked up text", ex); 
 
  696                 setPanelText(Bundle.IndexedText_errorMessage_errorGettingText(), 
true);
 
  699             updateControls(source);
 
  700             scrollToCurrentHit(source);