Add ability to edit selected rect
This commit is contained in:
parent
cc815f4245
commit
e1c2defd71
@ -31,6 +31,7 @@ INCLUDEPATH += src src/service src/capture src/ocr \
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/capture/capturearea.h \
|
src/capture/capturearea.h \
|
||||||
|
src/capture/captureareaeditor.h \
|
||||||
src/capture/captureareaselector.h \
|
src/capture/captureareaselector.h \
|
||||||
src/capture/capturer.h \
|
src/capture/capturer.h \
|
||||||
src/correct/corrector.h \
|
src/correct/corrector.h \
|
||||||
@ -60,6 +61,7 @@ HEADERS += \
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
src/capture/capturearea.cpp \
|
src/capture/capturearea.cpp \
|
||||||
|
src/capture/captureareaeditor.cpp \
|
||||||
src/capture/captureareaselector.cpp \
|
src/capture/captureareaselector.cpp \
|
||||||
src/capture/capturer.cpp \
|
src/capture/capturer.cpp \
|
||||||
src/correct/corrector.cpp \
|
src/correct/corrector.cpp \
|
||||||
|
@ -13,7 +13,7 @@ CaptureArea::CaptureArea(const QRect &rect, const Settings &settings)
|
|||||||
|
|
||||||
TaskPtr CaptureArea::task(const QPixmap &pixmap) const
|
TaskPtr CaptureArea::task(const QPixmap &pixmap) const
|
||||||
{
|
{
|
||||||
if (pixmap.isNull() || rect_.width() < 3 || rect_.height() < 3)
|
if (pixmap.isNull() || !isValid())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
auto task = std::make_shared<Task>();
|
auto task = std::make_shared<Task>();
|
||||||
@ -27,3 +27,18 @@ TaskPtr CaptureArea::task(const QPixmap &pixmap) const
|
|||||||
|
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CaptureArea::isValid() const
|
||||||
|
{
|
||||||
|
return !(rect_.width() < 3 || rect_.height() < 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QRect &CaptureArea::rect() const
|
||||||
|
{
|
||||||
|
return rect_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureArea::setRect(const QRect &rect)
|
||||||
|
{
|
||||||
|
rect_ = rect;
|
||||||
|
}
|
||||||
|
@ -13,7 +13,13 @@ public:
|
|||||||
CaptureArea(const QRect& rect, const Settings& settings);
|
CaptureArea(const QRect& rect, const Settings& settings);
|
||||||
TaskPtr task(const QPixmap& pixmap) const;
|
TaskPtr task(const QPixmap& pixmap) const;
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
const QRect& rect() const;
|
||||||
|
void setRect(const QRect& rect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class CaptureAreaEditor;
|
||||||
|
|
||||||
QRect rect_;
|
QRect rect_;
|
||||||
bool doTranslation_;
|
bool doTranslation_;
|
||||||
LanguageId sourceLanguage_;
|
LanguageId sourceLanguage_;
|
||||||
|
62
src/capture/captureareaeditor.cpp
Normal file
62
src/capture/captureareaeditor.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include "captureareaeditor.h"
|
||||||
|
#include "capturearea.h"
|
||||||
|
#include "captureareaselector.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "languagecodes.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "tesseract.h"
|
||||||
|
#include "translator.h"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QStringListModel>
|
||||||
|
|
||||||
|
CaptureAreaEditor::CaptureAreaEditor(CaptureAreaSelector &selector)
|
||||||
|
: QWidget(&selector)
|
||||||
|
, selector_(selector)
|
||||||
|
, doTranslation_(new QCheckBox(tr("Translate"), this))
|
||||||
|
, sourceLanguage_(new QComboBox(this))
|
||||||
|
, targetLanguage_(new QComboBox(this))
|
||||||
|
, sourceLanguageModel_(std::make_unique<QStringListModel>())
|
||||||
|
, targetLanguageModel_(std::make_unique<QStringListModel>())
|
||||||
|
{
|
||||||
|
setCursor(Qt::CursorShape::ArrowCursor);
|
||||||
|
|
||||||
|
auto layout = new QFormLayout(this);
|
||||||
|
layout->addRow(doTranslation_);
|
||||||
|
layout->addRow(tr("Recognition language"), sourceLanguage_);
|
||||||
|
layout->addRow(tr("Translation language"), targetLanguage_);
|
||||||
|
|
||||||
|
sourceLanguage_->setModel(sourceLanguageModel_.get());
|
||||||
|
targetLanguage_->setModel(targetLanguageModel_.get());
|
||||||
|
targetLanguage_->setEnabled(doTranslation_->isChecked());
|
||||||
|
|
||||||
|
connect(doTranslation_, &QCheckBox::toggled, //
|
||||||
|
targetLanguage_, &QComboBox::setEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
CaptureAreaEditor::~CaptureAreaEditor() = default;
|
||||||
|
|
||||||
|
void CaptureAreaEditor::updateSettings(const Settings &settings)
|
||||||
|
{
|
||||||
|
sourceLanguageModel_->setStringList(
|
||||||
|
Tesseract::availableLanguageNames(settings.tessdataPath));
|
||||||
|
targetLanguageModel_->setStringList(Translator::availableLanguageNames());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureAreaEditor::set(const CaptureArea &area)
|
||||||
|
{
|
||||||
|
doTranslation_->setChecked(area.doTranslation_);
|
||||||
|
sourceLanguage_->setCurrentText(LanguageCodes::name(area.sourceLanguage_));
|
||||||
|
targetLanguage_->setCurrentText(LanguageCodes::name(area.targetLanguage_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureAreaEditor::apply(CaptureArea &area) const
|
||||||
|
{
|
||||||
|
area.doTranslation_ = doTranslation_->isChecked();
|
||||||
|
area.sourceLanguage_ =
|
||||||
|
LanguageCodes::idForName(sourceLanguage_->currentText());
|
||||||
|
area.targetLanguage_ =
|
||||||
|
LanguageCodes::idForName(targetLanguage_->currentText());
|
||||||
|
}
|
29
src/capture/captureareaeditor.h
Normal file
29
src/capture/captureareaeditor.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stfwd.h"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QCheckBox;
|
||||||
|
class QComboBox;
|
||||||
|
class QStringListModel;
|
||||||
|
|
||||||
|
class CaptureAreaEditor : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CaptureAreaEditor(CaptureAreaSelector& selector);
|
||||||
|
~CaptureAreaEditor();
|
||||||
|
|
||||||
|
void set(const CaptureArea& area);
|
||||||
|
void apply(CaptureArea& area) const;
|
||||||
|
void updateSettings(const Settings& settings);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CaptureAreaSelector& selector_;
|
||||||
|
QCheckBox* doTranslation_;
|
||||||
|
QComboBox* sourceLanguage_;
|
||||||
|
QComboBox* targetLanguage_;
|
||||||
|
std::unique_ptr<QStringListModel> sourceLanguageModel_;
|
||||||
|
std::unique_ptr<QStringListModel> targetLanguageModel_;
|
||||||
|
};
|
@ -1,6 +1,8 @@
|
|||||||
#include "captureareaselector.h"
|
#include "captureareaselector.h"
|
||||||
#include "capturearea.h"
|
#include "capturearea.h"
|
||||||
|
#include "captureareaeditor.h"
|
||||||
#include "capturer.h"
|
#include "capturer.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "languagecodes.h"
|
#include "languagecodes.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
@ -13,6 +15,7 @@ CaptureAreaSelector::CaptureAreaSelector(Capturer &capturer,
|
|||||||
: capturer_(capturer)
|
: capturer_(capturer)
|
||||||
, settings_(settings)
|
, settings_(settings)
|
||||||
, pixmap_(pixmap)
|
, pixmap_(pixmap)
|
||||||
|
, editor_(std::make_unique<CaptureAreaEditor>(*this))
|
||||||
{
|
{
|
||||||
setWindowFlags(Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint |
|
setWindowFlags(Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint |
|
||||||
Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
|
Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
|
||||||
@ -21,6 +24,8 @@ CaptureAreaSelector::CaptureAreaSelector(Capturer &capturer,
|
|||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CaptureAreaSelector::~CaptureAreaSelector() = default;
|
||||||
|
|
||||||
void CaptureAreaSelector::activate()
|
void CaptureAreaSelector::activate()
|
||||||
{
|
{
|
||||||
setGeometry(pixmap_.rect());
|
setGeometry(pixmap_.rect());
|
||||||
@ -51,19 +56,15 @@ void CaptureAreaSelector::updateSettings()
|
|||||||
const auto translationState = settings_.doTranslation ? tr("on") : tr("off");
|
const auto translationState = settings_.doTranslation ? tr("on") : tr("off");
|
||||||
|
|
||||||
help_ = tr(R"(Recognition language: %1
|
help_ = tr(R"(Recognition language: %1
|
||||||
Translation language: %2 (%3))")
|
Translation language: %2 (%3)
|
||||||
|
Right click on selection - customize
|
||||||
|
Left click on selection - process)")
|
||||||
.arg(sourceName, targetName, translationState);
|
.arg(sourceName, targetName, translationState);
|
||||||
}
|
|
||||||
|
|
||||||
void CaptureAreaSelector::showEvent(QShowEvent * /*event*/)
|
area_.reset();
|
||||||
{
|
|
||||||
startSelectPos_ = currentSelectPos_ = QPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CaptureAreaSelector::keyPressEvent(QKeyEvent *event)
|
SOFT_ASSERT(editor_, return );
|
||||||
{
|
editor_->updateSettings(settings_);
|
||||||
if (event->key() == Qt::Key_Escape)
|
|
||||||
capturer_.canceled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureAreaSelector::paintEvent(QPaintEvent * /*event*/)
|
void CaptureAreaSelector::paintEvent(QPaintEvent * /*event*/)
|
||||||
@ -73,6 +74,15 @@ void CaptureAreaSelector::paintEvent(QPaintEvent * /*event*/)
|
|||||||
|
|
||||||
for (const auto &rect : helpRects_) drawHelpRects(painter, rect);
|
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();
|
auto selection = QRect(startSelectPos_, currentSelectPos_).normalized();
|
||||||
if (!selection.isValid())
|
if (!selection.isValid())
|
||||||
return;
|
return;
|
||||||
@ -116,8 +126,54 @@ void CaptureAreaSelector::drawHelpRects(QPainter &painter,
|
|||||||
painter.drawText(rect.current, Qt::AlignCenter, help_);
|
painter.drawText(rect.current, Qt::AlignCenter, help_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CaptureAreaSelector::drawCaptureArea(QPainter &painter,
|
||||||
|
const CaptureArea &area) const
|
||||||
|
{
|
||||||
|
painter.setBrush(QBrush(QColor(200, 200, 200, 50)));
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.drawRect(area.rect());
|
||||||
|
|
||||||
|
painter.setBrush({});
|
||||||
|
painter.setPen(Qt::red);
|
||||||
|
painter.drawRect(area.rect());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureAreaSelector::showEvent(QShowEvent * /*event*/)
|
||||||
|
{
|
||||||
|
editor_->hide();
|
||||||
|
area_.reset();
|
||||||
|
startSelectPos_ = currentSelectPos_ = QPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureAreaSelector::hideEvent(QHideEvent * /*event*/)
|
||||||
|
{
|
||||||
|
editor_->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureAreaSelector::keyPressEvent(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
if (event->key() == Qt::Key_Escape)
|
||||||
|
capturer_.canceled();
|
||||||
|
}
|
||||||
|
|
||||||
void CaptureAreaSelector::mousePressEvent(QMouseEvent *event)
|
void CaptureAreaSelector::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
|
SOFT_ASSERT(editor_, return );
|
||||||
|
if (editor_->isVisible()) {
|
||||||
|
if (editor_->geometry().contains(event->pos()))
|
||||||
|
return;
|
||||||
|
applyEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (area_ && area_->rect().contains(event->pos())) {
|
||||||
|
if (event->button() == Qt::LeftButton) {
|
||||||
|
capturer_.selected(*area_);
|
||||||
|
} else if (event->button() == Qt::RightButton) {
|
||||||
|
customize(*area_);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (startSelectPos_.isNull())
|
if (startSelectPos_.isNull())
|
||||||
startSelectPos_ = event->pos();
|
startSelectPos_ = event->pos();
|
||||||
}
|
}
|
||||||
@ -137,10 +193,8 @@ void CaptureAreaSelector::mouseMoveEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
void CaptureAreaSelector::mouseReleaseEvent(QMouseEvent *event)
|
void CaptureAreaSelector::mouseReleaseEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (startSelectPos_.isNull() || pixmap_.isNull()) {
|
if (startSelectPos_.isNull())
|
||||||
capturer_.canceled();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
const auto endPos = event->pos();
|
const auto endPos = event->pos();
|
||||||
const auto selection = QRect(startSelectPos_, endPos).normalized();
|
const auto selection = QRect(startSelectPos_, endPos).normalized();
|
||||||
@ -148,5 +202,33 @@ void CaptureAreaSelector::mouseReleaseEvent(QMouseEvent *event)
|
|||||||
startSelectPos_ = currentSelectPos_ = {};
|
startSelectPos_ = currentSelectPos_ = {};
|
||||||
|
|
||||||
const auto area = CaptureArea(selection, settings_);
|
const auto area = CaptureArea(selection, settings_);
|
||||||
capturer_.selected(area);
|
if (!area.isValid()) {
|
||||||
|
capturer_.canceled();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event->button() != Qt::RightButton) {
|
||||||
|
capturer_.selected(area);
|
||||||
|
} else {
|
||||||
|
area_ = std::make_unique<CaptureArea>(area);
|
||||||
|
customize(*area_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureAreaSelector::customize(const CaptureArea &area)
|
||||||
|
{
|
||||||
|
SOFT_ASSERT(editor_, return );
|
||||||
|
editor_->set(area);
|
||||||
|
editor_->move(QCursor::pos());
|
||||||
|
editor_->show();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureAreaSelector::applyEditor()
|
||||||
|
{
|
||||||
|
SOFT_ASSERT(editor_, return );
|
||||||
|
if (!editor_->isVisible() || !area_)
|
||||||
|
return;
|
||||||
|
editor_->apply(*area_);
|
||||||
|
editor_->hide();
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ class CaptureAreaSelector : public QWidget
|
|||||||
public:
|
public:
|
||||||
CaptureAreaSelector(Capturer &capturer, const Settings &settings,
|
CaptureAreaSelector(Capturer &capturer, const Settings &settings,
|
||||||
const QPixmap &pixmap);
|
const QPixmap &pixmap);
|
||||||
|
~CaptureAreaSelector();
|
||||||
|
|
||||||
void activate();
|
void activate();
|
||||||
void setScreenRects(const std::vector<QRect> &screens);
|
void setScreenRects(const std::vector<QRect> &screens);
|
||||||
@ -18,6 +19,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
|
void hideEvent(QHideEvent *event) override;
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
void mousePressEvent(QMouseEvent *event) override;
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
void mouseMoveEvent(QMouseEvent *event) override;
|
void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
@ -33,6 +35,10 @@ private:
|
|||||||
bool updateCurrentHelpRects();
|
bool updateCurrentHelpRects();
|
||||||
void drawHelpRects(QPainter &painter, const HelpRect &rect) const;
|
void drawHelpRects(QPainter &painter, const HelpRect &rect) const;
|
||||||
|
|
||||||
|
void customize(const CaptureArea &area);
|
||||||
|
void applyEditor();
|
||||||
|
void drawCaptureArea(QPainter &painter, const CaptureArea &area) const;
|
||||||
|
|
||||||
Capturer &capturer_;
|
Capturer &capturer_;
|
||||||
const Settings &settings_;
|
const Settings &settings_;
|
||||||
const QPixmap &pixmap_;
|
const QPixmap &pixmap_;
|
||||||
@ -40,4 +46,6 @@ private:
|
|||||||
QPoint currentSelectPos_;
|
QPoint currentSelectPos_;
|
||||||
QString help_;
|
QString help_;
|
||||||
std::vector<HelpRect> helpRects_;
|
std::vector<HelpRect> helpRects_;
|
||||||
|
std::unique_ptr<CaptureArea> area_;
|
||||||
|
std::unique_ptr<CaptureAreaEditor> editor_;
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@ class Corrector;
|
|||||||
class Recognizer;
|
class Recognizer;
|
||||||
class CaptureArea;
|
class CaptureArea;
|
||||||
class CaptureAreaSelector;
|
class CaptureAreaSelector;
|
||||||
|
class CaptureAreaEditor;
|
||||||
|
|
||||||
namespace update
|
namespace update
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user