#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_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; 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() { 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(¶ms, 0, sizeof(SANE_Parameters)); SANE_Status stat1 = p->m_saneAPI.sane_get_parameters_api(p->m_saneDev, ¶ms); if (SANE_STATUS_GOOD != stat1) { emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(stat1))); break; } HGUInt bufferSize = params.bytes_per_line * params.lines; HGByte *buffer = (HGByte *)malloc(bufferSize); if (NULL == buffer) { emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_NO_MEM))); break; } SANE_Int readSize = 0; SANE_Status stat2 = SANE_STATUS_GOOD; while (readSize < bufferSize) { SANE_Int len = 0; stat2 = p->m_saneAPI.sane_read_api(p->m_saneDev, buffer + readSize, bufferSize - readSize, &len); readSize += len; if (SANE_STATUS_GOOD != stat2) { break; } } if (SANE_STATUS_GOOD == stat2) { // bufferSize空间不够 free(buffer); emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_NO_MEM))); break; } else if (SANE_STATUS_EOF == stat2) { if (0 == readSize || readSize != params.bytes_per_line * params.lines) { free(buffer); emit p->eventFunc(-1, QString::fromUtf8(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_IO_ERROR))); break; } } else if (SANE_STATUS_CANCELLED == stat2) { free(buffer); break; } else { free(buffer); 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(buffer, &imgInfo, &img); if (NULL != img) { p->m_imageCallback(img, p->m_imageParam); p->imageCount(++imageCount); HGBase_DestroyImage(img); } } free(buffer); buffer = NULL; bufferSize = 0; 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; } } }