code_app/modules/saneui/dialog_device_scan.cpp

240 lines
7.0 KiB
C++

#include "dialog_device_scan.h"
#include "ui_dialog_device_scan.h"
#include "base/HGInc.h"
#include <QMessageBox>
#include <QCloseEvent>
#include <QTimer>
Dialog_Device_Scan::Dialog_Device_Scan(const SANEAPI* saneApi, SANE_Handle dev, const char *devName,
show_scan_ui_event_callback eventCallback, void *eventParam,
show_scan_ui_image_callback imageCallback, void *imageParam, QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog_Device_Scan)
{
ui->setupUi(this);
memcpy(&m_saneAPI, saneApi, sizeof(SANEAPI));
m_saneDev = dev;
m_eventCallback = eventCallback;
m_eventParam = eventParam;
m_imageCallback = imageCallback;
m_imageParam = imageParam;
m_buffer = NULL;
m_bufferSize = 0;
m_stopThread = HGFALSE;
m_thread = NULL;
setWindowTitle(QString::fromStdString(devName));
setWindowFlags(Qt::SubWindow | Qt::Popup);
m_timer = new QTimer(this);
connect(this, SIGNAL(eventFunc(int, QString)), this, SLOT(on_eventFunc(int, QString)));
connect(this, SIGNAL(imageCount(int)), this, SLOT(on_imageCount(int)));
ui->pushButton_Cancel->setVisible(false);
ui->pushButton_Complete->setVisible(true);
ui->label_imgRecived->setVisible(false);
ui->lineEdit_imgRecived->setVisible(false);
ui->label_totalImgRecived->setVisible(false);
ui->lineEdit_imgRecived->setText(QString::number(0));
startScan();
}
Dialog_Device_Scan::~Dialog_Device_Scan()
{
delete ui;
}
void Dialog_Device_Scan::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Escape)
{
e->ignore();
}
}
void Dialog_Device_Scan::on_eventFunc(int flag, QString errInfo)
{
ui->label->setText(errInfo);
m_stopThread = HGTRUE;
m_saneAPI.sane_cancel_api(m_saneDev);
HGBase_CloseThread(m_thread);
m_thread = NULL;
free(m_buffer);
m_buffer = NULL;
m_bufferSize = 0;
ui->pushButton_Cancel->setVisible(false);
ui->pushButton_Complete->setVisible(true);
ui->label_imgRecived->setVisible(false);
ui->lineEdit_imgRecived->setVisible(false);
ui->label_totalImgRecived->setVisible(true);
ui->label_totalImgRecived->setText(tr("Total scanned images: %1").arg(ui->lineEdit_imgRecived->text()));
if (0 == flag)
{
m_timer->start(1000);
connect(m_timer, SIGNAL(timeout()), this, SLOT(on_pushButton_Complete_clicked()));
}
}
void Dialog_Device_Scan::on_pushButton_Cancel_clicked()
{
m_saneAPI.sane_cancel_api(m_saneDev);
}
void Dialog_Device_Scan::on_pushButton_Complete_clicked()
{
accept();
if (nullptr != m_eventCallback)
{
m_eventCallback(SHOW_SCAN_UI_EVENT_SCANFINISHED, m_eventParam);
}
}
void Dialog_Device_Scan::on_imageCount(int count)
{
ui->lineEdit_imgRecived->setText(QString::number(count));
}
void Dialog_Device_Scan::startScan()
{
SANE_Parameters params;
memset(&params, 0, sizeof(SANE_Parameters));
SANE_Status stat = m_saneAPI.sane_get_parameters_api(m_saneDev, &params);
assert(SANE_STATUS_GOOD == stat);
m_bufferSize = params.bytes_per_line * params.lines;
m_buffer = (HGByte *)malloc(m_bufferSize);
if (NULL == m_buffer)
{
ui->label->setText(tr("Out of memory"));
return;
}
m_stopThread = HGFALSE;
HGBase_OpenThread(ThreadFunc, this, &m_thread);
ui->pushButton_Cancel->setVisible(true);
ui->pushButton_Complete->setVisible(false);
ui->label_imgRecived->setVisible(true);
ui->lineEdit_imgRecived->setVisible(true);
ui->label->setText(tr("Start scan"));
}
void Dialog_Device_Scan::closeEvent(QCloseEvent *e)
{
if (nullptr != m_thread)
{
QMessageBox::warning(this, tr("Warning"), tr("Scanning in progress, closing not allowed"));
e->ignore();
return;
}
}
void HGAPI Dialog_Device_Scan::ThreadFunc(HGThread thread, HGPointer param)
{
Dialog_Device_Scan* p = (Dialog_Device_Scan*)param;
SANE_Status stat = p->m_saneAPI.sane_start_api(p->m_saneDev);
if (SANE_STATUS_GOOD != stat)
{
emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(stat)));
return;
}
if (nullptr != p->m_eventCallback)
{
p->m_eventCallback(SHOW_SCAN_UI_EVENT_WORKING, p->m_eventParam);
}
int imageCount = 0;
while (!p->m_stopThread)
{
SANE_Parameters params;
memset(&params, 0, sizeof(SANE_Parameters));
SANE_Status stat1 = p->m_saneAPI.sane_get_parameters_api(p->m_saneDev, &params);
SANE_Int readSize = 0;
SANE_Status stat2 = SANE_STATUS_GOOD;
while (readSize < p->m_bufferSize)
{
SANE_Int len = 0;
stat2 = p->m_saneAPI.sane_read_api(p->m_saneDev, p->m_buffer + readSize, p->m_bufferSize - readSize, &len);
readSize += len;
if (SANE_STATUS_GOOD != stat2)
{
break;
}
}
if (SANE_STATUS_GOOD == stat2)
{
// m_bufferSize空间不够
emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_NO_MEM)));
break;
}
else if (SANE_STATUS_EOF == stat2)
{
if (SANE_STATUS_GOOD != stat1 || 0 == readSize || readSize != params.bytes_per_line * params.lines)
{
emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_IO_ERROR)));
break;
}
}
else if (SANE_STATUS_CANCELLED == stat2)
{
break;
}
else
{
emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(stat2)));
break;
}
if (nullptr != p->m_imageCallback)
{
HGUInt imgType = 0;
if (params.format == SANE_FRAME_GRAY)
{
if (1 == params.depth)
imgType = HGBASE_IMGTYPE_BINARY;
else if (8 == params.depth)
imgType = HGBASE_IMGTYPE_GRAY;
}
else if (params.format == SANE_FRAME_RGB)
{
imgType = HGBASE_IMGTYPE_RGB;
}
HGImageInfo imgInfo = { (HGUInt)params.pixels_per_line, (HGUInt)params.lines,
imgType, (HGUInt)params.bytes_per_line, HGBASE_IMGORIGIN_TOP };
HGImage img = NULL;
HGBase_CreateImageWithData((HGByte*)p->m_buffer, &imgInfo, &img);
if (NULL != img)
{
p->m_imageCallback(img, p->m_imageParam);
p->imageCount(++imageCount);
HGBase_DestroyImage(img);
}
}
SANE_Status stat3 = p->m_saneAPI.sane_start_api(p->m_saneDev);
if (SANE_STATUS_NO_DOCS == stat3)
{
emit p->eventFunc(0, tr("Scan complete"));
break;
}
else if (SANE_STATUS_GOOD != stat3)
{
emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(stat3)));
break;
}
}
}