Add ability to edit results
This commit is contained in:
parent
c9b2677bec
commit
1ff3fb1f1b
@ -42,6 +42,7 @@ HEADERS += \
|
||||
src/ocr/recognizerworker.h \
|
||||
src/ocr/tesseract.h \
|
||||
src/represent/representer.h \
|
||||
src/represent/resulteditor.h \
|
||||
src/represent/resultwidget.h \
|
||||
src/service/apptranslator.h \
|
||||
src/service/debug.h \
|
||||
@ -75,6 +76,7 @@ SOURCES += \
|
||||
src/ocr/recognizerworker.cpp \
|
||||
src/ocr/tesseract.cpp \
|
||||
src/represent/representer.cpp \
|
||||
src/represent/resulteditor.cpp \
|
||||
src/represent/resultwidget.cpp \
|
||||
src/service/apptranslator.cpp \
|
||||
src/service/debug.cpp \
|
||||
|
@ -38,8 +38,8 @@ Manager::Manager()
|
||||
recognizer_ = std::make_unique<Recognizer>(*this, *settings_);
|
||||
translator_ = std::make_unique<Translator>(*this, *settings_);
|
||||
corrector_ = std::make_unique<Corrector>(*this, *settings_);
|
||||
representer_ = std::make_unique<Representer>(*this, *tray_, *settings_);
|
||||
|
||||
representer_ =
|
||||
std::make_unique<Representer>(*this, *tray_, *settings_, *models_);
|
||||
qRegisterMetaType<TaskPtr>();
|
||||
|
||||
settings_->load();
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "representer.h"
|
||||
#include "debug.h"
|
||||
#include "geometryutils.h"
|
||||
#include "manager.h"
|
||||
#include "resulteditor.h"
|
||||
#include "resultwidget.h"
|
||||
#include "settings.h"
|
||||
#include "task.h"
|
||||
@ -8,15 +10,19 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QScreen>
|
||||
|
||||
Representer::Representer(Manager &manager, TrayIcon &tray,
|
||||
const Settings &settings)
|
||||
const Settings &settings, const CommonModels &models)
|
||||
: manager_(manager)
|
||||
, tray_(tray)
|
||||
, settings_(settings)
|
||||
, models_(models)
|
||||
{
|
||||
}
|
||||
|
||||
Representer::~Representer() = default;
|
||||
|
||||
void Representer::showLast()
|
||||
{
|
||||
SOFT_ASSERT(widget_, return );
|
||||
@ -27,18 +33,11 @@ void Representer::clipboardLast()
|
||||
{
|
||||
SOFT_ASSERT(widget_, return );
|
||||
SOFT_ASSERT(widget_->task(), return );
|
||||
const auto task = widget_->task();
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
auto text = task->recognized;
|
||||
if (!task->translated.isEmpty())
|
||||
text += QLatin1String(" - ") + task->translated;
|
||||
clipboard->setText(text);
|
||||
clipboardText(widget_->task());
|
||||
tray_.showInformation(
|
||||
QObject::tr("The last result was copied to the clipboard."));
|
||||
}
|
||||
|
||||
Representer::~Representer() = default;
|
||||
|
||||
void Representer::represent(const TaskPtr &task)
|
||||
{
|
||||
if (settings_.resultShowType == ResultMode::Tooltip)
|
||||
@ -53,6 +52,41 @@ void Representer::updateSettings()
|
||||
widget_->updateSettings();
|
||||
}
|
||||
|
||||
void Representer::clipboardText(const TaskPtr &task)
|
||||
{
|
||||
if (!task)
|
||||
return;
|
||||
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
auto text = task->recognized;
|
||||
if (!task->translated.isEmpty())
|
||||
text += QLatin1String(" - ") + task->translated;
|
||||
clipboard->setText(text);
|
||||
}
|
||||
|
||||
void Representer::clipboardImage(const TaskPtr &task)
|
||||
{
|
||||
if (!task)
|
||||
return;
|
||||
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
clipboard->setPixmap(task->captured);
|
||||
}
|
||||
|
||||
void Representer::edit(const TaskPtr &task)
|
||||
{
|
||||
if (!editor_)
|
||||
editor_ = std::make_unique<ResultEditor>(manager_, models_, settings_);
|
||||
|
||||
editor_->show(task);
|
||||
|
||||
const auto cursor = QCursor::pos();
|
||||
const auto screen = QApplication::screenAt(cursor);
|
||||
SOFT_ASSERT(screen, return );
|
||||
editor_->move(service::geometry::cornerAtPoint(cursor, editor_->size(),
|
||||
screen->geometry()));
|
||||
}
|
||||
|
||||
void Representer::showTooltip(const TaskPtr &task)
|
||||
{
|
||||
auto message = task->recognized + " - " + task->translated;
|
||||
@ -62,7 +96,7 @@ void Representer::showTooltip(const TaskPtr &task)
|
||||
void Representer::showWidget(const TaskPtr &task)
|
||||
{
|
||||
if (!widget_)
|
||||
widget_ = std::make_unique<ResultWidget>(settings_);
|
||||
widget_ = std::make_unique<ResultWidget>(*this, settings_);
|
||||
|
||||
widget_->show(task);
|
||||
}
|
||||
|
@ -4,11 +4,13 @@
|
||||
|
||||
enum class ResultMode;
|
||||
class ResultWidget;
|
||||
class ResultEditor;
|
||||
|
||||
class Representer
|
||||
{
|
||||
public:
|
||||
Representer(Manager &manager, TrayIcon &tray, const Settings &settings);
|
||||
Representer(Manager &manager, TrayIcon &tray, const Settings &settings,
|
||||
const CommonModels &models);
|
||||
~Representer();
|
||||
|
||||
void showLast();
|
||||
@ -16,6 +18,10 @@ public:
|
||||
void represent(const TaskPtr &task);
|
||||
void updateSettings();
|
||||
|
||||
void clipboardText(const TaskPtr &task);
|
||||
void clipboardImage(const TaskPtr &task);
|
||||
void edit(const TaskPtr &task);
|
||||
|
||||
private:
|
||||
void showTooltip(const TaskPtr &task);
|
||||
void showWidget(const TaskPtr &task);
|
||||
@ -23,5 +29,7 @@ private:
|
||||
Manager &manager_;
|
||||
TrayIcon &tray_;
|
||||
const Settings &settings_;
|
||||
const CommonModels &models_;
|
||||
std::unique_ptr<ResultWidget> widget_;
|
||||
std::unique_ptr<ResultEditor> editor_;
|
||||
};
|
||||
|
109
src/represent/resulteditor.cpp
Normal file
109
src/represent/resulteditor.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
#include "resulteditor.h"
|
||||
#include "commonmodels.h"
|
||||
#include "debug.h"
|
||||
#include "languagecodes.h"
|
||||
#include "manager.h"
|
||||
#include "settings.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QTextEdit>
|
||||
|
||||
ResultEditor::ResultEditor(Manager &manager, const CommonModels &models,
|
||||
const Settings &settings, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, manager_(manager)
|
||||
, settings_(settings)
|
||||
, image_(new QLabel(this))
|
||||
, recognizedEdit_(new QTextEdit(this))
|
||||
, sourceLanguage_(new QComboBox(this))
|
||||
, targetLanguage_(new QComboBox(this))
|
||||
, recognizeOnly_(new QPushButton(tr("Recognize"), this))
|
||||
, recognizeAndTranslate_(new QPushButton(tr("Recognize and translate"), this))
|
||||
, translateOnly_(new QPushButton(tr("Translate"), this))
|
||||
{
|
||||
image_->setAlignment(Qt::AlignCenter);
|
||||
|
||||
sourceLanguage_->setModel(models.sourceLanguageModel());
|
||||
targetLanguage_->setModel(models.targetLanguageModel());
|
||||
|
||||
connect(recognizeOnly_, &QPushButton::clicked, //
|
||||
this, &ResultEditor::recognize);
|
||||
connect(recognizeAndTranslate_, &QPushButton::clicked, //
|
||||
this, &ResultEditor::recognizeAndTranslate);
|
||||
connect(translateOnly_, &QPushButton::clicked, //
|
||||
this, &ResultEditor::translate);
|
||||
|
||||
auto layout = new QGridLayout(this);
|
||||
auto row = 0;
|
||||
layout->addWidget(image_, row, 0, 1, 2);
|
||||
|
||||
++row;
|
||||
layout->addWidget(new QLabel(tr("Recognize:")), row, 0);
|
||||
layout->addWidget(sourceLanguage_, row, 1);
|
||||
|
||||
++row;
|
||||
layout->addWidget(new QLabel(tr("Translate:")), row, 0);
|
||||
layout->addWidget(targetLanguage_, row, 1);
|
||||
|
||||
++row;
|
||||
layout->addWidget(recognizedEdit_, row, 0, 1, 2);
|
||||
|
||||
++row;
|
||||
auto box = new QHBoxLayout;
|
||||
layout->addLayout(box, row, 0, 1, 2);
|
||||
box->addWidget(recognizeOnly_);
|
||||
box->addWidget(recognizeAndTranslate_);
|
||||
box->addWidget(translateOnly_);
|
||||
}
|
||||
|
||||
void ResultEditor::show(const TaskPtr &task)
|
||||
{
|
||||
SOFT_ASSERT(task, return );
|
||||
task_ = task;
|
||||
|
||||
image_->setPixmap(task->captured);
|
||||
recognizedEdit_->setText(task->recognized);
|
||||
|
||||
const auto target = task->targetLanguage.isEmpty() ? settings_.targetLanguage
|
||||
: task->targetLanguage;
|
||||
targetLanguage_->setCurrentText(LanguageCodes::name(target));
|
||||
sourceLanguage_->setCurrentText(LanguageCodes::name(task->sourceLanguage));
|
||||
|
||||
QWidget::show();
|
||||
}
|
||||
|
||||
void ResultEditor::recognize()
|
||||
{
|
||||
task_->sourceLanguage =
|
||||
LanguageCodes::idForName(sourceLanguage_->currentText());
|
||||
task_->targetLanguage.clear();
|
||||
manager_.captured(task_);
|
||||
close();
|
||||
task_.reset();
|
||||
}
|
||||
|
||||
void ResultEditor::recognizeAndTranslate()
|
||||
{
|
||||
task_->sourceLanguage =
|
||||
LanguageCodes::idForName(sourceLanguage_->currentText());
|
||||
task_->targetLanguage =
|
||||
LanguageCodes::idForName(targetLanguage_->currentText());
|
||||
task_->translators = settings_.translators;
|
||||
manager_.captured(task_);
|
||||
close();
|
||||
task_.reset();
|
||||
}
|
||||
|
||||
void ResultEditor::translate()
|
||||
{
|
||||
task_->targetLanguage =
|
||||
LanguageCodes::idForName(targetLanguage_->currentText());
|
||||
task_->translators = settings_.translators;
|
||||
manager_.corrected(task_);
|
||||
close();
|
||||
task_.reset();
|
||||
}
|
38
src/represent/resulteditor.h
Normal file
38
src/represent/resulteditor.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "stfwd.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
class QMenu;
|
||||
class QTextEdit;
|
||||
class QComboBox;
|
||||
class QPushButton;
|
||||
|
||||
class ResultEditor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ResultEditor(Manager& manager, const CommonModels& models,
|
||||
const Settings& settings, QWidget* parent = nullptr);
|
||||
|
||||
void show(const TaskPtr& task);
|
||||
using QWidget::show;
|
||||
|
||||
private:
|
||||
void recognize();
|
||||
void recognizeAndTranslate();
|
||||
void translate();
|
||||
|
||||
Manager& manager_;
|
||||
const Settings& settings_;
|
||||
TaskPtr task_;
|
||||
QLabel* image_;
|
||||
QTextEdit* recognizedEdit_;
|
||||
QComboBox* sourceLanguage_;
|
||||
QComboBox* targetLanguage_;
|
||||
QPushButton* recognizeOnly_;
|
||||
QPushButton* recognizeAndTranslate_;
|
||||
QPushButton* translateOnly_;
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
#include "resultwidget.h"
|
||||
#include "debug.h"
|
||||
#include "representer.h"
|
||||
#include "settings.h"
|
||||
#include "task.h"
|
||||
|
||||
@ -7,14 +8,18 @@
|
||||
#include <QBoxLayout>
|
||||
#include <QDesktopWidget>
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
|
||||
ResultWidget::ResultWidget(const Settings &settings, QWidget *parent)
|
||||
ResultWidget::ResultWidget(Representer &representer, const Settings &settings,
|
||||
QWidget *parent)
|
||||
: QFrame(parent)
|
||||
, representer_(representer)
|
||||
, settings_(settings)
|
||||
, image_(new QLabel(this))
|
||||
, recognized_(new QLabel(this))
|
||||
, translated_(new QLabel(this))
|
||||
, contextMenu_(new QMenu(this))
|
||||
{
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint |
|
||||
Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
|
||||
@ -33,6 +38,18 @@ ResultWidget::ResultWidget(const Settings &settings, QWidget *parent)
|
||||
translated_->setAlignment(Qt::AlignCenter);
|
||||
translated_->setWordWrap(true);
|
||||
|
||||
{
|
||||
auto clipboardText = contextMenu_->addAction(tr("Copy text"));
|
||||
connect(clipboardText, &QAction::triggered, //
|
||||
this, &ResultWidget::copyText);
|
||||
auto clipboardImage = contextMenu_->addAction(tr("Copy image"));
|
||||
connect(clipboardImage, &QAction::triggered, //
|
||||
this, &ResultWidget::copyImage);
|
||||
auto edit = contextMenu_->addAction(tr("Edit..."));
|
||||
connect(edit, &QAction::triggered, //
|
||||
this, &ResultWidget::edit);
|
||||
}
|
||||
|
||||
const auto styleSheet =
|
||||
"#recognizeLabel, #translateLabel {"
|
||||
"color: black;"
|
||||
@ -120,36 +137,28 @@ bool ResultWidget::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress) {
|
||||
const auto button = static_cast<QMouseEvent *>(event)->button();
|
||||
if (button == Qt::LeftButton) {
|
||||
if (button == Qt::RightButton) {
|
||||
contextMenu_->exec(QCursor::pos());
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
// else if (button == Qt::RightButton) {
|
||||
// QAction *action = contextMenu_->exec(QCursor::pos());
|
||||
// if (recognizeSubMenu_->findChildren<QAction *>().contains(action)) {
|
||||
// ProcessingItem item = item_;
|
||||
// task->translated = task->recognized = QString();
|
||||
// task->ocrLanguage = dictionary_.ocrUiToCode(action->text());
|
||||
// emit requestRecognize(item);
|
||||
// } else if (translateSubMenu_->findChildren<QAction *>().contains(
|
||||
// action)) {
|
||||
// ProcessingItem item = item_;
|
||||
// task->translated.clear();
|
||||
// task->translateLanguage =
|
||||
// dictionary_.translateUiToCode(action->text()); emit
|
||||
// requestTranslate(item);
|
||||
// } else if (action == clipboardAction_) {
|
||||
// emit requestClipboard();
|
||||
// } else if (action == imageClipboardAction_) {
|
||||
// emit requestImageClipboard();
|
||||
// } else if (action == correctAction_) {
|
||||
// emit requestEdition(item_);
|
||||
// // Return because Manager calls showResult() before hide()
|
||||
// otherwise.return QWidget::eventFilter(watched, event);
|
||||
// }
|
||||
// }
|
||||
// hide();
|
||||
} else if (event->type() == QEvent::WindowDeactivate) {
|
||||
hide();
|
||||
}
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void ResultWidget::edit()
|
||||
{
|
||||
representer_.edit(task_);
|
||||
}
|
||||
|
||||
void ResultWidget::copyText()
|
||||
{
|
||||
representer_.clipboardText(task_);
|
||||
}
|
||||
|
||||
void ResultWidget::copyImage()
|
||||
{
|
||||
representer_.clipboardImage(task_);
|
||||
}
|
||||
|
@ -5,12 +5,14 @@
|
||||
#include <QFrame>
|
||||
|
||||
class QLabel;
|
||||
class QMenu;
|
||||
|
||||
class ResultWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ResultWidget(const Settings& settings, QWidget* parent = nullptr);
|
||||
ResultWidget(Representer& representer, const Settings& settings,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
const TaskPtr& task() const;
|
||||
void show(const TaskPtr& task);
|
||||
@ -20,9 +22,15 @@ public:
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
|
||||
private:
|
||||
void edit();
|
||||
void copyImage();
|
||||
void copyText();
|
||||
|
||||
Representer& representer_;
|
||||
const Settings& settings_;
|
||||
TaskPtr task_;
|
||||
QLabel* image_;
|
||||
QLabel* recognized_;
|
||||
QLabel* translated_;
|
||||
QMenu* contextMenu_;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user