<commit_before>/* LanguageTool, a natural language style checker
 * Copyright (C) 2012 <NAME> (http://www.danielnaber.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
package org.languagetool.gui;

import java.awt.Cursor;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;

import javax.swing.JTextPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

import org.apache.commons.lang.StringUtils;
import org.languagetool.Language;
import org.languagetool.LanguageMaintainedState;
import org.languagetool.rules.ITSIssueType;
import org.languagetool.rules.Rule;
import org.languagetool.rules.RuleMatch;
import org.languagetool.tools.ContextTools;

/**
 * Area where the result of text checking is displayed.
 */
class ResultArea {

  private static final String DEACTIVATE_URL = "http://languagetool.org/deactivate/";
  private static final String REACTIVATE_URL = "http://languagetool.org/reactivate/";
  private static final String LT_ERROR_MARKER_START = "<b><font bgcolor=\"#d7d7ff\">";
  private static final String SPELL_ERROR_MARKER_START = "<b><font bgcolor=\"#ffd7d7\">";

  private final ResourceBundle messages;
  private final JTextPane statusPane;
  private final LanguageToolSupport ltSupport;

  private String inputText;
  private String startText;
  private List<RuleMatch> allRuleMatches;
  private List<RuleMatch> ruleMatches;    // will be filtered to not show disabled rules
  private long runTime;

  ResultArea(final ResourceBundle messages, final LanguageToolSupport ltSupport, final JTextPane statusPane) {
    this.messages = messages;
    this.ltSupport = ltSupport;
    this.statusPane = statusPane;
    statusPane.setContentType("text/html");
    statusPane.setText(Main.HTML_GREY_FONT_START + messages.getString("resultAreaText") + Main.HTML_FONT_END);
    statusPane.setEditable(false);
    statusPane.addHyperlinkListener(new MyHyperlinkListener());
    statusPane.setTransferHandler(new RetainLineBreakTransferHandler());
    ltSupport.addLanguageToolListener(new LanguageToolListener() {
      @Override
      public void languageToolEventOccurred(LanguageToolEvent event) {
        if (event.getType() == LanguageToolEvent.Type.CHECKING_STARTED) {
          final Language lang = ltSupport.getLanguage();
          final String langName;
          if (lang.isExternal()) {
            langName = lang.getTranslatedName(messages) + Main.EXTERNAL_LANGUAGE_SUFFIX;
          } else {
            langName = lang.getTranslatedName(messages);
          }
          final String startCheckText = Main.HTML_GREY_FONT_START
              + org.languagetool.tools.Tools.i18n(messages, "startChecking", langName) + "..." + Main.HTML_FONT_END;
          statusPane.setText(startCheckText);
          setStartText(startCheckText);
          if (event.getCaller() == this) {
            statusPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
          }
        } else if (event.getType() == LanguageToolEvent.Type.CHECKING_FINISHED) {
          setRunTime(event.getElapsedTime());
          inputText = event.getSource().getTextComponent().getText();
          setRuleMatches(event.getSource().getMatches());
          displayResult();
          if (event.getCaller() == this) {
            statusPane.setCursor(Cursor.getDefaultCursor());
          }
        } else if (event.getType() == LanguageToolEvent.Type.RULE_DISABLED || event.getType() == LanguageToolEvent.Type.RULE_ENABLED) {
          inputText = event.getSource().getTextComponent().getText();
          setRuleMatches(event.getSource().getMatches());
          displayResult();
        }
      }
    });
  }

