#include "dialog_device_scan.hpp" #include "ui_dialog_device_scan.h" #include "base/HGInc.h" #include #include Dialog_Device_Scan::Dialog_Device_Scan(SANEAPI* saneApi, SANE_Handle dev, const char *devName, show_scan_ui_image_callback callback, void *callbackParam, QWidget *parent) : QDialog(parent), ui(new Ui::Dialog_Device_Scan) { ui->setupUi(this); memcpy(&m_saneAPI, saneApi, sizeof(SANEAPI)); m_saneDev = dev; m_callback = callback; m_callbackParam = callbackParam; m_buffer = NULL; m_bufferSize = 0; m_stopThread = HGFALSE; m_thread = NULL; setWindowTitle(QString::fromStdString(devName)); setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); qRegisterMetaType("SANE_Parameters"); qRegisterMetaType("SANE_Byte *"); connect(this, &Dialog_Device_Scan::eventFunc, this, &Dialog_Device_Scan::on_eventFunc, Qt::QueuedConnection); connect(this, &Dialog_Device_Scan::newImage, this, &Dialog_Device_Scan::on_newImage, Qt::QueuedConnection); ui->pushButton_Continue->setEnabled(true); ui->pushButton_Cancel->setEnabled(false); ui->pushButton_Complete->setEnabled(true); on_pushButton_Continue_clicked(); } Dialog_Device_Scan::~Dialog_Device_Scan() { delete ui; } void Dialog_Device_Scan::on_eventFunc(QString errInfo) { ui->listWidget->addItem(errInfo); ui->listWidget->scrollToBottom(); 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_Continue->setEnabled(true); ui->pushButton_Cancel->setEnabled(false); ui->pushButton_Complete->setEnabled(true); } void Dialog_Device_Scan::on_newImage(SANE_Parameters format, SANE_Byte *data) { if (NULL != m_callback) m_callback(&format, data, m_callbackParam); delete [] data; } void Dialog_Device_Scan::on_pushButton_Cancel_clicked() { m_saneAPI.sane_cancel_api(m_saneDev); } void Dialog_Device_Scan::on_pushButton_Complete_clicked() { accept(); } void Dialog_Device_Scan::on_pushButton_Continue_clicked() { 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 = 5000 * 4000; m_buffer = (HGByte *)malloc(m_bufferSize); if (NULL == m_buffer) { ui->listWidget->addItem(tr("Out of memory")); ui->listWidget->scrollToBottom(); return; } m_stopThread = HGFALSE; HGBase_OpenThread(ThreadFunc, this, &m_thread); ui->pushButton_Continue->setEnabled(false); ui->pushButton_Cancel->setEnabled(true); ui->pushButton_Complete->setEnabled(false); ui->listWidget->addItem(tr("Start scan")); ui->listWidget->scrollToBottom(); } void Dialog_Device_Scan::closeEvent(QCloseEvent *e) { if (NULL != 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(tr(p->m_saneAPI.sane_strstatus_api(stat))); return; } 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(tr(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_INVAL))); break; } else if (SANE_STATUS_EOF == stat2) { if (0 == readSize) { emit p->eventFunc(tr("Scan complete")); break; } else if (SANE_STATUS_GOOD != stat1 || readSize != params.bytes_per_line * params.lines) { emit p->eventFunc(tr(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_INVAL))); break; } } else if (SANE_STATUS_CANCELLED == stat2) { break; } else { emit p->eventFunc(tr(p->m_saneAPI.sane_strstatus_api(stat2))); break; } SANE_Byte *data = new HGByte [readSize]; memcpy(data, p->m_buffer, readSize); emit p->newImage(params, data); } }