#include "dialog_device_scan.h" #include "ui_dialog_device_scan.h" #include "base/HGInc.h" #include #include #include 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(windowFlags() & ~Qt::WindowCloseButtonHint); 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)); ui->label_imgUploaded->setVisible(false); ui->lineEdit_imgUploaded->setVisible(false); ui->label_totalImgUploaded->setVisible(false); ui->lineEdit_imgUploaded->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(false); ui->label_imgUploaded->setVisible(false); ui->lineEdit_imgUploaded->setVisible(false); ui->label_totalImgUploaded->setVisible(true); ui->label_totalImgUploaded->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)); ui->lineEdit_imgUploaded->setText(QString::number(count)); } void Dialog_Device_Scan::startScan() { SANE_Parameters params; memset(¶ms, 0, sizeof(SANE_Parameters)); SANE_Status stat = m_saneAPI.sane_get_parameters_api(m_saneDev, ¶ms); 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_imgUploaded->setVisible(true); ui->lineEdit_imgUploaded->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(¶ms, 0, sizeof(SANE_Parameters)); SANE_Status stat1 = p->m_saneAPI.sane_get_parameters_api(p->m_saneDev, ¶ms); 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_INVAL))); break; } else if (SANE_STATUS_EOF == stat2) { if (0 == readSize) { emit p->eventFunc(0, tr("Scan complete")); break; } else if (SANE_STATUS_GOOD != stat1 || readSize != params.bytes_per_line * params.lines) { emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_INVAL))); 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); } } } }