  private String getRuleMatchHtml(List<RuleMatch> ruleMatches, String text, String startCheckText) {
    final ContextTools contextTools = new ContextTools();
    final StringBuilder sb = new StringBuilder(200);
    if (ltSupport.getLanguage().getMaintainedState() != LanguageMaintainedState.ActivelyMaintained) {
      sb.append("<b>").append(messages.getString("unsupportedWarning")).append("</b><br><br>");
    }
    sb.append(startCheckText);
    sb.append("<br>\n");
    int i = 0;
    for (final RuleMatch match : ruleMatches) {
      final String output = org.languagetool.tools.Tools.i18n(messages, "result1", i + 1, match.getLine() + 1, match.getColumn());
      sb.append(output);
      final String msg = match.getMessage()
          .replaceAll("<suggestion>", "<b>").replaceAll("</suggestion>", "</b>")
          .replaceAll("<old>", "<b>").replaceAll("</old>", "</b>");
      sb.append("<b>").append(messages.getString("errorMessage")).append("</b> ");
      sb.append(msg);
      final RuleLink ruleLink = RuleLink.buildDeactivationLink(match.getRule());
      sb.append(" <a href=\"").append(ruleLink).append("\">").append(messages.getString("deactivateRule")).append("</a><br>\n");
      if (match.getSuggestedReplacements().size() > 0) {
        final String replacement = String.join("; ", match.getSuggestedReplacements());
        sb.append("<b>").append(messages.getString("correctionMessage")).append("</b> ").append(replacement).append("<br>\n");
      }
      if (ITSIssueType.Misspelling.equals(match.getRule().getLocQualityIssueType())) {
        contextTools.setErrorMarkerStart(SPELL_ERROR_MARKER_START);
      } else {
        contextTools.setErrorMarkerStart(LT_ERROR_MARKER_START);
      }
      final String context = contextTools.getContext(match.getFromPos(), match.getToPos(), text);
      sb.append("<b>").append(messages.getString("errorContext")).append("</b> ").append(context);
      sb.append("<br>\n");
      if (match.getRule().getUrl() != null && Desktop.isDesktopSupported()) {
        sb.append("<b>").append(messages.getString("moreInfo")).append("</b> <a href=\"");
        final String url = match.getRule().getUrl().toString();
        sb.append(url);
        final String shortUrl = StringUtils.abbreviate(url, 60);
        sb.append("\">").append(shortUrl).append("</a><br>\n");
      }
      i++;
    }
    sb.append(Main.HTML_GREY_FONT_START);
    sb.append(getDisabledRulesHtml());
    final String checkDone = org.languagetool.tools.Tools.i18n(messages, "checkDone", ruleMatches.size(), runTime);
    sb.append("<br>\n").append(checkDone);
    sb.append("<br>\n").append(messages.getString("makeLanguageToolBetter"));
    sb.append(Main.HTML_FONT_END).append("<br>\n");
    return sb.toString();
  }

