code_app/app/scantool/mainwindow.cpp

1525 lines
51 KiB
C++
Raw Normal View History

2024-04-23 09:44:22 +00:00
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCloseEvent>
2024-04-28 10:15:51 +00:00
#include <QMessageBox>
#include <QDateTime>
#include <QFileInfo>
#include "base/HGTime.h"
#include "base/HGUtility.h"
2024-05-07 08:09:36 +00:00
#include "base/HGBase64.h"
2024-05-22 08:34:09 +00:00
#include "base/HGCrash.h"
2024-04-28 10:15:51 +00:00
#include "imgproc/HGImgProc.h"
#include "imgproc/HGOCR.h"
#include "huagao/hgscanner_error.h"
2024-04-28 10:15:51 +00:00
#include "dialog_scaninfo.h"
#include "form_saveparam.h"
2024-04-30 09:16:13 +00:00
#include "sqlite3.h"
#include "cJSON.h"
#include "HGString.h"
2024-04-23 09:44:22 +00:00
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
2024-04-28 10:15:51 +00:00
, m_dlgAdd(nullptr)
, m_dlgScanInfo(nullptr)
, m_devHandle(nullptr)
, m_scanning(false)
, m_dpi(200)
, m_scanFileName("")
, m_scanImgFmtWriter(nullptr)
, m_ocrMsgPump(nullptr)
, m_ocrThread(nullptr)
, m_timerId(-1)
2024-04-23 09:44:22 +00:00
{
ui->setupUi(this);
2024-05-05 01:46:50 +00:00
this->setWindowIcon(QIcon(":images/image_rsc/png/logo.png"));
2024-04-23 09:44:22 +00:00
2024-05-22 08:34:09 +00:00
HGBase_RegisterCrashFunc(CrashFunc, this);
ui->pushButtonScan->setEnabled(false);
ui->pushButtonAdd->setEnabled(false);
ui->pushButtonModify->setEnabled(false);
2024-04-23 09:44:22 +00:00
m_trayIcon = new QSystemTrayIcon(this);
m_trayIcon->setIcon(QIcon(":images/image_rsc/png/logo.png"));
m_trayIcon->show();
2024-04-28 10:15:51 +00:00
m_trayIcon->setToolTip(tr("Scan Tool"));
2024-04-23 09:44:22 +00:00
qRegisterMetaType<QSystemTrayIcon::ActivationReason>("QSystemTrayIcon::ActivationReason");
connect(m_trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::on_trayActivated);
2024-04-28 10:15:51 +00:00
m_showAction = new QAction(tr("Show"), this);
connect(m_showAction, &QAction::triggered, this, &MainWindow::on_showMainWindowDlg);
2024-04-23 09:44:22 +00:00
m_quitAction = new QAction(tr("Exit"), this);
connect(m_quitAction, &QAction::triggered, this, &QCoreApplication::quit); //应用程序的退出
//创建菜单,添加菜单项
m_trayIconMenu = new QMenu(this);
2024-04-28 10:15:51 +00:00
m_trayIconMenu->addAction(m_showAction);
m_trayIconMenu->addSeparator(); //分割线
m_trayIconMenu->addAction(m_quitAction);
2024-04-23 09:44:22 +00:00
//给系统托盘添加右键菜单
m_trayIcon->setContextMenu(m_trayIconMenu);
2024-04-24 06:57:44 +00:00
ui->tableWidget->setColumnCount(4);
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableWidget->setStyleSheet("selection-background-color:rgb(0, 120, 215)");
ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableWidget->horizontalHeader()->setFixedHeight(40);
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
2024-05-10 08:48:21 +00:00
ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Device Type")));
ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Button Id")));
ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Device Config")));
ui->tableWidget->setHorizontalHeaderItem(3, new QTableWidgetItem(tr("Save Param")));
ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
ui->tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
2024-04-24 06:57:44 +00:00
ui->tableWidget->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
2024-04-26 09:27:47 +00:00
LoadCfg();
2024-04-24 06:57:44 +00:00
ui->tableWidget->setRowCount((int)m_vScanParams.size());
for (int index = 0; index < (int)m_vScanParams.size(); ++index)
{
ui->tableWidget->setRowHeight(index, 30);
ui->tableWidget->setItem(index, 0, new QTableWidgetItem(QString(m_vScanParams[index].deviceType.c_str())));
2024-04-24 06:57:44 +00:00
ui->tableWidget->item(index, 0)->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->item(index, 0)->setFlags(ui->tableWidget->item(index, 0)->flags() & ~Qt::ItemIsEditable);
QStringList btnTypeStr = {tr("Manual"), tr("Button 1"), tr("Button 2"), tr("Button 3"), tr("Button 4"), tr("Button 5")};
2024-04-26 05:15:43 +00:00
ui->tableWidget->setItem(index, 1, new QTableWidgetItem(btnTypeStr[m_vScanParams[index].buttonId]));
2024-04-24 06:57:44 +00:00
ui->tableWidget->item(index, 1)->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->item(index, 1)->setFlags(ui->tableWidget->item(index, 1)->flags() & ~Qt::ItemIsEditable);
ui->tableWidget->setItem(index, 2, new QTableWidgetItem(GetDesc(m_vScanParams[index].deviceConfigs)));
2024-04-24 06:57:44 +00:00
ui->tableWidget->item(index, 2)->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->item(index, 2)->setFlags(ui->tableWidget->item(index, 2)->flags() & ~Qt::ItemIsEditable);
ui->tableWidget->setItem(index, 3, new QTableWidgetItem(GetDesc(m_vScanParams[index].saveParam)));
ui->tableWidget->item(index, 3)->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->item(index, 3)->setFlags(ui->tableWidget->item(index, 3)->flags() & ~Qt::ItemIsEditable);
}
ui->tableWidget->selectRow(0);
2024-04-28 10:15:51 +00:00
m_dlgScanInfo = new Dialog_ScanInfo(this);
connect(this, SIGNAL(deviceArrive(QString)), this, SLOT(on_deviceArrive(QString)), Qt::QueuedConnection);
connect(this, SIGNAL(deviceRemove(QString)), this, SLOT(on_deviceRemove(QString)), Qt::QueuedConnection);
connect(this, SIGNAL(keyPress(unsigned int)), this, SLOT(on_keyPress(unsigned int)), Qt::QueuedConnection);
connect(this, SIGNAL(scanWorking()), this, SLOT(on_scanWorking()), Qt::QueuedConnection);
connect(this, SIGNAL(scanInfo(QString, bool)), this, SLOT(on_scanInfo(QString, bool)), Qt::QueuedConnection);
2024-04-28 10:15:51 +00:00
connect(this, SIGNAL(scanImage(unsigned int)), this, SLOT(on_scanImage(unsigned int)));
connect(this, SIGNAL(scanFinish()), this, SLOT(on_scanFinish()), Qt::QueuedConnection);
connect(this, SIGNAL(saneEventCloseDevice(void*, bool)), this, SLOT(on_saneEventCloseDevice(void*, bool)), Qt::QueuedConnection);
2024-04-28 10:15:51 +00:00
SANE_Int version_code = 0;
sane_init_ex(&version_code, sane_ex_callback, this);
2024-04-23 09:44:22 +00:00
}
MainWindow::~MainWindow()
{
2024-04-28 10:15:51 +00:00
assert(nullptr == m_dlgAdd);
if (NULL != m_devHandle)
{
StopScan();
sane_close(m_devHandle);
m_devHandle = NULL;
m_devName.clear();
}
sane_exit();
delete m_dlgScanInfo;
2024-04-23 09:44:22 +00:00
delete ui;
}
2024-04-28 10:15:51 +00:00
bool MainWindow::FindScanParam(const std::string &deviceType, unsigned int buttonId, int ignoreIndex)
2024-04-26 09:27:47 +00:00
{
2024-04-28 10:15:51 +00:00
for (int i = 0; i < (int)m_vScanParams.size(); ++i)
{
if (deviceType == m_vScanParams[i].deviceType && buttonId == m_vScanParams[i].buttonId)
{
if (-1 == ignoreIndex) // 表示均不忽略
{
return true;
}
else if (i != ignoreIndex)
{
return true;
}
}
}
return false;
2024-04-26 09:27:47 +00:00
}
2024-04-28 10:15:51 +00:00
void MainWindow::StopScan()
{
2024-04-28 10:15:51 +00:00
if (m_scanning)
{
assert(NULL != m_devHandle);
sane_cancel(m_devHandle);
m_scanning = false;
m_quitAction->setEnabled(true);
ui->pushButtonAdd->setEnabled(true);
ui->pushButtonModify->setEnabled(true);
ui->pushButtonRemove->setEnabled(true);
ui->comboBox->setEnabled(true);
ui->pushButtonScan->setEnabled(true);
m_dpi = 200;
}
}
2024-04-30 09:16:13 +00:00
std::vector<DeviceConfig> MainWindow::MakeDeviceConfigs(const std::string &str)
{
std::vector<DeviceConfig> deviceConfigs;
cJSON* json = cJSON_Parse(str.c_str());
if (NULL != json)
{
cJSON* p = json->child;
while (NULL != p)
{
if (0 != strcmp(p->string, "device_configs"))
{
p = p->next;
continue;
}
if (p->type != cJSON_Array)
{
break;
}
cJSON* pEx = p->child;
while (NULL != pEx)
{
if (pEx->type != cJSON_Object)
{
pEx = pEx->next;
continue;
}
std::string name;
int valueType = 0;
std::string stringValue;
int intValue = 0;
double doubleValue = 0;
bool boolValue = false;
cJSON* pEx2 = pEx->child;
while (NULL != pEx2)
{
if (0 == strcmp(pEx2->string, "name") && pEx2->type == cJSON_String)
{
name = pEx2->valuestring;
}
else if (0 == strcmp(pEx2->string, "value"))
{
if (pEx2->type == cJSON_String)
{
stringValue = pEx2->valuestring;
}
else if (pEx2->type == cJSON_Number)
{
intValue = pEx2->valueint;
doubleValue = pEx2->valuedouble;
}
else if (pEx2->type == cJSON_True)
{
boolValue = true;
}
else if (pEx2->type == cJSON_False)
{
boolValue = false;
}
}
else if (0 == strcmp(pEx2->string, "value_type") && pEx2->type == cJSON_Number)
{
valueType = pEx2->valueint;
}
pEx2 = pEx2->next;
}
DeviceConfig deviceConfig;
deviceConfig.name = name;
deviceConfig.valueType = valueType;
if (1 == deviceConfig.valueType)
deviceConfig.stringValue = stringValue;
else if (2 == deviceConfig.valueType)
deviceConfig.intValue = intValue;
else if (3 == deviceConfig.valueType)
deviceConfig.doubleValue = doubleValue;
else if (4 == deviceConfig.valueType)
deviceConfig.boolValue = boolValue;
2024-05-07 08:09:36 +00:00
else if (5 == deviceConfig.valueType)
{
HGSize length = 0;
HGBase_Base64Decode((const HGByte*)stringValue.c_str(), stringValue.size(), NULL, &length);
if (length == sizeof(SANE_Gamma))
{
HGBase_Base64Decode((const HGByte*)stringValue.c_str(), stringValue.size(), (HGByte*)&deviceConfig.gammaValue, &length);
}
}
2024-04-30 09:16:13 +00:00
deviceConfigs.push_back(deviceConfig);
pEx = pEx->next;
}
break;
}
cJSON_Delete(json);
}
return deviceConfigs;
}
std::string MainWindow::GetDeviceConfigsStr(const std::vector<DeviceConfig> &deviceConfigs)
{
std::string str;
cJSON* json = cJSON_CreateObject();
if (NULL != json)
{
cJSON* array = cJSON_CreateArray();
for (int i = 0; i < deviceConfigs.size(); ++i)
{
cJSON* obj = cJSON_CreateObject();
cJSON_AddItemToObject(obj, "name", cJSON_CreateString(deviceConfigs[i].name.c_str()));
cJSON_AddItemToObject(obj, "value_type", cJSON_CreateNumber(deviceConfigs[i].valueType));
if (1 == deviceConfigs[i].valueType)
{
cJSON_AddItemToObject(obj, "value", cJSON_CreateString(deviceConfigs[i].stringValue.c_str()));
}
else if (2 == deviceConfigs[i].valueType)
{
cJSON_AddItemToObject(obj, "value", cJSON_CreateNumber(deviceConfigs[i].intValue));
}
else if (3 == deviceConfigs[i].valueType)
{
cJSON_AddItemToObject(obj, "value", cJSON_CreateNumber(deviceConfigs[i].doubleValue));
}
else if (4 == deviceConfigs[i].valueType)
{
cJSON_AddItemToObject(obj, "value", deviceConfigs[i].boolValue ? cJSON_CreateTrue() : cJSON_CreateFalse());
}
2024-05-07 08:09:36 +00:00
else if (5 == deviceConfigs[i].valueType)
{
HGSize base64Size = 0;
HGBase_Base64Encode((const HGByte*)&deviceConfigs[i].gammaValue, sizeof(SANE_Gamma), nullptr, &base64Size);
char *base64 = (char *)malloc(base64Size + 1);
HGBase_Base64Encode((const HGByte*)&deviceConfigs[i].gammaValue, sizeof(SANE_Gamma), (HGByte*)base64, &base64Size);
base64[base64Size] = 0;
cJSON_AddItemToObject(obj, "value", cJSON_CreateString(base64));
free(base64);
}
2024-04-30 09:16:13 +00:00
cJSON_AddItemToArray(array, obj);
}
cJSON_AddItemToObject(json, "device_configs", array);
char* resp = cJSON_Print(json);
if (NULL != resp)
{
str = resp;
free(resp);
}
cJSON_Delete(json);
}
return str;
}
SaveParam MainWindow::MakeSaveParam(const std::string &str)
{
SaveParam saveParam = Form_SaveParam::GetDefSaveParam();
cJSON* json = cJSON_Parse(str.c_str());
if (NULL != json)
{
cJSON* p = json->child;
while (NULL != p)
{
if (0 != strcmp(p->string, "save_param"))
{
p = p->next;
continue;
}
if (p->type != cJSON_Object)
{
break;
}
cJSON* pEx = p->child;
while (NULL != pEx)
{
if (0 == strcmp(pEx->string, "save_path") && pEx->type == cJSON_String)
{
saveParam.savePath = Utf8ToStdString(pEx->valuestring);
}
else if (0 == strcmp(pEx->string, "use_subfolder_by_time") && pEx->type == cJSON_True)
{
saveParam.isUseSubfolderByTime = true;
}
else if (0 == strcmp(pEx->string, "use_subfolder_by_time") && pEx->type == cJSON_False)
{
saveParam.isUseSubfolderByTime = false;
}
else if (0 == strcmp(pEx->string, "use_subfolder_by_blank_pages") && pEx->type == cJSON_True)
{
saveParam.isUseSubfolderByBlankPages = true;
}
else if (0 == strcmp(pEx->string, "use_subfolder_by_blank_pages") && pEx->type == cJSON_False)
{
saveParam.isUseSubfolderByBlankPages = false;
}
else if (0 == strcmp(pEx->string, "use_subfolder_by_color") && pEx->type == cJSON_True)
{
saveParam.isUseSubfolderByColor = true;
}
else if (0 == strcmp(pEx->string, "use_subfolder_by_color") && pEx->type == cJSON_False)
{
saveParam.isUseSubfolderByColor = false;
}
else if (0 == strcmp(pEx->string, "jpeg_quality") && pEx->type == cJSON_Number)
{
saveParam.jpegQuality = pEx->valueint;
}
else if (0 == strcmp(pEx->string, "tiff_compression_bw") && pEx->type == cJSON_Number)
{
saveParam.tiffCompressionBW = pEx->valueint;
}
else if (0 == strcmp(pEx->string, "tiff_compression") && pEx->type == cJSON_Number)
{
saveParam.tiffCompression = pEx->valueint;
}
else if (0 == strcmp(pEx->string, "tiff_quality") && pEx->type == cJSON_Number)
{
saveParam.tiffQuality = pEx->valueint;
}
else if (0 == strcmp(pEx->string, "filename_prefix") && pEx->type == cJSON_String)
{
saveParam.fileNamePrefix = Utf8ToStdString(pEx->valuestring);
}
else if (0 == strcmp(pEx->string, "filename_start_index") && pEx->type == cJSON_Number)
{
saveParam.fileNameStartIndex = pEx->valueint;
}
else if (0 == strcmp(pEx->string, "filename_digits") && pEx->type == cJSON_Number)
{
saveParam.fileNameDigits = pEx->valueint;
}
else if (0 == strcmp(pEx->string, "filename_odd_even_type") && pEx->type == cJSON_Number)
{
saveParam.fileNameOddEvenType = pEx->valueint;
}
else if (0 == strcmp(pEx->string, "filename_ext") && pEx->type == cJSON_String)
{
saveParam.fileNameExt = Utf8ToStdString(pEx->valuestring);
}
else if (0 == strcmp(pEx->string, "ocr") && pEx->type == cJSON_True)
{
saveParam.isOcr = true;
}
else if (0 == strcmp(pEx->string, "ocr") && pEx->type == cJSON_False)
{
saveParam.isOcr = false;
}
else if (0 == strcmp(pEx->string, "save_as_multi_page") && pEx->type == cJSON_True)
{
saveParam.isSaveAsMultiPage = true;
}
else if (0 == strcmp(pEx->string, "save_as_multi_page") && pEx->type == cJSON_False)
{
saveParam.isSaveAsMultiPage = false;
}
else if (0 == strcmp(pEx->string, "multi_pages_type") && pEx->type == cJSON_Number)
{
saveParam.multiPagesType = pEx->valueint;
}
else if (0 == strcmp(pEx->string, "custom_multi_pages") && pEx->type == cJSON_Number)
{
saveParam.customMultiPages = pEx->valueint;
}
pEx = pEx->next;
}
break;
}
cJSON_Delete(json);
}
return saveParam;
}
std::string MainWindow::GetSaveParamStr(const SaveParam &saveParam)
{
std::string str;
cJSON* json = cJSON_CreateObject();
if (NULL != json)
{
cJSON* obj = cJSON_CreateObject();
cJSON_AddItemToObject(obj, "save_path", cJSON_CreateString(StdStringToUtf8(saveParam.savePath).c_str()));
cJSON_AddItemToObject(obj, "use_subfolder_by_time", saveParam.isUseSubfolderByTime ? cJSON_CreateTrue() : cJSON_CreateFalse());
cJSON_AddItemToObject(obj, "use_subfolder_by_blank_pages", saveParam.isUseSubfolderByBlankPages ? cJSON_CreateTrue() : cJSON_CreateFalse());
cJSON_AddItemToObject(obj, "use_subfolder_by_color", saveParam.isUseSubfolderByColor ? cJSON_CreateTrue() : cJSON_CreateFalse());
cJSON_AddItemToObject(obj, "jpeg_quality", cJSON_CreateNumber(saveParam.jpegQuality));
cJSON_AddItemToObject(obj, "tiff_compression_bw", cJSON_CreateNumber(saveParam.tiffCompressionBW));
cJSON_AddItemToObject(obj, "tiff_compression", cJSON_CreateNumber(saveParam.tiffCompression));
cJSON_AddItemToObject(obj, "tiff_quality", cJSON_CreateNumber(saveParam.tiffQuality));
cJSON_AddItemToObject(obj, "filename_prefix", cJSON_CreateString(StdStringToUtf8(saveParam.fileNamePrefix).c_str()));
cJSON_AddItemToObject(obj, "filename_start_index", cJSON_CreateNumber(saveParam.fileNameStartIndex));
cJSON_AddItemToObject(obj, "filename_digits", cJSON_CreateNumber(saveParam.fileNameDigits));
cJSON_AddItemToObject(obj, "filename_odd_even_type", cJSON_CreateNumber(saveParam.fileNameOddEvenType));
cJSON_AddItemToObject(obj, "filename_ext", cJSON_CreateString(StdStringToUtf8(saveParam.fileNameExt).c_str()));
cJSON_AddItemToObject(obj, "ocr", saveParam.isOcr ? cJSON_CreateTrue() : cJSON_CreateFalse());
cJSON_AddItemToObject(obj, "save_as_multi_page", saveParam.isSaveAsMultiPage ? cJSON_CreateTrue() : cJSON_CreateFalse());
cJSON_AddItemToObject(obj, "multi_pages_type", cJSON_CreateNumber(saveParam.multiPagesType));
cJSON_AddItemToObject(obj, "custom_multi_pages", cJSON_CreateNumber(saveParam.customMultiPages));
cJSON_AddItemToObject(json, "save_param", obj);
char* resp = cJSON_Print(json);
if (NULL != resp)
{
str = resp;
free(resp);
}
cJSON_Delete(json);
}
return str;
}
2024-04-28 10:15:51 +00:00
void MainWindow::LoadCfg()
{
2024-04-30 09:16:13 +00:00
m_vScanParams.clear();
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
char dbPath[256];
sprintf(dbPath, "%s%s", cfgPath, "config.db");
sqlite3 *sqlite = nullptr;
sqlite3_open_v2(dbPath, &sqlite, SQLITE_OPEN_READONLY | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
if (NULL == sqlite)
{
return;
}
sqlite3_stmt* stmt = NULL;
char sql[256];
sprintf(sql, "select * from scan_params");
int ret = sqlite3_prepare(sqlite, sql, -1, &stmt, NULL);
if (0 != ret)
{
sqlite3_close(sqlite);
return;
}
ret = sqlite3_step(stmt);
while (SQLITE_ROW == ret)
{
int id = sqlite3_column_int(stmt, 0);
const char* deviceType = (const char*)sqlite3_column_text(stmt, 1);
int buttonId = sqlite3_column_int(stmt, 2);
const char* deviceConfigs = (const char*)sqlite3_column_text(stmt, 3);
const char* saveParam = (const char*)sqlite3_column_text(stmt, 4);
ScanParam scanParam;
scanParam.deviceType = deviceType;
scanParam.buttonId = buttonId;
scanParam.deviceConfigs = MakeDeviceConfigs(deviceConfigs);
scanParam.saveParam = MakeSaveParam(saveParam);
m_vScanParams.push_back(scanParam);
ret = sqlite3_step(stmt);
}
ret = sqlite3_finalize(stmt);
assert(0 == ret);
sqlite3_close(sqlite);
2024-04-28 10:15:51 +00:00
}
void MainWindow::SaveCfg()
{
2024-04-30 09:16:13 +00:00
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
HGBase_CreateDir(cfgPath);
char dbPath[256];
sprintf(dbPath, "%s%s", cfgPath, "config.db");
HGBase_DeleteFile(dbPath);
sqlite3 *sqlite = nullptr;
sqlite3_open_v2(dbPath, &sqlite, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
if (NULL == sqlite)
{
return;
}
int ret = sqlite3_exec(sqlite, "create table scan_params (id integer primary key autoincrement, device_type text, "
"button_id integer, device_configs text, save_param text)", NULL, NULL, NULL);
if (0 != ret)
{
sqlite3_close(sqlite);
return;
}
for (int i = 0; i < (int)m_vScanParams.size(); ++i)
{
std::string deviceConfigsStr = GetDeviceConfigsStr(m_vScanParams[i].deviceConfigs);
std::string saveParamStr = GetSaveParamStr(m_vScanParams[i].saveParam);
char *sql = new char [1024 + deviceConfigsStr.size() + saveParamStr.size()];
sprintf(sql, "insert into scan_params (device_type, button_id, device_configs, save_param) values ('%s', '%d', '%s', '%s')",
m_vScanParams[i].deviceType.c_str(), m_vScanParams[i].buttonId, deviceConfigsStr.c_str(), saveParamStr.c_str());
sqlite3_exec(sqlite, sql, NULL, NULL, NULL);
}
sqlite3_close(sqlite);
2024-04-28 10:15:51 +00:00
}
QString MainWindow::GetDesc(const std::vector<DeviceConfig> &deviceConfigs)
{
2024-04-30 09:16:13 +00:00
QString desc = "-";
2024-04-28 10:15:51 +00:00
return desc;
}
QString MainWindow::GetDesc(const SaveParam &saveParam)
{
2024-04-30 09:16:13 +00:00
QString desc = "-";
2024-04-28 10:15:51 +00:00
return desc;
}
void MainWindow::StartScan(unsigned int buttonId)
{
if (nullptr == m_devHandle)
{
QMessageBox::information(this, tr("Tips"), tr("Device is offline"));
return;
}
if (m_scanning || nullptr != m_dlgAdd)
{
return;
}
std::string deviceType = m_devName.toStdString();
char v[256] = {0};
SANE_Status status = sane_control_option(m_devHandle, (SANE_Int)0x886D, SANE_ACTION_GET_VALUE, v, NULL);
if (SANE_STATUS_GOOD == status)
{
deviceType = v;
}
ScanParam scanParam;
bool find = false;
for (int i = 0; i < (int)m_vScanParams.size(); ++i)
{
if (deviceType == m_vScanParams[i].deviceType && buttonId == m_vScanParams[i].buttonId)
{
scanParam = m_vScanParams[i];
find = true;
}
}
if (!find)
{
Show();
ShowAddDialog(buttonId);
return;
}
2024-04-28 10:15:51 +00:00
// 1.恢复默认
SANE_Int num_dev_options = 0;
sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
for (int i = 1; i < num_dev_options; ++i)
{
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i);
if (NULL == desp)
continue;
const char* name = desp->name;
while (' ' == *name)
++name;
if (0 == strcmp(SANE_STD_OPT_NAME_RESTORE, name) && SANE_TYPE_BUTTON == desp->type)
{
sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, NULL, NULL);
break;
}
}
// 2.设置新的属性
for (int i = 0; i < (int)scanParam.deviceConfigs.size(); ++i)
{
if (5 == scanParam.deviceConfigs[i].valueType)
{
sane_control_option(m_devHandle, SANE_OPT_ID_CUSTOM_GAMMA, SANE_ACTION_SET_VALUE, &scanParam.deviceConfigs[i].gammaValue, NULL);
continue;
}
2024-04-28 10:15:51 +00:00
for (int j = 1; j < num_dev_options; ++j)
{
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, j);
if (NULL == desp)
continue;
const char* name = desp->name;
while (' ' == *name)
++name;
if (0 == strcmp(scanParam.deviceConfigs[i].name.c_str(), name))
{
if (SANE_TYPE_STRING == desp->type)
{
sane_control_option(m_devHandle, j, SANE_ACTION_SET_VALUE, (void*)scanParam.deviceConfigs[i].stringValue.c_str(), NULL);
}
else if (SANE_TYPE_INT == desp->type)
{
SANE_Int value = scanParam.deviceConfigs[i].intValue;
sane_control_option(m_devHandle, j, SANE_ACTION_SET_VALUE, &value, NULL);
}
else if (SANE_TYPE_FIXED == desp->type)
{
SANE_Fixed value = SANE_FIX(scanParam.deviceConfigs[i].doubleValue);
sane_control_option(m_devHandle, j, SANE_ACTION_SET_VALUE, &value, NULL);
}
else if (SANE_TYPE_BOOL == desp->type)
{
SANE_Bool value = (SANE_Bool)scanParam.deviceConfigs[i].boolValue;
sane_control_option(m_devHandle, j, SANE_ACTION_SET_VALUE, &value, NULL);
}
break;
}
}
}
// 3. 获取DPI
for (int i = 1; i < num_dev_options; ++i)
{
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i);
if (nullptr == desp)
continue;
if (SANE_TYPE_INT == desp->type)
{
SANE_Int value = 0;
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, nullptr);
if (0 == strcmp(desp->name, SANE_STD_OPT_NAME_RESOLUTION))
{
m_dpi = (HGUInt)value;
}
}
}
// 4.保存配置
assert(m_scanFileName.isEmpty());
assert(nullptr == m_scanImgFmtWriter);
m_aquireIntoSaveParam = scanParam.saveParam;
m_aquireIntoInBlank = true;
m_aquireIntoBatchStartIndex = 0;
m_aquireIntoPageIndex = 0;
m_aquireIntoMultiPageCount = 0;
QDateTime dateTime = QDateTime::currentDateTime();
2024-04-30 09:16:13 +00:00
if (m_aquireIntoSaveParam.isUseSubfolderByTime)
2024-04-28 10:15:51 +00:00
{
2024-04-30 09:16:13 +00:00
#ifdef HG_CMP_MSC
std::string newPath = m_aquireIntoSaveParam.savePath + dateTime.toString("yyyy-MM-dd").toStdString() + "\\";
#else
std::string newPath = m_aquireIntoSaveParam.savePath + dateTime.toString("yyyy-MM-dd").toStdString() + "/";
#endif
m_aquireIntoSaveParam.savePath = newPath;
2024-04-28 10:15:51 +00:00
}
2024-04-30 09:16:13 +00:00
if (m_aquireIntoSaveParam.isOcr)
2024-04-28 10:15:51 +00:00
{
HGBase_CreateMsgPump(&m_ocrMsgPump);
HGBase_OpenThread(ocrThreadFunc, this, &m_ocrThread);
}
m_scanning = true;
m_quitAction->setEnabled(false);
ui->pushButtonAdd->setEnabled(false);
ui->pushButtonModify->setEnabled(false);
ui->pushButtonRemove->setEnabled(false);
ui->comboBox->setEnabled(false);
ui->pushButtonScan->setEnabled(false);
status = sane_start(m_devHandle);
if (SANE_STATUS_GOOD != status)
{
if (NULL != m_ocrMsgPump)
{
HGBase_ExitMsgPump(m_ocrMsgPump);
HGBase_CloseThread(m_ocrThread);
m_ocrThread = NULL;
HGBase_DestroyMsgPump(m_ocrMsgPump);
m_ocrMsgPump = NULL;
}
m_scanning = false;
m_quitAction->setEnabled(true);
ui->pushButtonAdd->setEnabled(true);
ui->pushButtonModify->setEnabled(true);
ui->pushButtonRemove->setEnabled(true);
ui->comboBox->setEnabled(true);
ui->pushButtonScan->setEnabled(true);
m_dpi = 200;
emit scanWorking();
emit scanInfo((const char*)sane_strstatus(status), true);
emit scanFinish();
return;
}
}
void MainWindow::SaveImage(HGImage image)
2024-04-24 06:57:44 +00:00
{
2024-04-30 09:16:13 +00:00
if (m_aquireIntoSaveParam.isSaveAsMultiPage)
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
if (nullptr == m_scanImgFmtWriter)
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
assert(m_scanFileName.isEmpty());
2024-04-30 09:16:13 +00:00
HGBase_CreateDir(m_aquireIntoSaveParam.savePath.c_str());
2024-04-28 10:15:51 +00:00
QString scanFileName;
while (1)
{
2024-04-30 09:16:13 +00:00
scanFileName = QString::fromLocal8Bit(m_aquireIntoSaveParam.savePath.c_str()) + QString::fromLocal8Bit(m_aquireIntoSaveParam.fileNamePrefix.c_str())
+ QString("%1.%2").arg(m_aquireIntoSaveParam.fileNameStartIndex, m_aquireIntoSaveParam.fileNameDigits, 10, QLatin1Char('0'))
.arg(QString::fromLocal8Bit(m_aquireIntoSaveParam.fileNameExt.c_str()));
2024-04-28 10:15:51 +00:00
QFileInfo fileInfo(scanFileName);
if (fileInfo.isFile())
{
2024-04-30 09:16:13 +00:00
++m_aquireIntoSaveParam.fileNameStartIndex;
2024-04-28 10:15:51 +00:00
}
else
{
break;
}
}
HGUInt fmtType = 0;
if (nullptr != m_ocrMsgPump)
{
fmtType = HGIMGFMT_TYPE_TIFF;
}
2024-04-30 09:16:13 +00:00
HGImgFmt_OpenImageWriter(scanFileName.toLocal8Bit().toStdString().c_str(), fmtType, &m_scanImgFmtWriter);
2024-04-28 10:15:51 +00:00
if (nullptr != m_scanImgFmtWriter)
{
m_scanFileName = scanFileName;
}
}
if (nullptr != m_scanImgFmtWriter)
{
HGImgFmtSaveInfo saveInfo;
2024-04-30 09:16:13 +00:00
saveInfo.jpegQuality = (HGUInt)m_aquireIntoSaveParam.jpegQuality;
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_NONE;
2024-04-30 09:16:13 +00:00
saveInfo.tiffJpegQuality = (HGUInt)m_aquireIntoSaveParam.tiffQuality;
2024-04-28 10:15:51 +00:00
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
if (HGBASE_IMGTYPE_BINARY == imgInfo.type)
{
2024-04-30 09:16:13 +00:00
if (1 == m_aquireIntoSaveParam.tiffCompressionBW)
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_LZW;
2024-04-30 09:16:13 +00:00
else if (2 == m_aquireIntoSaveParam.tiffCompressionBW)
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_CCITTFAX4;
}
else
{
2024-04-30 09:16:13 +00:00
if (1 == m_aquireIntoSaveParam.tiffCompression)
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_LZW;
2024-04-30 09:16:13 +00:00
else if (2 == m_aquireIntoSaveParam.tiffCompression)
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_JPEG;
}
if (nullptr != m_ocrMsgPump)
{
saveInfo.jpegQuality = 100;
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_NONE;
saveInfo.tiffJpegQuality = 100;
}
if (HGBASE_ERR_OK == HGImgFmt_SaveImageToWriter(m_scanImgFmtWriter, image, &saveInfo))
{
++m_aquireIntoMultiPageCount;
2024-04-30 09:16:13 +00:00
if (1 == m_aquireIntoSaveParam.multiPagesType && m_aquireIntoMultiPageCount == m_aquireIntoSaveParam.customMultiPages)
2024-04-28 10:15:51 +00:00
{
HGImgFmt_CloseImageWriter(m_scanImgFmtWriter);
m_scanImgFmtWriter = nullptr;
if (nullptr != m_ocrMsgPump)
{
QString *filePath = new QString(m_scanFileName);
HGMsg msg;
msg.id = 1;
msg.data = filePath;
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(m_ocrMsgPump, &msg))
{
delete filePath;
}
}
m_scanFileName.clear();
2024-04-30 09:16:13 +00:00
++m_aquireIntoSaveParam.fileNameStartIndex;
2024-04-28 10:15:51 +00:00
m_aquireIntoMultiPageCount = 0;
}
}
2024-04-24 06:57:44 +00:00
}
}
2024-04-28 10:15:51 +00:00
else
{
assert(nullptr == m_scanImgFmtWriter);
2024-04-24 06:57:44 +00:00
2024-04-30 09:16:13 +00:00
QString savePath = QString::fromLocal8Bit(m_aquireIntoSaveParam.savePath.c_str());
if (m_aquireIntoSaveParam.isUseSubfolderByBlankPages)
2024-04-28 10:15:51 +00:00
{
HGBool isBlank = HGFALSE;
HGImgProc_ImageBlankCheck(image, nullptr, &isBlank);
if (isBlank)
{
m_aquireIntoInBlank = true;
}
else
{
if (m_aquireIntoInBlank)
{
++m_aquireIntoBatchStartIndex;
}
m_aquireIntoInBlank = false;
}
char batchDir[20];
sprintf(batchDir, "batch%d", m_aquireIntoBatchStartIndex);
2024-04-30 09:16:13 +00:00
#ifdef HG_CMP_MSC
savePath = savePath + batchDir + "\\";
#else
savePath = savePath + batchDir + "/";
#endif
2024-04-28 10:15:51 +00:00
}
2024-04-30 09:16:13 +00:00
if (m_aquireIntoSaveParam.isUseSubfolderByColor)
2024-04-28 10:15:51 +00:00
{
QString colorModeName;
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
if (HGBASE_IMGTYPE_BINARY == imgInfo.type)
colorModeName = tr("binary");
else if (HGBASE_IMGTYPE_GRAY == imgInfo.type)
colorModeName = tr("gray");
else
colorModeName = tr("rgb");
2024-04-30 09:16:13 +00:00
#ifdef HG_CMP_MSC
savePath = savePath + colorModeName + "\\";
#else
savePath = savePath + colorModeName + "/";
#endif
2024-04-28 10:15:51 +00:00
}
2024-04-30 09:16:13 +00:00
HGBase_CreateDir(savePath.toLocal8Bit().toStdString().c_str());
2024-04-28 10:15:51 +00:00
while (1)
{
2024-04-30 09:16:13 +00:00
m_scanFileName = savePath + QString::fromLocal8Bit(m_aquireIntoSaveParam.fileNamePrefix.c_str()) + QString("%1.%2")
.arg(m_aquireIntoSaveParam.fileNameStartIndex, m_aquireIntoSaveParam.fileNameDigits, 10, QLatin1Char('0'))
.arg(QString::fromLocal8Bit(m_aquireIntoSaveParam.fileNameExt.c_str()));
2024-04-28 10:15:51 +00:00
QFileInfo fileInfo(m_scanFileName);
if (fileInfo.isFile())
{
2024-04-30 09:16:13 +00:00
++m_aquireIntoSaveParam.fileNameStartIndex;
2024-04-28 10:15:51 +00:00
}
else
{
break;
}
}
HGImgFmtSaveInfo saveInfo;
2024-04-30 09:16:13 +00:00
saveInfo.jpegQuality = (HGUInt)m_aquireIntoSaveParam.jpegQuality;
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_NONE;
2024-04-30 09:16:13 +00:00
saveInfo.tiffJpegQuality = (HGUInt)m_aquireIntoSaveParam.tiffQuality;
2024-04-28 10:15:51 +00:00
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
if (HGBASE_IMGTYPE_BINARY == imgInfo.type)
{
2024-04-30 09:16:13 +00:00
if (1 == m_aquireIntoSaveParam.tiffCompressionBW)
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_LZW;
2024-04-30 09:16:13 +00:00
else if (2 == m_aquireIntoSaveParam.tiffCompressionBW)
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_CCITTFAX4;
}
else
{
2024-04-30 09:16:13 +00:00
if (1 == m_aquireIntoSaveParam.tiffCompression)
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_LZW;
2024-04-30 09:16:13 +00:00
else if (2 == m_aquireIntoSaveParam.tiffCompression)
2024-04-28 10:15:51 +00:00
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_JPEG;
}
HGUInt fmtType = 0;
if (nullptr != m_ocrMsgPump)
{
fmtType = HGIMGFMT_TYPE_TIFF;
saveInfo.jpegQuality = 100;
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_NONE;
saveInfo.tiffJpegQuality = 100;
}
2024-04-30 09:16:13 +00:00
if (HGBASE_ERR_OK == HGImgFmt_SaveImage(image, fmtType, &saveInfo, m_scanFileName.toLocal8Bit().toStdString().c_str()))
2024-04-28 10:15:51 +00:00
{
if (nullptr != m_ocrMsgPump)
{
QString *filePath = new QString(m_scanFileName);
HGMsg msg;
msg.id = 1;
msg.data = filePath;
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(m_ocrMsgPump, &msg))
{
delete filePath;
}
}
2024-04-30 09:16:13 +00:00
++m_aquireIntoSaveParam.fileNameStartIndex;
2024-04-28 10:15:51 +00:00
}
m_scanFileName.clear();
}
2024-04-24 06:57:44 +00:00
}
void MainWindow::Show()
{
show();
if (isMaximized())
showMaximized();
else
showNormal();
raise();
}
void MainWindow::ShowAddDialog(unsigned int buttonId)
{
if (nullptr == m_devHandle)
{
QMessageBox::information(this, tr("Tips"), tr("Device is offline"));
return;
}
std::string deviceType = m_devName.toStdString();
char v[256] = {0};
SANE_Status status = sane_control_option(m_devHandle, (SANE_Int)0x886D, SANE_ACTION_GET_VALUE, v, NULL);
if (SANE_STATUS_GOOD == status)
{
deviceType = v;
}
assert(nullptr == m_dlgAdd);
m_dlgAdd = new Dialog_Add(m_devHandle, this, deviceType, buttonId);
connect(this, SIGNAL(closeDevice()), m_dlgAdd, SLOT(on_closeDevice()));
if (m_dlgAdd->exec())
{
ScanParam scanParam = m_dlgAdd->GetScanParam();
m_vScanParams.push_back(scanParam);
SaveCfg();
ui->tableWidget->setRowCount((int)m_vScanParams.size());
int index = (int)m_vScanParams.size() - 1;
ui->tableWidget->setRowHeight(index, 30);
ui->tableWidget->setItem(index, 0, new QTableWidgetItem(QString(m_vScanParams[index].deviceType.c_str())));
ui->tableWidget->item(index, 0)->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->item(index, 0)->setFlags(ui->tableWidget->item(index, 0)->flags() & ~Qt::ItemIsEditable);
QStringList btnTypeStr = {tr("Manual"), tr("Button 1"), tr("Button 2"), tr("Button 3"), tr("Button 4"), tr("Button 5")};
ui->tableWidget->setItem(index, 1, new QTableWidgetItem(btnTypeStr[m_vScanParams[index].buttonId]));
ui->tableWidget->item(index, 1)->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->item(index, 1)->setFlags(ui->tableWidget->item(index, 1)->flags() & ~Qt::ItemIsEditable);
ui->tableWidget->setItem(index, 2, new QTableWidgetItem(GetDesc(m_vScanParams[index].deviceConfigs)));
ui->tableWidget->item(index, 2)->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->item(index, 2)->setFlags(ui->tableWidget->item(index, 2)->flags() & ~Qt::ItemIsEditable);
ui->tableWidget->setItem(index, 3, new QTableWidgetItem(GetDesc(m_vScanParams[index].saveParam)));
ui->tableWidget->item(index, 3)->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->item(index, 3)->setFlags(ui->tableWidget->item(index, 3)->flags() & ~Qt::ItemIsEditable);
ui->tableWidget->selectRow(index);
}
disconnect(this, SIGNAL(closeDevice()), m_dlgAdd, SLOT(on_closeDevice()));
delete m_dlgAdd;
m_dlgAdd = nullptr;
}
2024-04-28 10:15:51 +00:00
int MainWindow::sane_ex_callback(SANE_Handle hdev, int code, void* data, unsigned int* len, void* param)
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
(void)hdev;
(void)len;
MainWindow* p = (MainWindow*)param;
switch (code)
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
case SANE_EVENT_DEVICE_ARRIVED:
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
SANE_Device* sane_dev = (SANE_Device*)data;
emit p->deviceArrive(sane_dev->name);
}
break;
case SANE_EVENT_DEVICE_LEFT:
{
SANE_Device* sane_dev = (SANE_Device*)data;
emit p->deviceRemove(sane_dev->name);
}
break;
case SANE_EVENT_WORKING:
{
emit p->scanWorking();
emit p->scanInfo((const char*)data, false);
}
break;
case SANE_EVENT_SCAN_FINISHED:
{
emit p->scanInfo((const char*)data, (0 != *len));
emit p->scanFinish();
}
break;
case SANE_EVENT_STATUS:
{
//emit p->scanInfo((const char*)data, false);
}
break;
case SANE_EVENT_ERROR:
{
//emit p->scanInfo((const char*)data, (0 != *len));
}
break;
case SANE_EVENT_DEV_KEY_PRESSED:
{
emit p->keyPress(*len);
}
break;
case SANE_EVENT_START_AS_SERVICE:
{
return 1;
}
break;
case SANE_EVENT_SCANNER_CLOSED:
{
bool isOnline = *(bool*)data;
emit p->saneEventCloseDevice((void*)hdev, isOnline);
}
break;
2024-04-28 10:15:51 +00:00
case SANE_EVENT_IMAGE_OK:
{
++p->m_aquireIntoPageIndex;
emit p->scanImage(p->m_aquireIntoPageIndex);
2024-04-30 09:16:13 +00:00
if ((1 == p->m_aquireIntoSaveParam.fileNameOddEvenType && 1 != p->m_aquireIntoPageIndex % 2)
|| (2 == p->m_aquireIntoSaveParam.fileNameOddEvenType && 0 != p->m_aquireIntoPageIndex % 2))
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
// 跳过
2024-04-24 06:57:44 +00:00
}
2024-04-28 10:15:51 +00:00
else
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
SANE_Image* sane_img = (SANE_Image*)data;
HGUInt imgType = 0;
if (sane_img->header.format == SANE_FRAME_GRAY)
{
if (1 == sane_img->header.depth)
imgType = HGBASE_IMGTYPE_BINARY;
else if (8 == sane_img->header.depth)
imgType = HGBASE_IMGTYPE_GRAY;
}
else if (sane_img->header.format == SANE_FRAME_RGB)
imgType = HGBASE_IMGTYPE_RGB;
HGByte* data = sane_img->data;
HGImageInfo imgInfo = { (HGUInt)sane_img->header.pixels_per_line, (HGUInt)sane_img->header.lines,
imgType, (HGUInt)sane_img->header.bytes_per_line, HGBASE_IMGORIGIN_TOP };
HGImage img = NULL;
HGBase_CreateImageFromData(data, &imgInfo, NULL, 0, HGBASE_IMGORIGIN_TOP, &img);
if (NULL != img)
{
HGBase_SetImageDpi(img, p->m_dpi, p->m_dpi);
p->SaveImage(img);
HGBase_DestroyImage(img);
}
2024-04-24 06:57:44 +00:00
}
}
2024-04-28 10:15:51 +00:00
break;
2024-04-24 06:57:44 +00:00
}
2024-04-28 10:15:51 +00:00
return 0;
2024-04-24 06:57:44 +00:00
}
2024-04-28 10:15:51 +00:00
void MainWindow::ocrThreadFunc(HGThread thread, HGPointer param)
2024-04-26 09:27:47 +00:00
{
2024-04-28 10:15:51 +00:00
MainWindow *p = (MainWindow*)param;
HGBase_RunMsgPump(p->m_ocrMsgPump, ocrMsgPumpFunc, param);
2024-04-26 09:27:47 +00:00
}
2024-04-28 10:15:51 +00:00
void MainWindow::ocrMsgPumpFunc(HGMsgPump msgPump, const HGMsg *msg, HGPointer param)
2024-04-26 09:27:47 +00:00
{
2024-04-28 10:15:51 +00:00
MainWindow *p = (MainWindow*)param;
if (msg->id == 1)
{
QString *filePath = (QString *)msg->data;
HGOCRMgr ocrMgr = NULL;
HGImgProc_CreateOCRMgr(HGIMGPROC_OCRALGO_DEFAULT, &ocrMgr);
if (NULL != ocrMgr)
{
HGImgFmtReader reader = NULL;
HGImgFmt_OpenImageReader(filePath->toLocal8Bit().toStdString().c_str(), 0, &reader);
if (NULL != reader)
{
HGUInt count = 0;
HGImgFmt_GetImagePageCount(reader, &count);
for (HGUInt i = 0; i < count; ++i)
{
HGImage image = NULL;
HGImgFmt_LoadImageFromReader(reader, i, NULL, 0, 0, &image);
if (NULL != image)
{
HGImgProc_AddToImageOCRList(ocrMgr, image);
HGBase_DestroyImage(image);
}
}
HGImgFmt_CloseImageReader(reader);
}
//HGBase_DeleteFile(filePath->toLocal8Bit().toStdString().c_str());
HGImgProc_ImageListOCRToFile(ocrMgr, 0, filePath->toLocal8Bit().toStdString().c_str(), NULL, NULL);
HGImgProc_DestroyOCRMgr(ocrMgr);
}
delete filePath;
}
2024-04-26 09:27:47 +00:00
}
2024-05-22 08:34:09 +00:00
void MainWindow::CrashFunc(HGPointer crashAddr, HGPointer param)
{
HGChar crashName[256];
HGBase_GetLogFilePath(crashName, 256);
strcat(crashName, "crash.dmp");
if (HGBASE_ERR_OK == HGBase_MakeCrashFile(crashName))
{
HGChar excpStr[64];
#ifdef HG_64BIT
sprintf(excpStr, "0x%016p", crashAddr);
#else
sprintf(excpStr, "0x%08p", crashAddr);
#endif
}
}
2024-04-28 10:15:51 +00:00
void MainWindow::closeEvent(QCloseEvent *e)
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
if (m_trayIcon->isVisible()) //托盘是显示的
{
hide(); // 隐藏主窗口
e->ignore(); //忽略关闭事件,这样才不会关闭程序
}
}
2024-04-24 06:57:44 +00:00
void MainWindow::timerEvent(QTimerEvent *e)
{
if (e->timerId() == m_timerId)
{
SANE_Status status = sane_open(ui->comboBox->currentText().toStdString().c_str(), &m_devHandle);
if (SANE_STATUS_GOOD == status)
{
m_devName = ui->comboBox->currentText();
ui->pushButtonScan->setEnabled(true);
ui->pushButtonAdd->setEnabled(true);
ui->pushButtonModify->setEnabled(true);
this->killTimer(m_timerId);
m_timerId = -1;
}
}
}
2024-04-28 10:15:51 +00:00
void MainWindow::on_deviceArrive(QString devName)
{
if (devName.contains("306") || devName.contains("307") || devName.contains("358"))
ui->comboBox->addItem(devName);
2024-04-24 06:57:44 +00:00
}
2024-04-28 10:15:51 +00:00
void MainWindow::on_deviceRemove(QString devName)
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
if (devName == m_devName)
{
assert(nullptr != m_devHandle);
StopScan();
2024-05-07 08:09:36 +00:00
emit closeDevice();
2024-04-28 10:15:51 +00:00
sane_close(m_devHandle);
m_devHandle = NULL;
m_devName.clear();
ui->pushButtonScan->setEnabled(false);
ui->pushButtonAdd->setEnabled(false);
ui->pushButtonModify->setEnabled(false);
2024-04-28 10:15:51 +00:00
}
2024-04-24 06:57:44 +00:00
2024-04-28 10:15:51 +00:00
for (int i = 0; i < ui->comboBox->count(); ++i)
{
if (ui->comboBox->itemText(i) == devName)
{
ui->comboBox->removeItem(i);
break;
}
}
}
2024-04-24 06:57:44 +00:00
2024-04-28 10:15:51 +00:00
void MainWindow::on_keyPress(unsigned int buttonId)
{
assert(nullptr != m_devHandle);
StartScan(buttonId);
2024-04-24 06:57:44 +00:00
}
2024-04-28 10:15:51 +00:00
void MainWindow::on_scanWorking()
2024-04-23 09:44:22 +00:00
{
2024-04-28 10:15:51 +00:00
m_dlgScanInfo->Start();
}
void MainWindow::on_scanInfo(QString info, bool error)
{
m_dlgScanInfo->SetScanInfo(info, error);
}
void MainWindow::on_scanImage(unsigned int count)
{
m_dlgScanInfo->SetScanCount(count);
}
void MainWindow::on_scanFinish()
{
if (nullptr != m_scanImgFmtWriter)
2024-04-23 09:44:22 +00:00
{
2024-04-28 10:15:51 +00:00
HGImgFmt_CloseImageWriter(m_scanImgFmtWriter);
m_scanImgFmtWriter = nullptr;
if (nullptr != m_ocrMsgPump)
{
QString *filePath = new QString(m_scanFileName);
HGMsg msg;
msg.id = 1;
msg.data = filePath;
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(m_ocrMsgPump, &msg))
{
delete filePath;
}
}
m_scanFileName.clear();
2024-04-30 09:16:13 +00:00
++m_aquireIntoSaveParam.fileNameStartIndex;
2024-04-28 10:15:51 +00:00
m_aquireIntoMultiPageCount = 0;
}
if (NULL != m_ocrMsgPump)
{
HGBase_ExitMsgPump(m_ocrMsgPump);
HGBase_CloseThread(m_ocrThread);
m_ocrThread = NULL;
HGBase_DestroyMsgPump(m_ocrMsgPump);
m_ocrMsgPump = NULL;
2024-04-23 09:44:22 +00:00
}
2024-04-28 10:15:51 +00:00
StopScan();
m_dlgScanInfo->Finish();
}
void MainWindow::on_comboBox_currentIndexChanged(const QString &arg1)
{
if (-1 != m_timerId)
{
this->killTimer(m_timerId);
m_timerId = -1;
}
2024-04-28 10:15:51 +00:00
if (NULL != m_devHandle)
{
StopScan();
2024-05-07 08:09:36 +00:00
emit closeDevice();
2024-04-28 10:15:51 +00:00
sane_close(m_devHandle);
m_devHandle = NULL;
m_devName.clear();
ui->pushButtonScan->setEnabled(false);
ui->pushButtonAdd->setEnabled(false);
ui->pushButtonModify->setEnabled(false);
2024-04-28 10:15:51 +00:00
}
SANE_Status status = sane_open(arg1.toStdString().c_str(), &m_devHandle);
if (SANE_STATUS_GOOD == status)
{
m_devName = arg1;
ui->pushButtonScan->setEnabled(true);
ui->pushButtonAdd->setEnabled(true);
ui->pushButtonModify->setEnabled(true);
}
else
{
m_timerId = this->startTimer(5000);
2024-04-28 10:15:51 +00:00
}
}
void MainWindow::on_pushButtonScan_clicked()
{
assert(!m_scanning && nullptr == m_dlgAdd);
StartScan(0);
2024-04-23 09:44:22 +00:00
}
void MainWindow::on_trayActivated(QSystemTrayIcon::ActivationReason reason)
{
if (QSystemTrayIcon::Trigger == reason)
{
}
else if (QSystemTrayIcon::DoubleClick == reason)
{
Show();
2024-04-23 09:44:22 +00:00
}
else if (QSystemTrayIcon::MiddleClick == reason)
{
}
}
2024-04-24 07:08:43 +00:00
void MainWindow::on_showMainWindowDlg()
{
Show();
2024-04-23 09:44:22 +00:00
}
void MainWindow::on_saneEventCloseDevice(void* devHandle, bool isOnline)
{
assert(nullptr != m_devHandle || nullptr != devHandle);
if (devHandle != m_devHandle)
return;
StopScan();
emit closeDevice();
sane_close(m_devHandle);
m_devHandle = NULL;
m_devName.clear();
ui->pushButtonScan->setEnabled(false);
ui->pushButtonAdd->setEnabled(false);
ui->pushButtonModify->setEnabled(false);
if (-1 != m_timerId)
{
this->killTimer(m_timerId);
m_timerId = -1;
}
if (isOnline)
m_timerId = this->startTimer(5000);
}
void MainWindow:: on_pushButtonAdd_clicked()
2024-04-24 06:57:44 +00:00
{
ShowAddDialog(0);
2024-04-24 06:57:44 +00:00
}
void MainWindow::on_pushButtonModify_clicked()
2024-04-23 09:44:22 +00:00
{
2024-04-24 06:57:44 +00:00
int index = ui->tableWidget->currentRow();
if (-1 == index)
{
QMessageBox::information(this, tr("Tips"), tr("No item selected"));
return;
}
2024-04-28 10:15:51 +00:00
if (nullptr == m_devHandle)
{
QMessageBox::information(this, tr("Tips"), tr("Device is offline"));
return;
}
2024-04-28 10:15:51 +00:00
std::string deviceType = m_devName.toStdString();
char v[256] = {0};
2024-04-28 10:15:51 +00:00
SANE_Status status = sane_control_option(m_devHandle, (SANE_Int)0x886D, SANE_ACTION_GET_VALUE, v, NULL);
if (SANE_STATUS_GOOD == status)
{
deviceType = v;
}
if (deviceType != m_vScanParams[index].deviceType)
{
QMessageBox::information(this, tr("Tips"), tr("Device type mismatch"));
return;
}
2024-04-28 10:15:51 +00:00
assert(nullptr == m_dlgAdd);
m_dlgAdd = new Dialog_Add(m_devHandle, this, m_vScanParams[index], index);
2024-05-07 08:09:36 +00:00
connect(this, SIGNAL(closeDevice()), m_dlgAdd, SLOT(on_closeDevice()));
2024-04-28 10:15:51 +00:00
if (m_dlgAdd->exec())
2024-04-24 06:57:44 +00:00
{
2024-04-28 10:15:51 +00:00
ScanParam scanParam = m_dlgAdd->GetScanParam();
2024-04-24 06:57:44 +00:00
m_vScanParams[index] = scanParam;
2024-04-26 09:27:47 +00:00
SaveCfg();
2024-04-24 06:57:44 +00:00
ui->tableWidget->item(index, 0)->setText(QString::fromStdString(m_vScanParams[index].deviceType));
2024-04-24 06:57:44 +00:00
QStringList btnTypeStr = {tr("Manual"), tr("Button 1"), tr("Button 2"), tr("Button 3"), tr("Button 4"), tr("Button 5")};
2024-05-10 08:48:21 +00:00
ui->tableWidget->item(index, 1)->setText(btnTypeStr[m_vScanParams[index].buttonId]);
2024-04-24 06:57:44 +00:00
ui->tableWidget->item(index, 2)->setText(GetDesc(m_vScanParams[index].deviceConfigs));
2024-04-24 06:57:44 +00:00
ui->tableWidget->item(index, 3)->setText(GetDesc(m_vScanParams[index].saveParam));
}
2024-04-28 10:15:51 +00:00
2024-05-07 08:09:36 +00:00
disconnect(this, SIGNAL(closeDevice()), m_dlgAdd, SLOT(on_closeDevice()));
2024-04-28 10:15:51 +00:00
delete m_dlgAdd;
m_dlgAdd = nullptr;
2024-04-24 06:57:44 +00:00
}
void MainWindow::on_pushButtonRemove_clicked()
{
int index = ui->tableWidget->currentRow();
if (-1 == index)
{
QMessageBox::information(this, tr("Tips"), tr("No item selected"));
return;
}
QMessageBox msg(QMessageBox::Question, tr("Question"),
tr("Are you sure you want to remove the item?"),
QMessageBox::Yes | QMessageBox::No, this);
msg.exec();
if (msg.clickedButton() != msg.button(QMessageBox::Yes))
{
return;
}
m_vScanParams.erase(m_vScanParams.begin() + index);
2024-04-26 09:27:47 +00:00
SaveCfg();
2024-04-24 06:57:44 +00:00
ui->tableWidget->removeRow(index);
2024-04-23 09:44:22 +00:00
}