<commit_before>#include "captureareaselector.h"
#include "capturearea.h"
#include "captureareaeditor.h"
#include "capturer.h"
#include "debug.h"
#include "geometryutils.h"
#include "languagecodes.h"
#include "settings.h"

#include <QMouseEvent>
#include <QPainter>

CaptureAreaSelector::CaptureAreaSelector(Capturer &capturer,
                                         const Settings &settings,
                                         const CommonModels &models,
                                         const QPixmap &pixmap)
  : capturer_(capturer)
  , settings_(settings)
  , pixmap_(pixmap)
  , editor_(std::make_unique<CaptureAreaEditor>(models, this))
{
  setWindowFlags(Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint |
                 Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
  setCursor(Qt::CrossCursor);
  setMouseTracking(true);
  setAttribute(Qt::WA_OpaquePaintEvent);
}

CaptureAreaSelector::~CaptureAreaSelector() = default;

void CaptureAreaSelector::activate()
{
  setGeometry(pixmap_.rect());
  show();
  activateWindow();
}

bool CaptureAreaSelector::hasLocked() const
{
  return area_ && area_->isLocked();
}

void CaptureAreaSelector::captureLocked()
{
  SOFT_ASSERT(hasLocked(), return );
  capturer_.selected(*area_);
}

void CaptureAreaSelector::setScreenRects(const std::vector<QRect> &screens)
{
  auto helpRect = fontMetrics().boundingRect({}, 0, help_);
  helpRect.setSize(helpRect.size() * 1.4);

  helpRects_.clear();
  helpRects_.reserve(screens.size());
  for (const auto &screen : screens) {
    auto possible = std::vector<QRect>(2, helpRect);
    possible[0].moveTopLeft(screen.topLeft());
    possible[1].moveTopRight(screen.topRight());
    helpRects_.push_back({possible[0], possible});
  }
}

void CaptureAreaSelector::updateSettings()
{
  const auto sourceName = LanguageCodes::name(settings_.sourceLanguage);
  const auto targetName = LanguageCodes::name(settings_.targetLanguage);

  const auto translationState = settings_.doTranslation ? tr("on") : tr("off");

  help_ = tr(R"(Recognition language: %1
Translation language: %2 (%3)
Right click on selection - customize
Left click on selection - process)")
              .arg(sourceName, targetName, translationState);

  area_.reset();
}

void CaptureAreaSelector::paintEvent(QPaintEvent * /*event*/)
{
  QPainter painter(this);
  painter.drawPixmap(rect(), pixmap_);

  for (const auto &rect : helpRects_) drawHelpRects(painter, rect);

  if (area_)
    drawCaptureArea(painter, *area_);

  if (editor_->isVisible()) {
    painter.setBrush(QBrush(QColor(200, 200, 200, 200)));
    painter.setPen(Qt::NoPen);
    painter.drawRect(editor_->geometry());
  }

  auto selection = QRect(startSelectPos_, currentSelectPos_).normalized();
  if (!selection.isValid())
    return;

  const auto area = CaptureArea(selection, settings_);
  drawCaptureArea(painter, area);
}

bool CaptureAreaSelector::updateCurrentHelpRects()
{
  const auto cursor = mapFromGlobal(QCursor::pos());
  auto changed = false;

  for (auto &screenHelp : helpRects_) {
    if (!screenHelp.current.contains(cursor))
      continue;

    for (const auto &screenPossible : screenHelp.possible) {
      if (screenPossible.contains(cursor))
        continue;

      screenHelp.current = screenPossible;
      changed = true;
      break;
    }
  }

  return changed;
}

void CaptureAreaSelector::drawHelpRects(QPainter &painter,
                                        const HelpRect &rect) const
{
  painter.setBrush(QBrush(QColor(200, 200, 200, 200)));
  painter.setPen(Qt::NoPen);
  painter.drawRect(rect.current);

  painter.setBrush({});
  painter.setPen(Qt::black);
  painter.drawText(rect.current, Qt::AlignCenter, help_);
}

void CaptureAreaSelector::drawCaptureArea(QPainter &painter,
                                          const CaptureArea &area) const
{
  const auto areaRect = area.rect();
  const auto toolTip = area.toolTip();
  auto toolTipRect = painter.boundingRect(QRect(), 0, toolTip);
  toolTipRect.moveTopLeft(areaRect.topLeft() - QPoint(0, toolTipRect.height()));

  painter.setBrush(QBrush(QColor(200, 200, 200, 50)));
  painter.setPen(Qt::NoPen);
  painter.drawRect(areaRect);

  painter.setBrush(QBrush(QColor(200, 200, 200, 150)));
  painter.drawRect(toolTipRect);

  painter.setBrush({});
  painter.setPen(Qt::red);
  painter.drawRect(areaRect);

  painter.setPen(Qt::white);
  painter.drawText(toolTipRect, 0, toolTip);
}

void CaptureAreaSelector::showEvent(QShowEvent * /*event*/)
{
  editor_->hide();
  if (area_ && !area_->isLocked())
    area_.reset();
  startSelectPos_ = currentSelectPos_ = QPoint();
}

void CaptureAreaSelector::hideEvent(QHideEvent * /*event*/)
{
  editor_->hide();
}
<commit_msg>Change help and area tooltip drawing<commit_after>#include "captureareaselector.h"
#include "capturearea.h"
#include "captureareaeditor.h"
#include "capturer.h"
#include "debug.h"
#include "geometryutils.h"
#include "languagecodes.h"
#include "settings.h"

#include <QMouseEvent>
#include <QPainter>

CaptureAreaSelector::CaptureAreaSelector(Capturer &capturer,
                                         const Settings &settings,
                                         const CommonModels &models,
                                         const QPixmap &pixmap)
  : capturer_(capturer)
  , settings_(settings)
  , pixmap_(pixmap)
  , editor_(std::make_unique<CaptureAreaEditor>(models, this))
{
  setWindowFlags(Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint |
                 Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
  setCursor(Qt::CrossCursor);
  setMouseTracking(true);
  setAttribute(Qt::WA_OpaquePaintEvent);

  help_ = tr(R"(Right click on selection - customize
Left click on selection - process
Esc - cancel)");
}

CaptureAreaSelector::~CaptureAreaSelector() = default;

void CaptureAreaSelector::activate()
{
  setGeometry(pixmap_.rect());
  show();
  activateWindow();
}

bool CaptureAreaSelector::hasLocked() const
{
  return area_ && area_->isLocked();
}

void CaptureAreaSelector::captureLocked()
{
  SOFT_ASSERT(hasLocked(), return );
  capturer_.selected(*area_);
}

void CaptureAreaSelector::setScreenRects(const std::vector<QRect> &screens)
{
  auto helpRect = fontMetrics().boundingRect({}, 0, help_);
  helpRect.setSize(helpRect.size() * 1.4);

  helpRects_.clear();
  helpRects_.reserve(screens.size());
  for (const auto &screen : screens) {
    auto possible = std::vector<QRect>(2, helpRect);
    possible[0].moveTopLeft(screen.topLeft());
    possible[1].moveTopRight(screen.topRight());
    helpRects_.push_back({possible[0], possible});
  }
}

void CaptureAreaSelector::updateSettings()
{
  area_.reset();
}

void CaptureAreaSelector::paintEvent(QPaintEvent * /*event*/)
{
  QPainter painter(this);
  painter.drawPixmap(rect(), pixmap_);

  for (const auto &rect : helpRects_) drawHelpRects(painter, rect);

  if (area_)
    drawCaptureArea(painter, *area_);

  if (editor_->isVisible()) {
    painter.setBrush(QBrush(QColor(200, 200, 200, 200)));
    painter.setPen(Qt::NoPen);
    painter.drawRect(editor_->geometry());
  }

  auto selection = QRect(startSelectPos_, currentSelectPos_).normalized();
  if (!selection.isValid())
    return;

  const auto area = CaptureArea(selection, settings_);
  drawCaptureArea(painter, area);
}

bool CaptureAreaSelector::updateCurrentHelpRects()
{
  const auto cursor = mapFromGlobal(QCursor::pos());
  auto changed = false;

  for (auto &screenHelp : helpRects_) {
    if (!screenHelp.current.contains(cursor))
      continue;

    for (const auto &screenPossible : screenHelp.possible) {
      if (screenPossible.contains(cursor))
        continue;

      screenHelp.current = screenPossible;
      changed = true;
      break;
    }
  }

  return changed;
}

void CaptureAreaSelector::drawHelpRects(QPainter &painter,
                                        const HelpRect &rect) const
{
  painter.setBrush(QBrush(QColor(200, 200, 200, 200)));
  painter.setPen(Qt::NoPen);
  painter.drawRect(rect.current);

  painter.setBrush({});
  painter.setPen(Qt::black);
  painter.drawText(rect.current, Qt::AlignCenter, help_);
}

void CaptureAreaSelector::drawCaptureArea(QPainter &painter,
                                          const CaptureArea &area) const
{
  const auto areaRect = area.rect();
  const auto toolTip = area.toolTip();
  auto toolTipRect = painter.boundingRect(QRect(), 0, toolTip);
  toolTipRect.moveTopLeft(areaRect.topLeft() - QPoint(0, toolTipRect.height()));

  painter.setBrush(QBrush(QColor(200, 200, 200, 50)));
  painter.setPen(Qt::NoPen);
  painter.drawRect(areaRect);

  painter.setBrush(QBrush(QColor(200, 200, 200, 200)));
  painter.drawRect(toolTipRect);

  painter.setBrush({});
  painter.setPen(Qt::red);
  painter.drawRect(areaRect);

  painter.setPen(Qt::black);
  painter.drawText(toolTipRect, 0, toolTip);
}

void CaptureAreaSelector::showEvent(QShowEvent * /*event*/)
{
  editor_->hide();
  if (area_ && !area_->isLocked())
    area_.reset();
  startSelectPos_ = currentSelectPos_ = QPoint();
}

void CaptureAreaSelector::hideEvent(QHideEvent * /*event*/)
{
  editor_->hide();
}

{'fraction_non_alphanumeric': 0.13803680981595093, 'fraction_numerical': 0.013255915863277826, 'mean_word_length': 4.160542679479932, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7373332', 'n_tokens_mistral': 3005, 'n_tokens_neox': 2869, 'n_words': 523}