  private String getDisabledRulesHtml() {<commit_msg>tiny code cleanup to avoid IntelliJ warning<commit_after>/* LanguageTool, a natural language style checker
 * Copyright (C) 2012 <NAME> (http://www.danielnaber.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
package org.languagetool.gui;

import java.awt.Cursor;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;

import javax.swing.JTextPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

import org.apache.commons.lang.StringUtils;
import org.languagetool.Language;
import org.languagetool.LanguageMaintainedState;
import org.languagetool.rules.ITSIssueType;
import org.languagetool.rules.Rule;
import org.languagetool.rules.RuleMatch;
import org.languagetool.tools.ContextTools;

/**
 * Area where the result of text checking is displayed.
 */
class ResultArea {

  private static final String DEACTIVATE_URL = "http://languagetool.org/deactivate/";
  private static final String REACTIVATE_URL = "http://languagetool.org/reactivate/";
  private static final String LT_ERROR_MARKER_START = "<b><font bgcolor=\"#d7d7ff\">";
  private static final String SPELL_ERROR_MARKER_START = "<b><font bgcolor=\"#ffd7d7\">";

  private final ResourceBundle messages;
  private final JTextPane statusPane;
  private final LanguageToolSupport ltSupport;

  private String inputText;
  private String startText;
  private List<RuleMatch> allRuleMatches;
  private List<RuleMatch> ruleMatches;    // will be filtered to not show disabled rules
  private long runTime;

  ResultArea(final ResourceBundle messages, final LanguageToolSupport ltSupport, final JTextPane statusPane) {
    this.messages = messages;
    this.ltSupport = ltSupport;
    this.statusPane = statusPane;
    statusPane.setContentType("text/html");
    statusPane.setText(Main.HTML_GREY_FONT_START + messages.getString("resultAreaText") + Main.HTML_FONT_END);
    statusPane.setEditable(false);
    statusPane.addHyperlinkListener(new MyHyperlinkListener());
    statusPane.setTransferHandler(new RetainLineBreakTransferHandler());
    ltSupport.addLanguageToolListener(new LanguageToolListener() {
      @Override
      public void languageToolEventOccurred(LanguageToolEvent event) {
        if (event.getType() == LanguageToolEvent.Type.CHECKING_STARTED) {
          final Language lang = ltSupport.getLanguage();
          final String langName;
          if (lang.isExternal()) {
            langName = lang.getTranslatedName(messages) + Main.EXTERNAL_LANGUAGE_SUFFIX;
          } else {
            langName = lang.getTranslatedName(messages);
          }
          final String startCheckText = Main.HTML_GREY_FONT_START
              + org.languagetool.tools.Tools.i18n(messages, "startChecking", langName) + "..." + Main.HTML_FONT_END;
          statusPane.setText(startCheckText);
          setStartText(startCheckText);
          if (event.getCaller() == this) {
            statusPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
          }
        } else if (event.getType() == LanguageToolEvent.Type.CHECKING_FINISHED) {
          setRunTime(event.getElapsedTime());
          inputText = event.getSource().getTextComponent().getText();
          setRuleMatches(event.getSource().getMatches());
          displayResult();
          if (event.getCaller() == this) {
            statusPane.setCursor(Cursor.getDefaultCursor());
          }
        } else if (event.getType() == LanguageToolEvent.Type.RULE_DISABLED || event.getType() == LanguageToolEvent.Type.RULE_ENABLED) {
          inputText = event.getSource().getTextComponent().getText();
          setRuleMatches(event.getSource().getMatches());
          displayResult();
        }
      }
    });
  }

  private String getRuleMatchHtml(List<RuleMatch> ruleMatches, String text, String startCheckText) {
    final ContextTools contextTools = new ContextTools();
    final StringBuilder sb = new StringBuilder(200);
    if (ltSupport.getLanguage().getMaintainedState() != LanguageMaintainedState.ActivelyMaintained) {
      sb.append("<b>").append(messages.getString("unsupportedWarning")).append("</b><br><br>");
    }
    sb.append(startCheckText);
    sb.append("<br>\n");
    int i = 0;
    for (final RuleMatch match : ruleMatches) {
      final String output = org.languagetool.tools.Tools.i18n(messages, "result1", i + 1, match.getLine() + 1, match.getColumn());
      sb.append(output);
      final String msg = match.getMessage()
          .replaceAll("<suggestion>", "<b>").replaceAll("</suggestion>", "</b>")
          .replaceAll("<old>", "<b>").replaceAll("</old>", "</b>");
      sb.append("<b>").append(messages.getString("errorMessage")).append("</b> ");
      sb.append(msg);
      final RuleLink ruleLink = RuleLink.buildDeactivationLink(match.getRule());
      sb.append(" <a href=\"").append(ruleLink).append("\">").append(messages.getString("deactivateRule")).append("</a><br>\n");
      if (match.getSuggestedReplacements().size() > 0) {
        final String replacement = String.join("; ", match.getSuggestedReplacements());
        sb.append("<b>").append(messages.getString("correctionMessage")).append("</b> ").append(replacement).append("<br>\n");
      }
      if (ITSIssueType.Misspelling == match.getRule().getLocQualityIssueType()) {
        contextTools.setErrorMarkerStart(SPELL_ERROR_MARKER_START);
      } else {
        contextTools.setErrorMarkerStart(LT_ERROR_MARKER_START);
      }
      final String context = contextTools.getContext(match.getFromPos(), match.getToPos(), text);
      sb.append("<b>").append(messages.getString("errorContext")).append("</b> ").append(context);
      sb.append("<br>\n");
      if (match.getRule().getUrl() != null && Desktop.isDesktopSupported()) {
        sb.append("<b>").append(messages.getString("moreInfo")).append("</b> <a href=\"");
        final String url = match.getRule().getUrl().toString();
        sb.append(url);
        final String shortUrl = StringUtils.abbreviate(url, 60);
        sb.append("\">").append(shortUrl).append("</a><br>\n");
      }
      i++;
    }
    sb.append(Main.HTML_GREY_FONT_START);
    sb.append(getDisabledRulesHtml());
    final String checkDone = org.languagetool.tools.Tools.i18n(messages, "checkDone", ruleMatches.size(), runTime);
    sb.append("<br>\n").append(checkDone);
    sb.append("<br>\n").append(messages.getString("makeLanguageToolBetter"));
    sb.append(Main.HTML_FONT_END).append("<br>\n");
    return sb.toString();
  }

  private String getDisabledRulesHtml() {
{'fraction_non_alphanumeric': 0.13321005410588316, 'fraction_numerical': 0.005068146017396069, 'mean_word_length': 3.923128792987188, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6024089', 'n_tokens_mistral': 4323, 'n_tokens_neox': 4208, 'n_words': 899}