更新同步最新代码
This commit is contained in:
parent
bbd9bb0aca
commit
4d5dfb8352
1
AUTHORS
1
AUTHORS
|
@ -1,2 +1,3 @@
|
|||
yushuoqi <yushuoqi@kylinos.cn>
|
||||
zhaoyuzhen <zhaoyuzhen@kylinos.cn>
|
||||
fanyuchen <fanyuchen@kylinos.cn>
|
|
@ -7,8 +7,7 @@ Other image processing tips can also be reflected in this software, such as clip
|
|||
|
||||
![Main Picture](docs/scanner.png)
|
||||
|
||||
## Author's Home page
|
||||
:point_right: [Franklin-Qi](https://github.com/Franklin-Qi)
|
||||
|
||||
|
||||
## Function lists
|
||||
- [x] Normal scanning(different device, type, resolution, size, color mode, formats)
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
![Main Picture](docs/scanner.png)
|
||||
|
||||
## 作者博客页面
|
||||
:point_right: [Franklin-Qi](https://github.com/Franklin-Qi)
|
||||
|
||||
## 功能列表
|
||||
- [x] 正常扫描(根据不同的设备类型,分辨率,尺寸,色彩模式,保存格式)
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
kylin-scanner (3.2.1-0k2.0) yangtze; urgency=medium
|
||||
|
||||
* BUG号:无
|
||||
* 需求号:#22628 扫描仪自动安装驱动需求
|
||||
* 其他改动说明: 同步最新功能代码,添加扫描仪驱动自动安装功能,pdf多页扫描保存为一个pdf文件功能,剔除OpenCV相关代码(一键美化和智能纠偏算法改变),OCR改用SDK提供的开源算法。
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- fanyuchen <fanyuchen@kylinos.cn> Sat, 23 Sep 2023 14:59:40 +0800
|
||||
|
||||
kylin-scanner (3.2.1-0k1.3) yangtze; urgency=medium
|
||||
|
||||
* BUG号:#I5XFGZ 【平板模式】【扫描】已扫描多张图片,左侧预览图可以左右拖动
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#include (./codec/kylinimagecodec/kylinimagecodec.pro)
|
||||
|
||||
# QT modules
|
||||
QT += \
|
||||
core \
|
||||
|
@ -13,52 +11,47 @@ QT += \
|
|||
svg
|
||||
|
||||
# 配置kysdk
|
||||
PKGCONFIG += kysdk-kabase kysdk-waylandhelper kysdk-qtwidgets kysdk-waylandhelper kysdk-alm kysdk-ukenv kysdk-log kysdk-diagnostics
|
||||
PKGCONFIG += kysdk-alm kysdk-qtwidgets kysdk-ukenv kysdk-diagnostics kysdk-powermanagement kysdk-waylandhelper kysdk-ocr
|
||||
INCLUDEPATH += /usr/include/kysdk/applications/kabase/
|
||||
INCLUDEPATH += kabase/ \
|
||||
kabase/Qt
|
||||
INCLUDEPATH += ./src/kabase/
|
||||
INCLUDEPATH += ./src/kabase/Qt/
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = kylin-scanner
|
||||
INCLUDEPATH += \
|
||||
$$PWD/src/device/avahi_qt/ \
|
||||
$$PWD/src/device/qt_zeroconf/ \
|
||||
$$PWD/src/device
|
||||
|
||||
TARGET = kylin-scanner
|
||||
TEMPLATE = app
|
||||
|
||||
PROJECT_ROOTDIR = $$PWD
|
||||
|
||||
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
|
||||
|
||||
CONFIG += \
|
||||
c++11 \
|
||||
link_pkgconfig
|
||||
CONFIG += c++11 \
|
||||
link_pkgconfig
|
||||
|
||||
PKGCONFIG += \
|
||||
gio-2.0 \
|
||||
gio-unix-2.0 \
|
||||
opencv4 \
|
||||
gsettings-qt \
|
||||
libudev
|
||||
libudev \
|
||||
|
||||
|
||||
LIBS += \
|
||||
-llept \
|
||||
-lpthread \
|
||||
-ltesseract \
|
||||
-lX11 \
|
||||
# -ljpeg \
|
||||
-L/usr/lib/libukui-log4qt.so.1.0.0 -lukui-log4qt\
|
||||
-ltiff \
|
||||
-lfreeimage
|
||||
|
||||
#opencv
|
||||
INCLUDEPATH += /usr/include/opencv4/
|
||||
LIBS += -lopencv_core \
|
||||
-lopencv_imgcodecs \
|
||||
-lopencv_imgproc \
|
||||
|
||||
#freeimage
|
||||
#LIBS += -lkylinimagecodec
|
||||
LIBS += -lfreeimage \
|
||||
-lfreeimageplus \
|
||||
|
||||
|
||||
INCLUDEPATH += /usr/include/cImg.h
|
||||
unix:!macx: LIBS += -L$$PWD/../../../usr/lib/x86_64-linux-gnu/ -lsane
|
||||
|
||||
INCLUDEPATH += $$PWD/../../../usr/lib/x86_64-linux-gnu
|
||||
|
@ -77,14 +70,15 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
src/beauty.cpp \
|
||||
src/crop.cpp \
|
||||
src/customtablewidget.cpp \
|
||||
src/detectpagewidget.cpp \
|
||||
src/displaywidget.cpp \
|
||||
src/failedpagewidget.cpp \
|
||||
src/global.cpp \
|
||||
src/globalsignal.cpp \
|
||||
src/imageBaseOP/loadimage.cpp \
|
||||
src/imageBaseOP/pngsaver.cpp \
|
||||
src/imageBaseOP/savefilebase.cpp \
|
||||
src/imageOp/imageoperationbase.cpp \
|
||||
src/imageOp/imageoperationbeauty.cpp \
|
||||
|
@ -97,7 +91,8 @@ SOURCES += \
|
|||
src/leftsuccesspagewidget.cpp \
|
||||
src/main.cpp \
|
||||
src/mainwidget.cpp \
|
||||
src/ocrobject.cpp \
|
||||
src/newdevicelistpage.cpp \
|
||||
src/nodevicewidget.cpp \
|
||||
src/rectify.cpp \
|
||||
src/runningdialog.cpp \
|
||||
src/saneobject.cpp \
|
||||
|
@ -121,17 +116,21 @@ SOURCES += \
|
|||
src/utils/login1_dbus.cpp \
|
||||
src/utils/rotatechangeinfo.cpp \
|
||||
src/utils/xatom-helper.cpp \
|
||||
src/watermarkdialog.cpp
|
||||
src/waittingdialog.cpp \
|
||||
src/watermarkdialog.cpp \
|
||||
src/custom_push_button.cpp \
|
||||
src/navigator.cpp \
|
||||
|
||||
HEADERS += \
|
||||
src/beauty.h \
|
||||
src/crop.h \
|
||||
src/customtablewidget.h \
|
||||
src/detectpagewidget.h \
|
||||
src/displaywidget.h \
|
||||
src/failedpagewidget.h \
|
||||
src/global.h \
|
||||
src/globalsignal.h \
|
||||
src/imageBaseOP/loadimage.h \
|
||||
src/imageBaseOP/pngsaver.h \
|
||||
src/imageBaseOP/savefilebase.h \
|
||||
src/imageOp/imageoperationbase.h \
|
||||
src/imageOp/imageoperationbeauty.h \
|
||||
|
@ -145,7 +144,8 @@ HEADERS += \
|
|||
src/leftimagehandlesuccesspagewidget.h \
|
||||
src/leftsuccesspagewidget.h \
|
||||
src/mainwidget.h \
|
||||
src/ocrobject.h \
|
||||
src/newdevicelistpage.h \
|
||||
src/nodevicewidget.h \
|
||||
src/rectify.h \
|
||||
src/runningdialog.h \
|
||||
src/saneobject.h \
|
||||
|
@ -169,7 +169,11 @@ HEADERS += \
|
|||
src/utils/login1_dbus.h \
|
||||
src/utils/rotatechangeinfo.h \
|
||||
src/utils/xatom-helper.h \
|
||||
src/watermarkdialog.h
|
||||
src/waittingdialog.h \
|
||||
src/watermarkdialog.h \
|
||||
src/custom_push_button.h \
|
||||
src/navigator.h \
|
||||
src/kabase/buriedpoint.hpp \
|
||||
|
||||
# Manual
|
||||
DISTFILES += \
|
||||
|
@ -182,10 +186,53 @@ DISTFILES += \
|
|||
src/icons/waiting/loading6.svg \
|
||||
src/icons/waiting/loading7.svg
|
||||
|
||||
LIBS += \
|
||||
-lusb-1.0 \
|
||||
-ludev \
|
||||
-lbsd \
|
||||
-lpthread \
|
||||
-lavahi-common -lavahi-client \
|
||||
-lnetsnmp -lnetsnmpagent -lnetsnmpmibs
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/src/device/snmpwalk_browser.h \
|
||||
$$PWD/src/device/avahi_qt/qt_watch.h \
|
||||
$$PWD/src/device/ukui_apt.h \
|
||||
$$PWD/src/device/qt_zeroconf/zconfservicebrowser.h \
|
||||
$$PWD/src/device/qt_zeroconf/zconfserviceclient.h \
|
||||
$$PWD/src/device/qt_zeroconf/zconfservice.h \
|
||||
$$PWD/src/device/device_information.h \
|
||||
$$PWD/src/device/base_info.h \
|
||||
$$PWD/src/device/network_device_detector.h \
|
||||
$$PWD/src/device/common.h \
|
||||
$$PWD/src/device/usbFinder.h \
|
||||
$$PWD/src/device/singleton.h \
|
||||
$$PWD/src/device/deviceFinder.h \
|
||||
$$PWD/src/device/connect.h \
|
||||
$$PWD/src/device/snmpFinder.h
|
||||
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/src/device/device_information.cpp \
|
||||
$$PWD/src/device/avahi_qt/qt_watch.cpp \
|
||||
$$PWD/src/device/network_device_detector.cpp \
|
||||
$$PWD/src/device/common.cpp \
|
||||
$$PWD/src/device/snmpwalk_browser.cpp \
|
||||
$$PWD/src/device/ukui_apt.cpp \
|
||||
$$PWD/src/device/base_info.cpp \
|
||||
$$PWD/src/device/qt_zeroconf/zconfserviceclient.cpp \
|
||||
$$PWD/src/device/qt_zeroconf/zconfservicebrowser.cpp \
|
||||
$$PWD/src/device/qt_zeroconf/zconfservice.cpp \
|
||||
$$PWD/src/device/usbFinder.cpp \
|
||||
$$PWD/src/device/deviceFinder.cpp \
|
||||
$$PWD/src/device/connect.cpp \
|
||||
$$PWD/src/device/snmpFinder.cpp
|
||||
|
||||
|
||||
# UI files
|
||||
FORMS += \
|
||||
src/about/about.ui \
|
||||
src/titlebar/titlebar.ui
|
||||
src/titlebar/titlebar.ui \
|
||||
|
||||
# Translation
|
||||
TRANSLATIONS += \
|
||||
|
@ -193,7 +240,8 @@ TRANSLATIONS += \
|
|||
translations/kylin-scanner_bo_CN.ts \
|
||||
translations/kylin-scanner_kk.ts \
|
||||
translations/kylin-scanner_ky.ts \
|
||||
translations/kylin-scanner_ug.ts
|
||||
translations/kylin-scanner_ug.ts \
|
||||
translations/kylin-scanner_mn.ts
|
||||
|
||||
!system($$PWD/translations/generate_translations_pm.sh): error("Failed to generate pm")
|
||||
system($$shell_path(cp $$PROJECT_ROOTDIR/translations/*.qm $$OUT_PWD/))
|
||||
|
|
497
src/beauty.cpp
497
src/beauty.cpp
|
@ -1,497 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021, KylinSoft Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "beauty.h"
|
||||
#include <ukui-log4qt.h>
|
||||
|
||||
KYCBeautyWidget::KYCBeautyWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void averageFilterCV(Mat src, Mat &dst)
|
||||
{
|
||||
blur(src, dst, Size(3, 3), Point(-1, -1));
|
||||
}
|
||||
|
||||
void gaussianFilterCV(Mat src, Mat &dst)
|
||||
{
|
||||
GaussianBlur(src, dst, Size(5, 5), 5, 5);
|
||||
}
|
||||
|
||||
void medianFilterCV(Mat src, Mat &dst)
|
||||
{
|
||||
medianBlur(src, dst, 5);
|
||||
}
|
||||
|
||||
void bilateralFilterCV(Mat src, Mat &dst)
|
||||
{
|
||||
bilateralFilter(src, dst, 5, 100, 3);
|
||||
}
|
||||
|
||||
QImage *sharpen(QImage *origin)
|
||||
{
|
||||
QImage *novelImage = new QImage(* origin);
|
||||
|
||||
int kernel [3][3] = {{0, -1, 0},
|
||||
{-1, 5, -1},
|
||||
{0, -1, 0}
|
||||
};
|
||||
int kernelSize = 3;
|
||||
int sumKernel = 1;
|
||||
int r, g, b;
|
||||
QColor color;
|
||||
|
||||
for (int x = kernelSize / 2; x < novelImage->width() - (kernelSize / 2); ++x) {
|
||||
for (int y = kernelSize / 2; y < novelImage->height() - (kernelSize / 2); ++y) {
|
||||
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
|
||||
for (int i = -kernelSize / 2; i <= kernelSize / 2; ++i) {
|
||||
for (int j = -kernelSize / 2; j <= kernelSize / 2; ++j) {
|
||||
color = QColor(origin->pixel(x + i, y + j));
|
||||
r += color.red() * kernel[kernelSize / 2 + i][kernelSize / 2 + j];
|
||||
g += color.green() * kernel[kernelSize / 2 + i][kernelSize / 2 + j];
|
||||
b += color.blue() * kernel[kernelSize / 2 + i][kernelSize / 2 + j];
|
||||
}
|
||||
}
|
||||
|
||||
r = qBound(0, r / sumKernel, 255);
|
||||
g = qBound(0, g / sumKernel, 255);
|
||||
b = qBound(0, b / sumKernel, 255);
|
||||
|
||||
novelImage->setPixel(x, y, qRgb(r, g, b));
|
||||
|
||||
}
|
||||
}
|
||||
return novelImage;
|
||||
}
|
||||
|
||||
|
||||
void sharpenCV(Mat src, Mat &dst)
|
||||
{
|
||||
KyInfo() << "sharp()";
|
||||
|
||||
Point2i anchor(-1, -1);
|
||||
double delta = 0;
|
||||
|
||||
const Mat kernel = (Mat_<char>(3, 3) <<
|
||||
0, -1, 0,
|
||||
-1, 5, -1,
|
||||
0, -1, 0);
|
||||
|
||||
filter2D(src, dst, dst.depth(), kernel, anchor, delta);
|
||||
KyInfo() << "sharp() end";
|
||||
}
|
||||
|
||||
static void checkHsl(int &hue, int &saturation, int &lumination)
|
||||
{
|
||||
if (hue < -180 )
|
||||
hue = -180;
|
||||
|
||||
if (saturation < -255)
|
||||
saturation = -255;
|
||||
|
||||
if (lumination < -255 )
|
||||
lumination = -255;
|
||||
|
||||
if (hue > 180)
|
||||
hue = 180;
|
||||
|
||||
if (saturation > 255)
|
||||
saturation = 255;
|
||||
|
||||
if (lumination > 255)
|
||||
lumination = 255;
|
||||
|
||||
}
|
||||
|
||||
void hslCV(Mat src, Mat &dst)
|
||||
{
|
||||
// H:0~180, S:0~255, V:0~255
|
||||
int hue = 5;
|
||||
int saturation = 10;
|
||||
int lumination = 0;
|
||||
if (dst.empty())
|
||||
dst.create(src.rows, src.cols, src.type());
|
||||
|
||||
Mat temp;
|
||||
temp.create(src.rows, src.cols, src.type());
|
||||
|
||||
cvtColor(src, temp, CV_RGB2HSV);
|
||||
|
||||
int i, j;
|
||||
Size size = src.size();
|
||||
int chns = src.channels();
|
||||
|
||||
if (temp.isContinuous()) {
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
checkHsl(hue, saturation, lumination);
|
||||
|
||||
for ( i = 0; i < size.height; ++i) {
|
||||
unsigned char *srcHSL = (unsigned char *)temp.data + temp.step * i;
|
||||
for ( j = 0; j < size.width; ++j) {
|
||||
float val = srcHSL[j * chns] + hue;
|
||||
if (val < 0)
|
||||
val = 0.0;
|
||||
if (val > 180 )
|
||||
val = 180;
|
||||
srcHSL[j * chns] = static_cast<unsigned char>(val);
|
||||
|
||||
val = srcHSL[j * chns + 1] + saturation;
|
||||
if ( val < 0)
|
||||
val = 0;
|
||||
if ( val > 255 )
|
||||
val = 255;
|
||||
srcHSL[j * chns + 1] = static_cast<unsigned char>(val);
|
||||
|
||||
val = srcHSL[j * chns + 2] + lumination;
|
||||
if ( val < 0)
|
||||
val = 0;
|
||||
if ( val > 255 )
|
||||
val = 255;
|
||||
srcHSL[j * chns + 2] = static_cast<unsigned char>(val);
|
||||
}
|
||||
}
|
||||
|
||||
cvtColor(temp, dst, CV_HSV2RGB);
|
||||
if (temp.empty())
|
||||
temp.release();
|
||||
}
|
||||
|
||||
void luminanceContrastCV(Mat src, Mat &dst)
|
||||
{
|
||||
KyInfo() << "psLuminanceContrastCV()";
|
||||
Mat new_image = Mat::zeros(src.size(), src.type());
|
||||
double alpha = 1.0; // contrast
|
||||
int beta = 5; // brightness
|
||||
int i, j, c;
|
||||
|
||||
for (i = 0; i < src.rows; ++i) {
|
||||
for (j = 0; j < src.cols; ++j) {
|
||||
for (c = 0; c < 3; ++c) {
|
||||
new_image.at<Vec3b>(i, j)[c] =
|
||||
saturate_cast<uchar>( alpha * (src.at<Vec3b>(i, j)[c]) + beta );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
dst = new_image.clone();
|
||||
KyInfo() << "psLuminanceContrastCV() end";
|
||||
}
|
||||
|
||||
void saturationCV(Mat src, Mat &dst)
|
||||
{
|
||||
KyInfo() << "saturation()";
|
||||
Mat new_img;
|
||||
|
||||
const int max_increment = 200;
|
||||
const int saturation = 100;
|
||||
float increment = (saturation - 80) * 1.0 / max_increment;
|
||||
|
||||
for (int col = 0; col < src.cols; col++) {
|
||||
for (int row = 0; row < src.rows; row++) {
|
||||
uchar r = src.at<Vec3b> (row, col)[2];
|
||||
uchar g = src.at<Vec3b> (row, col)[1];
|
||||
uchar b = src.at<Vec3b> (row, col)[0];
|
||||
|
||||
float maxn = max (r, max (g, b));
|
||||
float minn = min (r, min (g, b));
|
||||
|
||||
float delta, value;
|
||||
delta = (maxn - minn) / 255;
|
||||
value = (maxn + minn) / 255;
|
||||
|
||||
float new_r = 0.0f, new_g = 0.0f, new_b = 0.0f;
|
||||
|
||||
const double eps = 1.0e-6;
|
||||
if (fabs(delta - 0.0) <= eps) {
|
||||
new_img.at<Vec3b> (row, col)[0] = new_b;
|
||||
new_img.at<Vec3b> (row, col)[1] = new_g;
|
||||
new_img.at<Vec3b> (row, col)[2] = new_r;
|
||||
continue;
|
||||
}
|
||||
|
||||
float light = 0.0f, sat = 0.0f, alpha = 0.0f;
|
||||
light = value / 2;
|
||||
|
||||
if (light < 0.5f) {
|
||||
sat = delta / value;
|
||||
} else {
|
||||
sat = delta / (2 - value);
|
||||
}
|
||||
|
||||
KyInfo() << "1";
|
||||
if (increment >= 0) {
|
||||
if ((increment + sat) >= 1) {
|
||||
alpha = sat;
|
||||
} else {
|
||||
alpha = 1 - increment;
|
||||
}
|
||||
alpha = 1 / alpha - 1;
|
||||
new_r = r + (r - light * 255) * alpha;
|
||||
new_g = g + (g - light * 255) * alpha;
|
||||
new_b = b + (b - light * 255) * alpha;
|
||||
} else {
|
||||
alpha = increment;
|
||||
new_r = light * 255 + (r - light * 255) * (1 + alpha);
|
||||
new_g = light * 255 + (g - light * 255) * (1 + alpha);
|
||||
new_b = light * 255 + (b - light * 255) * (1 + alpha);
|
||||
}
|
||||
KyInfo() << "2";
|
||||
new_img.at<Vec3f> (row, col)[0] = new_b;
|
||||
KyInfo() << "3";
|
||||
new_img.at<Vec3f> (row, col)[1] = new_g;
|
||||
KyInfo() << "4";
|
||||
new_img.at<Vec3f> (row, col)[2] = new_r;
|
||||
KyInfo() << "5";
|
||||
}
|
||||
}
|
||||
|
||||
dst = new_img.clone();
|
||||
KyInfo() << "saturation() end";
|
||||
}
|
||||
|
||||
|
||||
void histogramEqualizationCV(Mat src, Mat &dst)
|
||||
{
|
||||
std::vector<Mat> channels;
|
||||
Mat imageBlue, imageGreen, imageRed;
|
||||
|
||||
assert(src.data != NULL);
|
||||
|
||||
split(src, channels);
|
||||
|
||||
imageBlue = channels.at(0);
|
||||
equalizeHist(imageBlue, imageBlue);
|
||||
|
||||
imageGreen = channels.at(1);
|
||||
equalizeHist(imageGreen, imageGreen);
|
||||
|
||||
imageRed = channels.at(2);
|
||||
equalizeHist(imageRed, imageRed);
|
||||
|
||||
merge(channels, dst);
|
||||
}
|
||||
|
||||
void contrastCV(Mat src, Mat &dst)
|
||||
{
|
||||
const Mat kernel = (Mat_<float>(3, 3) <<
|
||||
0, -1, 0,
|
||||
0, 5, 0,
|
||||
0, -1, 0);
|
||||
|
||||
filter2D(src, dst, CV_8UC3, kernel);
|
||||
}
|
||||
|
||||
|
||||
void logarithmCV(Mat src, Mat &dst)
|
||||
{
|
||||
Mat imageLog(src.size(), CV_32FC3);
|
||||
for (int i = 0; i < src.rows; ++i) {
|
||||
for (int j = 0; j < src.cols; ++j) {
|
||||
imageLog.at<Vec3f>(i, j)[0] = log1p(src.at<Vec3b>(i, j)[0]);
|
||||
imageLog.at<Vec3f>(i, j)[1] = log1p(src.at<Vec3b>(i, j)[1]);
|
||||
imageLog.at<Vec3f>(i, j)[2] = log1p(src.at<Vec3b>(i, j)[2]);
|
||||
}
|
||||
}
|
||||
normalize(imageLog, imageLog, 0, 255, CV_MINMAX);
|
||||
convertScaleAbs(imageLog, imageLog);
|
||||
|
||||
dst = imageLog.clone();
|
||||
}
|
||||
|
||||
void gammaCV(Mat src, Mat &dst)
|
||||
{
|
||||
Mat imageGamma(src.size(), CV_32FC3);
|
||||
for (int i = 0; i < src.rows; ++i) {
|
||||
for (int j = 0; j < src.cols; ++j) {
|
||||
imageGamma.at<Vec3f>(i, j)[0] = (src.at<Vec3b>(i, j)[0]) * (src.at<Vec3b>(i,
|
||||
j)[0]) * (src.at<Vec3b>(i, j)[0]);
|
||||
imageGamma.at<Vec3f>(i, j)[1] = (src.at<Vec3b>(i, j)[1]) * (src.at<Vec3b>(i,
|
||||
j)[1]) * (src.at<Vec3b>(i, j)[1]);
|
||||
imageGamma.at<Vec3f>(i, j)[2] = (src.at<Vec3b>(i, j)[2]) * (src.at<Vec3b>(i,
|
||||
j)[2]) * (src.at<Vec3b>(i, j)[2]);
|
||||
}
|
||||
}
|
||||
normalize(imageGamma, imageGamma, 0, 255, CV_MINMAX);
|
||||
convertScaleAbs(imageGamma, imageGamma);
|
||||
dst = imageGamma.clone();
|
||||
}
|
||||
|
||||
QImage *greyScale(QImage *origin)
|
||||
{
|
||||
QImage *novelImage = new QImage(origin->width(), origin->height(), QImage::Format_ARGB32);
|
||||
|
||||
QColor oldColor;
|
||||
|
||||
for (int x = 0; x < novelImage->width(); ++x) {
|
||||
for (int y = 0; y < novelImage->height(); ++y) {
|
||||
oldColor = QColor(origin->pixel(x, y));
|
||||
|
||||
// gray RGB is set average of oldRGB
|
||||
int average = (oldColor.red() + oldColor.green() + oldColor.blue()) / 3;
|
||||
novelImage->setPixel(x, y, qRgb(average, average, average));
|
||||
}
|
||||
}
|
||||
|
||||
return novelImage;
|
||||
}
|
||||
|
||||
|
||||
QImage *lumimance(int delta, QImage *origin)
|
||||
{
|
||||
QImage *novelImage = new QImage(origin->width(), origin->height(), QImage::Format_ARGB32);
|
||||
|
||||
QColor oldColor;
|
||||
|
||||
for (int x = 0; x < novelImage->width(); ++x) {
|
||||
for (int y = 0; y < novelImage->height(); ++y) {
|
||||
oldColor = QColor(origin->pixel(x, y));
|
||||
|
||||
// RGB common add delta
|
||||
novelImage->setPixel(x, y, qRgb(oldColor.red() + delta,
|
||||
oldColor.green() + delta,
|
||||
oldColor.blue() + delta));
|
||||
}
|
||||
}
|
||||
|
||||
return novelImage;
|
||||
|
||||
}
|
||||
|
||||
QImage *saturation(int delta, QImage *origin)
|
||||
{
|
||||
QImage *novelImage = new QImage(origin->width(), origin->height(), QImage::Format_ARGB32);
|
||||
|
||||
QColor oldColor;
|
||||
QColor novelColor;
|
||||
int h, s, l;
|
||||
|
||||
for (int x = 0; x < novelImage->width(); ++x) {
|
||||
for (int y = 0; y < novelImage->height(); ++y) {
|
||||
oldColor = QColor(origin->pixel(x, y));
|
||||
|
||||
novelColor = oldColor.toHsl();
|
||||
h = novelColor.hue();
|
||||
s = novelColor.saturation() + delta;
|
||||
l = novelColor.lightness();
|
||||
|
||||
//Check if the new value is [0, 255]
|
||||
s = qBound(0, s, 255);
|
||||
|
||||
novelColor.setHsl(h, s, l);
|
||||
|
||||
novelImage->setPixel(x, y, qRgb(novelColor.red(), novelColor.green(), novelColor.blue()));
|
||||
}
|
||||
}
|
||||
|
||||
return novelImage;
|
||||
}
|
||||
|
||||
QImage *warmToned(int delta, QImage *origin)
|
||||
{
|
||||
QImage *newImage = new QImage(origin->width(), origin->height(), QImage::Format_ARGB32);
|
||||
|
||||
QColor oldColor;
|
||||
int r, g, b;
|
||||
|
||||
for (int x = 0; x < newImage->width(); ++x) {
|
||||
for (int y = 0; y < newImage->height(); ++y) {
|
||||
oldColor = QColor(origin->pixel(x, y));
|
||||
|
||||
r = oldColor.red() + delta;
|
||||
g = oldColor.green() + delta;
|
||||
b = oldColor.blue();
|
||||
|
||||
//we check if the new values are between 0 and 255
|
||||
r = qBound(0, r, 255);
|
||||
g = qBound(0, g, 255);
|
||||
|
||||
newImage->setPixel(x, y, qRgb(r, g, b));
|
||||
}
|
||||
}
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
|
||||
QImage *coolToned(int delta, QImage *origin)
|
||||
{
|
||||
QImage *newImage = new QImage(origin->width(), origin->height(), QImage::Format_ARGB32);
|
||||
|
||||
QColor oldColor;
|
||||
int r, g, b;
|
||||
|
||||
for (int x = 0; x < newImage->width(); ++x) {
|
||||
for (int y = 0; y < newImage->height(); ++y) {
|
||||
oldColor = QColor(origin->pixel(x, y));
|
||||
|
||||
r = oldColor.red();
|
||||
g = oldColor.green();
|
||||
b = oldColor.blue() + delta;
|
||||
|
||||
//we check if the new value is between 0 and 255
|
||||
b = qBound(0, b, 255);
|
||||
|
||||
newImage->setPixel(x, y, qRgb(r, g, b));
|
||||
}
|
||||
}
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
QImage *drawFrame(QImage *origin, const char *filename)
|
||||
{
|
||||
QImage *newImage = new QImage(* origin);
|
||||
QPainter painter;
|
||||
|
||||
painter.begin(newImage);
|
||||
|
||||
painter.drawImage(0, 0, QImage(filename));
|
||||
|
||||
painter.end();
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
void oneClickBeauty(const char *filename)
|
||||
{
|
||||
Mat src, dst;
|
||||
|
||||
src = imread(filename);
|
||||
|
||||
if (!src.data) {
|
||||
KyInfo() << filename << "image load error!";
|
||||
return;
|
||||
}
|
||||
|
||||
bilateralFilterCV(src, dst);
|
||||
|
||||
luminanceContrastCV(dst, dst);
|
||||
hslCV(dst, dst);
|
||||
sharpenCV(dst, dst);
|
||||
|
||||
imwrite(filename, dst);
|
||||
}
|
78
src/beauty.h
78
src/beauty.h
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021, KylinSoft Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BEAUTY_H
|
||||
#define BEAUTY_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/photo.hpp>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc_c.h>
|
||||
using namespace cv;
|
||||
//using namespace std;
|
||||
|
||||
#include "globalsignal.h"
|
||||
#include "saneobject.h"
|
||||
|
||||
//#define CV_MINMAX 32
|
||||
|
||||
void luminanceContrastCV(Mat src, Mat &dst);
|
||||
void saturationCV(Mat src, Mat &dst);
|
||||
void sharpenCV(Mat src, Mat &dst);
|
||||
void hslCV(Mat src, Mat &dst);
|
||||
|
||||
void averageFilterCV(Mat src, Mat &dst);
|
||||
void gaussianFilterCV(Mat src, Mat &dst);
|
||||
void medianFilterCV(Mat src, Mat &dst);
|
||||
void bilateralFilterCV(Mat src, Mat &dst);
|
||||
|
||||
void histogramEqualizationCV(Mat src, Mat &dst);
|
||||
void contrastCV(Mat src, Mat &dst);
|
||||
void logarithmCV(Mat src, Mat &dst);
|
||||
void gammaCV(Mat src, Mat &dst);
|
||||
|
||||
|
||||
QImage *sharpen(QImage *origin);
|
||||
QImage *greyScale(QImage *origin);
|
||||
QImage *lumimance(int delta, QImage *origin);
|
||||
QImage *saturation(int delta, QImage *origin);
|
||||
QImage *warmToned(int delta, QImage *origin);
|
||||
QImage *coolToned(int delta, QImage *origin);
|
||||
QImage *drawFrame(QImage *origin, const char *filename);
|
||||
|
||||
|
||||
void oneClickBeauty(const char *filename);
|
||||
|
||||
|
||||
class KYCBeautyWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit KYCBeautyWidget(QWidget *parent = nullptr);
|
||||
|
||||
};
|
||||
|
||||
#endif // BEAUTY_H
|
78
src/crop.cpp
78
src/crop.cpp
|
@ -46,7 +46,7 @@ void CropLabel::paintEvent(QPaintEvent *event)
|
|||
{
|
||||
QLabel::paintEvent(event); // draw label background
|
||||
|
||||
// QPainter painter(this);
|
||||
QPainter painter(this);
|
||||
painter.begin(this);
|
||||
QPen pen(QColor(55, 144, 250), 1);
|
||||
painter.setPen(pen);
|
||||
|
@ -55,25 +55,42 @@ void CropLabel::paintEvent(QPaintEvent *event)
|
|||
borderPath.setFillRule(Qt::WindingFill);
|
||||
borderPath.addRect(0, 0, this->width(), this->height()); // need judge
|
||||
|
||||
// int W = m_endX - m_startX;
|
||||
// int H = m_endY - m_startY;
|
||||
|
||||
int W = m_endX - m_beginX;
|
||||
int H = m_endY - m_beginY;
|
||||
m_beginPoint.setX(m_beginX);
|
||||
m_beginPoint.setY(m_beginY);
|
||||
m_endPoint.setX(m_endX);
|
||||
m_endPoint.setY(m_endY);
|
||||
|
||||
m_currentSelectRect = getRect(m_beginPoint, m_endPoint);
|
||||
|
||||
QPainterPath cropPath;
|
||||
cropPath.addRect(m_currentSelectRect);
|
||||
|
||||
|
||||
// draw different pixmap
|
||||
if(!(H == 0 && W == 0)){
|
||||
drawPixmapBorder(m_currentSelectRect, W, H);
|
||||
}
|
||||
painter.drawPixmap(m_currentSelectRect.x()-m_leftTopPixmapSize.width()/2, m_currentSelectRect.y()-m_leftTopPixmapSize.height()/2,
|
||||
m_leftTopPixmapSize.width(), m_leftTopPixmapSize.height(), m_leftTopPixmap);
|
||||
|
||||
painter.drawPixmap(m_currentSelectRect.x()+W/2-m_topPixmapSize.width()/2, m_currentSelectRect.y()-m_topPixmapSize.height()/2,
|
||||
m_topPixmapSize.width(), m_topPixmapSize.height(), m_topPixmap);
|
||||
|
||||
painter.drawPixmap(m_currentSelectRect.x()+W-m_rightTopPixmapSize.width()/2, m_currentSelectRect.y()-m_rightTopPixmapSize.height()/2,
|
||||
m_rightTopPixmapSize.width(), m_rightTopPixmapSize.height(), m_rightTopPixmap);
|
||||
|
||||
painter.drawPixmap(m_currentSelectRect.x()+W-m_rightPixmapSize.width()/2, m_currentSelectRect.y()+H/2-m_rightPixmapSize.height()/2,
|
||||
m_rightPixmapSize.width(), m_rightPixmapSize.height(), m_rightPixmap);
|
||||
|
||||
painter.drawPixmap(m_currentSelectRect.x()+W-m_rightBottomPixmapSize.width()/2, m_currentSelectRect.y()+H-m_rightBottomPixmapSize.height()/2,
|
||||
m_rightBottomPixmapSize.width(), m_rightBottomPixmapSize.height(), m_rightBottomPixmap);
|
||||
|
||||
painter.drawPixmap(m_currentSelectRect.x()+W/2-m_bottomPixmapSize.width()/2, m_currentSelectRect.y()+H-m_bottomPixmapSize.height()/2,
|
||||
m_bottomPixmapSize.width(), m_bottomPixmapSize.height(), m_bottomPixmap);
|
||||
|
||||
painter.drawPixmap(m_currentSelectRect.x()-m_leftBottomPixmapSize.width()/2, m_currentSelectRect.y()+H-m_leftBottomPixmapSize.height()/2,
|
||||
m_leftBottomPixmapSize.width(), m_leftBottomPixmapSize.height(), m_leftBottomPixmap);
|
||||
|
||||
painter.drawPixmap(m_currentSelectRect.x()-m_leftPixmapSize.width()/2, m_currentSelectRect.y()+H/2-m_leftPixmapSize.height()/2,
|
||||
m_leftPixmapSize.width(), m_leftPixmapSize.height(), m_leftPixmap);
|
||||
|
||||
// draw crop rect path
|
||||
painter.drawPath(cropPath);
|
||||
|
@ -84,7 +101,7 @@ void CropLabel::paintEvent(QPaintEvent *event)
|
|||
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
painter.fillPath(outPath, QColor(0, 0, 0, 100));
|
||||
painter.end();
|
||||
|
||||
if(!(H == 0 && W == 0)){
|
||||
emit paintCompleteSignal();
|
||||
}
|
||||
|
@ -123,7 +140,6 @@ void CropLabel::calculateDetectRegion(){
|
|||
|
||||
void CropLabel::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
// QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor));
|
||||
m_isPressed = true;
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
//判断按下的手柄的区域位置
|
||||
|
@ -222,6 +238,7 @@ void CropLabel::mouseMoveEvent(QMouseEvent *event)
|
|||
m_beginY = judgePosition(m_beginY,0,m_origRect.height());
|
||||
m_endX = judgePosition(m_endX,0,m_origRect.width());
|
||||
m_endY = judgePosition(m_endY,0,m_origRect.height());
|
||||
|
||||
m_beginPoint.setX(m_beginX);
|
||||
m_beginPoint.setY(m_beginY);
|
||||
m_endPoint.setX(m_endX);
|
||||
|
@ -299,35 +316,6 @@ bool CropLabel::isPressPointInCropRegion(QPoint mousePressPoint)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CropLabel::drawPixmapBorder(QRect rect, int W, int H)
|
||||
{
|
||||
painter.drawPixmap(rect.x()-m_leftTopPixmapSize.width()/2, rect.y()-m_leftTopPixmapSize.height()/2,
|
||||
m_leftTopPixmapSize.width(), m_leftTopPixmapSize.height(), m_leftTopPixmap);
|
||||
|
||||
painter.drawPixmap(rect.x()+W/2-m_topPixmapSize.width()/2, rect.y()-m_topPixmapSize.height()/2,
|
||||
m_topPixmapSize.width(), m_topPixmapSize.height(), m_topPixmap);
|
||||
|
||||
painter.drawPixmap(rect.x()+W-m_rightTopPixmapSize.width()/2, rect.y()-m_rightTopPixmapSize.height()/2,
|
||||
m_rightTopPixmapSize.width(), m_rightTopPixmapSize.height(), m_rightTopPixmap);
|
||||
|
||||
painter.drawPixmap(rect.x()+W-m_rightPixmapSize.width()/2, rect.y()+H/2-m_rightPixmapSize.height()/2,
|
||||
m_rightPixmapSize.width(), m_rightPixmapSize.height(), m_rightPixmap);
|
||||
|
||||
painter.drawPixmap(rect.x()+W-m_rightBottomPixmapSize.width()/2, rect.y()+H-m_rightBottomPixmapSize.height()/2,
|
||||
m_rightBottomPixmapSize.width(), m_rightBottomPixmapSize.height(), m_rightBottomPixmap);
|
||||
|
||||
painter.drawPixmap(rect.x()+W/2-m_bottomPixmapSize.width()/2, rect.y()+H-m_bottomPixmapSize.height()/2,
|
||||
m_bottomPixmapSize.width(), m_bottomPixmapSize.height(), m_bottomPixmap);
|
||||
|
||||
painter.drawPixmap(rect.x()-m_leftBottomPixmapSize.width()/2, rect.y()+H-m_leftBottomPixmapSize.height()/2,
|
||||
m_leftBottomPixmapSize.width(), m_leftBottomPixmapSize.height(), m_leftBottomPixmap);
|
||||
|
||||
painter.drawPixmap(rect.x()-m_leftPixmapSize.width()/2, rect.y()+H/2-m_leftPixmapSize.height()/2,
|
||||
m_leftPixmapSize.width(), m_leftPixmapSize.height(), m_leftPixmap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QRect CropLabel::getRect(const QPoint &m_beginPoint, const QPoint &m_endPoint)
|
||||
{
|
||||
int W = m_endPoint.x() - m_beginPoint.x();
|
||||
|
@ -340,20 +328,26 @@ QRect CropLabel::getRect(const QPoint &m_beginPoint, const QPoint &m_endPoint)
|
|||
}
|
||||
|
||||
|
||||
void CropLabel::initCropSettings()
|
||||
void CropLabel::initCropSettings(int width, int height)
|
||||
{
|
||||
// Not show crop box in first crop operation
|
||||
m_origRect.setRect(0,0,this->width(),this->height());
|
||||
m_beginX = 0;
|
||||
m_beginY = 0;
|
||||
m_endX = m_origRect.width();
|
||||
m_endY = m_origRect.height();
|
||||
if(width == 0 || height == 0){
|
||||
m_endX = m_origRect.width()-1;
|
||||
m_endY = m_origRect.height()-1;
|
||||
}else{
|
||||
m_endX = width-1;
|
||||
m_endY = height-1;
|
||||
}
|
||||
m_beginPoint = QPoint(m_beginX, m_beginY);
|
||||
m_endPoint = QPoint(m_endX, m_endY);
|
||||
update();
|
||||
calculateDetectRegion();
|
||||
|
||||
m_hasCropRegion = false;
|
||||
|
||||
}
|
||||
|
||||
void CropLabel::loadAllPixmaps()
|
||||
|
|
|
@ -50,7 +50,6 @@ public:
|
|||
|
||||
int judgePosition(int origin, int min, int max);
|
||||
bool isPressPointInCropRegion(QPoint mousePressPoint);
|
||||
bool drawPixmapBorder(QRect rect, int W, int H);
|
||||
QRect getRect(const QPoint &m_beginPoint, const QPoint &m_endPoint);
|
||||
void calculateDetectRegion();
|
||||
void initCropRegion();
|
||||
|
@ -72,7 +71,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void initCropSettings();
|
||||
void initCropSettings(int width=0, int height=0);
|
||||
void loadAllPixmaps();
|
||||
|
||||
enum CropStates {
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
#include "custom_push_button.h"
|
||||
#include <QDebug>
|
||||
|
||||
CustomPushButton::CustomPushButton(QWidget *parent)
|
||||
: kdk::KPushButton(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CustomPushButton::CustomPushButton(QString &text, QWidget *parent)
|
||||
: kdk::KPushButton(parent), m_fullText(text)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CustomPushButton::setText(const QString &text)
|
||||
{
|
||||
setFullText(text);
|
||||
}
|
||||
|
||||
void CustomPushButton::setFullText(const QString &text)
|
||||
{
|
||||
m_fullText = text;
|
||||
update();
|
||||
}
|
||||
|
||||
void CustomPushButton::setTextLimitShrink(const QString &text, int width)
|
||||
{
|
||||
this->setMinimumWidth(qMin(this->fontMetrics().width(text), width));
|
||||
setFullText(text);
|
||||
}
|
||||
|
||||
void CustomPushButton::setTextLimitExpand(const QString &text)
|
||||
{
|
||||
int textWidth = this->fontMetrics().width(text);
|
||||
this->setMaximumWidth(textWidth);
|
||||
setFullText(text);
|
||||
}
|
||||
|
||||
QString CustomPushButton::fullText() const
|
||||
{
|
||||
return m_fullText;
|
||||
}
|
||||
|
||||
void CustomPushButton::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
kdk::KPushButton::paintEvent(event);
|
||||
elideText();
|
||||
}
|
||||
|
||||
void CustomPushButton::elideText()
|
||||
{
|
||||
int margin = 32;
|
||||
QFontMetrics fm = this->fontMetrics();
|
||||
int dif = fm.width(m_fullText) + margin - this->width() ;
|
||||
if (dif > 0) {
|
||||
QString showText = fm.elidedText(m_fullText, Qt::ElideRight, this->width() - margin);
|
||||
kdk::KPushButton::setText(showText);
|
||||
if (showText != m_fullText) {
|
||||
QString str = m_fullText;
|
||||
this->setToolTip(str);
|
||||
} else {
|
||||
this->setToolTip("");
|
||||
}
|
||||
} else {
|
||||
kdk::KPushButton::setText(m_fullText);
|
||||
this->setToolTip("");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef CUSTOM_PUSH_BUTTON_H
|
||||
#define CUSTOM_PUSH_BUTTON_H
|
||||
|
||||
#include <kpushbutton.h>
|
||||
#include <QString>
|
||||
|
||||
class CustomPushButton : public kdk::KPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CustomPushButton(QWidget *parent=0);
|
||||
explicit CustomPushButton(QString &text, QWidget *parent=0);
|
||||
|
||||
void setText(const QString &text);
|
||||
void setFullText(const QString &text);
|
||||
void setTextLimitShrink(const QString &text, int width);
|
||||
void setTextLimitExpand(const QString &text);
|
||||
QString fullText() const;
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
private:
|
||||
void elideText();
|
||||
private:
|
||||
QString m_fullText;
|
||||
};
|
||||
#endif // CUSTOM_PUSH_BUTTON_H
|
|
@ -0,0 +1,48 @@
|
|||
#include "customtablewidget.h"
|
||||
|
||||
CustomTableWidget::CustomTableWidget(QList<QString> header, QWidget *parent) : QTreeWidget(parent)
|
||||
{
|
||||
this->setColumnCount(2);
|
||||
this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
// 将表格变为禁止编辑,取消焦点
|
||||
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
this->setFocusPolicy(Qt::NoFocus);
|
||||
// 设置表格不可选中
|
||||
this->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
// 设置水平方向的表头标签与垂直方向上的表头标签,注意必须在初始化行列之后进行,否则,没有效果
|
||||
this->setHeaderLabels(header);
|
||||
|
||||
//设置表头文字左对齐
|
||||
this->header()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
this->header()->setFixedHeight(40);
|
||||
this->header()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
//设置交替背景色
|
||||
this->setAlternatingRowColors(true);
|
||||
this->setUniformRowHeights(true);
|
||||
|
||||
this->setMouseTracking(true);
|
||||
this->setRootIsDecorated(false);
|
||||
}
|
||||
|
||||
void CustomTableWidget::insertItem(int i, QStringList content)
|
||||
{
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setFixedHeight(40);
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(content);
|
||||
item->setSizeHint(i, QSize(240, 40));
|
||||
item->setTextAlignment(0, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
this->insertTopLevelItem(i, item);
|
||||
this->setItemWidget(item, 2, widget);
|
||||
}
|
||||
|
||||
QStringList CustomTableWidget::getSelectedRow()
|
||||
{
|
||||
QList<QTreeWidgetItem*> items = this->selectedItems();
|
||||
QStringList contents;
|
||||
for(int i = 0; i < items.length(); i++){
|
||||
for(int j = 0; j <items.at(i)->columnCount(); j++){
|
||||
contents.append(items.at(i)->text(j));
|
||||
}
|
||||
}
|
||||
return contents;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef CUSTOMTABLEWIDGET_H
|
||||
#define CUSTOMTABLEWIDGET_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTreeWidget>
|
||||
#include <QScrollArea>
|
||||
#include <QHeaderView>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
class CustomTableWidget : public QTreeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CustomTableWidget(QList<QString> header, QWidget *parent = nullptr);
|
||||
|
||||
void insertItem(int i, QStringList content);
|
||||
QStringList getSelectedRow();
|
||||
};
|
||||
|
||||
#endif // CUSTOMTABLEWIDGET_H
|
|
@ -16,30 +16,34 @@
|
|||
*
|
||||
*/
|
||||
#include "detectpagewidget.h"
|
||||
#include <gsettings.hpp>
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
|
||||
#include "include/theme.h"
|
||||
|
||||
DetectPageWidget::DetectPageWidget(QWidget *parent) : QWidget(parent),
|
||||
m_detectPageIcon(new QLabel()),
|
||||
m_detectPageText(new QLabel()),
|
||||
m_detectPageVLayout(new QVBoxLayout())
|
||||
m_detectPageIcon(new QLabel(this)),
|
||||
m_detectPageText(new QLabel(this)),
|
||||
m_detectPageVLayout(new QVBoxLayout(this))
|
||||
{
|
||||
if (QGSettings::isSchemaInstalled(UKUI_THEME_GSETTING_PATH)) {
|
||||
m_themeData = new QGSettings(UKUI_THEME_GSETTING_PATH);
|
||||
}
|
||||
setupGui();
|
||||
initTheme();
|
||||
initConnect();
|
||||
}
|
||||
|
||||
void DetectPageWidget::setupGui()
|
||||
{
|
||||
this->setProperty("useSystemStyleBlur", true);
|
||||
setAutoFillBackground(true);
|
||||
setBackgroundRole(QPalette::Window);
|
||||
|
||||
getFileListNum();
|
||||
|
||||
waitingTimer = new QTimer();
|
||||
setWaitTimerStart();
|
||||
|
||||
|
||||
m_detectPageIcon->setFixedSize(DetectPageIconSize);
|
||||
// m_detectPageIcon->setPixmap(QIcon::fromTheme("kylin-scanner").pixmap(m_detectPageIcon->size()));
|
||||
|
||||
m_detectPageText->setEnabled(false);
|
||||
m_detectPageText->setText(tr("Detect scanners, please waiting"));
|
||||
|
||||
|
@ -55,34 +59,15 @@ void DetectPageWidget::setupGui()
|
|||
|
||||
|
||||
}
|
||||
void DetectPageWidget::initTheme(){
|
||||
if (isDarkTheme()) {
|
||||
themeColor = "black";
|
||||
} else {
|
||||
themeColor = "white";
|
||||
}
|
||||
}
|
||||
|
||||
void DetectPageWidget::initConnect()
|
||||
{
|
||||
connect(waitingTimer, SIGNAL(timeout()), this, SLOT(showWaitImages()));
|
||||
|
||||
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &DetectPageWidget::initTheme);
|
||||
|
||||
connect(g_user_signal, &GlobalUserSignal::detectPageWaitTimerStartSignal, this, &DetectPageWidget::setWaitTimerStart);
|
||||
connect(g_user_signal, &GlobalUserSignal::detectPageWaitTimerStopSignal, this, &DetectPageWidget::setWaitTimerStop);
|
||||
|
||||
}
|
||||
bool DetectPageWidget::isDarkTheme()
|
||||
{
|
||||
QString systemTheme = kdk::kabase::Gsettings::getSystemTheme().toString();
|
||||
|
||||
if (systemTheme == STYLE_NAME_KEY_DARK || systemTheme == STYLE_NAME_KEY_BLACK) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void DetectPageWidget::getFileListNum()
|
||||
{
|
||||
path = ":/loading/";
|
||||
|
@ -111,16 +96,11 @@ void DetectPageWidget::showWaitImages()
|
|||
{
|
||||
fileinfo = GetFileList(path).at(count);
|
||||
m_detectPageIcon->setScaledContents(true);
|
||||
|
||||
// QPixmap pix(70, 70);
|
||||
// pix.load(fileinfo.filePath());
|
||||
// m_detectPageIcon->setPixmap(pix);
|
||||
|
||||
|
||||
if (! themeColor.compare("white", Qt::CaseInsensitive)) {
|
||||
m_detectPageIcon->setPixmap(SVGHandler::loadSvgColor(fileinfo.filePath(), "black", 70));
|
||||
} else {
|
||||
themeColor = m_themeData->get("styleName").toString();
|
||||
if (themeColor.compare("ukui-dark", Qt::CaseInsensitive) == 0 || themeColor.compare("ukui-black", Qt::CaseInsensitive) == 0) {
|
||||
m_detectPageIcon->setPixmap(SVGHandler::loadSvgColor(fileinfo.filePath(), "white", 70));
|
||||
} else {
|
||||
m_detectPageIcon->setPixmap(SVGHandler::loadSvgColor(fileinfo.filePath(), "black", 70));
|
||||
}
|
||||
|
||||
++count;
|
||||
|
|
|
@ -32,12 +32,13 @@
|
|||
#include <QFileInfoList>
|
||||
#include <QDir>
|
||||
#include <QMovie>
|
||||
|
||||
#include <QGSettings>
|
||||
#include <ukui-log4qt.h>
|
||||
#include "globalsignal.h"
|
||||
#include "svghandler.h"
|
||||
|
||||
#define DetectPageIconSize QSize(40, 40)
|
||||
#define UKUI_THEME_GSETTING_PATH "org.ukui.style"
|
||||
|
||||
class DetectPageWidget : public QWidget
|
||||
{
|
||||
|
@ -47,7 +48,6 @@ public:
|
|||
|
||||
void setupGui();
|
||||
void initConnect();
|
||||
|
||||
void getFileListNum();
|
||||
QFileInfoList GetFileList(QString path);
|
||||
|
||||
|
@ -56,22 +56,19 @@ public slots:
|
|||
void setWaitTimerStart();
|
||||
void setWaitTimerStop();
|
||||
|
||||
private slots:
|
||||
void initTheme();
|
||||
|
||||
private:
|
||||
int num = 0;
|
||||
int count = 0;
|
||||
|
||||
QFileInfo fileinfo;
|
||||
QString path;
|
||||
QTimer *waitingTimer;
|
||||
QTimer *waitingTimer = nullptr;
|
||||
QLabel *m_detectPageIcon = nullptr;
|
||||
QLabel *m_detectPageText = nullptr;
|
||||
QString themeColor = "white";
|
||||
QLabel *m_detectPageIcon;
|
||||
QLabel *m_detectPageText;
|
||||
QVBoxLayout *m_detectPageVLayout;
|
||||
QGSettings *m_themeData = nullptr;
|
||||
|
||||
bool isDarkTheme();
|
||||
QVBoxLayout *m_detectPageVLayout = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
project(device LANGUAGES CXX C)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11")
|
||||
set(prj_name ${PROJECT_NAME})
|
||||
find_package(QT NAMES Qt6 Qt5)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets LinguistTools Network DBus REQUIRED)
|
||||
|
||||
include_directories(
|
||||
${PROJECT_SOURCE_DIR}/avahi_qt/
|
||||
${PROJECT_SOURCE_DIR}/qt_zeroconf/
|
||||
)
|
||||
|
||||
set(SRC
|
||||
./qt_zeroconf/zconfserviceclient.h
|
||||
./qt_zeroconf/zconfservice.h
|
||||
./qt_zeroconf/zconfservicebrowser.h
|
||||
./deviceFinder.h
|
||||
./avahi_qt/qt_watch.h
|
||||
./singleton.h
|
||||
./connect.h
|
||||
./snmpFinder.h
|
||||
./network_device_detector.h
|
||||
./base_info.h
|
||||
./common.h
|
||||
./device_information.h
|
||||
./ukui_apt.h
|
||||
./snmpwalk_browser.h
|
||||
./usbFinder.h
|
||||
|
||||
./device_information.cpp
|
||||
./common.cpp
|
||||
./qt_zeroconf/zconfservicebrowser.cpp
|
||||
./qt_zeroconf/zconfservice.cpp
|
||||
./qt_zeroconf/zconfserviceclient.cpp
|
||||
./network_device_detector.cpp
|
||||
./base_info.cpp
|
||||
./avahi_qt/qt_watch.cpp
|
||||
./deviceFinder.cpp
|
||||
./snmpwalk_browser.cpp
|
||||
./connect.cpp
|
||||
./usbFinder.cpp
|
||||
./snmpFinder.cpp
|
||||
./ukui_apt.cpp
|
||||
./main.cpp
|
||||
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SRC})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::DBus)
|
||||
target_link_libraries(${prj_name} "-lusb-1.0")
|
||||
target_link_libraries(${prj_name} "-ludev")
|
||||
target_link_libraries(${prj_name} "-lcups")
|
||||
target_link_libraries(${PROJECT_NAME} "-lpthread -lz")
|
||||
target_link_libraries(${PROJECT_NAME} "-lbsd")
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_search_module(GLIB REQUIRED glib-2.0)
|
||||
include_directories(${GLIB_INCLUDE_DIRS})
|
||||
target_link_libraries(${prj_name} "-lglib-2.0")
|
||||
|
||||
find_library(NETSNMPAGENT "netsnmpagent")
|
||||
find_library(NETSNMPMIBS "netsnmpmibs")
|
||||
find_library(NETSNMP "netsnmp")
|
||||
target_link_libraries(${prj_name} ${NETSNMPAGENT} ${NETSNMPMIBS} ${NETSNMP})
|
||||
|
||||
target_link_libraries(${prj_name} "-lavahi-common -lavahi-client")
|
|
@ -0,0 +1,152 @@
|
|||
/***
|
||||
This file is part of avahi.
|
||||
|
||||
avahi is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
avahi is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with avahi; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA.
|
||||
***/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <QSocketNotifier>
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
#include <avahi-common/timeval.h>
|
||||
|
||||
#include "qt_watch.h"
|
||||
|
||||
|
||||
AvahiWatch::AvahiWatch(int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void* userdata) :
|
||||
m_in(0), m_out(0), m_callback(callback), m_fd(fd), m_userdata(userdata), m_incallback(false)
|
||||
{
|
||||
setWatchedEvents(event);
|
||||
}
|
||||
|
||||
AvahiWatch::~AvahiWatch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AvahiWatch::gotIn()
|
||||
{
|
||||
m_lastEvent = AVAHI_WATCH_IN;
|
||||
m_incallback=true;
|
||||
m_callback(this,m_fd,m_lastEvent,m_userdata);
|
||||
m_incallback=false;
|
||||
}
|
||||
|
||||
void AvahiWatch::gotOut()
|
||||
{
|
||||
m_lastEvent = AVAHI_WATCH_IN;
|
||||
m_incallback=true;
|
||||
m_callback(this,m_fd,m_lastEvent,m_userdata);
|
||||
m_incallback=false;
|
||||
}
|
||||
|
||||
void AvahiWatch::setWatchedEvents(AvahiWatchEvent event)
|
||||
{
|
||||
if (!(event & AVAHI_WATCH_IN)) { delete m_in; m_in=0; }
|
||||
if (!(event & AVAHI_WATCH_OUT)) { delete m_out; m_out=0; }
|
||||
if (event & AVAHI_WATCH_IN) {
|
||||
m_in = new QSocketNotifier(m_fd,QSocketNotifier::Read, this);
|
||||
connect(m_in,SIGNAL(activated(int)),SLOT(gotIn()));
|
||||
}
|
||||
if (event & AVAHI_WATCH_OUT) {
|
||||
m_out = new QSocketNotifier(m_fd,QSocketNotifier::Write, this);
|
||||
connect(m_out,SIGNAL(activated(int)),SLOT(gotOut()));
|
||||
}
|
||||
}
|
||||
|
||||
AvahiTimeout::AvahiTimeout(const struct timeval* tv, AvahiTimeoutCallback callback, void *userdata) :
|
||||
m_callback(callback), m_userdata(userdata)
|
||||
{
|
||||
connect(&m_timer, SIGNAL(timeout()), this, SLOT(timeout()));
|
||||
|
||||
m_timer.setSingleShot(true);
|
||||
|
||||
update(tv);
|
||||
}
|
||||
|
||||
AvahiTimeout::~AvahiTimeout()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AvahiTimeout::update(const struct timeval *tv)
|
||||
{
|
||||
m_timer.stop();
|
||||
if (tv) {
|
||||
AvahiUsec u = avahi_age(tv)/1000;
|
||||
m_timer.start( (u>0) ? 0 : -u);
|
||||
}
|
||||
}
|
||||
|
||||
void AvahiTimeout::timeout()
|
||||
{
|
||||
m_callback(this,m_userdata);
|
||||
}
|
||||
|
||||
static AvahiWatch* q_watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback,
|
||||
void *userdata)
|
||||
{
|
||||
return new AvahiWatch(fd, event, callback, userdata);
|
||||
}
|
||||
|
||||
static void q_watch_update(AvahiWatch *w, AvahiWatchEvent events)
|
||||
{
|
||||
w->setWatchedEvents(events);
|
||||
}
|
||||
|
||||
static AvahiWatchEvent q_watch_get_events(AvahiWatch *w)
|
||||
{
|
||||
return w->getEvents();
|
||||
}
|
||||
|
||||
static void q_watch_free(AvahiWatch *w)
|
||||
{
|
||||
delete w;
|
||||
}
|
||||
|
||||
static AvahiTimeout* q_timeout_new(const AvahiPoll *api, const struct timeval *tv, AvahiTimeoutCallback callback,
|
||||
void *userdata)
|
||||
{
|
||||
return new AvahiTimeout(tv, callback, userdata);
|
||||
}
|
||||
|
||||
static void q_timeout_update(AvahiTimeout *t, const struct timeval *tv)
|
||||
{
|
||||
t->update(tv);
|
||||
}
|
||||
|
||||
static void q_timeout_free(AvahiTimeout *t)
|
||||
{
|
||||
delete t;
|
||||
}
|
||||
|
||||
const AvahiPoll* avahi_qt_poll_get(void)
|
||||
{
|
||||
static const AvahiPoll qt_poll = {
|
||||
NULL,
|
||||
q_watch_new,
|
||||
q_watch_update,
|
||||
q_watch_get_events,
|
||||
q_watch_free,
|
||||
q_timeout_new,
|
||||
q_timeout_update,
|
||||
q_timeout_free
|
||||
};
|
||||
|
||||
return &qt_poll;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef QAVAHI_H
|
||||
#define QAVAHI_H
|
||||
|
||||
/***
|
||||
This file is part of avahi.
|
||||
|
||||
avahi is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
avahi is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with avahi; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA.
|
||||
***/
|
||||
|
||||
/** \file qt_watch.h Qt main loop adapter */
|
||||
|
||||
#include <QSocketNotifier>
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
|
||||
#include <avahi-common/watch.h>
|
||||
#include <avahi-common/cdecl.h>
|
||||
|
||||
class AvahiWatch : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AvahiWatch(int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void* userdata);
|
||||
~AvahiWatch();
|
||||
AvahiWatchEvent getEvents() const { return m_incallback ? m_lastEvent : (AvahiWatchEvent)0; }
|
||||
void setWatchedEvents(AvahiWatchEvent event);
|
||||
|
||||
private Q_SLOTS:
|
||||
void gotIn();
|
||||
void gotOut();
|
||||
|
||||
private:
|
||||
QSocketNotifier* m_in;
|
||||
QSocketNotifier* m_out;
|
||||
//FIXME: ERR and HUP?
|
||||
AvahiWatchCallback m_callback;
|
||||
AvahiWatchEvent m_lastEvent;
|
||||
int m_fd;
|
||||
void* m_userdata;
|
||||
bool m_incallback;
|
||||
};
|
||||
|
||||
class AvahiTimeout : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AvahiTimeout(const struct timeval* tv, AvahiTimeoutCallback callback, void* userdata);
|
||||
~AvahiTimeout();
|
||||
void update(const struct timeval* tv);
|
||||
|
||||
private Q_SLOTS:
|
||||
void timeout();
|
||||
|
||||
private:
|
||||
QTimer m_timer;
|
||||
AvahiTimeoutCallback m_callback;
|
||||
void* m_userdata;
|
||||
};
|
||||
|
||||
AVAHI_C_DECL_BEGIN
|
||||
|
||||
/** Setup abstract poll structure for integration with Qt main loop */
|
||||
const AvahiPoll* avahi_qt_poll_get(void)
|
||||
#ifdef HAVE_VISIBILITY_HIDDEN
|
||||
__attribute__ ((visibility("default")))
|
||||
#endif
|
||||
;
|
||||
|
||||
AVAHI_C_DECL_END
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
#include "base_info.h"
|
||||
#include "common.h"
|
||||
|
||||
BaseInfo::BaseInfo()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
BaseInfo::~BaseInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BaseInfo::init()
|
||||
{
|
||||
m_appDisplayName = "Scanner";
|
||||
m_debianArchitecture = getRetFromCommand(QStringList{"dpkg", "--print-architecture"});
|
||||
m_serverAddress = "api.kylinos.cn";
|
||||
}
|
||||
|
||||
QString BaseInfo::getAppDisplayName()
|
||||
{
|
||||
return m_appDisplayName;
|
||||
}
|
||||
|
||||
QString BaseInfo::getDebianArchitecture()
|
||||
{
|
||||
return m_debianArchitecture;
|
||||
}
|
||||
|
||||
QString BaseInfo::getServerAddress()
|
||||
{
|
||||
return m_serverAddress;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef BASEINFO_H
|
||||
#define BASEINFO_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include "singleton.h"
|
||||
|
||||
class BaseInfo : public QObject,
|
||||
public Singleton<BaseInfo>
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class Singleton<BaseInfo>;
|
||||
private:
|
||||
BaseInfo();
|
||||
~BaseInfo() override;
|
||||
|
||||
void init();
|
||||
public:
|
||||
QString getAppDisplayName();
|
||||
QString getDebianArchitecture();
|
||||
QString getServerAddress();
|
||||
private:
|
||||
QString m_appDisplayName;
|
||||
QString m_debianArchitecture;
|
||||
QString m_serverAddress;
|
||||
};
|
||||
|
||||
#endif // BASEINFO_H
|
|
@ -0,0 +1,192 @@
|
|||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include <QStringList>
|
||||
#include <QDebug>
|
||||
#include <QProcess>
|
||||
#include <QByteArray>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
CheckRes checkCommand(const QStringList &command)
|
||||
{
|
||||
if (command.isEmpty())
|
||||
return MAINWINDOW;
|
||||
else if(command.at(0).compare("debug")==0)
|
||||
return DEBUG;
|
||||
else if(command.at(0).compare("show")==0)
|
||||
return MAINWINDOW;
|
||||
else if (command.size() != 2) {
|
||||
return CHECK_FALSE;
|
||||
}
|
||||
else if (command.at(0).compare("add")==0
|
||||
|| command.at(0).compare("remove")==0
|
||||
|| command.at(0).compare("add_uri")==0 ) {
|
||||
|
||||
return POPWINDOW;
|
||||
}
|
||||
return CHECK_FALSE;
|
||||
}
|
||||
|
||||
QString getRetFromCommand(const QStringList &command)
|
||||
{
|
||||
QProcess proc;
|
||||
QStringList options;
|
||||
options << "-c"<< command.join(" ");
|
||||
proc.closeWriteChannel();
|
||||
proc.start("bash", options);
|
||||
if (!proc.waitForFinished())
|
||||
return "";
|
||||
QString res = QString(proc.readAll());
|
||||
proc.close();
|
||||
if(res.right(1) == "\n")
|
||||
res.chop(1);
|
||||
return res;
|
||||
}
|
||||
|
||||
void runCommand(const QStringList &command)
|
||||
{
|
||||
QProcess proc;
|
||||
QStringList options;
|
||||
options << "-c"<< command.join(" ");
|
||||
proc.closeWriteChannel();
|
||||
proc.startDetached("bash", options);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
QByteArray qstringTochar(const QString &qstr)
|
||||
{
|
||||
if (qstr.isEmpty())
|
||||
return nullptr;
|
||||
QByteArray ba = qstr.toLocal8Bit();
|
||||
return ba;
|
||||
}
|
||||
|
||||
QString getUserName()
|
||||
{
|
||||
uid_t uid;
|
||||
uid_t NO_UID = -1;
|
||||
struct passwd *pw;
|
||||
|
||||
errno = 0;
|
||||
uid = geteuid ();
|
||||
if (uid == -1 && errno) {
|
||||
qDebug () << "get uid error";
|
||||
return "";
|
||||
}
|
||||
pw = getpwuid (uid);
|
||||
if (!pw) {
|
||||
qDebug ("cannot find name for user ID %lu", (unsigned long int) uid);
|
||||
return "";
|
||||
}
|
||||
return QString(pw->pw_name);
|
||||
}
|
||||
|
||||
bool isAdministratorUser()
|
||||
{
|
||||
static gid_t list[100];
|
||||
int n_gp = getgroups(100,list);
|
||||
struct group *gp;
|
||||
for(int i = 0;i < n_gp; i++) {
|
||||
gp = getgrgid(list[i]);
|
||||
if (!gp) {
|
||||
continue;
|
||||
}
|
||||
if(QString(gp->gr_name) == "lpadmin") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void specialDeviceCheck(QString &vendor, QString &model)
|
||||
{
|
||||
QMap<QString, QString>::const_iterator iter = mfgConvertMap.begin();
|
||||
while (iter != mfgConvertMap.end())
|
||||
{
|
||||
if (iter.key().compare(vendor, Qt::CaseInsensitive) == 0) {
|
||||
vendor = iter.value();
|
||||
break;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
if (model.indexOf("HP") == 0) {
|
||||
model.remove(0, 2);
|
||||
if (model.at(0) == " ") {
|
||||
model.remove(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (model.contains(" series")) {
|
||||
model.remove(" series");
|
||||
}
|
||||
}
|
||||
|
||||
QString devicePathCheck(const QString &path)
|
||||
{
|
||||
QString ppath = path;
|
||||
if (ppath.contains("unbind@"))
|
||||
ppath.remove("unbind@");
|
||||
if (ppath.contains("bind@"))
|
||||
ppath.remove("bind@");
|
||||
return ppath;
|
||||
}
|
||||
|
||||
bool ipIsValid(const QString &ipAddr)
|
||||
{
|
||||
QRegExp rx2("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$");
|
||||
if (!rx2.exactMatch(ipAddr)) {
|
||||
return false;
|
||||
} else {
|
||||
QStringList pieces = ipAddr.split(".");
|
||||
bool ok = true;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int num = pieces.value(i).toInt(&ok, 10); //合理性判断
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
if (num > 255) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool printerNameIsLegal(const QString &printerName)
|
||||
{
|
||||
if (printerName.contains(" ")
|
||||
|| printerName.contains("/")
|
||||
|| printerName.contains("\\")
|
||||
|| printerName.contains("'")
|
||||
|| printerName.contains('"')
|
||||
|| printerName.contains("?")
|
||||
|| printerName.contains("#")
|
||||
|| printerName.toLocal8Bit().size() > 127) {
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool processCheck(const QString &processName) {
|
||||
QString cmd = QString("ps -ef | grep %1 | grep -v grep | awk '{print $2}'").arg(processName);
|
||||
QString res = getRetFromCommand(cmd.split(" "));
|
||||
if (res != "" && res.toInt() > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString getPackageVersion(const QString &packageName)
|
||||
{
|
||||
QString res{QString()};
|
||||
if (packageName.isEmpty()) {
|
||||
return res;
|
||||
}
|
||||
QString cmd = QString("/usr/bin/dpkg-query -W -f='${Version}\\n' %1").arg(packageName);
|
||||
res = ::getRetFromCommand(cmd.split(" "));
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#ifndef KYLIN_PRINTER_COMMON_H
|
||||
#define KYLIN_PRINTER_COMMON_H
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
#include <map>
|
||||
|
||||
#define QTC(x) (qstringTochar(x).data())
|
||||
|
||||
enum CheckRes{
|
||||
CHECK_FALSE = 0,
|
||||
MAINWINDOW,
|
||||
POPWINDOW,
|
||||
DEBUG,
|
||||
};
|
||||
|
||||
enum class PopWinStatus : int
|
||||
{
|
||||
HIDE = 0,
|
||||
INSTALLING,
|
||||
INSTALL_SUCCESS,
|
||||
INSTALL_FAIL,
|
||||
};
|
||||
|
||||
CheckRes checkCommand(const QStringList &command);
|
||||
|
||||
QString getRetFromCommand(const QStringList &command);
|
||||
|
||||
void runCommand(const QStringList &command);
|
||||
|
||||
QByteArray qstringTochar(const QString &qstr);
|
||||
|
||||
QString getUserName();
|
||||
|
||||
bool isAdministratorUser();
|
||||
|
||||
const QMap<QString, QString> mfgConvertMap = {
|
||||
std::map<QString, QString>::value_type("Lenovo Image", "Lenovo"),
|
||||
std::map<QString, QString>::value_type("Fuji Xerox", "Fuji-Xerox"),
|
||||
std::map<QString, QString>::value_type("INDEX BRAILLE", "INDEX-BRAILLE"),
|
||||
std::map<QString, QString>::value_type("KONICA MINOLTA", "KONICA-MINOLTA"),
|
||||
std::map<QString, QString>::value_type("Hewlett-Packard", "HP")
|
||||
};
|
||||
|
||||
void specialDeviceCheck(QString &vendor, QString &model);
|
||||
|
||||
extern QString devicePathCheck(const QString &path);
|
||||
|
||||
extern bool ipIsValid(const QString &ipAddr);
|
||||
|
||||
extern bool printerNameIsLegal(const QString &printerName);
|
||||
|
||||
enum class CommonStatusFlag : int
|
||||
{
|
||||
NONE = 0,
|
||||
SUCCESS,
|
||||
FAIL,
|
||||
|
||||
ERROR_EXIST_SAME_PRINTER,
|
||||
};
|
||||
|
||||
struct CommonStatus {
|
||||
CommonStatusFlag status{CommonStatusFlag::NONE};
|
||||
QString message{QString()};
|
||||
};
|
||||
|
||||
extern bool processCheck(const QString &processName);
|
||||
|
||||
QString getPackageVersion(const QString &packageName);
|
||||
|
||||
#endif // KYLIN_PRINTER_COMMON_H
|
|
@ -0,0 +1,54 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "connect.h"
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
|
||||
// return : - 0 on success or -1 on error
|
||||
// addrname: - Hostname or IP address
|
||||
// port - Port number
|
||||
int try_connect(const char *addrname, int port)
|
||||
{
|
||||
int fd; /* Socket */
|
||||
int status; /* Connection status */
|
||||
struct sockaddr_in ipv4;
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
qDebug("ERROR: Unable to create socket: %s\n",
|
||||
strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
bzero(&ipv4, sizeof(ipv4));
|
||||
ipv4.sin_family = AF_INET;
|
||||
ipv4.sin_addr.s_addr = inet_addr(addrname);
|
||||
ipv4.sin_port = htons(port);
|
||||
|
||||
struct timeval timeout={5,0};
|
||||
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval));
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));
|
||||
|
||||
status = connect(fd, (struct sockaddr *)&ipv4, (socklen_t)sizeof(ipv4));
|
||||
|
||||
close(fd);
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
int tryConnectFromHost(const QString &hostname)
|
||||
{
|
||||
QHostInfo host = QHostInfo::fromName(hostname);
|
||||
return host.error();
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef KYLIN_PRINTER_CONNECT_H
|
||||
#define KYLIN_PRINTER_CONNECT_H
|
||||
|
||||
int try_connect(const char *addrname, int port);
|
||||
|
||||
int tryConnectFromHost(const QString &hostname);
|
||||
|
||||
#endif // KYLIN_PRINTER_CONNECT_H
|
|
@ -0,0 +1,215 @@
|
|||
//
|
||||
// Created by oubayasho on 2023/6/6.
|
||||
//
|
||||
|
||||
#include "deviceFinder.h"
|
||||
#include "usbFinder.h"
|
||||
#include "snmpFinder.h"
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include "common.h"
|
||||
#include "connect.h"
|
||||
#include <sane/sane.h>
|
||||
#include <buriedpoint.hpp>
|
||||
#include "base_info.h"
|
||||
|
||||
bool deviceFinder::checkDeviceExistInSane(DeviceInformation &deviceInformation)
|
||||
{
|
||||
if (m_saneInfoList.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (deviceInformation.model.isEmpty() || deviceInformation.vendor.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto saneInfo : m_saneInfoList) {
|
||||
if (saneInfo.vendor == deviceInformation.vendor && saneInfo.model == deviceInformation.model) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool packageIsInstalled(const QString &debName, const QString &packageName)
|
||||
{
|
||||
// brscan5chn_1.2.5-0_amd64.deb
|
||||
QString packageVersion = getPackageVersion(packageName);
|
||||
if (packageVersion.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
QString deb(debName);
|
||||
if (!deb.contains("_")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
deb.remove(0, deb.indexOf("_") + 1);
|
||||
|
||||
if (!deb.contains("_")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString debVersion = deb.left(deb.indexOf("_"));
|
||||
if (debVersion.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (debVersion != packageVersion) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deviceFinder::infoCheck(DeviceInformation &deviceInformation) {
|
||||
if (m_isServerAddressConnected) {
|
||||
getPackagesNameFromHttp(deviceInformation);
|
||||
} else {
|
||||
if (checkDeviceExistInSane(deviceInformation)) {
|
||||
return false;
|
||||
} else {
|
||||
if (deviceInformation.type == DeviceType::SCANNER) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
qDebug() << deviceInformation;
|
||||
if (deviceInformation.type != DeviceType::SCANNER) {
|
||||
return false;
|
||||
}
|
||||
int needInstall = false;
|
||||
for (int i = 0; i < deviceInformation.packageNameList.size(); i++) {
|
||||
if (packageIsInstalled(deviceInformation.debNameList[i], deviceInformation.packageNameList[i]) == false) {
|
||||
needInstall = true;
|
||||
}
|
||||
}
|
||||
if (needInstall == true) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
deviceFinder::deviceFinder(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
m_thread = new QThread();
|
||||
moveToThread(m_thread);
|
||||
|
||||
connect(m_thread, &QThread::started, this, &deviceFinder::dowork);
|
||||
|
||||
connect(this, &deviceFinder::finished, m_thread, &QThread::quit);
|
||||
connect(this, &deviceFinder::finished, this, &deviceFinder::deleteLater);
|
||||
connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater);
|
||||
}
|
||||
|
||||
deviceFinder::~deviceFinder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void deviceFinder::dowork()
|
||||
{
|
||||
if (tryConnectFromHost(BaseInfo::instance().getServerAddress())) {
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerServerAddressConnectFail)));
|
||||
buried_data.insert(std::make_pair("action", std::string("connect to ") + BaseInfo::instance().getServerAddress().toStdString() + " failed."));
|
||||
buried_data.insert(std::make_pair("function", "in deviceFinder.cpp function dowork()"));
|
||||
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
|
||||
m_isServerAddressConnected = false;
|
||||
qDebug() << "cannot connect to server address!";
|
||||
} else {
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerServerAddressConnectSuccess)));
|
||||
buried_data.insert(std::make_pair("action", std::string("connect to ") + BaseInfo::instance().getServerAddress().toStdString() + " succeed."));
|
||||
buried_data.insert(std::make_pair("function", "in deviceFinder.cpp function dowork()"));
|
||||
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
|
||||
m_isServerAddressConnected = true;
|
||||
}
|
||||
if (m_isServerAddressConnected == false) {
|
||||
const SANE_Device **saneDeviceList{nullptr};
|
||||
sane_get_devices(&saneDeviceList, 0);
|
||||
for (int i = 0; saneDeviceList[i]; i++) {
|
||||
DeviceInformation info;
|
||||
info.vendor = QString("%1").arg(saneDeviceList[i]->vendor);
|
||||
info.model = QString("%1").arg(saneDeviceList[i]->model);
|
||||
specialDeviceCheck(info.model, info.vendor);
|
||||
m_saneInfoList.append(info);
|
||||
}
|
||||
}
|
||||
usbFinder u;
|
||||
u.dowork();
|
||||
auto list = u.getList();
|
||||
qDebug() << list;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (infoCheck(list[i])) {
|
||||
m_infoList.append(list[i]);
|
||||
}
|
||||
}
|
||||
list.clear();
|
||||
snmpFinder s;
|
||||
s.dowork();
|
||||
list = s.getList();
|
||||
qDebug() << list;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (infoCheck(list[i])) {
|
||||
m_infoList.append(list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加埋点信息
|
||||
if(m_isServerAddressConnected){
|
||||
buriedDeviceInfomation(m_infoList);
|
||||
}
|
||||
|
||||
succeed();
|
||||
}
|
||||
|
||||
QList<DeviceInformation> deviceFinder::getList()
|
||||
{
|
||||
return m_infoList;
|
||||
}
|
||||
|
||||
void deviceFinder::doPackageWork()
|
||||
{
|
||||
this->succeed();
|
||||
}
|
||||
|
||||
void deviceFinder::buriedDeviceInfomation(QList<DeviceInformation> list)
|
||||
{
|
||||
for(int i = 0; i < list.size(); i++){
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::kylinScannerDeviceAndDriverName)));
|
||||
buried_data.insert(std::make_pair("device_vendor", list[i].vendor.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_name", list[i].name.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_model", list[i].model.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_serial", list[i].serial.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_VID", list[i].VID.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_PID", list[i].PID.toLocal8Bit().data()));
|
||||
QString deb;
|
||||
for(int j = 0; j < list[i].debNameList.length(); ++j){
|
||||
deb += list[i].debNameList.at(j);
|
||||
deb += ";";
|
||||
}
|
||||
buried_data.insert(std::make_pair("debDriver", deb.toLocal8Bit().data()));
|
||||
|
||||
QString pkg;
|
||||
for(int j = 0; j < list[i].packageNameList.length(); ++j){
|
||||
pkg += list[i].packageNameList.at(j);
|
||||
deb += ";";
|
||||
}
|
||||
buried_data.insert(std::make_pair("packageNameList", pkg.toLocal8Bit().data()));
|
||||
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::StabilityType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// Created by oubayasho on 2023/6/6.
|
||||
//
|
||||
|
||||
#ifndef UNTITLED6_DEVICEFINDER_H
|
||||
#define UNTITLED6_DEVICEFINDER_H
|
||||
|
||||
#include <QTimer>
|
||||
#include "device_information.h"
|
||||
//#include "network_device_detector.h"
|
||||
#include <QThread>
|
||||
#include <sane/sane.h>
|
||||
|
||||
class deviceFinder : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
deviceFinder(QObject *parent = nullptr);
|
||||
~deviceFinder();
|
||||
QList<DeviceInformation> getList();
|
||||
Q_SIGNALS:
|
||||
void finished();
|
||||
void succeed();
|
||||
void failed();
|
||||
public:
|
||||
void startWorker(){
|
||||
if(m_thread!=nullptr)
|
||||
m_thread->start();
|
||||
}
|
||||
private:
|
||||
void dowork();
|
||||
void doPackageWork();
|
||||
bool infoCheck(DeviceInformation &deviceInformation);
|
||||
bool checkDeviceExistInSane(DeviceInformation &deviceInformation);
|
||||
void buriedDeviceInfomation(QList<DeviceInformation> list);
|
||||
QThread *m_thread{nullptr};
|
||||
QList<DeviceInformation> m_infoList;
|
||||
QList<DeviceInformation> m_saneInfoList;
|
||||
bool m_isServerAddressConnected{false};
|
||||
};
|
||||
|
||||
|
||||
#endif//UNTITLED6_DEVICEFINDER_H
|
|
@ -0,0 +1,196 @@
|
|||
#include <string>
|
||||
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QEventLoop>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QSysInfo>
|
||||
#include <QByteArray>
|
||||
#include <QDataStream>
|
||||
#include <buriedpoint.hpp>
|
||||
|
||||
#include "device_information.h"
|
||||
#include "base_info.h"
|
||||
|
||||
QString devInfoPrint(const DeviceInformation &debugInfo)
|
||||
{
|
||||
QString info = QString (
|
||||
QString("\n")
|
||||
+ QString("+++++++++++++++++++++++++++++++++\n")
|
||||
+ QString("connectType is: ") + QString::number(int(debugInfo.connectType)) + QString('\n')
|
||||
+ QString("protocolType is: ") + QString::number(int(debugInfo.protocolType)) + QString('\n')
|
||||
+ QString("name is: ") + debugInfo.name + QString('\n')
|
||||
+ QString("vendor is: ") + debugInfo.vendor + QString("\n")
|
||||
+ QString("model is: ") + debugInfo.model + QString("\n")
|
||||
+ QString("serial is: ") + debugInfo.serial + QString("\n")
|
||||
+ QString("uri is: ") + debugInfo.uri + QString("\n")
|
||||
+ QString("debNameList is: ") + debugInfo.debNameList.join(",") + QString("\n")
|
||||
+ QString("packageNameList is: ") + debugInfo.packageNameList.join(",") + QString("\n")
|
||||
+ QString("makeAndModel is: ") + debugInfo.makeAndModel + QString("\n")
|
||||
+ QString("uuid is: ") + debugInfo.uuid + QString("\n")
|
||||
+ QString("deviceId is: ") + debugInfo.deviceId + QString("\n")
|
||||
);
|
||||
if (debugInfo.connectType == ConnectType::InfoFrom_USB) {
|
||||
info += QString (
|
||||
QString("sysPath is: ") + debugInfo.sysPath + QString('\n')
|
||||
+ QString("devicePath is: ") + debugInfo.devicePath + QString("\n")
|
||||
+ QString("deviceType is: ") + debugInfo.deviceType + QString("\n")
|
||||
+ QString("busNumber is: ") + debugInfo.busNumber + QString("\n")
|
||||
+ QString("deviceNumber is: ") + debugInfo.deviceNumber + QString("\n")
|
||||
+ QString("VID is: ") + debugInfo.VID + QString("\n")
|
||||
+ QString("PID is: ") + debugInfo.PID + QString("\n")
|
||||
);
|
||||
}
|
||||
else {
|
||||
info += QString (
|
||||
QString("networkNode is: ") + debugInfo.networkNode + QString('\n')
|
||||
+ QString("host is: ") + debugInfo.host + QString('\n')
|
||||
);
|
||||
}
|
||||
info += QString("+++++++++++++++++++++++++++++++++\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
QDebug operator << (QDebug debug, const DeviceInformation &debugInfo)
|
||||
{
|
||||
debug.noquote();
|
||||
debug << devInfoPrint(debugInfo);
|
||||
return debug;
|
||||
}
|
||||
|
||||
QStringList getPackagesNameFromHttp(DeviceInformation &device)
|
||||
{
|
||||
QStringList res;
|
||||
|
||||
QString httpRequest = QString("https://%1/api/v1/getprintertype?systemVersion=%2&arch=%3%4%5%6%7")
|
||||
.arg(QString(BaseInfo::instance().getServerAddress()))
|
||||
.arg(QString("V10SP1"))
|
||||
.arg(BaseInfo::instance().getDebianArchitecture())
|
||||
.arg(device.PID.size() ? QString("&pid=" + device.PID) : "")
|
||||
.arg(device.VID.size() ? QString("&vid=" + device.VID) : "")
|
||||
.arg(device.vendor.size() ? QString("&manufacter=" + device.vendor) : "")
|
||||
.arg(device.model.size() ? QString("&model=" + device.model) : "");
|
||||
if(httpRequest.contains("+")){
|
||||
httpRequest.replace("+", "%2B");
|
||||
}
|
||||
// qDebug() << httpRequest;
|
||||
QNetworkAccessManager manager;
|
||||
QNetworkRequest netRequest;
|
||||
QNetworkReply *netReply;
|
||||
QEventLoop loop;
|
||||
qDebug () << "http link is :" << httpRequest;
|
||||
netRequest.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
|
||||
netRequest.setUrl(QUrl(httpRequest));
|
||||
netReply = manager.get(netRequest);
|
||||
|
||||
QTimer timer;
|
||||
QObject::connect(netReply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||
QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
||||
timer.start(10000);
|
||||
loop.exec();
|
||||
|
||||
if (netReply->error() != QNetworkReply::NoError) {
|
||||
return res;
|
||||
}
|
||||
|
||||
QByteArray strRateAll = netReply->readAll();
|
||||
qDebug() << "http result is"<<strRateAll;
|
||||
if (strRateAll == "") {
|
||||
qDebug() << "http request error: cannot get info form: " << httpRequest;
|
||||
return res;
|
||||
}
|
||||
QJsonParseError jsonParserError;
|
||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(strRateAll, &jsonParserError );
|
||||
qDebug() << strRateAll;
|
||||
if ( jsonDocument.isNull() || jsonParserError.error != QJsonParseError::NoError ) {
|
||||
qDebug () << "json解析失败";
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
qDebug() << "json解析成功!";
|
||||
}
|
||||
if (jsonDocument.isObject()) {
|
||||
QJsonObject jsonObject = jsonDocument.object();
|
||||
if ( jsonObject.contains("data")
|
||||
&& jsonObject.value("data").isArray() ) {
|
||||
|
||||
QJsonArray jsonArray = jsonObject.value("data").toArray();
|
||||
for ( int i = 0; i < jsonArray.size(); i++) {
|
||||
if (jsonArray.at(i).isObject()) {
|
||||
QJsonObject packages = jsonArray.at(i).toObject();
|
||||
qDebug() << packages;
|
||||
if ( !packages.contains("type")
|
||||
|| !packages.contains("packageName")
|
||||
|| !packages.contains("others")
|
||||
) {
|
||||
continue ;
|
||||
}
|
||||
|
||||
if (!packages.value("type").isString()) {
|
||||
continue ;
|
||||
}
|
||||
|
||||
device.type = DeviceType::SCANNER;
|
||||
|
||||
if (!packages.value("packageName").isString()) {
|
||||
buriedNoDriverDevice(device);
|
||||
continue ;
|
||||
}
|
||||
|
||||
device.others += packages.value("others").toString();
|
||||
|
||||
res.append(packages.value("packageName").toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QSet<QString> resSet = res.toSet();
|
||||
QStringList debPackages = resSet.toList();
|
||||
for (auto package : debPackages) {
|
||||
if (package.contains("\n")) {
|
||||
auto pkglist = package.split("\n");
|
||||
device.debNameList.append(pkglist);
|
||||
} else {
|
||||
device.debNameList.append(package);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < device.debNameList.size(); i++) {
|
||||
QString name = device.debNameList.at(i);
|
||||
device.packageNameList.append(name.left(name.indexOf("_")));
|
||||
}
|
||||
|
||||
return device.packageNameList;
|
||||
}
|
||||
|
||||
DeviceInformation::DeviceInformation()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void buriedNoDriverDevice(DeviceInformation device)
|
||||
{
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::kylinScannerDeviceNoDriver)));
|
||||
buried_data.insert(std::make_pair("device_vendor", device.vendor.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_name", device.name.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_model", device.model.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_serial", device.serial.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_VID", device.VID.toLocal8Bit().data()));
|
||||
buried_data.insert(std::make_pair("device_PID", device.PID.toLocal8Bit().data()));
|
||||
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::StabilityType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
#ifndef DEVICE_INFORMATION_H
|
||||
#define DEVICE_INFORMATION_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <map>
|
||||
|
||||
enum class ConnectType : int {
|
||||
InfoFrom_Invalid = 0,
|
||||
InfoFrom_USB,
|
||||
InfoFrom_NETWORK_DETECT,
|
||||
InfoFrom_PRINTER_IP,
|
||||
InfoFrom_REMOTE_IP
|
||||
};
|
||||
|
||||
enum class DeviceType : int {
|
||||
NONE = 0,
|
||||
PRINTER,
|
||||
SCANNER
|
||||
};
|
||||
|
||||
enum class ProtocolType : int {
|
||||
NONE = 0,
|
||||
LPD, // lpd://${打印机网络节点}/${打印机服务}
|
||||
IPP, // ipp://${IP}:${端口}/ipp/print
|
||||
HTTP, // http://${IP}
|
||||
SOCKET, // socket://${IP}:${端口}
|
||||
DNSSD, // dnssd://${打印机名称}._ipp._tcp.local/?uuid=${UUID}
|
||||
HTTPS,
|
||||
};
|
||||
|
||||
const QMap<QString, ProtocolType> protocolMap = {
|
||||
std::map<QString, ProtocolType>::value_type("none", ProtocolType::NONE),
|
||||
std::map<QString, ProtocolType>::value_type("lpd", ProtocolType::LPD),
|
||||
std::map<QString, ProtocolType>::value_type("ipp", ProtocolType::IPP),
|
||||
std::map<QString, ProtocolType>::value_type("http", ProtocolType::HTTP),
|
||||
std::map<QString, ProtocolType>::value_type("socket", ProtocolType::SOCKET),
|
||||
std::map<QString, ProtocolType>::value_type("dnssd", ProtocolType::DNSSD),
|
||||
std::map<QString, ProtocolType>::value_type("https", ProtocolType::HTTPS)
|
||||
};
|
||||
|
||||
class DeviceInformation {
|
||||
public:
|
||||
DeviceInformation();
|
||||
// 公有部分
|
||||
DeviceType type{DeviceType::NONE};
|
||||
ConnectType connectType{ConnectType::InfoFrom_Invalid};
|
||||
ProtocolType protocolType{ProtocolType::NONE};
|
||||
QString name{QString()}; // 打印机的名字
|
||||
QString vendor{QString()}; // 供应商
|
||||
QString model{QString()}; // 型号
|
||||
QString serial{QString()}; // 序列号
|
||||
QString uri{QString()}; // 设备uri
|
||||
QStringList debNameList{QStringList()};
|
||||
QStringList packageNameList{QStringList()}; // 包名
|
||||
QString makeAndModel{QString()}; // make-and-model
|
||||
QString uuid{QString()};
|
||||
QString ppdName{QString()};
|
||||
QString deviceId{QString()};
|
||||
QString others{QString()};
|
||||
|
||||
// usb 部分
|
||||
QString sysPath{QString()}; // sys下的目录
|
||||
QString devicePath{QString()}; // dev下的目录 绝对路径
|
||||
QString deviceType{QString()}; // 设备种类 打印机为07
|
||||
QString busNumber{QString()};
|
||||
QString deviceNumber{QString()};
|
||||
QString VID{QString()}; // usb vid
|
||||
QString PID{QString()}; // usb pid
|
||||
|
||||
// 网络部分
|
||||
QString networkNode;
|
||||
QString host;
|
||||
};
|
||||
|
||||
extern QString devInfoPrint(const DeviceInformation&);
|
||||
|
||||
extern QDebug operator<<(QDebug debug, const DeviceInformation&);
|
||||
|
||||
extern QStringList getPackagesNameFromHttp(DeviceInformation&);
|
||||
|
||||
void buriedNoDriverDevice(DeviceInformation device);
|
||||
|
||||
Q_DECLARE_METATYPE(DeviceInformation)
|
||||
|
||||
#endif // DEVICE_INFORMATION_H
|
|
@ -0,0 +1,55 @@
|
|||
#include <iostream>
|
||||
#include <QCoreApplication>
|
||||
#include "deviceFinder.h"
|
||||
#include "ukui_apt.h"
|
||||
|
||||
|
||||
|
||||
void testfind()
|
||||
{
|
||||
deviceFinder *f = new deviceFinder;
|
||||
QObject::connect(f, &deviceFinder::succeed, [=]() {
|
||||
qDebug() << "Install succeed";
|
||||
qDebug() << f->getList();
|
||||
f->finished();
|
||||
});
|
||||
QObject::connect(f, &deviceFinder::failed, [=]() {
|
||||
qDebug() << "Install failed";
|
||||
});
|
||||
f->startWorker();
|
||||
}
|
||||
|
||||
void testapt() {
|
||||
AptUtilHelper* aptHelper = new AptUtilHelper(DeviceInformation());
|
||||
QObject::connect(aptHelper, &AptUtilHelper::succeed, [=]() {
|
||||
qDebug() << "Install succeed";
|
||||
});
|
||||
QObject::connect(aptHelper, &AptUtilHelper::failed, [=]() {
|
||||
qDebug() << "Install failed";
|
||||
});
|
||||
aptHelper->startWorker();
|
||||
}
|
||||
|
||||
void testdeb() {
|
||||
DebUtilHelper* debHelper = new DebUtilHelper("brscan5chn_1.2.5-0_amd64.deb");
|
||||
QObject::connect(debHelper, &DebUtilHelper::succeed, [=]() {
|
||||
qDebug() << "Install succeed";
|
||||
|
||||
});
|
||||
QObject::connect(debHelper, &DebUtilHelper::failed, [=]() {
|
||||
qDebug() << "Install failed";
|
||||
});
|
||||
debHelper->startWorker();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
|
||||
testfind();
|
||||
// testapt();
|
||||
// testdeb();
|
||||
|
||||
return app.exec();
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
#include <QThread>
|
||||
|
||||
#include "network_device_detector.h"
|
||||
#include "zconfservicebrowser.h"
|
||||
#include "snmpwalk_browser.h"
|
||||
#include "common.h"
|
||||
|
||||
QString getValueBySnmpwalk(const QString &name, const QString &key)
|
||||
{
|
||||
std::string sname = name.toStdString();
|
||||
std::string skey = key.toStdString();
|
||||
|
||||
const char * cname = sname.c_str();
|
||||
const char * ckey = skey.c_str();
|
||||
|
||||
std::vector<OidNode> oids = {
|
||||
{ ckey },
|
||||
};
|
||||
|
||||
|
||||
std::vector<HostNode> hosts = {
|
||||
{ cname, "public" },
|
||||
};
|
||||
|
||||
std::vector<std::string> buf;
|
||||
|
||||
if (::snmpwalkBrowser_initialize(oids) != STAT_SUCCESS) {
|
||||
return QString ("error");
|
||||
}
|
||||
int ans = ::snmpwalkBrowser_synchronous(buf, hosts, oids);
|
||||
if (ans != STAT_SUCCESS) {
|
||||
return QString("error");
|
||||
}
|
||||
if (!buf.size()) {
|
||||
return QString("error");
|
||||
}
|
||||
QString res = QString(buf.at(0).c_str());
|
||||
|
||||
if (res.contains("IpAddress")
|
||||
|| res.contains("STRING")) {
|
||||
|
||||
res = res.split(":").at(1);
|
||||
res.remove(0,1);
|
||||
res.remove("\"");
|
||||
return res;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// NetworkDeviceDetector start
|
||||
NetworkDeviceDetector::~NetworkDeviceDetector()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NetworkDeviceDetector::NetworkDeviceDetector(/* args */)
|
||||
{
|
||||
/**
|
||||
* @brief zconfserver循环事件
|
||||
*
|
||||
*/
|
||||
connect(ZConfServiceBrowser::getInstance(), &ZConfServiceBrowser::serviceEntryAdded,
|
||||
this, &NetworkDeviceDetector::zconfPreSet,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect (this, &NetworkDeviceDetector::autoDetectStart, [=](){
|
||||
|
||||
|
||||
ZConfServiceBrowser::getInstance()->browse();
|
||||
});
|
||||
|
||||
connect (this, &NetworkDeviceDetector::autoDetectStop, [=](){
|
||||
|
||||
// m_thread->deleteLater();
|
||||
});
|
||||
|
||||
connect (this, &NetworkDeviceDetector::newDeviceSend,
|
||||
this, &NetworkDeviceDetector::newDeviceGet,
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
DetectResult NetworkDeviceDetector::detectNetWorkNode(DeviceInformation &deviceInfo)
|
||||
{
|
||||
deviceInfo.networkNode = ::getValueBySnmpwalk(deviceInfo.host, "1.3.6.1.2.1.1.5");
|
||||
if (deviceInfo.networkNode.isEmpty()) {
|
||||
return DetectResult::DETECT_ERROR;
|
||||
}
|
||||
return DetectResult::DETECT_OK;
|
||||
}
|
||||
|
||||
DetectResult NetworkDeviceDetector::detectVendorAndModel(DeviceInformation &deviceInfo)
|
||||
{
|
||||
|
||||
QString res = ::getValueBySnmpwalk(deviceInfo.host, "1.3.6.1.2.1.25.3.2.1.3");
|
||||
|
||||
if (res.isEmpty() || res == "error") {
|
||||
return DetectResult::DETECT_ERROR;
|
||||
}
|
||||
// Brother ADS-3600W
|
||||
if (res.contains(' ')) {
|
||||
deviceInfo.vendor = res.left(res.indexOf(' '));
|
||||
deviceInfo.model = res.right(res.size() - 1 - res.indexOf(' '));
|
||||
} else {
|
||||
deviceInfo.vendor = res;
|
||||
}
|
||||
|
||||
|
||||
return DetectResult::DETECT_OK;
|
||||
}
|
||||
|
||||
DetectResult NetworkDeviceDetector::detectSerial(DeviceInformation &deviceInfo)
|
||||
{
|
||||
deviceInfo.serial = ::getValueBySnmpwalk(deviceInfo.host, "1.3.6.1.2.1.43.5.1.1.17");
|
||||
if (deviceInfo.serial.isEmpty()) {
|
||||
return DetectResult::DETECT_ERROR;
|
||||
}
|
||||
return DetectResult::DETECT_OK;
|
||||
}
|
||||
|
||||
|
||||
DeviceInformation NetworkDeviceDetector::newDeviceGet(DeviceInformation &deviceInfo)
|
||||
{
|
||||
|
||||
if (deviceInfo.host.isEmpty())
|
||||
return DeviceInformation();
|
||||
|
||||
|
||||
if (deviceInfo.host == "error") {
|
||||
deviceInfo.connectType = ConnectType::InfoFrom_Invalid;
|
||||
return DeviceInformation();
|
||||
}
|
||||
|
||||
if (deviceInfo.host.isEmpty()) {
|
||||
deviceInfo.connectType = ConnectType::InfoFrom_Invalid;
|
||||
return DeviceInformation();
|
||||
}
|
||||
|
||||
if (!ipIsValid(deviceInfo.host)) {
|
||||
deviceInfo.connectType = ConnectType::InfoFrom_Invalid;
|
||||
return DeviceInformation();
|
||||
}
|
||||
|
||||
this->detectVendorAndModel (deviceInfo);
|
||||
this->detectSerial (deviceInfo);
|
||||
|
||||
if (deviceInfo.vendor.isEmpty()
|
||||
|| deviceInfo.model.isEmpty() ) {
|
||||
|
||||
deviceInfo.connectType = ConnectType::InfoFrom_Invalid;
|
||||
}
|
||||
|
||||
|
||||
switch (deviceInfo.connectType)
|
||||
{
|
||||
case (ConnectType::InfoFrom_Invalid):
|
||||
case (ConnectType::InfoFrom_USB):
|
||||
return DeviceInformation();
|
||||
|
||||
case (ConnectType::InfoFrom_NETWORK_DETECT):
|
||||
emit this->findNetworkConnect(deviceInfo);
|
||||
return DeviceInformation();
|
||||
case (ConnectType::InfoFrom_PRINTER_IP):
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
return DeviceInformation();
|
||||
}
|
||||
|
||||
void NetworkDeviceDetector::zconfPreSet(QString name) {
|
||||
DeviceInformation deviceInfo;
|
||||
qDebug() << name;
|
||||
deviceInfo.connectType = ConnectType::InfoFrom_NETWORK_DETECT;
|
||||
deviceInfo.host = ZConfServiceBrowser::getInstance()->serviceEntry(name).ip;
|
||||
|
||||
emit this->newDeviceSend(deviceInfo);
|
||||
return ;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef NETWORK_DEVICE_DETECTOR_H
|
||||
#define NETWORK_DEVICE_DETECTOR_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "device_information.h"
|
||||
#include "zconfservicebrowser.h"
|
||||
|
||||
enum class DetectResult : int
|
||||
{
|
||||
DETECT_OK = 0,
|
||||
DETECT_ERROR,
|
||||
};
|
||||
|
||||
enum class SetResult : int
|
||||
{
|
||||
SET_OK = 0,
|
||||
SET_ERROR,
|
||||
};
|
||||
|
||||
class NetworkDeviceDetector: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NetworkDeviceDetector();
|
||||
~NetworkDeviceDetector();
|
||||
private:
|
||||
QMap<QString, DeviceInformation> m_mpDevInfo;
|
||||
|
||||
|
||||
DetectResult detectNetWorkNode (DeviceInformation &);
|
||||
|
||||
DetectResult detectVendorAndModel (DeviceInformation &);
|
||||
|
||||
DetectResult detectSerial (DeviceInformation &);
|
||||
|
||||
|
||||
DeviceInformation newDeviceGet(DeviceInformation &);
|
||||
|
||||
void zconfPreSet(QString name);
|
||||
|
||||
Q_SIGNALS:
|
||||
void autoDetectStart();
|
||||
void autoDetectStop();
|
||||
void newDeviceSend(DeviceInformation &);
|
||||
void findNetworkConnect(DeviceInformation &);
|
||||
};
|
||||
|
||||
#endif // NETWORK_DEVICE_DETECTOR_H
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* This file is part of qtzeroconf. (c) 2012 Johannes Hilden
|
||||
* https://github.com/johanneshilden/qtzeroconf
|
||||
*
|
||||
* qtzeroconf is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* qtzeroconf is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with qtzeroconf; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
#include <QStringBuilder>
|
||||
#include <avahi-client/publish.h>
|
||||
#include <avahi-common/error.h>
|
||||
#include <avahi-common/alternative.h>
|
||||
#include "zconfserviceclient.h"
|
||||
#include "zconfservice.h"
|
||||
|
||||
class ZConfServicePrivate
|
||||
{
|
||||
public:
|
||||
ZConfServicePrivate()
|
||||
: client(0), group(0), error(0)
|
||||
{
|
||||
}
|
||||
|
||||
static void callback(AvahiEntryGroup *group, AvahiEntryGroupState state, void *userdata)
|
||||
{
|
||||
Q_UNUSED(group);
|
||||
ZConfService *serviceGroup = static_cast<ZConfService *>(userdata);
|
||||
if (serviceGroup) {
|
||||
switch (state)
|
||||
{
|
||||
case AVAHI_ENTRY_GROUP_ESTABLISHED:
|
||||
emit serviceGroup->entryGroupEstablished();
|
||||
qDebug() << ("Service '" % serviceGroup->m_ptr->name % "' successfully establised.");
|
||||
break;
|
||||
case AVAHI_ENTRY_GROUP_COLLISION:
|
||||
emit serviceGroup->entryGroupNameCollision();
|
||||
break;
|
||||
case AVAHI_ENTRY_GROUP_FAILURE:
|
||||
emit serviceGroup->entryGroupFailure();
|
||||
qDebug() << ("Entry group failure: " % serviceGroup->errorString());
|
||||
break;
|
||||
case AVAHI_ENTRY_GROUP_UNCOMMITED:
|
||||
qDebug() << "AVAHI_ENTRY_GROUP_UNCOMMITED";
|
||||
break;
|
||||
case AVAHI_ENTRY_GROUP_REGISTERING:
|
||||
qDebug() << "AVAHI_ENTRY_GROUP_REGISTERING";
|
||||
} // end switch
|
||||
}
|
||||
}
|
||||
|
||||
ZConfServiceClient *client;
|
||||
AvahiEntryGroup *group;
|
||||
QString name;
|
||||
in_port_t port;
|
||||
QString type;
|
||||
int error;
|
||||
};
|
||||
|
||||
/*!
|
||||
\class ZConfService
|
||||
|
||||
\brief This class provides Avahi Zeroconf service registration. It can be
|
||||
used by server applications to announce a service on the local area network.
|
||||
|
||||
Typical use involves creating an instance of ZConfService and calling
|
||||
registerService() with a service name and port number.
|
||||
*/
|
||||
|
||||
ZConfService::ZConfService(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_ptr(new ZConfServicePrivate)
|
||||
{
|
||||
m_ptr->client = new ZConfServiceClient(this);
|
||||
m_ptr->client->run();
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the object and releases all resources associated with it.
|
||||
*/
|
||||
ZConfService::~ZConfService()
|
||||
{
|
||||
if (m_ptr->group)
|
||||
avahi_entry_group_free(m_ptr->group);
|
||||
delete m_ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the service group was added and commited without error.
|
||||
*/
|
||||
bool ZConfService::isValid() const
|
||||
{
|
||||
return (m_ptr->group && !m_ptr->error);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a human readable error string with details of the last error that
|
||||
occured.
|
||||
*/
|
||||
QString ZConfService::errorString() const
|
||||
{
|
||||
if (!m_ptr->client->m_client)
|
||||
return "No client!";
|
||||
return avahi_strerror(avahi_client_errno(m_ptr->client->m_client));
|
||||
}
|
||||
|
||||
/*!
|
||||
Registers a Zeroconf service on the LAN. If no service type is specified,
|
||||
"_http._tcp" is assumed. Needless to say, the server should be available
|
||||
and listen on the specified port.
|
||||
*/
|
||||
void ZConfService::registerService(QString name, in_port_t port, QString type)
|
||||
{
|
||||
if (!m_ptr->client->m_client || AVAHI_CLIENT_S_RUNNING
|
||||
!= avahi_client_get_state(m_ptr->client->m_client)) {
|
||||
qDebug() << "ZConfService error: Client is not running.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_ptr->name = name;
|
||||
m_ptr->port = port;
|
||||
m_ptr->type = type;
|
||||
|
||||
if (!m_ptr->group) {
|
||||
m_ptr->group = avahi_entry_group_new(m_ptr->client->m_client,
|
||||
ZConfServicePrivate::callback,
|
||||
this);
|
||||
}
|
||||
if (avahi_entry_group_is_empty(m_ptr->group)) {
|
||||
m_ptr->error = avahi_entry_group_add_service(m_ptr->group,
|
||||
AVAHI_IF_UNSPEC,
|
||||
AVAHI_PROTO_INET,
|
||||
(AvahiPublishFlags) 0,
|
||||
m_ptr->name.toLatin1().data(),
|
||||
m_ptr->type.toLatin1().data(),
|
||||
0,
|
||||
0,
|
||||
m_ptr->port,
|
||||
NULL);
|
||||
if (!m_ptr->error) {
|
||||
m_ptr->error = avahi_entry_group_commit(m_ptr->group);
|
||||
}
|
||||
if (m_ptr->error)
|
||||
qDebug() << ("Error creating service: " % errorString());
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Deregisters the service associated with this object. You can reuse the same
|
||||
ZConfService object at any time to register another service on the network.
|
||||
*/
|
||||
void ZConfService::resetService()
|
||||
{
|
||||
avahi_entry_group_reset(m_ptr->group);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* This file is part of qtzeroconf. (c) 2012 Johannes Hilden
|
||||
* https://github.com/johanneshilden/qtzeroconf
|
||||
*
|
||||
* qtzeroconf is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* qtzeroconf is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with qtzeroconf; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#ifndef ZCONFSERVICE_H
|
||||
#define ZCONFSERVICE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
class ZConfServicePrivate;
|
||||
class ZConfService : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ZConfService(QObject *parent = 0);
|
||||
~ZConfService();
|
||||
|
||||
bool isValid() const;
|
||||
QString errorString() const;
|
||||
|
||||
signals:
|
||||
void entryGroupEstablished();
|
||||
void entryGroupNameCollision();
|
||||
void entryGroupFailure();
|
||||
|
||||
public slots:
|
||||
void registerService(QString name, in_port_t port, QString type = "_http._tcp");
|
||||
void resetService();
|
||||
|
||||
protected:
|
||||
ZConfServicePrivate *const m_ptr;
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(ZConfService);
|
||||
};
|
||||
|
||||
#endif // ZCONFSERVICE_H
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* This file is part of qtzeroconf. (c) 2012 Johannes Hilden
|
||||
* https://github.com/johanneshilden/qtzeroconf
|
||||
*
|
||||
* qtzeroconf is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* qtzeroconf is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with qtzeroconf; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#include <QHash>
|
||||
#include <QStringBuilder>
|
||||
#include <QDebug>
|
||||
#include <cassert>
|
||||
#include <avahi-common/error.h>
|
||||
#include "zconfservicebrowser.h"
|
||||
#include "zconfserviceclient.h"
|
||||
|
||||
/*!
|
||||
\struct ZConfServiceEntry
|
||||
|
||||
\brief This struct contains information about a particular Zeroconf service
|
||||
available on the local network.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\property QString ZConfServiceEntry::ip
|
||||
|
||||
A string representation of the IPv4 or IPv6 IP address associated with this
|
||||
service.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\property QString ZConfServiceEntry::domain
|
||||
|
||||
The domain associated with this service.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\property QString ZConfServiceEntry::host
|
||||
|
||||
The host name associated with this service.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\property uint16_t ZConfServiceEntry::port
|
||||
|
||||
The IP port number associated with this service.
|
||||
*/
|
||||
|
||||
/*!
|
||||
A human-readable string representation of the network layer protocol used
|
||||
by this service. Possible values are "IPv4", "IPv6", and "Unspecified".
|
||||
*/
|
||||
QString ZConfServiceEntry::protocolName() const
|
||||
{
|
||||
switch (protocol)
|
||||
{
|
||||
case AVAHI_PROTO_INET: return "IPv4";
|
||||
case AVAHI_PROTO_INET6: return "IPv6";
|
||||
default: return "Unspecified";
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool ZConfServiceEntry::isCached() const
|
||||
|
||||
Returns true if this response originates from the cache.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool ZConfServiceEntry::isWideArea() const
|
||||
|
||||
Returns true if this response originates from wide area DNS.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool ZConfServiceEntry::isMulticast() const
|
||||
|
||||
Returns true if this response originates from multicast DNS.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool ZConfServiceEntry::isLocal() const
|
||||
|
||||
Returns true if this service resides on and was announced by the local host.
|
||||
*/
|
||||
|
||||
class ZConfServiceBrowserPrivate
|
||||
{
|
||||
public:
|
||||
ZConfServiceBrowserPrivate(ZConfServiceClient *client)
|
||||
: client(client), browser(0)
|
||||
{
|
||||
}
|
||||
|
||||
static void callback(AvahiServiceBrowser *browser,
|
||||
AvahiIfIndex interface,
|
||||
AvahiProtocol protocol,
|
||||
AvahiBrowserEvent event,
|
||||
const char *name,
|
||||
const char *type,
|
||||
const char *domain,
|
||||
AvahiLookupResultFlags flags,
|
||||
void *userdata)
|
||||
{
|
||||
Q_UNUSED(browser);
|
||||
Q_UNUSED(flags);
|
||||
|
||||
ZConfServiceBrowser *serviceBrowser = static_cast<ZConfServiceBrowser *>(userdata);
|
||||
if (serviceBrowser) {
|
||||
switch (event) {
|
||||
case AVAHI_BROWSER_FAILURE:
|
||||
qDebug() << ("Avahi browser error: " % QString(avahi_strerror(avahi_client_errno(serviceBrowser->m_ptr->client->m_client))));
|
||||
break;
|
||||
case AVAHI_BROWSER_NEW:
|
||||
qDebug() << ("New service '" % QString(name) % "' of type " % QString(type) % " in domain " % QString(domain) % ".");
|
||||
|
||||
// We ignore the returned resolver object. In the callback
|
||||
// function we free it. If the server is terminated before
|
||||
// the callback function is called the server will free
|
||||
// the resolver for us.
|
||||
if (!(avahi_service_resolver_new(serviceBrowser->m_ptr->client->m_client,
|
||||
interface,
|
||||
protocol,
|
||||
name,
|
||||
serviceBrowser->m_ptr->type.toLatin1().data(),
|
||||
domain,
|
||||
AVAHI_PROTO_INET,
|
||||
(AvahiLookupFlags) 0,
|
||||
ZConfServiceBrowserPrivate::resolve,
|
||||
serviceBrowser)))
|
||||
qDebug() << ("Failed to resolve service '" % QString(name) % "': " % avahi_strerror(avahi_client_errno(serviceBrowser->m_ptr->client->m_client)));
|
||||
break;
|
||||
case AVAHI_BROWSER_REMOVE:
|
||||
serviceBrowser->m_ptr->entries.remove(name);
|
||||
emit serviceBrowser->serviceEntryRemoved(name);
|
||||
qDebug() << "Service '" % QString(name) % "' removed from the network.";
|
||||
break;
|
||||
case AVAHI_BROWSER_ALL_FOR_NOW:
|
||||
case AVAHI_BROWSER_CACHE_EXHAUSTED:
|
||||
qDebug() << (AVAHI_BROWSER_ALL_FOR_NOW == event
|
||||
? "AVAHI_BROWSER_ALL_FOR_NOW"
|
||||
: "AVAHI_BROWSER_CACHE_EXHAUSTED");
|
||||
} // end switch
|
||||
}
|
||||
}
|
||||
|
||||
static void resolve(AvahiServiceResolver *resolver,
|
||||
AvahiIfIndex interface,
|
||||
AvahiProtocol protocol,
|
||||
AvahiResolverEvent event,
|
||||
const char *name,
|
||||
const char *type,
|
||||
const char *domain,
|
||||
const char *host_name,
|
||||
const AvahiAddress *address,
|
||||
uint16_t port,
|
||||
AvahiStringList *txt,
|
||||
AvahiLookupResultFlags flags,
|
||||
void *userdata)
|
||||
{
|
||||
Q_UNUSED(interface);
|
||||
Q_UNUSED(type);
|
||||
Q_UNUSED(txt);
|
||||
for (AvahiStringList* i = txt; i ; i = i->next) {
|
||||
qDebug("%s\n", (char*)(i->text));
|
||||
}
|
||||
ZConfServiceBrowser *serviceBrowser = static_cast<ZConfServiceBrowser *>(userdata);
|
||||
if (serviceBrowser) {
|
||||
switch (event) {
|
||||
case AVAHI_RESOLVER_FAILURE:
|
||||
qDebug() << ("Failed to resolve service '" % QString(name) % "': " % avahi_strerror(avahi_client_errno(serviceBrowser->m_ptr->client->m_client)));
|
||||
break;
|
||||
case AVAHI_RESOLVER_FOUND:
|
||||
{
|
||||
char a[AVAHI_ADDRESS_STR_MAX];
|
||||
avahi_address_snprint(a, sizeof(a), address);
|
||||
// qDebug() << txt;
|
||||
ZConfServiceEntry entry;
|
||||
entry.ip = QString(a);
|
||||
entry.domain = domain;
|
||||
entry.host = host_name;
|
||||
entry.port = port;
|
||||
entry.protocol = protocol;
|
||||
entry.flags = flags;
|
||||
serviceBrowser->m_ptr->entries.insert(name, entry);
|
||||
emit serviceBrowser->serviceEntryAdded(name);
|
||||
}
|
||||
}
|
||||
avahi_service_resolver_free(resolver);
|
||||
}
|
||||
}
|
||||
|
||||
typedef QHash<QString, ZConfServiceEntry> ZConfServiceEntryTable;
|
||||
|
||||
ZConfServiceClient *const client;
|
||||
AvahiServiceBrowser *browser;
|
||||
ZConfServiceEntryTable entries;
|
||||
QString type;
|
||||
};
|
||||
|
||||
/*!
|
||||
\class ZConfServiceBrowser
|
||||
|
||||
\brief AvahiServiceBrowser wrapper that lets you browse for services
|
||||
available on the local network. This class can be used to handle Zeroconf
|
||||
service discovery in a Qt-based client application.
|
||||
|
||||
Instantiate a ZConfServiceBrowser object and call browse() with the desired
|
||||
service type as argument (e.g., "_http._tcp" or "_ipp._tcp").
|
||||
|
||||
ZConfServiceBrowser will emit serviceEntryAdded() when a new service is
|
||||
discovered and serviceEntryRemoved() when a service is removed from the
|
||||
network.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Creates a Zeroconf service browser. Call browse() to start browsing for
|
||||
services.
|
||||
*/
|
||||
ZConfServiceBrowser::ZConfServiceBrowser(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_ptr(new ZConfServiceBrowserPrivate(new ZConfServiceClient(this)))
|
||||
{
|
||||
connect(m_ptr->client, SIGNAL(clientRunning()), this, SLOT(createServiceBrowser()));
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the browser object and releases all resources associated with it.
|
||||
*/
|
||||
ZConfServiceBrowser::~ZConfServiceBrowser()
|
||||
{
|
||||
if (m_ptr->browser)
|
||||
avahi_service_browser_free(m_ptr->browser);
|
||||
delete m_ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
Browses for Zeroconf services on the LAN. This is a non-blocking call.
|
||||
ZConfServiceBrowser will emit serviceEntryAdded() when a new service is
|
||||
discovered and serviceEntryRemoved() when a service is removed from the
|
||||
network.
|
||||
*/
|
||||
void ZConfServiceBrowser::browse(QString serviceType)
|
||||
{
|
||||
m_ptr->type = serviceType;
|
||||
assert(m_ptr->client);
|
||||
m_ptr->client->run();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a ZConfServiceEntry struct with detailed information about the
|
||||
Zeroconf service associated with the name.
|
||||
*/
|
||||
ZConfServiceEntry ZConfServiceBrowser::serviceEntry(QString name)
|
||||
{
|
||||
return m_ptr->entries.value(name);
|
||||
}
|
||||
|
||||
void ZConfServiceBrowser::createServiceBrowser()
|
||||
{
|
||||
if (m_ptr->browser)
|
||||
return;
|
||||
m_ptr->browser = avahi_service_browser_new(m_ptr->client->m_client,
|
||||
AVAHI_IF_UNSPEC,
|
||||
AVAHI_PROTO_INET,
|
||||
m_ptr->type.toLatin1().data(),
|
||||
NULL,
|
||||
(AvahiLookupFlags) 0,
|
||||
ZConfServiceBrowserPrivate::callback,
|
||||
this);
|
||||
}
|
||||
|
||||
ZConfServiceBrowser *ZConfServiceBrowser::getInstance()
|
||||
{
|
||||
static ZConfServiceBrowser *instance = nullptr;
|
||||
if (nullptr == instance) {
|
||||
instance = new ZConfServiceBrowser(nullptr);
|
||||
}
|
||||
return instance;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* This file is part of qtzeroconf. (c) 2012 Johannes Hilden
|
||||
* https://github.com/johanneshilden/qtzeroconf
|
||||
*
|
||||
* qtzeroconf is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* qtzeroconf is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with qtzeroconf; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#ifndef ZCONFSERVICEBROWSER_H
|
||||
#define ZCONFSERVICEBROWSER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <stdint.h>
|
||||
#include <avahi-client/lookup.h>
|
||||
|
||||
struct ZConfServiceEntry
|
||||
{
|
||||
QString ip;
|
||||
QString domain;
|
||||
QString host;
|
||||
uint16_t port;
|
||||
AvahiProtocol protocol;
|
||||
AvahiLookupResultFlags flags;
|
||||
|
||||
QString protocolName() const;
|
||||
inline bool isValid() const { return !(ip.isEmpty() && host.isEmpty()); }
|
||||
|
||||
inline bool isCached() const { return flags & AVAHI_LOOKUP_RESULT_CACHED; }
|
||||
inline bool isWideArea() const { return flags & AVAHI_LOOKUP_RESULT_WIDE_AREA; }
|
||||
inline bool isMulticast() const { return flags & AVAHI_LOOKUP_RESULT_MULTICAST; }
|
||||
inline bool isLocal() const { return flags & AVAHI_LOOKUP_RESULT_LOCAL; }
|
||||
};
|
||||
|
||||
class ZConfServiceBrowserPrivate;
|
||||
class ZConfServiceBrowser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ZConfServiceBrowser *getInstance();
|
||||
explicit ZConfServiceBrowser(QObject *parent = 0);
|
||||
~ZConfServiceBrowser();
|
||||
|
||||
void browse(QString serviceType = "_scanner._tcp");
|
||||
ZConfServiceEntry serviceEntry(QString name);
|
||||
|
||||
Q_SIGNALS:
|
||||
void serviceEntryAdded(QString);
|
||||
void serviceEntryRemoved(QString);
|
||||
|
||||
protected slots:
|
||||
void createServiceBrowser();
|
||||
|
||||
protected:
|
||||
ZConfServiceBrowserPrivate *const m_ptr;
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(ZConfServiceBrowser);
|
||||
};
|
||||
|
||||
#endif // ZCONFSERVICEBROWSER_H
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* This file is part of qtzeroconf. (c) 2012 Johannes Hilden
|
||||
* https://github.com/johanneshilden/qtzeroconf
|
||||
*
|
||||
* qtzeroconf is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* qtzeroconf is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with qtzeroconf; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
#include "qt_watch.h"
|
||||
#include <avahi-common/error.h>
|
||||
#include "zconfserviceclient.h"
|
||||
|
||||
void ZConfServiceClient::run()
|
||||
{
|
||||
if (m_client)
|
||||
return;
|
||||
avahi_client_new(m_poll, (AvahiClientFlags) 0, ZConfServiceClient::callback, this, &m_error);
|
||||
}
|
||||
|
||||
QString ZConfServiceClient::errorString() const
|
||||
{
|
||||
return avahi_strerror(m_error);
|
||||
}
|
||||
|
||||
ZConfServiceClient::ZConfServiceClient(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_poll(avahi_qt_poll_get()),
|
||||
m_client(0),
|
||||
m_error(0)
|
||||
{
|
||||
}
|
||||
|
||||
ZConfServiceClient::~ZConfServiceClient()
|
||||
{
|
||||
if (m_client)
|
||||
// This will automatically free all associated browser,
|
||||
// resolve and entry group objects.
|
||||
avahi_client_free(m_client);
|
||||
}
|
||||
|
||||
void ZConfServiceClient::callback(AvahiClient *client, AvahiClientState state, void *userdata)
|
||||
{
|
||||
ZConfServiceClient *service = static_cast<ZConfServiceClient *>(userdata);
|
||||
if (service) {
|
||||
service->m_client = client;
|
||||
switch (state)
|
||||
{
|
||||
case AVAHI_CLIENT_S_RUNNING:
|
||||
qDebug() << "AVAHI_CLIENT_S_RUNNING";
|
||||
// The server has started up successfully and registered its host
|
||||
// name on the network.
|
||||
emit service->clientRunning();
|
||||
break;
|
||||
case AVAHI_CLIENT_FAILURE:
|
||||
qDebug() << "AVAHI_CLIENT_FAILURE";
|
||||
emit service->clientFailure();
|
||||
break;
|
||||
case AVAHI_CLIENT_S_COLLISION:
|
||||
case AVAHI_CLIENT_S_REGISTERING:
|
||||
qDebug() << (AVAHI_CLIENT_S_COLLISION == state
|
||||
? "AVAHI_CLIENT_S_COLLISION"
|
||||
: "AVAHI_CLIENT_S_REGISTERING");
|
||||
emit service->clientReset();
|
||||
break;
|
||||
case AVAHI_CLIENT_CONNECTING:
|
||||
qDebug() << "AVAHI_CLIENT_CONNECTING";
|
||||
emit service->clientConnecting();
|
||||
} // end switch
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* This file is part of qtzeroconf. (c) 2012 Johannes Hilden
|
||||
* https://github.com/johanneshilden/qtzeroconf
|
||||
*
|
||||
* qtzeroconf is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* qtzeroconf is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with qtzeroconf; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#ifndef ZCONFSERVICECLIENT_H
|
||||
#define ZCONFSERVICECLIENT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <avahi-client/client.h>
|
||||
|
||||
class ZConfServiceClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void clientRunning();
|
||||
void clientFailure();
|
||||
void clientConnecting();
|
||||
void clientReset();
|
||||
|
||||
private:
|
||||
friend class ZConfService;
|
||||
friend class ZConfServiceBrowser;
|
||||
friend class ZConfServiceBrowserPrivate;
|
||||
|
||||
ZConfServiceClient(QObject *parent = 0);
|
||||
~ZConfServiceClient();
|
||||
|
||||
void run();
|
||||
QString errorString() const;
|
||||
|
||||
static void callback(AvahiClient *client, AvahiClientState state, void *userdata);
|
||||
|
||||
const AvahiPoll *const m_poll;
|
||||
AvahiClient *m_client;
|
||||
int m_error;
|
||||
};
|
||||
|
||||
#endif // ZCONFSERVICECLIENT_H
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
template<typename T>
|
||||
class Singleton {
|
||||
public:
|
||||
static T& instance() {
|
||||
static T instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected:
|
||||
Singleton() {}
|
||||
virtual ~Singleton() {}
|
||||
|
||||
private:
|
||||
Singleton(const Singleton&) = delete;
|
||||
Singleton& operator= (const Singleton) = delete;
|
||||
};
|
|
@ -0,0 +1,114 @@
|
|||
//
|
||||
// Created by oubayasho on 2023/6/8.
|
||||
//
|
||||
|
||||
#include "snmpFinder.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
bool uriCheck(const QString &uri, const QString &scheme)
|
||||
{
|
||||
const QString uriSplit = "://";
|
||||
if (uri.isEmpty() || scheme.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!uri.contains(uriSplit)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString uriScheme = uri.left(uri.indexOf(uriSplit));
|
||||
if (scheme != uriScheme) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uri.rightRef(uri.size() - uriSplit.size() - uri.indexOf(uriSplit)).isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
snmpFinder::snmpFinder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
snmpFinder::~snmpFinder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void snmpFinder::dowork()
|
||||
{
|
||||
QString res = ::getRetFromCommand(QStringList{"/usr/lib/cups/backend/snmp"});
|
||||
if (res.isEmpty()) {
|
||||
return ;
|
||||
}
|
||||
QStringList rres = res.split("\n");
|
||||
for (QString r : rres) {
|
||||
parseSnmpInfo(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QList<DeviceInformation> snmpFinder::getList()
|
||||
{
|
||||
return m_snmpInfoList;
|
||||
}
|
||||
|
||||
void snmpFinder::parseSnmpInfo(QString &info)
|
||||
{
|
||||
qDebug() << info;
|
||||
if (info.isEmpty()) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (!info.contains(' ')) {
|
||||
return ;
|
||||
}
|
||||
|
||||
QString type = info.left(info.indexOf(' '));
|
||||
if (type != "network") {
|
||||
return ;
|
||||
}
|
||||
|
||||
info.remove(0, type.size() + 1);
|
||||
|
||||
if (!info.contains(' ')) {
|
||||
return ;
|
||||
}
|
||||
|
||||
QString uri = info.left(info.indexOf(' '));
|
||||
|
||||
if (!uriCheck(uri, "socket")) {
|
||||
return ;
|
||||
}
|
||||
|
||||
DeviceInformation dev;
|
||||
dev.host = uri.right(uri.size() - 3 - uri.indexOf("://"));
|
||||
|
||||
info.remove(0, uri.size() + 1);
|
||||
|
||||
if (!info.contains("\"")) {
|
||||
return ;
|
||||
}
|
||||
|
||||
info.remove(0, 1);
|
||||
|
||||
if (!info.contains("\"")) {
|
||||
return ;
|
||||
}
|
||||
|
||||
QString makeAndModel = info.left(info.indexOf("\""));
|
||||
|
||||
if (makeAndModel.contains(' ')) {
|
||||
dev.vendor = makeAndModel.left(makeAndModel.indexOf(' '));
|
||||
dev.model = makeAndModel.right(makeAndModel.size() - 1 - makeAndModel.indexOf(' '));
|
||||
} else {
|
||||
dev.vendor = makeAndModel;
|
||||
}
|
||||
dev.connectType = ConnectType::InfoFrom_NETWORK_DETECT;
|
||||
specialDeviceCheck(dev.vendor, dev.model);
|
||||
m_snmpInfoList.append(dev);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// Created by oubayasho on 2023/6/8.
|
||||
//
|
||||
|
||||
#ifndef DEVICE_SNMPFINDER_H
|
||||
#define DEVICE_SNMPFINDER_H
|
||||
#include "device_information.h"
|
||||
|
||||
class snmpFinder {
|
||||
public:
|
||||
snmpFinder();
|
||||
~snmpFinder();
|
||||
void dowork();
|
||||
QList<DeviceInformation> getList();
|
||||
|
||||
private:
|
||||
QList<DeviceInformation> m_snmpInfoList;
|
||||
void parseSnmpInfo(QString &info);
|
||||
};
|
||||
|
||||
#endif // DEVICE_SNMPFINDER_H
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* NET-SNMP demo
|
||||
*
|
||||
* This program demonstrates different ways to query a list of hosts
|
||||
* for a list of variables.
|
||||
*
|
||||
* It would of course be faster just to send one query for all variables,
|
||||
* but the intention is to demonstrate the difference between synchronous
|
||||
* and asynchronous operation.
|
||||
*
|
||||
* Niels Baggesen (Niels.Baggesen@uni-c.dk), 1999.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "snmpwalk_browser.h"
|
||||
|
||||
int find_first_oid(netsnmp_session *ss, oid *base, int base_length)
|
||||
{
|
||||
netsnmp_pdu *response;
|
||||
netsnmp_pdu *pdu;
|
||||
int running = 1;
|
||||
int status;
|
||||
int length = 0;
|
||||
pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
|
||||
snmp_add_null_var(pdu, base, base_length);
|
||||
while (running)
|
||||
{
|
||||
// 这一句在一些情况下会报 “corrupted size vs. prev_size“
|
||||
// 导致程序段错误,但是概率较低,之前会在输出错误的ip地址偶尔复现,
|
||||
// 暂时没有可以稳定复现的方法,也没有定位到问题的原因,怀疑和网络环境有关
|
||||
status = snmp_synch_response(ss, pdu, &response);
|
||||
if (status != STAT_SUCCESS || !response)
|
||||
{
|
||||
snmp_sess_perror("snmp_synch_response", ss);
|
||||
return -1;
|
||||
}
|
||||
if (response->errstat != SNMP_ERR_NOERROR)
|
||||
{
|
||||
fprintf(stderr, "snmp: Error in packet: %s\n", snmp_errstring(response->errstat));
|
||||
return -1;
|
||||
}
|
||||
if (response && snmp_oid_compare(response->variables->name, SNMP_MIN(base_length, response->variables->name_length), base, base_length) != 0)
|
||||
running = 0;
|
||||
else
|
||||
{
|
||||
memcpy(base, response->variables->name, response->variables->name_length * sizeof(oid));
|
||||
length = response->variables->name_length;
|
||||
pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
|
||||
snmp_add_null_var(pdu, response->variables->name, response->variables->name_length);
|
||||
running = 0;
|
||||
}
|
||||
snmp_free_pdu(response);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize
|
||||
*/
|
||||
int initialize(std::vector<OidNode> &oids)
|
||||
{
|
||||
/* Win32: init winsock */
|
||||
SOCK_STARTUP;
|
||||
|
||||
/* initialize library */
|
||||
init_snmp("asynchapp");
|
||||
|
||||
/* parse the oids */
|
||||
for (size_t i = 0; i < oids.size(); i++) {
|
||||
OidNode *op = &oids[i];
|
||||
op->OidLen = sizeof(op->Oid) / sizeof(op->Oid[0]);
|
||||
if (!read_objid(op->Name, op->Oid, (size_t *)&(op->OidLen))) {
|
||||
snmp_perror("read_objid");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* simple printing of returned data
|
||||
*/
|
||||
int print_result(std::vector<std::string> &output,
|
||||
int status,
|
||||
struct snmp_session *sp,
|
||||
struct snmp_pdu *pdu,
|
||||
int &res)
|
||||
{
|
||||
char buf[1024];
|
||||
struct variable_list *vp;
|
||||
|
||||
res = status;
|
||||
switch (status)
|
||||
{
|
||||
case STAT_SUCCESS:
|
||||
res = int(pdu->errstat);
|
||||
vp = pdu->variables;
|
||||
if (pdu->errstat == SNMP_ERR_NOERROR) {
|
||||
while (vp) {
|
||||
snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp);
|
||||
// snprintf(buf, sizeof(buf), "%s", buf);
|
||||
// fprintf(stdout, "%s: %s\n", sp->peername, buf);
|
||||
output.push_back(buf);
|
||||
vp = vp->next_variable;
|
||||
}
|
||||
}
|
||||
else if (pdu->errstat == SNMP_ERR_NOSUCHNAME) {
|
||||
qDebug("%s: %s: %s\n",
|
||||
sp->peername, buf, snmp_errstring(pdu->errstat));
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
for (int ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++)
|
||||
;
|
||||
if (vp)
|
||||
snprint_objid(buf, sizeof(buf), vp->name, vp->name_length);
|
||||
else
|
||||
strcpy(buf, "(none)");
|
||||
qDebug("%s: %s: %s\n",
|
||||
sp->peername, buf, snmp_errstring(pdu->errstat));
|
||||
}
|
||||
return 1;
|
||||
case STAT_TIMEOUT:
|
||||
qDebug("%s: Timeout\n", sp->peername);
|
||||
return 0;
|
||||
case STAT_ERROR:
|
||||
snmp_perror(sp->peername);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* simple synchronous loop
|
||||
*/
|
||||
void synchronous(std::vector<std::string> &buf,
|
||||
const std::vector<HostNode> &hosts,
|
||||
std::vector<OidNode> &oids,
|
||||
int &res)
|
||||
{
|
||||
for (size_t i = 0; i < hosts.size(); i++)
|
||||
{
|
||||
const HostNode *hp = &hosts[i];
|
||||
struct snmp_session ss, *sp;
|
||||
|
||||
snmp_sess_init(&ss); /* initialize session */
|
||||
ss.version = SNMP_VERSION_1;
|
||||
ss.peername = strdup(hp->name);
|
||||
ss.community = (u_char *)strdup(hp->community);
|
||||
ss.community_len = strlen((char *)(ss.community));
|
||||
if (!(sp = snmp_open(&ss)))
|
||||
{
|
||||
snmp_perror("snmp_open");
|
||||
continue;
|
||||
}
|
||||
for (size_t j = 0; j < oids.size(); j++)
|
||||
{
|
||||
OidNode *op = &oids[j];
|
||||
struct snmp_pdu *req, *resp;
|
||||
int status;
|
||||
// printf("%s %d\n",op->Name, op->OidLen);
|
||||
int new_length = find_first_oid(sp, op->Oid, op->OidLen);
|
||||
if (new_length == -1) {
|
||||
res = STAT_ERROR;
|
||||
return;
|
||||
}
|
||||
req = snmp_pdu_create(SNMP_MSG_GET);
|
||||
snmp_add_null_var(req, op->Oid, new_length);
|
||||
status = snmp_synch_response(sp, req, &resp);
|
||||
if (!print_result(buf, status, sp, resp, res))
|
||||
break;
|
||||
snmp_free_pdu(resp);
|
||||
}
|
||||
snmp_close(sp);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int snmpwalkBrowser_initialize(std::vector<OidNode> &oids)
|
||||
{
|
||||
return initialize(oids);
|
||||
}
|
||||
|
||||
int snmpwalkBrowser_synchronous(std::vector<std::string> &buf,
|
||||
const std::vector<HostNode> &hosts,
|
||||
std::vector<OidNode> &oids)
|
||||
{
|
||||
if (hosts.size() != 1) {
|
||||
return -1;
|
||||
}
|
||||
int res = 0;
|
||||
// std::cout << hosts[0].name << ' ' <<oids[0].Name << std::endl;
|
||||
synchronous(buf, hosts, oids, res);
|
||||
// std::cout << hosts[0].name << ' ' <<oids[0].Name << std::endl;
|
||||
// std::cout << buf[0] << std::endl;
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef SNMPWALK_BROWSER_H
|
||||
#define SNMPWALK_BROWSER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <net-snmp/net-snmp-config.h>
|
||||
#include <net-snmp/net-snmp-includes.h>
|
||||
|
||||
/*
|
||||
* a list of hosts to query
|
||||
*/
|
||||
struct HostNode
|
||||
{
|
||||
const char *name;
|
||||
const char *community;
|
||||
};
|
||||
// HostNode hosts[] = {
|
||||
// { "192.168.17.90", "public" },
|
||||
// { NULL }
|
||||
// };
|
||||
|
||||
/*
|
||||
* a list of variables to query for
|
||||
*/
|
||||
struct OidNode
|
||||
{
|
||||
const char *Name;
|
||||
oid Oid[MAX_OID_LEN];
|
||||
int OidLen;
|
||||
};
|
||||
// struct OidNode oids[] = {
|
||||
// { "1.3.6.1.2.1.4.20.1.1" },
|
||||
// { "1.3.6.1.2.1.4.20.1.3" },
|
||||
// { "1.3.6.1.2.1.1.5" },
|
||||
// { "1.3.6.1.2.1.43.9.2.1.8" },
|
||||
// { "1.3.6.1.2.1.25.3.2.1.3" },
|
||||
// { "1.3.6.1.2.1.43.5.1.1.17" },
|
||||
// { NULL }
|
||||
// };
|
||||
|
||||
|
||||
|
||||
int snmpwalkBrowser_initialize(std::vector<OidNode> &oids);
|
||||
|
||||
int snmpwalkBrowser_synchronous(std::vector<std::string> &buf,
|
||||
const std::vector<HostNode> &hosts,
|
||||
std::vector<OidNode> &oids);
|
||||
|
||||
#endif // SNMPWALK_BROWSER_H
|
|
@ -0,0 +1,142 @@
|
|||
#include "ukui_apt.h"
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
#include <QtDBus>
|
||||
#include <QTimer>
|
||||
|
||||
static const QString KUM_DEST = "com.kylin.systemupgrade";
|
||||
static const QString KUM_PATH = "/com/kylin/systemupgrade";
|
||||
static const QString KUM_IFACE = "com.kylin.systemupgrade.interface";
|
||||
|
||||
AptUtilHelper::AptUtilHelper(DeviceInformation device,QObject *parent) : QObject(parent),m_device(device)
|
||||
{
|
||||
auto sysBus = QDBusConnection::systemBus();
|
||||
sysBus.connect(KUM_DEST, KUM_PATH, KUM_IFACE, QString("UpdateInstallFinished"),
|
||||
this, SLOT(onRecvApt(bool, QStringList, QString, QString)));
|
||||
sysBus.connect(KUM_DEST, KUM_PATH, KUM_IFACE, QString("InstalldebStatusChanged"),
|
||||
this, SLOT(onInstalldebStatusChanged(int, QString, QString)));
|
||||
m_thread = new QThread;
|
||||
moveToThread(m_thread);
|
||||
connect(m_thread, &QThread::started, this, &AptUtilHelper::processPkg);
|
||||
connect(this, &AptUtilHelper::succeed, this, &AptUtilHelper::finished);
|
||||
connect(this, &AptUtilHelper::failed, this, &AptUtilHelper::finished);
|
||||
connect(this, &AptUtilHelper::finished, m_thread, &QThread::quit);
|
||||
connect(this, &AptUtilHelper::finished, this, &AptUtilHelper::deleteLater);
|
||||
connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater);
|
||||
}
|
||||
|
||||
AptUtilHelper::~AptUtilHelper()
|
||||
{
|
||||
qDebug() << "~~~~~~~~destroy...";
|
||||
}
|
||||
|
||||
void AptUtilHelper::processPkg()
|
||||
{
|
||||
qDebug("Pkg Worker Started!");
|
||||
//Get Package...
|
||||
if (m_device.packageNameList.isEmpty())
|
||||
getPackagesNameFromHttp(m_device);
|
||||
m_packages = m_device.packageNameList;
|
||||
|
||||
qDebug() << m_packages;
|
||||
installPackage(m_packages);
|
||||
m_timer = new QTimer(this);
|
||||
connect(m_timer, &QTimer::timeout, [=](){emit failed("Install timeout.");});
|
||||
m_timer->start(180000);
|
||||
qDebug("Worker Ended!");
|
||||
}
|
||||
|
||||
void AptUtilHelper::onInstalldebStatusChanged(int progress , QString status, QString current_details)
|
||||
{
|
||||
qDebug() << QString("InstalldebStatusChanged progress = %1 , status = %2 ,current_details = %3").arg(progress).arg(status).arg(current_details);
|
||||
}
|
||||
|
||||
|
||||
void AptUtilHelper::onRecvApt(bool success, QStringList updateGroup, QString errorString, QString errorDesc) {
|
||||
qDebug() << "onReceiveKumAptSignal" << success;
|
||||
if(success == false) {
|
||||
//Error
|
||||
qDebug() << "Install package failed..."<< errorString << " " << errorDesc;
|
||||
m_packages.clear();
|
||||
emit failed(errorString);
|
||||
}else if(success == true) {
|
||||
qDebug() << "Installed." << m_packages;
|
||||
emit succeed();
|
||||
} else {
|
||||
qDebug() << "installing...";
|
||||
}
|
||||
}
|
||||
|
||||
void AptUtilHelper::installPackage(QStringList packageName)
|
||||
{
|
||||
qDebug() << "Package:" << packageName;
|
||||
qDebug() << "installPackage 1:";
|
||||
QDBusConnection bus = QDBusConnection::systemBus();
|
||||
QDBusInterface dbus_iface(KUM_DEST,KUM_PATH, KUM_IFACE, bus);
|
||||
qDebug() << dbus_iface.call("InstallPackages", packageName);
|
||||
}
|
||||
|
||||
DebUtilHelper::DebUtilHelper(QString debName,QObject *parent) :
|
||||
QObject(parent),
|
||||
m_debName(debName)
|
||||
{
|
||||
auto sysBus = QDBusConnection::systemBus();
|
||||
sysBus.connect(KUM_DEST, KUM_PATH, KUM_IFACE, QString("InstalldebFinished"),
|
||||
this, SLOT(onRecvApt(bool, QString, QString)));
|
||||
sysBus.connect(KUM_DEST, KUM_PATH, KUM_IFACE, QString("InstalldebStatusChanged"),
|
||||
this, SLOT(onInstalldebStatusChanged(int, QString, QString)));
|
||||
m_thread = new QThread;
|
||||
moveToThread(m_thread);
|
||||
connect(m_thread, &QThread::started, this, &DebUtilHelper::processDeb);
|
||||
connect(this, &DebUtilHelper::succeed, this, &DebUtilHelper::finished);
|
||||
connect(this, &DebUtilHelper::failed, this, &DebUtilHelper::finished);
|
||||
connect(this, &DebUtilHelper::finished, m_thread, &QThread::quit);
|
||||
connect(this, &DebUtilHelper::finished, this, &DebUtilHelper::deleteLater);
|
||||
connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater);
|
||||
//thread->start();
|
||||
}
|
||||
|
||||
DebUtilHelper::~DebUtilHelper()
|
||||
{
|
||||
qDebug() << "~~~~~~~~destroy...";
|
||||
}
|
||||
|
||||
void DebUtilHelper::processDeb()
|
||||
{
|
||||
qDebug("Deb Worker Started!");
|
||||
qDebug() << m_debName;
|
||||
installLocalDeb(m_debName);
|
||||
m_timer = new QTimer(this);
|
||||
connect(m_timer, &QTimer::timeout, [=](){emit failed("Install timeout.");});
|
||||
m_timer->start(60000);
|
||||
qDebug("Deb Worker Ended!");
|
||||
}
|
||||
|
||||
void DebUtilHelper::onInstalldebStatusChanged(int progress , QString status, QString current_details)
|
||||
{
|
||||
qDebug() << QString("InstalldebStatusChanged progress = %1 , status = %2 ,current_details = %3").arg(progress).arg(status).arg(current_details);
|
||||
}
|
||||
|
||||
void DebUtilHelper::onRecvApt(bool success, QString errorString, QString errorDesc) {
|
||||
qDebug() << "onReceiveKumAptSignal" << success;
|
||||
if(success == false) {
|
||||
//Error
|
||||
qDebug() << "Install package failed..."<< errorString << " " << errorDesc;
|
||||
emit failed(errorString);
|
||||
}else if(success == true) {
|
||||
qDebug() << "Installed." << m_debName;
|
||||
emit succeed();
|
||||
} else {
|
||||
qDebug() << "installing...";
|
||||
}
|
||||
}
|
||||
|
||||
void DebUtilHelper::installLocalDeb(QString debFilePath)
|
||||
{
|
||||
qDebug() << "Package:" << debFilePath;
|
||||
qDebug() << "installLocalDeb 2:";
|
||||
QDBusConnection bus = QDBusConnection::systemBus();
|
||||
QDBusInterface dbus_iface(KUM_DEST, KUM_PATH, KUM_IFACE, bus);
|
||||
qDebug() << dbus_iface.call("InstallDebFile", "kylin-scanner", debFilePath, true, true, QLocale::system().name());
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
#ifndef UKUI_APT_H
|
||||
#define UKUI_APT_H
|
||||
// Use QObject
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
// Use libqapt as apt interface
|
||||
//#include <qapt/backend.h>
|
||||
//#include <qapt/debfile.h>
|
||||
//#include <qapt/package.h>
|
||||
//#include <qapt/transaction.h>
|
||||
//
|
||||
#include "device_information.h"
|
||||
#include <QThread>
|
||||
|
||||
class QTimer;
|
||||
|
||||
enum class ukuiAptError : int {
|
||||
UKUI_APT_SUCCESS = 0,
|
||||
UKUI_APT_CANNOT_ACCESS_SERVER,
|
||||
UKUI_APT_NO_SUCH_PACKAGE,
|
||||
UKUI_APT_INSTALL_FAIL,
|
||||
};
|
||||
|
||||
enum class ukuiInstallStatus : int {
|
||||
UKUI_INSTALL_START = 0,
|
||||
UKUI_INSTALL_IN_PROGRESS,
|
||||
UKUI_INSTALL_SUCCESS,
|
||||
UKUI_INSTALL_FAIL,
|
||||
};
|
||||
|
||||
//Worker Class
|
||||
//TODO : 需要手动判断包是否已经安装,优化匹配速度
|
||||
class AptUtilHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AptUtilHelper(DeviceInformation device,QObject *parent = nullptr);
|
||||
~AptUtilHelper();
|
||||
Q_SIGNALS:
|
||||
void installEnd();
|
||||
void finished();
|
||||
void succeed();
|
||||
void failed(QString err);
|
||||
void error(QString err);
|
||||
//暂时还没发出来
|
||||
void alreadyInstalled();
|
||||
private slots:
|
||||
void onInstalldebStatusChanged(int, QString, QString);
|
||||
void onRecvApt(bool, QStringList, QString, QString);
|
||||
public:
|
||||
void startWorker(){
|
||||
if(m_thread!=nullptr)
|
||||
m_thread->start();
|
||||
}
|
||||
private:
|
||||
void processPkg();
|
||||
void installPackage(QStringList packageName);
|
||||
QThread *m_thread{nullptr};
|
||||
QTimer *m_timer{nullptr};
|
||||
QString m_packageName = "";
|
||||
DeviceInformation m_device = DeviceInformation();
|
||||
QStringList m_packages = QStringList();
|
||||
};
|
||||
|
||||
//TODO : 需要手动判断包是否已经安装,优化匹配速度
|
||||
class DebUtilHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DebUtilHelper(QString debName,QObject *parent = nullptr);
|
||||
~DebUtilHelper();
|
||||
Q_SIGNALS:
|
||||
void installEnd();
|
||||
void finished();
|
||||
void failed(QString err);
|
||||
void succeed();
|
||||
void error(QString err);
|
||||
//暂时还没发出来
|
||||
void alreadyInstalled();
|
||||
private slots:
|
||||
void onInstalldebStatusChanged(int, QString, QString);
|
||||
void onRecvApt(bool, QString, QString);
|
||||
public:
|
||||
void startWorker(){
|
||||
if(m_thread!=nullptr)
|
||||
m_thread->start();
|
||||
}
|
||||
private:
|
||||
void processDeb();
|
||||
void installLocalDeb(QString debFilePath);
|
||||
//工作线程
|
||||
QThread *m_thread{nullptr};
|
||||
QTimer *m_timer{nullptr};
|
||||
QString m_debName = "";
|
||||
};
|
||||
|
||||
#endif //UKUI_APT_H
|
|
@ -0,0 +1,312 @@
|
|||
//
|
||||
// Created by oubayasho on 2023/6/5.
|
||||
//
|
||||
|
||||
#include "usbFinder.h"
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <QDebug>
|
||||
#include "common.h"
|
||||
#include <libudev.h>
|
||||
#include <glib.h>
|
||||
|
||||
|
||||
void
|
||||
parse_device_id (const char *device_id,
|
||||
struct device_id_s *id)
|
||||
{
|
||||
QString s = QString(device_id);
|
||||
|
||||
if (s.size() == 0)
|
||||
return;
|
||||
|
||||
if (s[s.size() - 1] == '\n')
|
||||
s.chop(1);
|
||||
|
||||
|
||||
id->full_device_id = s;
|
||||
|
||||
QStringList ls = s.split(";");
|
||||
|
||||
for (auto ss : ls) {
|
||||
if (id->mfg.isEmpty()
|
||||
&& (ss.indexOf("MANUFACTURER") == 0 || ss.indexOf("MFG") == 0)
|
||||
&& (ss.contains(":"))) {
|
||||
|
||||
id->mfg = ss.split(":").at(1);
|
||||
}
|
||||
|
||||
else if (id->mdl.isEmpty()
|
||||
&& (ss.indexOf("MODEL") == 0 || ss.indexOf("MDL") == 0)
|
||||
&& (ss.contains(":"))) {
|
||||
|
||||
id->mdl = ss.split(":").at(1);
|
||||
}
|
||||
|
||||
else if (id->sern.isEmpty()
|
||||
&& (ss.indexOf("SERIALNUMBER") == 0 || ss.indexOf("SERN") == 0 || ss.indexOf("SN") == 0)
|
||||
&& (ss.contains(":"))) {
|
||||
|
||||
id->sern = ss.split(":").at(1);
|
||||
}
|
||||
|
||||
else if (id->cls.isEmpty()
|
||||
&& (ss.indexOf("CLS") == 0 || ss.indexOf("CLASS") == 0)
|
||||
&& (ss.contains(":"))) {
|
||||
|
||||
id->cls = ss.split(":").at(1);
|
||||
}
|
||||
}
|
||||
// 特殊打印机处理
|
||||
specialDeviceCheck(id->mfg, id->mdl);
|
||||
return ;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_ieee1284_id_from_child (struct udev *udev, struct udev_device *parent)
|
||||
{
|
||||
struct udev_enumerate *udev_enum;
|
||||
struct udev_list_entry *item, *first = NULL;
|
||||
char *device_id = NULL;
|
||||
|
||||
udev_enum = udev_enumerate_new (udev);
|
||||
if (!udev_enum) {
|
||||
qDebug ("udev_enumerate_new failed");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (udev_enumerate_add_match_parent (udev_enum, parent) < 0) {
|
||||
udev_enumerate_unref (udev_enum);
|
||||
qDebug ("uname to add parent match");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (udev_enumerate_scan_devices (udev_enum) < 0) {
|
||||
udev_enumerate_unref (udev_enum);
|
||||
qDebug ("udev_enumerate_scan_devices failed");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
first = udev_enumerate_get_list_entry (udev_enum);
|
||||
udev_list_entry_foreach (item, first) {
|
||||
const char *ieee1284_id = NULL;
|
||||
struct udev_device *dev;
|
||||
// qDebug() << udev_list_entry_get_name (item);
|
||||
dev = udev_device_new_from_syspath (udev,
|
||||
udev_list_entry_get_name (item));
|
||||
if (dev == NULL)
|
||||
continue;
|
||||
|
||||
ieee1284_id = udev_device_get_sysattr_value (dev, "ieee1284_id");
|
||||
if (ieee1284_id)
|
||||
device_id = g_strdup (ieee1284_id);
|
||||
|
||||
udev_device_unref (dev);
|
||||
if (device_id)
|
||||
break;
|
||||
}
|
||||
|
||||
udev_enumerate_unref (udev_enum);
|
||||
return device_id;
|
||||
}
|
||||
|
||||
|
||||
// /dev/bus/usb/001/067
|
||||
void
|
||||
devpath_from_usb_devaddr (const QString &devaddr, DeviceInformation &info)
|
||||
{
|
||||
if (devaddr.isEmpty()) {
|
||||
return ;
|
||||
}
|
||||
|
||||
struct udev *udev = nullptr;
|
||||
udev = udev_new ();
|
||||
|
||||
struct udev_enumerate *udev_enum = nullptr;
|
||||
udev_enum = udev_enumerate_new (udev);
|
||||
if (udev_enum == nullptr) {
|
||||
qDebug() << "udev_enumerate_new failed";
|
||||
udev_unref (udev);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (udev_enumerate_add_match_property (udev_enum, "DEVNAME", QTC(devaddr)) < 0) {
|
||||
udev_unref (udev);
|
||||
udev_enumerate_unref (udev_enum);
|
||||
qDebug() << "udev_enumerate_add_match_property failed";
|
||||
return ;
|
||||
}
|
||||
|
||||
if (udev_enumerate_scan_devices (udev_enum) < 0) {
|
||||
udev_unref (udev);
|
||||
udev_enumerate_unref (udev_enum);
|
||||
qDebug() << "udev_enumerate_scan_devices failed";
|
||||
return ;
|
||||
}
|
||||
|
||||
struct udev_list_entry *first = nullptr;
|
||||
first = udev_enumerate_get_list_entry (udev_enum);
|
||||
if (first == nullptr) {
|
||||
udev_unref (udev);
|
||||
udev_enumerate_unref (udev_enum);
|
||||
qDebug ("no device named %s found", QTC(devaddr));
|
||||
return ;
|
||||
}
|
||||
|
||||
struct udev_device *device;
|
||||
device = udev_device_new_from_syspath (udev,
|
||||
udev_list_entry_get_name (first));
|
||||
if (device == nullptr) {
|
||||
udev_unref (udev);
|
||||
udev_enumerate_unref (udev_enum);
|
||||
qDebug ("unable to examine device");
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
info.serial = QString(udev_device_get_sysattr_value (device, "serial"));
|
||||
info.vendor = QString(udev_device_get_sysattr_value (device, "manufacturer"));
|
||||
info.model = QString(udev_device_get_sysattr_value (device, "product"));
|
||||
|
||||
device_id_s id;
|
||||
parse_device_id(get_ieee1284_id_from_child (udev, device), &id);
|
||||
info.deviceId = id.full_device_id;
|
||||
if (info.vendor.isEmpty()) {
|
||||
info.vendor = id.mfg;
|
||||
}
|
||||
if (info.model.isEmpty()) {
|
||||
info.model = id.mdl;
|
||||
}
|
||||
if (info.serial.isEmpty()) {
|
||||
info.serial = id.sern;
|
||||
}
|
||||
|
||||
if (id.cls == "SCANNER") {
|
||||
info.type = DeviceType::SCANNER;
|
||||
}
|
||||
|
||||
specialDeviceCheck(info.vendor, info.model);
|
||||
|
||||
|
||||
|
||||
// qDebug() << get_ieee1284_id_from_child (udev, device);
|
||||
// qDebug() << udev_device_get_devpath (device);
|
||||
// qDebug() << udev_device_get_property_value(device, "SUBSYSTEM");
|
||||
// qDebug() << udev_device_get_property_value(device, "DEVNAME");
|
||||
// qDebug() << udev_device_get_property_value(device, "ID_VENDOR");
|
||||
// qDebug() << udev_device_get_property_value(device, "ID_MODEL");
|
||||
// qDebug() << udev_device_get_property_value(device, "ID_SERIAL");
|
||||
// qDebug() << udev_device_get_property_value(device, "ID_BUS");
|
||||
// qDebug() << udev_device_get_property_value(device, "ID_PATH");
|
||||
// qDebug() << udev_device_get_property_value(device, "ID_USB_DRIVER");
|
||||
// qDebug() << udev_device_get_sysattr_value (device, "serial");
|
||||
// qDebug() << udev_device_get_sysattr_value (device, "ieee1284_id");
|
||||
// qDebug() << udev_device_get_sysattr_value (device, "idVendor");
|
||||
// qDebug() << udev_device_get_sysattr_value (device, "idProduct");
|
||||
// qDebug() << udev_device_get_sysattr_value (device, "manufacturer");
|
||||
// qDebug() << udev_device_get_sysattr_value (device, "product");
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool usbClassCheck(int bInterfaceClass, int bInterfaceSubClass)
|
||||
{
|
||||
switch (bInterfaceClass) {
|
||||
case LIBUSB_CLASS_PRINTER:
|
||||
case LIBUSB_CLASS_IMAGE:
|
||||
return true;
|
||||
case LIBUSB_CLASS_VENDOR_SPEC:
|
||||
if (bInterfaceSubClass == LIBUSB_CLASS_VENDOR_SPEC) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
usbFinder::usbFinder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
usbFinder::~usbFinder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void usbFinder::dowork()
|
||||
{
|
||||
int numdevs = 0;
|
||||
libusb_device **list = nullptr;
|
||||
struct libusb_device *device = nullptr;
|
||||
struct libusb_device_descriptor devdesc;
|
||||
libusb_init(nullptr);
|
||||
numdevs = libusb_get_device_list(nullptr, &list);
|
||||
if (numdevs <= 0) {
|
||||
libusb_free_device_list(list, 1);
|
||||
libusb_exit(nullptr);
|
||||
return ;
|
||||
}
|
||||
qDebug("numdevs is %d\n", numdevs);
|
||||
for (int i = 0; i < numdevs; i++)
|
||||
{
|
||||
|
||||
device = list[i];
|
||||
|
||||
if (libusb_get_device_descriptor(device, &devdesc) < 0)
|
||||
continue;
|
||||
|
||||
if (!devdesc.bNumConfigurations || !devdesc.idVendor || !devdesc.idProduct) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DeviceInformation info;
|
||||
info.connectType = ConnectType::InfoFrom_Invalid;
|
||||
|
||||
for (int conf = 0; conf < devdesc.bNumConfigurations; conf++) {
|
||||
struct libusb_config_descriptor *confptr = NULL;
|
||||
if (libusb_get_config_descriptor(device, conf, &confptr) < 0)
|
||||
continue;
|
||||
const libusb_interface *ifaceptr;
|
||||
int iface;
|
||||
for (iface = 0, ifaceptr = confptr->interface;
|
||||
iface < confptr->bNumInterfaces;
|
||||
iface++, ifaceptr++) {
|
||||
int altset;
|
||||
const struct libusb_interface_descriptor *altptr;
|
||||
struct libusb_device_handle *handle = NULL;
|
||||
for (altset = 0, altptr = ifaceptr->altsetting; altset < ifaceptr->num_altsetting; altset ++, altptr ++) {
|
||||
qDebug("%x %x %x %x\n", altptr->bInterfaceClass, altptr->bInterfaceSubClass, devdesc.idVendor, devdesc.idProduct);
|
||||
if (!usbClassCheck(altptr->bInterfaceClass, altptr->bInterfaceSubClass)) {
|
||||
continue ;
|
||||
}
|
||||
|
||||
info.VID = QString("%1").arg(devdesc.idVendor, 4, 16, QLatin1Char('0'));
|
||||
info.PID = QString("%1").arg(devdesc.idProduct, 4, 16, QLatin1Char('0'));
|
||||
info.busNumber = QString("%1").arg(libusb_get_bus_number(device), 3, 10, QLatin1Char('0'));
|
||||
info.deviceNumber = QString("%1").arg(libusb_get_device_address(device), 3, 10, QLatin1Char('0'));
|
||||
handle = NULL;
|
||||
qDebug() << info;
|
||||
QString devaddr = QString("/dev/bus/usb/%1/%2").arg(info.busNumber).arg(info.deviceNumber);
|
||||
devpath_from_usb_devaddr(QTC(devaddr), info);
|
||||
qDebug() << info;
|
||||
if (info.vendor.size() && info.model.size())
|
||||
info.connectType = ConnectType::InfoFrom_USB;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (info.connectType == ConnectType::InfoFrom_USB)
|
||||
m_usbInfoList.append(info);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
QList<DeviceInformation> usbFinder::getList()
|
||||
{
|
||||
return m_usbInfoList;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// Created by oubayasho on 2023/6/5.
|
||||
//
|
||||
|
||||
#ifndef UNTITLED6_USBFINDER_H
|
||||
#define UNTITLED6_USBFINDER_H
|
||||
|
||||
#include "device_information.h"
|
||||
|
||||
struct device_id_s {
|
||||
QString full_device_id;
|
||||
QString mfg;
|
||||
QString mdl;
|
||||
QString sern;
|
||||
QString cls;
|
||||
};
|
||||
|
||||
void
|
||||
parse_device_id (const char *device_id, struct device_id_s *id);
|
||||
|
||||
|
||||
class usbFinder {
|
||||
public:
|
||||
usbFinder();
|
||||
~usbFinder();
|
||||
void dowork();
|
||||
QList<DeviceInformation> getList();
|
||||
private:
|
||||
QList<DeviceInformation> m_usbInfoList;
|
||||
};
|
||||
|
||||
|
||||
#endif//UNTITLED6_USBFINDER_H
|
|
@ -20,10 +20,9 @@
|
|||
|
||||
DisplayWidget::DisplayWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_defaultConnectDetectPageWidget(new DetectPageWidget()),
|
||||
m_defaultConnectFailedPageWidget(new FailedPageWidget()),
|
||||
m_defaultConnectSuccessPageWidget(new SuccessPageWidget()),
|
||||
// m_defaultConnectSuccessPageScrollArea(new QScrollArea()),
|
||||
m_defaultConnectDetectPageWidget(new DetectPageWidget(this)),
|
||||
m_defaultConnectFailedPageWidget(new FailedPageWidget(this)),
|
||||
m_defaultConnectSuccessPageWidget(new SuccessPageWidget(this)),
|
||||
m_displayStackedLayout(new QStackedLayout(this))
|
||||
{
|
||||
setupGui();
|
||||
|
@ -32,17 +31,10 @@ DisplayWidget::DisplayWidget(QWidget *parent) :
|
|||
|
||||
void DisplayWidget::setupGui()
|
||||
{
|
||||
// m_defaultConnectSuccessPageScrollArea->setWidget(m_defaultConnectSuccessPageScrollArea);
|
||||
// m_defaultConnectSuccessPageScrollArea->setWidgetResizable(true);
|
||||
// m_defaultConnectSuccessPageScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
// m_defaultConnectSuccessPageScrollArea->setFrameShape(QFrame::NoFrame);
|
||||
// m_defaultConnectSuccessPageScrollArea->setFixedWidth(ScanSettingsWidgetWidth);
|
||||
// m_defaultConnectSuccessPageWidget->adjustSize();
|
||||
|
||||
m_displayStackedLayout->addWidget(m_defaultConnectDetectPageWidget);
|
||||
m_displayStackedLayout->addWidget(m_defaultConnectFailedPageWidget);
|
||||
m_displayStackedLayout->addWidget(m_defaultConnectSuccessPageWidget);
|
||||
// m_displayStackedLayout->addWidget(m_defaultConnectSuccessPageScrollArea);
|
||||
|
||||
m_displayStackedLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_displayStackedLayout->setCurrentWidget(m_defaultConnectDetectPageWidget);
|
||||
}
|
||||
|
@ -51,7 +43,14 @@ void DisplayWidget::initConnect()
|
|||
{
|
||||
connect(m_defaultConnectFailedPageWidget, &FailedPageWidget::scanButtonClicked, this, &DisplayWidget::showDetectPageSlot);
|
||||
connect(g_user_signal, &GlobalUserSignal::switchToDetectPageSignal, this, &DisplayWidget::showDetectPageSlot);
|
||||
// connect(g_user_signal, &GlobalUserSignal::switchToFailPageSignal, this, &DisplayWidget::showFailedPageSlot);
|
||||
connect(g_user_signal, &GlobalUserSignal::refreshListInFilePage, [=](){
|
||||
if(m_displayStackedLayout->currentWidget() == m_defaultConnectFailedPageWidget){
|
||||
m_defaultConnectFailedPageWidget->clickfiledPageButton();
|
||||
}else
|
||||
{
|
||||
emit g_user_signal->refreshListSignal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DisplayWidget::showDetectPageSlot()
|
||||
|
@ -66,9 +65,6 @@ void DisplayWidget::showSuccessPageSlot(bool isSucceed)
|
|||
{
|
||||
m_displayStackedLayout->setCurrentWidget(m_defaultConnectSuccessPageWidget);
|
||||
g_user_signal->setIsFailPage(false);
|
||||
|
||||
// m_displayStackedLayout->setCurrentWidget(m_defaultConnectSuccessPageScrollArea);
|
||||
|
||||
m_defaultConnectSuccessPageWidget->updateScanSettingsSlot(isSucceed);
|
||||
}
|
||||
|
||||
|
@ -82,8 +78,5 @@ void DisplayWidget::showSuccessImageHandlePageSlot()
|
|||
{
|
||||
m_displayStackedLayout->setCurrentWidget(m_defaultConnectSuccessPageWidget);
|
||||
g_user_signal->setIsFailPage(false);
|
||||
|
||||
// m_displayStackedLayout->setCurrentWidget(m_defaultConnectSuccessPageScrollArea);
|
||||
|
||||
m_defaultConnectSuccessPageWidget->showLeftImageHandleSuccessPage();
|
||||
}
|
||||
|
|
|
@ -55,12 +55,11 @@ public slots:
|
|||
|
||||
|
||||
private:
|
||||
DetectPageWidget *m_defaultConnectDetectPageWidget;
|
||||
FailedPageWidget *m_defaultConnectFailedPageWidget;
|
||||
SuccessPageWidget *m_defaultConnectSuccessPageWidget;
|
||||
// QScrollArea *m_defaultConnectSuccessPageScrollArea;
|
||||
DetectPageWidget *m_defaultConnectDetectPageWidget = nullptr;
|
||||
FailedPageWidget *m_defaultConnectFailedPageWidget = nullptr;
|
||||
SuccessPageWidget *m_defaultConnectSuccessPageWidget = nullptr;
|
||||
|
||||
QStackedLayout *m_displayStackedLayout;
|
||||
QStackedLayout *m_displayStackedLayout = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
#include "failedpagewidget.h"
|
||||
#include <ukui-log4qt.h>
|
||||
#include <gsettings.hpp>
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
#include "include/theme.h"
|
||||
|
||||
FailedPageWidget::FailedPageWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_failedPageIcon(new QLabel()),
|
||||
m_failedPageText(new QLabel()),
|
||||
m_failedPageButton(new QPushButton()),
|
||||
m_failedPageVLayout(new QVBoxLayout())
|
||||
m_failedPageIcon(new QLabel(this)),
|
||||
m_failedPageText(new QLabel(this)),
|
||||
m_failedPageButton(new QPushButton(this)),
|
||||
m_failedPageVLayout(new QVBoxLayout(this))
|
||||
{
|
||||
setupGui();
|
||||
initConnect();
|
||||
|
@ -18,28 +22,29 @@ FailedPageWidget::FailedPageWidget(QWidget *parent) :
|
|||
void FailedPageWidget::initTheme(){
|
||||
if (isDarkTheme()) {
|
||||
themeColor = "black";
|
||||
m_failedPageIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_dark.svg"));
|
||||
m_failedPageIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_dark.svg").scaled(FailedPageIconSize));
|
||||
|
||||
} else {
|
||||
themeColor = "white";
|
||||
m_failedPageIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_light.svg"));
|
||||
m_failedPageIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_light.svg").scaled(FailedPageIconSize));
|
||||
}
|
||||
}
|
||||
bool FailedPageWidget::isDarkTheme()
|
||||
{
|
||||
QString systemTheme = kdk::kabase::Gsettings::getSystemTheme().toString();
|
||||
|
||||
QString systemTheme = kdk::GsettingMonitor::getSystemTheme().toString();
|
||||
if (systemTheme == STYLE_NAME_KEY_DARK || systemTheme == STYLE_NAME_KEY_BLACK) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void FailedPageWidget::setupGui()
|
||||
{
|
||||
m_failedPageIcon->setFixedSize(FailedPageIconSize);
|
||||
|
||||
m_failedPageText->setEnabled(false);
|
||||
m_failedPageText->setText(tr("Not detect scanners, please connect scanners firstly!"));
|
||||
m_failedPageText->setText(tr("No available scan devices"));
|
||||
|
||||
m_failedPageButton->setProperty("isImportant",true);
|
||||
m_failedPageButton->setMinimumSize(FailedPageButtonSize);
|
||||
|
@ -69,18 +74,24 @@ void FailedPageWidget::initConnect()
|
|||
connect(m_failedPageButton, &QPushButton::clicked, this, [=](){
|
||||
emit scanButtonClicked();
|
||||
});
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemFontSizeChange,this,&FailedPageWidget::fontSizeChanged);
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &FailedPageWidget::initTheme);
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemFontSizeChange,this,&FailedPageWidget::fontSizeChanged);
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemThemeChange, this, &FailedPageWidget::initTheme);
|
||||
connect(GlobalUserSignal::getInstance(),&GlobalUserSignal::rotationChangedSig,this,&FailedPageWidget::rotateChangedSlot);
|
||||
}
|
||||
|
||||
void FailedPageWidget::fontSizeChanged()
|
||||
{
|
||||
float systemFontSize = kdk::kabase::Gsettings::getSystemFontSize().toFloat();
|
||||
float systemFontSize = kdk::GsettingMonitor::getSystemFontSize().toFloat();
|
||||
QFont font;
|
||||
font.setPointSize(systemFontSize);
|
||||
m_failedPageButton->setFont(font);
|
||||
}
|
||||
|
||||
void FailedPageWidget::clickfiledPageButton()
|
||||
{
|
||||
m_failedPageButton->click();
|
||||
}
|
||||
|
||||
void FailedPageWidget::rotateChangedSlot(bool isPCMode){
|
||||
if(isPCMode){
|
||||
m_failedPageButton->setMinimumSize(FailedPageButtonSize);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <QThread>
|
||||
#include<QSize>
|
||||
|
||||
#define FailedPageIconSize QSize(128, 128)
|
||||
#define FailedPageIconSize QSize(96, 96)
|
||||
#define FailedPageButtonSize QSize(102, 36)
|
||||
#define FailedPageButtonSizePADMODE QSize(110, 48)
|
||||
|
||||
|
@ -34,21 +34,20 @@ signals:
|
|||
void scanButtonClicked();
|
||||
|
||||
private:
|
||||
QLabel *m_failedPageIcon;
|
||||
QLabel *m_failedPageText;
|
||||
QPushButton *m_failedPageButton;
|
||||
QVBoxLayout *m_failedPageVLayout;
|
||||
QLabel *m_failedPageIcon = nullptr;
|
||||
QLabel *m_failedPageText = nullptr;
|
||||
QPushButton *m_failedPageButton = nullptr;
|
||||
QVBoxLayout *m_failedPageVLayout = nullptr;
|
||||
QString themeColor = "white";
|
||||
|
||||
bool isDarkTheme();
|
||||
|
||||
public slots:
|
||||
void fontSizeChanged();
|
||||
void rotateChangedSlot(bool isPCMode);
|
||||
|
||||
void clickfiledPageButton();
|
||||
private slots:
|
||||
void initTheme();
|
||||
|
||||
void rotateChangedSlot(bool isPCMode);
|
||||
};
|
||||
|
||||
#endif // FAILEDPAGEWIDGET_H
|
||||
|
|
|
@ -23,7 +23,6 @@ void Global::global_init() {
|
|||
{
|
||||
g_settings->setValue("General/display_env", "x11");
|
||||
}
|
||||
// isWayland = (g_settings->value("General/display_env").toString() == "wayland");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -109,11 +109,6 @@ void GlobalUserSignal::startScanOperation()
|
|||
emit startScanOperationSignal();
|
||||
}
|
||||
|
||||
void GlobalUserSignal::stopScanOperation()
|
||||
{
|
||||
emit stopScanOperationSignal();
|
||||
}
|
||||
|
||||
void GlobalUserSignal::stopOrFinishedScan()
|
||||
{
|
||||
emit stopOrFinishedScanSignal();
|
||||
|
@ -139,9 +134,9 @@ void GlobalUserSignal::updateSaveNameTextAfterScanSuccess()
|
|||
emit updateSaveNameTextAfterScanSuccessSignal();
|
||||
}
|
||||
|
||||
void GlobalUserSignal::closeWindowSaveAs()
|
||||
void GlobalUserSignal::closeWindowSaveAs(bool exitApp)
|
||||
{
|
||||
emit closeWindowSaveAsSignal();
|
||||
emit closeWindowSaveAsSignal(exitApp);
|
||||
}
|
||||
|
||||
void GlobalUserSignal::saveAsButtonClicked(QString filepath)
|
||||
|
@ -303,7 +298,14 @@ GlobalConfigSignal::GlobalConfigSignal(QObject *parent)
|
|||
|
||||
m_scannerPnmImagePath = QStandardPaths::standardLocations(QStandardPaths::TempLocation).at(0)+ "/kylin-scanner/images";
|
||||
|
||||
m_scannerImagePath = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).at(0) + "/kylin-scanner-images";
|
||||
QLocale locale = QLocale::system().name();
|
||||
if(locale.language() == QLocale::Chinese){
|
||||
m_scannerImagePath = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).at(0) + "/扫描图像";
|
||||
}else if(locale.language() == QLocale::English){
|
||||
m_scannerImagePath = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).at(0) + "/kylin-scanner-images";
|
||||
}else if(locale.language() == QLocale::Tibetan){
|
||||
m_scannerImagePath = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).at(0) + "/བཤར་འབེབས་འབུར་ཐོན་";
|
||||
}
|
||||
|
||||
|
||||
m_scannerTempPath = QDir::tempPath() + "/kylin-scanner";
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
void setCurrentMode(bool isPCMode);
|
||||
|
||||
bool exitWindowWithSaveFlag = false;
|
||||
|
||||
void setDeviceList(const SANE_Device **list);
|
||||
QList<SANE_Device> getDeviceList();
|
||||
void setDeviceInUse(SANE_Device device);
|
||||
|
@ -69,7 +70,6 @@ public:
|
|||
void openDeviceStatus(bool openSucceed);
|
||||
|
||||
void startScanOperation();
|
||||
void stopScanOperation();
|
||||
|
||||
void stopOrFinishedScan();
|
||||
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
void showImageAfterClickedThumbnail(QString loadPath);
|
||||
void updateSaveNameTextAfterScanSuccess();
|
||||
|
||||
void closeWindowSaveAs();
|
||||
void closeWindowSaveAs(bool exitApp = false);
|
||||
void saveAsButtonClicked(QString filepath);
|
||||
void sendMailButtonClicked();
|
||||
|
||||
|
@ -143,7 +143,7 @@ signals:
|
|||
void toolbarRectifyOperationStopSignal();
|
||||
|
||||
void sendMailButtonClickedSignal();
|
||||
void closeWindowSaveAsSignal();
|
||||
void closeWindowSaveAsSignal(bool exitApp = false);
|
||||
void saveAsButtonClickedSignal(QString filepath);
|
||||
|
||||
void updateSaveNameTextAfterScanSuccessSignal();
|
||||
|
@ -155,7 +155,6 @@ signals:
|
|||
|
||||
void stopOrFinishedScanSignal();
|
||||
|
||||
void stopScanOperationSignal();
|
||||
void startScanOperationSignal();
|
||||
|
||||
void openDeviceStatusSignal(bool openSucceed);
|
||||
|
@ -181,16 +180,24 @@ signals:
|
|||
void changeToConnectuccessPageSignal();
|
||||
void startUsbHotPlugThreadSignal();
|
||||
void closeUsbHotPlugThreadSignal();
|
||||
|
||||
void switchToSuccessPageSignal();
|
||||
void updateConnectSuccessTextSignal(bool hasdevice);
|
||||
void setExitFlagTrueSignal();
|
||||
void setExitFlagFalseSignal();
|
||||
void startHotPlugSignal();
|
||||
void refreshListInFilePage();
|
||||
void refreshListSignal();
|
||||
void setScanIconDisableSignal();
|
||||
void hotPlugScanCompleteSignal();
|
||||
void posChange(QPoint pos);
|
||||
void resetNavigatorsignal();
|
||||
void showScanWidgetSignal(QString path);
|
||||
void findNoDriverDeviceSignal();
|
||||
void cancleCorpSignal();
|
||||
void mutexUnlockSignal();
|
||||
void exitOcrWhenScanSignal();
|
||||
void rotationChangedSig(bool);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
static GlobalUserSignal* instance;
|
||||
bool m_isPCMode = true;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <QDebug>
|
||||
#include <QPixmap>
|
||||
#include <QThread>
|
||||
|
||||
#include <CImg.h>
|
||||
LoadImage::LoadImage(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_flag = false;
|
||||
|
@ -15,7 +15,16 @@ void LoadImage::loadImageToWidget(QString loadPath, QString save_path, QImage *i
|
|||
m_flag = false;
|
||||
return;
|
||||
}
|
||||
img->load(loadPath);
|
||||
QFileInfo loadPathInfo(loadPath);
|
||||
QString newLoadPath = loadPathInfo.absolutePath() + "/" + loadPathInfo.baseName() + ".jpg";
|
||||
|
||||
loadAndSave(newLoadPath, loadPath);
|
||||
|
||||
// cv::imwrite(std::string(newLoadPath.toLocal8Bit().data()), KylinImageCodec::loadImageToMat(loadPath).mat);
|
||||
|
||||
img->load(newLoadPath);
|
||||
|
||||
|
||||
double proportion;
|
||||
{
|
||||
if (img->isNull()) {
|
||||
|
@ -54,10 +63,19 @@ void LoadImage::loadImageToWidget(QString loadPath, QString save_path, QImage *i
|
|||
container->setAlignment(Qt::AlignCenter | Qt::AlignVCenter | Qt::AlignHCenter);
|
||||
}
|
||||
QImage image = *img;
|
||||
|
||||
qDebug() << &image << " " << img;
|
||||
if(m_flag){
|
||||
m_flag = false;
|
||||
return;
|
||||
}
|
||||
emit finished(save_path, proportion, image);
|
||||
}
|
||||
|
||||
void LoadImage::loadAndSave(QString newLoadPath, QString loadPath)
|
||||
{
|
||||
cimg_library::CImg<unsigned char> img(loadPath.toLocal8Bit().data());
|
||||
if(!QFile(newLoadPath).exists()){
|
||||
img.save_jpeg(newLoadPath.toLocal8Bit().data());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <QObject>
|
||||
#include <QImage>
|
||||
#include <QLabel>
|
||||
#include <FreeImage.h>
|
||||
#include <QFileInfo>
|
||||
|
||||
class LoadImage : public QObject
|
||||
{
|
||||
|
@ -15,7 +17,7 @@ public slots:
|
|||
void loadImageToWidget(QString loadPath, QString save_path, QImage *img, QLabel *container,double scale, bool rotationFlag,QSize labSize);
|
||||
private:
|
||||
bool m_flag;
|
||||
|
||||
void loadAndSave(QString newLoadPath, QString loadPath);
|
||||
|
||||
signals:
|
||||
void finished(QString, double, QImage);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#include "pngsaver.h"
|
||||
|
||||
|
||||
PngSaver::PngSaver(QObject *parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PngSaver::PngSaver(QString name, QString oldpath)
|
||||
: m_oldpath(oldpath),
|
||||
m_name(name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PngSaver::doSave()
|
||||
{
|
||||
QImage img;
|
||||
img.load(m_oldpath);
|
||||
img.save(m_name);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef PNGSAVER_H
|
||||
#define PNGSAVER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
#include <QString>
|
||||
|
||||
class PngSaver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PngSaver(QObject *parent = nullptr);
|
||||
PngSaver(QString name, QString oldpath);
|
||||
QString m_oldpath;
|
||||
QString m_name;
|
||||
|
||||
public slots:
|
||||
void doSave();
|
||||
|
||||
};
|
||||
|
||||
#endif // PNGSAVER_H
|
|
@ -1,11 +1,13 @@
|
|||
#include "savefilebase.h"
|
||||
#include <QFile>
|
||||
#include <QImage>
|
||||
#include "../saneobject.h"
|
||||
#include <QPixmap>
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QThread>
|
||||
#include "pngsaver.h"
|
||||
#include <QApplication>
|
||||
|
||||
constexpr inline int U(const char *str)
|
||||
{
|
||||
|
@ -32,11 +34,21 @@ bool SaveFileBase::imageSave(QImage *imgOP)
|
|||
/*****************mark***************************/
|
||||
QImage tmp = imgOP->copy();
|
||||
/*****************mark***************************/
|
||||
if (m_fileName.endsWith(".png") || m_fileName.endsWith(".jpg") || m_fileName.endsWith(".bmp"))
|
||||
if (m_fileName.endsWith(".jpg") || m_fileName.endsWith(".bmp"))
|
||||
tmp.save(m_fileName);
|
||||
if (m_fileName.endsWith(".tiff")){
|
||||
saveAsTiff(tmp, m_fileName);
|
||||
}
|
||||
if(m_fileName.endsWith(".png")){
|
||||
QString oldpath = "/tmp/kylin-scanner/images/" + QFileInfo(m_fileName).baseName() + ".jpg";
|
||||
PngSaver *saver = new PngSaver(m_fileName, oldpath);
|
||||
QThread *thread = new QThread();
|
||||
saver->moveToThread(thread);
|
||||
connect(thread, &QThread::started, saver, &PngSaver::doSave);
|
||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||
connect(thread, &QThread::finished, saver, &PngSaver::deleteLater);
|
||||
thread->start();
|
||||
}
|
||||
} else {
|
||||
if (!m_fileName.endsWith(".txt"))
|
||||
m_fileName += ".txt";
|
||||
|
@ -63,19 +75,56 @@ void SaveFileBase::saveToPdf(QImage *imgOP)
|
|||
|
||||
int pageMargin = 0;
|
||||
pdfWriter->setPageMargins(QMarginsF(pageMargin, pageMargin, pageMargin, pageMargin));
|
||||
|
||||
if(tmp.width() < tmp.height()){
|
||||
pdfWriter->setPageOrientation(QPageLayout::Portrait);
|
||||
}else{
|
||||
pdfWriter->setPageOrientation(QPageLayout::Landscape);
|
||||
}
|
||||
QPainter *pdfPainter = new QPainter(pdfWriter);
|
||||
|
||||
int yCurrentP = 0;
|
||||
int xCurrentP = 0;
|
||||
|
||||
QPixmap pixmap = QPixmap::fromImage(tmp);
|
||||
|
||||
pdfPainter->drawPixmap(xCurrentP, yCurrentP, pixmap.width(), pixmap.height(), pixmap);
|
||||
|
||||
|
||||
pdfPainter->end();
|
||||
delete pdfPainter;
|
||||
delete pdfWriter;
|
||||
pdfFile.close();
|
||||
g_user_signal->exitWindowWithSaveFlag = false;
|
||||
m_pdfCount++;
|
||||
m_pdfName.append(m_fileName);
|
||||
if(m_pdfCount == g_sane_object->scanPageNumber && g_sane_object->scanPageNumber != 1){
|
||||
QFileInfo a = QFileInfo(m_fileName);
|
||||
|
||||
QString outputName = a.absolutePath() + "/" + a.baseName().split("[")[0] + ".pdf";
|
||||
QString str = QString("gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=%1 ").arg(outputName);
|
||||
for(int i = 0; i < m_pdfName.length(); i++){
|
||||
str += m_pdfName[i];
|
||||
str += " ";
|
||||
}
|
||||
qDebug() << str;
|
||||
QProcess *process = new QProcess();
|
||||
process->start(str);
|
||||
m_pdfCount = 0;
|
||||
if(process->waitForFinished()){
|
||||
for(int i = 0; i < m_pdfName.length(); i++){
|
||||
QFile a(m_pdfName[i]);
|
||||
if(a.exists()){
|
||||
a.remove();
|
||||
}
|
||||
}
|
||||
m_pdfName.clear();
|
||||
process->close();
|
||||
}
|
||||
}
|
||||
if(g_sane_object->scanPageNumber = 1){
|
||||
m_pdfName.clear();
|
||||
m_pdfCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SaveFileBase::setPdfSize(QPdfWriter *pdfWriter, QString size)
|
||||
|
@ -121,47 +170,65 @@ void SaveFileBase::setPdfSize(QPdfWriter *pdfWriter, QString size)
|
|||
void SaveFileBase::saveAsTiff(QImage image, QString file_name)
|
||||
{
|
||||
m_tiffImageList.append(image);
|
||||
m_fileImages.append(file_name);
|
||||
image.save(file_name);
|
||||
QString fileTrueName = QFileInfo(file_name).absolutePath() + "/" + QFileInfo(file_name).baseName() + ".tiff";
|
||||
m_fileImages.append(fileTrueName);
|
||||
image.save(fileTrueName);
|
||||
|
||||
QString save_name = g_sane_object->saveFullScanFileName + ".tif";
|
||||
QString save_name = g_sane_object->saveFullScanFileName + ".tiff";
|
||||
if(!QFile::exists(save_name)){
|
||||
m_tiffImageList[0].save(save_name);
|
||||
}
|
||||
|
||||
FREE_IMAGE_FORMAT fif = FIF_TIFF;
|
||||
FIBITMAP *page;
|
||||
int s = g_sane_object->scanPageNumber;
|
||||
if(m_tiffImageList.length() == g_sane_object->scanPageNumber){
|
||||
|
||||
int i = 1;
|
||||
int count = 0;
|
||||
while(1){
|
||||
QString path = "/tmp/kylin-scanner/images/" + QFileInfo(save_name).completeBaseName() + "[" + QString::number(i) + "]" + + ".pnm";
|
||||
QFileInfo file(path);
|
||||
if(file.exists()){
|
||||
i++;
|
||||
count++;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
FIMULTIBITMAP *newfile;
|
||||
if(m_tiffImageList.length() == count){
|
||||
FIMULTIBITMAP *src = FreeImage_OpenMultiBitmap(fif, save_name.toLocal8Bit().data(), false, false, true, 0);
|
||||
for(int i = 1; i < m_tiffImageList.length(); i++){
|
||||
QString newFileName = m_fileImages[i];
|
||||
FIMULTIBITMAP *newfile = FreeImage_OpenMultiBitmap(fif, newFileName.toLocal8Bit().data(), false, true);
|
||||
newfile = FreeImage_OpenMultiBitmap(fif, newFileName.toLocal8Bit().data(), false, true);
|
||||
page = FreeImage_LockPage(newfile, 0);
|
||||
m_filist.append(FreeImage_Clone(page));
|
||||
FreeImage_UnlockPage(newfile, page, 0);
|
||||
}
|
||||
FreeImage_CloseMultiBitmap(src);
|
||||
}
|
||||
|
||||
if(m_filist.length() == (g_sane_object->scanPageNumber - 1)){
|
||||
bool result = false;
|
||||
if(m_filist.length() == (count - 1)){
|
||||
FIMULTIBITMAP *out = FreeImage_OpenMultiBitmap(fif, save_name.toLocal8Bit().data(), false, false);
|
||||
for(int i = 0; i < m_filist.length(); i++){
|
||||
FreeImage_AppendPage(out, m_filist.at(i));
|
||||
}
|
||||
bool result = FreeImage_CloseMultiBitmap(out);
|
||||
result = FreeImage_CloseMultiBitmap(out);
|
||||
}
|
||||
|
||||
if(result){
|
||||
for(int j = 0; j < m_fileImages.length(); j++){
|
||||
QString filename = m_fileImages.at(j);
|
||||
if(result || g_sane_object->userInfo.pageNumber.compare(QApplication::tr("Single"), Qt::CaseInsensitive) == 0){
|
||||
for(int j = 0; j < m_fileImages.length(); j++){
|
||||
QString filename = m_fileImages.at(j);
|
||||
if(filename != save_name){
|
||||
QFile *a = new QFile(filename);
|
||||
a->remove();
|
||||
if(a->exists()){
|
||||
a->remove();
|
||||
}
|
||||
a->deleteLater();
|
||||
}
|
||||
m_tiffImageList.clear();
|
||||
m_fileImages.clear();
|
||||
}
|
||||
m_tiffImageList.clear();
|
||||
m_fileImages.clear();
|
||||
m_filist.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,11 @@
|
|||
#include <QObject>
|
||||
#include <QPdfWriter>
|
||||
#include <QImage>
|
||||
#include <opencv4/opencv2/core.hpp>
|
||||
#include <opencv4/opencv2/imgcodecs.hpp>
|
||||
#include <opencv4/opencv2/imgproc.hpp>
|
||||
#include <tiff.h>
|
||||
#include <tiffio.h>
|
||||
#include <FreeImage.h>
|
||||
#include <QFile>
|
||||
#include <QProcess>
|
||||
|
||||
class SaveFileBase : public QObject
|
||||
{
|
||||
|
@ -29,6 +27,8 @@ private:
|
|||
QList<QImage> m_tiffImageList;
|
||||
QStringList m_fileImages;
|
||||
QList<FIBITMAP*> m_filist;
|
||||
int m_pdfCount = 0;
|
||||
QStringList m_pdfName;
|
||||
signals:
|
||||
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ public:
|
|||
|
||||
QImage *m_origin;
|
||||
QStack<QImage> *m_stackImage;
|
||||
bool isInterupt;
|
||||
bool isInterupt = false;
|
||||
QImage imageCopy(QImage *origin, QStack<QImage> *stackImage);
|
||||
bool getIsInterrupt();
|
||||
void interuptOp();
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "imageoperationbeauty.h"
|
||||
#include "../beauty.h"
|
||||
#include "../include/common.h"
|
||||
#include <QDebug>
|
||||
|
||||
|
@ -10,64 +9,85 @@ ImageOperationBeauty::ImageOperationBeauty(QImage *origin, QStack<QImage> *stack
|
|||
m_stackImage = stackImage;
|
||||
isInterupt = false;
|
||||
}
|
||||
|
||||
void ImageOperationBeauty::ImageOP(){
|
||||
QImage res = imageCopy(m_origin,m_stackImage);
|
||||
cv::Mat target = Image2Mat(&res);
|
||||
beauty(target);
|
||||
QImage res = imageCopy(m_origin, m_stackImage);
|
||||
beauty(res);
|
||||
emit finished();
|
||||
}
|
||||
void ImageOperationBeauty::beauty(cv::Mat src){
|
||||
Mat dst;
|
||||
if (!src.data) {
|
||||
qDebug() << ScanningPicture << "image load error!";
|
||||
return;
|
||||
}
|
||||
if(isInterupt){
|
||||
return;
|
||||
}
|
||||
bilateralFilterCV(src, dst);
|
||||
if(isInterupt){
|
||||
return;
|
||||
}
|
||||
luminanceContrastCV(dst, dst);
|
||||
if(isInterupt){
|
||||
return;
|
||||
}
|
||||
hslCV(dst, dst);
|
||||
if(isInterupt){
|
||||
return;
|
||||
}
|
||||
sharpenCV(dst, dst);
|
||||
if(isInterupt){
|
||||
return;
|
||||
}
|
||||
imwrite(ScanningPicture, dst);
|
||||
}
|
||||
cv::Mat ImageOperationBeauty::Image2Mat(QImage *img){
|
||||
cv::Mat res;
|
||||
switch (img->format()){
|
||||
case QImage::Format_ARGB32_Premultiplied:
|
||||
res = cv::Mat(img->height(),img->width(),CV_8UC4,(uchar*)img->bits(),img->bytesPerLine());
|
||||
break;
|
||||
case QImage::Format_RGB888:
|
||||
res = cv::Mat(img->height(),img->width(),CV_8UC3,(uchar*)img->bits(),img->bytesPerLine());
|
||||
break;
|
||||
case QImage::Format_Indexed8:
|
||||
case QImage::Format_Grayscale8:
|
||||
res = cv::Mat(img->height(),img->width(),CV_8UC1,(uchar*)img->bits(),img->bytesPerLine());
|
||||
cvtColor(res,res,CV_GRAY2BGR);
|
||||
break;
|
||||
case QImage::Format_RGB32:
|
||||
res = cv::Mat(img->height(),img->width(),CV_8UC4,(uchar*)img->bits(),img->bytesPerLine());
|
||||
cvtColor(res,res,CV_BGRA2BGR);
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug() << "image format:" << img->format();
|
||||
*img = img->convertToFormat(QImage::Format_RGB32);
|
||||
res = Mat(img->height(),img->width(),CV_8UC4,const_cast<uchar*>(img->bits()),static_cast<size_t>(img->bytesPerLine()));
|
||||
cvtColor(res,res,CV_BGR2RGB);
|
||||
void ImageOperationBeauty::beauty(const QImage inputImage)
|
||||
{
|
||||
// 将图像转换为灰度图
|
||||
QImage grayImage = inputImage.convertToFormat(QImage::Format_Grayscale8);
|
||||
|
||||
// 创建输出图像
|
||||
QImage outputImage = grayImage;
|
||||
|
||||
int width = grayImage.width();
|
||||
int height = grayImage.height();
|
||||
|
||||
// 计算图像的平均亮度
|
||||
int sum = 0;
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
QRgb pixel = grayImage.pixel(x, y);
|
||||
sum += qGray(pixel);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
int averageBrightness = sum / (width * height);
|
||||
|
||||
// 提高图像的对比度和锐度,并根据平均亮度调整亮度
|
||||
for (int y = 1; y < height - 1; ++y)
|
||||
{
|
||||
for (int x = 1; x < width - 1; ++x)
|
||||
{
|
||||
// 获取中心像素值
|
||||
QRgb centerPixel = grayImage.pixel(x, y);
|
||||
int centerGray = qGray(centerPixel);
|
||||
|
||||
// 计算邻近像素的平均灰度值
|
||||
sum = 0;
|
||||
for (int j = -1; j <= 1; ++j)
|
||||
{
|
||||
for (int i = -1; i <= 1; ++i)
|
||||
{
|
||||
QRgb pixel = grayImage.pixel(x + i, y + j);
|
||||
sum += qGray(pixel);
|
||||
}
|
||||
}
|
||||
int averageGray = sum / 9;
|
||||
|
||||
// 计算高反差保留滤波后的像素值
|
||||
int newGray = qBound(0, centerGray + (centerGray - averageGray), 255);
|
||||
|
||||
// 根据平均亮度调整亮度
|
||||
int brightness = qBound(0, newGray + (newGray - averageBrightness) * 2, 255);
|
||||
|
||||
// 猜想补全模糊的字体内容
|
||||
if (centerGray < averageGray)
|
||||
{
|
||||
// 补全模糊的字体内容
|
||||
brightness = qBound(0, centerGray + qAbs(centerGray - averageGray) * 2, 255);
|
||||
}
|
||||
|
||||
// USM锐化
|
||||
float usmAmount = 0.8; // USM锐化的强度,可以调整此值
|
||||
int usmGray = centerGray + static_cast<int>((centerGray - brightness) * usmAmount);
|
||||
brightness = qBound(0, usmGray, 255);
|
||||
|
||||
// 增强对比度
|
||||
float contrastAmount = 1.5;
|
||||
brightness = qBound(0, static_cast<int>((brightness -128) * contrastAmount) + 128, 255);
|
||||
|
||||
// 更新像素值
|
||||
outputImage.setPixel(x, y, qRgb(brightness, brightness, brightness));
|
||||
}
|
||||
}
|
||||
|
||||
outputImage.save(ScanningPicture);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
#define IMAGEOPERATIONBEAUTY_H
|
||||
|
||||
#include "imageoperationbase.h"
|
||||
#include <opencv4/opencv2/core.hpp>
|
||||
#include <opencv4/opencv2/imgcodecs.hpp>
|
||||
#include <opencv4/opencv2/imgproc.hpp>
|
||||
using namespace cv;
|
||||
|
||||
#include "../runningdialog.h"
|
||||
|
||||
class ImageOperationBeauty : public ImageOperationBase
|
||||
|
@ -14,8 +11,7 @@ public:
|
|||
ImageOperationBeauty(QImage *origin, QStack<QImage> *stackImage);
|
||||
virtual void ImageOP();
|
||||
private:
|
||||
void beauty(cv::Mat);
|
||||
cv::Mat Image2Mat(QImage *img);
|
||||
void beauty(const QImage inputImage);
|
||||
void showBeautyRunningDialog();
|
||||
|
||||
};
|
||||
|
|
|
@ -1,61 +1,35 @@
|
|||
#include "imageoperationocr.h"
|
||||
#include <tesseract/baseapi.h>
|
||||
#include "../src/saneobject.h"
|
||||
#include <leptonica/allheaders.h>
|
||||
#include "../saneobject.h"
|
||||
#include "../include/common.h"
|
||||
#include <QDebug>
|
||||
#include <libkyocr.hpp>
|
||||
|
||||
ImageOperationOCR::ImageOperationOCR(QImage *origin, QString path)
|
||||
{
|
||||
m_origin = origin;
|
||||
m_path = path;
|
||||
isInterupt = false;
|
||||
}
|
||||
|
||||
ImageOperationOCR::ImageOperationOCR(QImage *origin)
|
||||
{
|
||||
m_origin = origin;
|
||||
isInterupt = false;
|
||||
}
|
||||
|
||||
void ImageOperationOCR::ImageOP(){
|
||||
ocr();
|
||||
|
||||
QVector<QString> result;
|
||||
kdk::kdkOCR OCR;
|
||||
std::vector<std::string> ret = OCR.getCls(m_path.toStdString(), 4);
|
||||
std::transform(ret.begin(), ret.end(), std::back_inserter(result), [](const std::string &v) {
|
||||
return QString::fromStdString(v);
|
||||
});
|
||||
QString results = "";
|
||||
for(int i = 0; i < result.length(); i++){
|
||||
results.append(result.at(i));
|
||||
}
|
||||
g_sane_object->ocrOutputText = results;
|
||||
g_user_signal->toolbarOcrOperationFinished();
|
||||
emit finished();
|
||||
}
|
||||
void ImageOperationOCR::ocr(){
|
||||
qDebug() << "begin to run ocr thread !\n";
|
||||
m_origin->save(ScanningPicture);
|
||||
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
|
||||
|
||||
if (api->Init(NULL, "chi_sim")) {
|
||||
qDebug() << "Could not initialize tesseract.\n";
|
||||
g_sane_object->ocrOutputText = tr("Unable to read text");
|
||||
return;
|
||||
}
|
||||
if(isInterupt){
|
||||
if (api)
|
||||
api->End();
|
||||
return;
|
||||
}
|
||||
qDebug() << "before pixRead.";
|
||||
Pix *image = pixRead(ScanningPicture);
|
||||
if (! image) {
|
||||
qDebug() << "pixRead error!";
|
||||
g_sane_object->ocrOutputText = tr("Unable to read text");
|
||||
if (api)
|
||||
api->End();
|
||||
return;
|
||||
}
|
||||
if(isInterupt){
|
||||
if (api)
|
||||
api->End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (image) {
|
||||
qDebug() << "before setImage.";
|
||||
api->SetImage(image);
|
||||
g_sane_object->ocrOutputText = api->GetUTF8Text();
|
||||
}
|
||||
qDebug() << "before destroy image.";
|
||||
if (api) {
|
||||
api->End();
|
||||
}
|
||||
if (image) {
|
||||
pixDestroy(&image);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
class ImageOperationOCR : public ImageOperationBase
|
||||
{
|
||||
public:
|
||||
ImageOperationOCR(QImage *);
|
||||
ImageOperationOCR(QImage *origin);
|
||||
ImageOperationOCR(QImage *origin, QString path);
|
||||
virtual void ImageOP();
|
||||
private:
|
||||
void ocr();
|
||||
QString m_path;
|
||||
};
|
||||
|
||||
#endif // IMAGEOPERATIONOCR_H
|
||||
|
|
|
@ -1,61 +1,24 @@
|
|||
#include "imageoperationrectify.h"
|
||||
#include "../src/rectify.h"
|
||||
#include "../rectify.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include <QTime>
|
||||
ImageOperationRectify::ImageOperationRectify(QImage *origin, QStack<QImage> *stackImage)
|
||||
{
|
||||
m_origin = origin;
|
||||
m_stackImage = stackImage;
|
||||
isInterupt = false;
|
||||
}
|
||||
|
||||
void ImageOperationRectify::ImageOP(){
|
||||
QImage imgCopy = imageCopy(m_origin,m_stackImage);
|
||||
if(isInterupt){
|
||||
emit finished();
|
||||
return;
|
||||
}
|
||||
cv::Mat target = Image2Mat(&imgCopy);
|
||||
QImage imgCopy = imageCopy(m_origin, m_stackImage);
|
||||
int res = 0;
|
||||
if(isInterupt){
|
||||
emit finished();
|
||||
return;
|
||||
}
|
||||
res = ImageRectify(&target);
|
||||
|
||||
res = ImageRectify(m_origin);
|
||||
if(res == 0){
|
||||
qDebug() << "rectify success!";
|
||||
}else if(res == 1){
|
||||
qDebug() << "no need to rectify, success!";
|
||||
isInterupt = true;
|
||||
}else{
|
||||
isInterupt = true;
|
||||
qDebug() << "rectify exit!";
|
||||
}
|
||||
emit finished();
|
||||
}
|
||||
cv::Mat ImageOperationRectify::Image2Mat(QImage *img){
|
||||
cv::Mat res;
|
||||
switch (img->format()){
|
||||
case QImage::Format_ARGB32_Premultiplied:
|
||||
res = cv::Mat(img->height(),img->width(),CV_8UC4,(uchar*)img->bits(),img->bytesPerLine());
|
||||
break;
|
||||
case QImage::Format_RGB888:
|
||||
res = cv::Mat(img->height(),img->width(),CV_8UC3,(uchar*)img->bits(),img->bytesPerLine());
|
||||
break;
|
||||
case QImage::Format_Indexed8:
|
||||
case QImage::Format_Grayscale8:
|
||||
res = cv::Mat(img->height(),img->width(),CV_8UC1,(uchar*)img->bits(),img->bytesPerLine());
|
||||
cvtColor(res,res,CV_GRAY2BGR);
|
||||
break;
|
||||
case QImage::Format_RGB32:
|
||||
res = cv::Mat(img->height(),img->width(),CV_8UC4,(uchar*)img->bits(),img->bytesPerLine());
|
||||
cvtColor(res,res,CV_BGRA2BGR);
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug() << "image format:" << img->format();
|
||||
*img = img->convertToFormat(QImage::Format_RGB32);
|
||||
res = Mat(img->height(),img->width(),CV_8UC4,const_cast<uchar*>(img->bits()),static_cast<size_t>(img->bytesPerLine()));
|
||||
cvtColor(res,res,CV_BGR2RGB);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,20 +4,12 @@
|
|||
#include "imageoperationbase.h"
|
||||
#include "imageoperationbase.h"
|
||||
#include <QImage>
|
||||
#include <opencv4/opencv2/core.hpp>
|
||||
#include <opencv4/opencv2/imgcodecs.hpp>
|
||||
#include <opencv4/opencv2/imgproc.hpp>
|
||||
#include <opencv2/imgproc/imgproc_c.h>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
class ImageOperationRectify : public ImageOperationBase
|
||||
{
|
||||
public:
|
||||
ImageOperationRectify(QImage *origin, QStack<QImage> *stackImage);
|
||||
virtual void ImageOP();
|
||||
private:
|
||||
cv::Mat Image2Mat(QImage *img);
|
||||
};
|
||||
|
||||
#endif // IMAGEOPERATIONRECTIFY_H
|
||||
|
|
|
@ -60,6 +60,7 @@ void imageOperationWaterMark::waterMark(QImage *opImage){
|
|||
|
||||
QImage transformImg = pix.toImage();
|
||||
transformImg.save(ScanningPicture);
|
||||
painter.end();
|
||||
}
|
||||
void imageOperationWaterMark::setText(QString text){
|
||||
m_text = text;
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
/******** LeftSuccessPageWidget ********/
|
||||
#define LeftSuccessPageWidth (MainWidgetWidth-ScanSettingsWidgetWidth)
|
||||
#define LeftSuccessPageHeight (MainWidgetHeight-TitlebarHeight)
|
||||
#define LeftSuccessPageIconSize QSize(128, 128)
|
||||
#define LeftSuccessPageIconSize QSize(96, 96)
|
||||
|
||||
/******** LeftImageHandleSuccessPageWidget ********/
|
||||
#define LeftImageHandleSuccessPageWidth (MainWidgetWidth-ScanSettingsWidgetWidth)
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
namespace kabase
|
||||
{
|
||||
|
||||
class KabaseLog
|
||||
class Log
|
||||
{
|
||||
public:
|
||||
KabaseLog() = default;
|
||||
~KabaseLog() = default;
|
||||
Log() = default;
|
||||
~Log() = default;
|
||||
|
||||
static void logOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
|
@ -50,4 +50,4 @@ public:
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -206,12 +206,19 @@ public:
|
|||
KylinScannerTextRecognition = 0x160003, /* 文本识别 */
|
||||
KylinScannerCutting = 0x160004, /* 裁剪 */
|
||||
KylinScannerRotate = 0x160005, /* 旋转 */
|
||||
KylinScannerImage = 0x160006, /* 镜像 */
|
||||
KylinScannerMirror = 0x160006, /* 镜像 */
|
||||
KylinScannerAddWatermark = 0x160007, /* 加水印 */
|
||||
KylinScannerSendMail = 0x160008, /* 发送邮件 */
|
||||
KylinScannerSaveAs = 0x160009, /* 另存为 */
|
||||
KylinScannerSinglePageScan = 0x160010, /* 单页扫描 */
|
||||
KylinScannerMultiPageScan = 0x160011, /* 多页扫描 */
|
||||
KylinScannerFindNoDriverDevice = 0x160012, /* 查询未安装驱动设备信息 */
|
||||
KylinScannerServerAddressConnectFail = 0x160013, /* 链接网络失败 */
|
||||
KylinScannerServerAddressConnectSuccess = 0x160014, /* 链接网络成功 */
|
||||
KylinScannerDriverCanAutoInstall = 0x160015, /* 可以自动安装 */
|
||||
KylinScannerNoDriver = 0x160015, /* 无驱动包,无法自动安装 */
|
||||
kylinScannerDeviceAndDriverName = 0x160016, /* 检测到的扫描仪信息和对应的驱动 */
|
||||
kylinScannerDeviceNoDriver = 0x160017, /* 无驱动信息的扫描仪设备信息 */
|
||||
|
||||
KylinCalendarMonthDetails = 0x170001, /* 查看月详情 */
|
||||
KylinCalendarMonthSwitch = 0x170002, /* 月切换 */
|
||||
|
@ -299,8 +306,16 @@ public:
|
|||
|
||||
return true;
|
||||
};
|
||||
|
||||
static std::string convertPTtoString(PT point){
|
||||
std::string hex;
|
||||
std::stringstream ss;
|
||||
ss << std::hex << point;
|
||||
ss >> hex;
|
||||
return hex.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -18,15 +18,14 @@
|
|||
#include "leftimagehandlesuccesspagewidget.h"
|
||||
|
||||
LeftImageHandleSuccessPageWidget::LeftImageHandleSuccessPageWidget(QWidget *parent) : QWidget(parent),
|
||||
m_thumbnailWidget(new ThumbnailWidget()),
|
||||
m_showImageWidget(new ShowImageWidget()),
|
||||
m_showOcrWidget (new showOcrWidget()),
|
||||
m_showImageOrOcrStackWidget (new QStackedWidget),
|
||||
m_leftImageHandleSuccessPageHLayout(new QHBoxLayout)
|
||||
m_thumbnailWidget(new ThumbnailWidget(this)),
|
||||
m_showImageWidget(new ShowImageWidget(this)),
|
||||
m_showOcrWidget(new showOcrWidget(this)),
|
||||
m_showImageOrOcrStackWidget(new QStackedWidget(this)),
|
||||
m_leftImageHandleSuccessPageHLayout(new QHBoxLayout(this))
|
||||
{
|
||||
setupGui();
|
||||
initConnect();
|
||||
initSettings();
|
||||
}
|
||||
|
||||
void LeftImageHandleSuccessPageWidget::setupGui()
|
||||
|
@ -35,28 +34,26 @@ void LeftImageHandleSuccessPageWidget::setupGui()
|
|||
|
||||
m_showImageOrOcrStackWidget->addWidget(m_showImageWidget);
|
||||
m_showImageOrOcrStackWidget->addWidget(m_showOcrWidget);
|
||||
m_showOcrWidget->setParent(m_showImageOrOcrStackWidget);
|
||||
m_showImageOrOcrStackWidget->setCurrentWidget(m_showImageWidget);
|
||||
|
||||
m_leftImageHandleSuccessPageHLayout->setSpacing(0);
|
||||
m_leftImageHandleSuccessPageHLayout->addWidget(m_thumbnailWidget);
|
||||
// m_leftImageHandleSuccessPageHLayout->addStretch();
|
||||
m_leftImageHandleSuccessPageHLayout->addWidget(m_showImageOrOcrStackWidget);
|
||||
// m_leftImageHandleSuccessPageHLayout->addStretch();
|
||||
m_leftImageHandleSuccessPageHLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
setLayout(m_leftImageHandleSuccessPageHLayout);
|
||||
|
||||
}
|
||||
|
||||
void LeftImageHandleSuccessPageWidget::initConnect()
|
||||
{
|
||||
connect(g_user_signal, &GlobalUserSignal::switchPageSig, this, &LeftImageHandleSuccessPageWidget::showOcrWidgetSlot);
|
||||
// connect(g_user_signal, &GlobalUserSignal::startScanOperationSignal, this, &LeftImageHandleSuccessPageWidget::showImageWidgetSlot);
|
||||
}
|
||||
|
||||
void LeftImageHandleSuccessPageWidget::initSettings()
|
||||
{
|
||||
|
||||
connect(m_showOcrWidget, &showOcrWidget::updateTextEdit, this, &LeftImageHandleSuccessPageWidget::updatOcrText);
|
||||
connect(g_user_signal, &GlobalUserSignal::exitOcrWhenScanSignal, [=](){
|
||||
if(m_showImageOrOcrStackWidget->currentIndex() != 0){
|
||||
m_showImageOrOcrStackWidget->setCurrentWidget(m_showImageWidget);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void LeftImageHandleSuccessPageWidget::showOcrWidgetSlot()
|
||||
|
@ -76,3 +73,8 @@ void LeftImageHandleSuccessPageWidget::showImageWidgetSlot()
|
|||
|
||||
g_user_signal->stopOcrTimer();
|
||||
}
|
||||
|
||||
void LeftImageHandleSuccessPageWidget::updatOcrText()
|
||||
{
|
||||
m_showOcrWidget->setOcrText();
|
||||
}
|
||||
|
|
|
@ -43,17 +43,16 @@ public:
|
|||
|
||||
void setupGui();
|
||||
void initConnect();
|
||||
void initSettings();
|
||||
|
||||
private:
|
||||
ThumbnailWidget *m_thumbnailWidget;
|
||||
ThumbnailWidget *m_thumbnailWidget = nullptr;
|
||||
|
||||
ShowImageWidget *m_showImageWidget;
|
||||
showOcrWidget *m_showOcrWidget;
|
||||
QStackedWidget *m_showImageOrOcrStackWidget;
|
||||
QVBoxLayout *m_showImageAndToolBarVLayout;
|
||||
ShowImageWidget *m_showImageWidget = nullptr;
|
||||
showOcrWidget *m_showOcrWidget = nullptr;
|
||||
QStackedWidget *m_showImageOrOcrStackWidget = nullptr;
|
||||
QVBoxLayout *m_showImageAndToolBarVLayout = nullptr;
|
||||
|
||||
QHBoxLayout *m_leftImageHandleSuccessPageHLayout;
|
||||
QHBoxLayout *m_leftImageHandleSuccessPageHLayout = nullptr;
|
||||
|
||||
|
||||
signals:
|
||||
|
@ -61,7 +60,7 @@ signals:
|
|||
public slots:
|
||||
void showOcrWidgetSlot();
|
||||
void showImageWidgetSlot();
|
||||
|
||||
void updatOcrText();
|
||||
};
|
||||
|
||||
#endif // LEFTIMAGEHANDLESUCCESSPAGEWIDGET_H
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
*/
|
||||
#include "leftsuccesspagewidget.h"
|
||||
#include "include/theme.h"
|
||||
#include <gsettings.hpp>
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
#include "globalsignal.h"
|
||||
|
||||
LeftSuccessPageWidget::LeftSuccessPageWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
|
@ -27,19 +28,30 @@ LeftSuccessPageWidget::LeftSuccessPageWidget(QWidget *parent) :
|
|||
{
|
||||
setupGui();
|
||||
initTheme();
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &LeftSuccessPageWidget::initTheme);
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemThemeChange, this, &LeftSuccessPageWidget::initTheme);
|
||||
connect(g_user_signal, &GlobalUserSignal::updateConnectSuccessTextSignal, this, &LeftSuccessPageWidget::updateText);
|
||||
}
|
||||
|
||||
void LeftSuccessPageWidget::initTheme(){
|
||||
if (isDarkTheme()) {
|
||||
m_connectSuccessIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_dark.svg"));
|
||||
m_connectSuccessIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_dark.svg").scaled(LeftSuccessPageIconSize));
|
||||
} else {
|
||||
m_connectSuccessIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_light.svg"));
|
||||
m_connectSuccessIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_light.svg").scaled(LeftSuccessPageIconSize));
|
||||
}
|
||||
}
|
||||
|
||||
void LeftSuccessPageWidget::updateText(bool hasdevice)
|
||||
{
|
||||
if(hasdevice){
|
||||
m_connectSuccessText->setText(tr("Connect scanners, please click scan button to start scanning."));
|
||||
}else{
|
||||
m_connectSuccessText->setText(tr("No scanner detected, plug in a new scanner to refresh the device list."));
|
||||
}
|
||||
}
|
||||
|
||||
bool LeftSuccessPageWidget::isDarkTheme()
|
||||
{
|
||||
QString systemTheme = kdk::kabase::Gsettings::getSystemTheme().toString();
|
||||
QString systemTheme = kdk::GsettingMonitor::getSystemTheme().toString();
|
||||
|
||||
if (systemTheme == STYLE_NAME_KEY_DARK || systemTheme == STYLE_NAME_KEY_BLACK) {
|
||||
return true;
|
||||
|
@ -51,16 +63,21 @@ bool LeftSuccessPageWidget::isDarkTheme()
|
|||
void LeftSuccessPageWidget::setupGui()
|
||||
{
|
||||
setMinimumSize(LeftSuccessPageWidth, LeftSuccessPageHeight);
|
||||
m_connectSuccessIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_light.svg"));
|
||||
m_connectSuccessIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_light.svg").scaled(LeftSuccessPageIconSize));
|
||||
m_connectSuccessIcon->setFixedSize(LeftSuccessPageIconSize);
|
||||
|
||||
m_connectSuccessText->setMinimumSize(550, 50);
|
||||
m_connectSuccessText->setMaximumSize(550, 100);
|
||||
m_connectSuccessText->setWordWrap(true);
|
||||
m_connectSuccessText->setEnabled(false);
|
||||
m_connectSuccessText->setText(tr("Connect scanners, please click scan button to start scanning."));
|
||||
m_connectSuccessText->setAlignment(Qt::AlignCenter);
|
||||
|
||||
|
||||
m_connectSuccessVLayout->setSpacing(0);
|
||||
m_connectSuccessVLayout->addStretch();
|
||||
m_connectSuccessVLayout->addWidget(m_connectSuccessIcon, 0, Qt::AlignCenter | Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
m_connectSuccessVLayout->addSpacing(13);
|
||||
m_connectSuccessVLayout->addSpacing(8);
|
||||
m_connectSuccessVLayout->addWidget(m_connectSuccessText, 0, Qt::AlignCenter | Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
m_connectSuccessVLayout->addStretch();
|
||||
m_connectSuccessVLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
|
|
@ -43,13 +43,13 @@ public:
|
|||
signals:
|
||||
|
||||
private:
|
||||
QLabel *m_connectSuccessIcon;
|
||||
QLabel *m_connectSuccessText;
|
||||
QVBoxLayout *m_connectSuccessVLayout;
|
||||
QLabel *m_connectSuccessIcon = nullptr;
|
||||
QLabel *m_connectSuccessText = nullptr;
|
||||
QVBoxLayout *m_connectSuccessVLayout = nullptr;
|
||||
bool isDarkTheme();
|
||||
private slots:
|
||||
void initTheme();
|
||||
|
||||
void updateText(bool hasdevice);
|
||||
};
|
||||
|
||||
#endif // LEFTSUCCESSPAGEWIDGET_H
|
||||
|
|
63
src/main.cpp
63
src/main.cpp
|
@ -15,12 +15,7 @@
|
|||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include "include/common.h"
|
||||
#include "globalsignal.h"
|
||||
#include "mainwidget.h"
|
||||
#include "scandialog.h"
|
||||
#include "singleapplication.h"
|
||||
#include "global.h"
|
||||
#include <QApplication>
|
||||
#include <QByteArray>
|
||||
#include <QDir>
|
||||
|
@ -38,15 +33,17 @@
|
|||
#include <QFileInfo>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include "kabaselog.hpp"
|
||||
#include <log.hpp>
|
||||
#include <kysdk/applications/singleapplication.h>
|
||||
#include "windowmanage.hpp"
|
||||
#include <singleapplication.h>
|
||||
#include <QDebug>
|
||||
#include "include/common.h"
|
||||
#include "globalsignal.h"
|
||||
#include "mainwidget.h"
|
||||
#include "scandialog.h"
|
||||
#include "global.h"
|
||||
|
||||
#define TRANS_PATH "/usr/share/kylin-scanner/translations"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//using namespace Global;
|
||||
|
||||
|
||||
|
@ -151,7 +148,7 @@ static QString getAppVersion()
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* 使用sdk管理日志 */
|
||||
qInstallMessageHandler(::kabase::KabaseLog::logOutput);
|
||||
qInstallMessageHandler(kabase::Log::logOutput);
|
||||
|
||||
QString scannerFileName;
|
||||
if (argc > 1) {
|
||||
|
@ -161,23 +158,21 @@ int main(int argc, char *argv[])
|
|||
int exitCode = 0;
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
/* 适配4K屏 */
|
||||
::kabase::WindowManage::setScalingProperties();
|
||||
|
||||
kdk::QtSingleApplication app(argc, argv);
|
||||
|
||||
createScannerDir();
|
||||
|
||||
getSystemArchitecture();
|
||||
app.setApplicationVersion("3.2.0.8");
|
||||
app.setWindowIcon (QIcon::fromTheme("kylin-scanner"));
|
||||
QLocale loc = QLocale::system().name();
|
||||
app.setApplicationVersion(getAppVersion());
|
||||
app.setWindowIcon(QIcon::fromTheme("kylin-scanner"));
|
||||
|
||||
if (app.isRunning()) {
|
||||
qDebug() << "is running";
|
||||
|
@ -262,16 +257,14 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
qDebug() << "加载中文失败";
|
||||
}
|
||||
if(locale == "zh_CN"){
|
||||
if(trans_SDK.load(":/translations/gui_zh_CN.qm")){
|
||||
app.installTranslator(&trans_SDK);
|
||||
}
|
||||
}
|
||||
if(locale == "bo_CN"){
|
||||
if(trans_SDK.load(":/translations/gui_bo_CN.qm")){
|
||||
app.installTranslator(&trans_SDK);
|
||||
}
|
||||
}
|
||||
|
||||
if(!trans_SDK.load(":/translations/gui_" + locale + ".qm")){
|
||||
qDebug() << "Load translations file" <<QLocale() << "failed!";
|
||||
}else{
|
||||
QApplication::installTranslator(&trans_SDK);
|
||||
}
|
||||
|
||||
|
||||
app.setApplicationName(QApplication::tr("Scanner"));
|
||||
if (! app.isRunning()) {
|
||||
QString userNow = getCurrentUserName();
|
||||
|
@ -295,7 +288,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* 移除标题栏 */
|
||||
::kabase::WindowManage::removeHeader(w);
|
||||
kabase::WindowManage::removeHeader(w);
|
||||
|
||||
/* 解决置顶失效 */
|
||||
kabase::WindowManage::keepWindowAbove(w->windowId);
|
||||
|
@ -303,17 +296,9 @@ int main(int argc, char *argv[])
|
|||
w->show();
|
||||
|
||||
/* 居中显示 */
|
||||
::kabase::WindowManage::setMiddleOfScreen(w);
|
||||
kabase::WindowManage::setMiddleOfScreen(w);
|
||||
|
||||
|
||||
return app.exec();
|
||||
#if 0
|
||||
// For restart application
|
||||
if (exitCode == MainWidget::EXIT_CODE_REBOOT) {
|
||||
KyInfo() << "reboot";
|
||||
QProcess::startDetached(qApp->applicationFilePath(), QStringList());
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,32 +21,26 @@
|
|||
#include <QWidgetList>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QTimer>
|
||||
#include <kylin_system/window_management.hpp>
|
||||
#include <gsettings.hpp>
|
||||
#include <kylin_system/user_manual.hpp>
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
#include "Qt/windowmanage.hpp"
|
||||
#include <kysdk/applications/usermanual.h>
|
||||
#include <KWindowEffects>
|
||||
#include <kylin_system/window_management.hpp>
|
||||
#include <kysdk/kysdk-system/libkylockscreen.h>
|
||||
#include "usb.h"
|
||||
#include "kabase/Qt/windowmanage.hpp"
|
||||
|
||||
|
||||
|
||||
static bool isExited = false; //! exit scan thread
|
||||
|
||||
int const MainWidget::EXIT_CODE_REBOOT = -123456789;
|
||||
|
||||
MainWidget::MainWidget(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_titleBar(new TitleBar()),
|
||||
m_displayWidget(new DisplayWidget()),
|
||||
// m_displayScrollArea(new QScrollArea),
|
||||
m_mainWidgetVLayout(new QVBoxLayout())
|
||||
m_titleBar(new TitleBar(this)),
|
||||
m_displayWidget(new DisplayWidget(this)),
|
||||
m_mainWidgetVLayout(new QVBoxLayout(this))
|
||||
{
|
||||
GlobalUserSignal::getInstance()->setCurrentMode(rotateInfo.getCurrentMode());
|
||||
connect(&rotateInfo,&RotateChangeInfo::rotationChanged,this,&MainWidget::rotationChanged);
|
||||
kabase::WindowManage::getWindowId(&windowId);
|
||||
setupGui();
|
||||
initConnect();
|
||||
initGsettings();
|
||||
installEventFilter(this);
|
||||
|
||||
if (g_config_signal->m_kylinScannerImageDebug) {
|
||||
scanThreadFinishedSlot(SANE_STATUS_GOOD);
|
||||
|
@ -61,7 +55,6 @@ MainWidget::~MainWidget()
|
|||
g_sane_object->stopSaneRead(true);
|
||||
|
||||
exit(0);
|
||||
|
||||
}
|
||||
void MainWidget::rotationChanged(bool isPCMode,int width,int height){
|
||||
GlobalUserSignal::getInstance()->setCurrentMode(isPCMode);
|
||||
|
@ -69,36 +62,28 @@ void MainWidget::rotationChanged(bool isPCMode,int width,int height){
|
|||
}
|
||||
void MainWidget::setupGui()
|
||||
{
|
||||
// Frosted glass effect, must before than XAtomHelper
|
||||
this->setProperty("useSystemStyleBlur", true);
|
||||
|
||||
this->setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
|
||||
// Add window control protocol
|
||||
::kabase::WindowManage::removeHeader(this);
|
||||
kabase::WindowManage::removeHeader(this);
|
||||
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
// resize(MainWidgetWidth, MainWidgetHeight);
|
||||
setMinimumSize(MainWidgetWidth, MainWidgetHeight);
|
||||
setMaximumSize(4096, 2160);
|
||||
setWindowTitle(tr("kylin-scanner"));
|
||||
// this->setWindowIcon(QIcon::fromTheme("kylin-scanner"));
|
||||
setMouseTracking(true);
|
||||
setAutoFillBackground(true);
|
||||
setAcceptDrops(true);
|
||||
this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
this->setWindowTitle(tr("Scanner"));
|
||||
this->setMouseTracking(true);
|
||||
this->setAcceptDrops(true);
|
||||
|
||||
this->setObjectName("MainWindow");
|
||||
|
||||
m_mainWidgetVLayout->addWidget(m_titleBar);
|
||||
m_mainWidgetVLayout->addWidget(m_displayWidget);
|
||||
m_mainWidgetVLayout->setSpacing(0);
|
||||
m_mainWidgetVLayout->setContentsMargins(0, 0, 0, 0);
|
||||
this->setLayout(m_mainWidgetVLayout);
|
||||
|
||||
this->resize(MainWidgetWidth, MainWidgetHeight);
|
||||
this->setMinimumSize(MainWidgetWidth, MainWidgetHeight);
|
||||
|
||||
// Center window
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
move((screen->geometry().width() - MainWidgetWidth) / 2, (screen->geometry().height() - MainWidgetHeight) / 2);
|
||||
|
||||
this->setObjectName("MainWindow");
|
||||
|
||||
m_mainWidgetVLayout->setSpacing(0);
|
||||
m_mainWidgetVLayout->addWidget(m_titleBar);
|
||||
m_mainWidgetVLayout->addWidget(m_displayWidget);
|
||||
m_mainWidgetVLayout->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(m_mainWidgetVLayout);
|
||||
|
||||
}
|
||||
|
||||
void MainWidget::initConnect()
|
||||
|
@ -127,27 +112,23 @@ void MainWidget::initConnect()
|
|||
connect(g_user_signal, &GlobalUserSignal::closeUsbHotPlugThreadSignal, this, [=](){m_usbHotplugThread.exitWindowFlag = true;});
|
||||
connect(g_user_signal, &GlobalUserSignal::startHotPlugSignal, this, &MainWidget::startHotPlutSlot);
|
||||
connect(g_user_signal, &GlobalUserSignal::hotPlugScanCompleteSignal, this, [=](){g_sane_object->hotPlugScanCompleteSlot();});
|
||||
|
||||
//字体,透明度改变
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemFontSizeChange, this, &MainWidget::fontSizeChange);
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemTransparencyChange, this, &MainWidget::transparencyChange);
|
||||
|
||||
connect(g_user_signal, &GlobalUserSignal::findNoDriverDeviceSignal, this, [=](){
|
||||
m_waittingDialog = new WaittingDialog(this);
|
||||
m_waittingDialog->show();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWidget::initGsettings()
|
||||
{
|
||||
themeChange();
|
||||
transparencyChange();
|
||||
fontSizeChange();
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &MainWidget::themeChange);
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemFontSizeChange, this, &MainWidget::fontSizeChange);
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemTransparencyChange, this, &MainWidget::transparencyChange);
|
||||
}
|
||||
|
||||
bool MainWidget::isDarkTheme()
|
||||
{
|
||||
QString systemTheme = kdk::kabase::Gsettings::getSystemTheme().toString();
|
||||
|
||||
if (systemTheme == STYLE_NAME_KEY_DARK || systemTheme == STYLE_NAME_KEY_BLACK) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemFontSizeChange, this, &MainWidget::fontSizeChange);
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemTransparencyChange, this, &MainWidget::transparencyChange);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,27 +146,15 @@ void MainWidget::resizeDisplayWidget()
|
|||
m_displayWidget->resize(this->width(), this->height() - TitlebarHeight);
|
||||
}
|
||||
|
||||
void MainWidget::themeChange()
|
||||
{
|
||||
QPalette pal(palette());
|
||||
if (isDarkTheme()) {
|
||||
pal.setColor(QPalette::Background, QColor(64, 64, 64));
|
||||
} else {
|
||||
pal.setColor(QPalette::Background, QColor(240, 240, 240));
|
||||
}
|
||||
setAutoFillBackground(true);
|
||||
setPalette(pal);
|
||||
}
|
||||
|
||||
void MainWidget::fontSizeChange()
|
||||
{
|
||||
float fontSize = kdk::kabase::Gsettings::getSystemFontSize().toFloat();
|
||||
{
|
||||
float fontSize = kdk::GsettingMonitor::getSystemFontSize().toFloat();
|
||||
KyInfo() << "fontSize = " << fontSize;
|
||||
}
|
||||
|
||||
void MainWidget::transparencyChange()
|
||||
{
|
||||
double transparencyValue = kdk::kabase::Gsettings::getSystemTransparency().toDouble();
|
||||
double transparencyValue = kdk::GsettingMonitor::getSystemTransparency().toDouble();
|
||||
g_config_signal->m_transparency = transparencyValue * 255;
|
||||
this->update();
|
||||
}
|
||||
|
@ -193,26 +162,14 @@ void MainWidget::warnMsg(QString msg)
|
|||
{
|
||||
QMessageBox *msgBox = new QMessageBox();
|
||||
m_msgBoxList.append(msgBox);
|
||||
if (isDarkTheme()) {
|
||||
QPalette pal(palette());
|
||||
pal.setColor(QPalette::Background, QColor(0, 0, 0));
|
||||
msgBox->setAutoFillBackground(true);
|
||||
msgBox->setPalette(pal);
|
||||
} else {
|
||||
QPalette pal(palette());
|
||||
pal.setColor(QPalette::Background, QColor(255, 255, 255));
|
||||
msgBox->setAutoFillBackground(true);
|
||||
msgBox->setPalette(pal);
|
||||
}
|
||||
msgBox->setWindowModality(Qt::ApplicationModal);
|
||||
msgBox->setAttribute(Qt::WA_ShowModal, true);
|
||||
|
||||
msgBox->setText(msg);
|
||||
msgBox->setIcon(QMessageBox::Warning);
|
||||
// msgBox->setWindowIcon(QIcon::fromTheme("kylin-scanner"));
|
||||
msgBox->setWindowTitle(tr("Scanner"));
|
||||
msgBox->setStandardButtons(QMessageBox::Yes);
|
||||
msgBox->setStandardButtons(QMessageBox::Ok);
|
||||
msgBox->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
msgBox->button(QMessageBox::Yes)->setText(tr("Yes"));
|
||||
|
||||
QWidget *widget = nullptr;
|
||||
QWidgetList widgetList = QApplication::allWidgets();
|
||||
|
@ -230,28 +187,26 @@ void MainWidget::warnMsg(QString msg)
|
|||
}
|
||||
|
||||
QTimer* timer = new QTimer();
|
||||
timer->start(10000);
|
||||
timer->start(20000);
|
||||
timer->setSingleShot(true);
|
||||
connect(timer, &QTimer::timeout, msgBox, &QMessageBox::accept);
|
||||
connect(msgBox, &QMessageBox::accepted, msgBox, &QMessageBox::deleteLater);
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, [=]{
|
||||
if (isDarkTheme()) {
|
||||
QPalette pal(palette());
|
||||
pal.setColor(QPalette::Background, QColor(0, 0, 0));
|
||||
msgBox->setAutoFillBackground(true);
|
||||
msgBox->setPalette(pal);
|
||||
} else {
|
||||
QPalette pal(palette());
|
||||
pal.setColor(QPalette::Background, QColor(255, 255, 255));
|
||||
msgBox->setAutoFillBackground(true);
|
||||
msgBox->setPalette(pal);
|
||||
connect(msgBox, &QMessageBox::accepted, msgBox, [=](){
|
||||
if(m_msgBoxList.contains(msgBox)){
|
||||
m_msgBoxList.removeOne(msgBox);
|
||||
}
|
||||
msgBox->deleteLater();
|
||||
});
|
||||
|
||||
msgBox->show();
|
||||
if(m_msgBoxList.length() > 1){
|
||||
for(int i = 0; i < m_msgBoxList.length(); ++i){
|
||||
if(m_msgBoxList.at(i) != msgBox){
|
||||
m_msgBoxList.at(i)->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
msgBox->exec();
|
||||
}
|
||||
|
||||
|
||||
void MainWidget::reboot()
|
||||
{
|
||||
qApp->exit(EXIT_CODE_REBOOT);
|
||||
|
@ -354,17 +309,22 @@ void MainWidget::keyReleaseEvent(QKeyEvent *event)
|
|||
}
|
||||
return QWidget::keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
void MainWidget::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
m_titleBar->on_m_closeBtn_clicked();
|
||||
}
|
||||
void MainWidget::showHelpDialog()
|
||||
{
|
||||
kdk::kabase::UserManualManagement userManualTest;
|
||||
if (!userManualTest.callUserManual(kdk::kabase::AppName::KylinScanner)) {
|
||||
kdk::UserManual userManualTest;
|
||||
if (!userManualTest.callUserManual("kylin-scanner")) {
|
||||
qCritical() << "user manual call fail!";
|
||||
}
|
||||
return;
|
||||
}
|
||||
void MainWidget::dbusInhabitSlot(){
|
||||
|
||||
flag = sessionManagementTest.setInhibitLockScreen(kdk::kabase::AppName::KylinFontViewer , QString("TestReason"));
|
||||
flag = kdk_set_inhibit_lockscreen("kylin-scanner" , "TestReason");
|
||||
if (flag == 0) {
|
||||
qCritical() << "set inhibit lock screen fail";
|
||||
return;
|
||||
|
@ -373,7 +333,7 @@ void MainWidget::dbusInhabitSlot(){
|
|||
}
|
||||
void MainWidget::dbusUnInhabitSlot(){
|
||||
/* 取消禁止锁屏 */
|
||||
sessionManagementTest.unInhibitLockScreen(flag);
|
||||
kdk_un_inhibit_lockscreen(flag);
|
||||
qDebug()<<"test result:un_inhabit";
|
||||
}
|
||||
|
||||
|
@ -400,24 +360,11 @@ void MainWidget::closeWindowSlot()
|
|||
exit(0);
|
||||
}
|
||||
|
||||
void MainWidget::styleSettingsChanged(QString)
|
||||
{
|
||||
QPalette pal(palette());
|
||||
if (isDarkTheme()) {
|
||||
pal.setColor(QPalette::Background, QColor(38, 38, 38));
|
||||
} else {
|
||||
pal.setColor(QPalette::Background, QColor(255, 255, 255));
|
||||
}
|
||||
setAutoFillBackground(true);
|
||||
setPalette(pal);
|
||||
}
|
||||
|
||||
void MainWidget::detectScanDevicesSlot()
|
||||
{
|
||||
if (! m_detectScanDevicesThread.isRunning()) {
|
||||
KyInfo() << "Not running detect scan devices thread. Let's detect ...";
|
||||
m_detectScanDevicesThread.start();
|
||||
m_usbHotplugThread.start();
|
||||
g_user_signal->detectPageWaitTimerStart();
|
||||
}
|
||||
}
|
||||
|
@ -429,31 +376,15 @@ void MainWidget::detectScanDeviceThreadFinishedSlot(bool isDetected)
|
|||
if (isDetected) {
|
||||
// while detect scan device thread finished, we should open the first device to get scan parameters
|
||||
g_sane_object->openSaneDeviceForPage(0);
|
||||
|
||||
m_displayWidget->showSuccessPageSlot(isDetected);
|
||||
} else {
|
||||
emit g_user_signal->findNoDriverDeviceSignal(); // 展示正在检测扫描仪模态窗口
|
||||
m_displayWidget->showFailedPageSlot();
|
||||
m_devFinder = new deviceFinder();
|
||||
QObject::connect(m_devFinder, &deviceFinder::succeed, this, &MainWidget::showNewDeviceListPageSuccessSlot);
|
||||
QObject::connect(m_devFinder, &deviceFinder::succeed, this, &MainWidget::showNewDeviceListPageFailSlot);
|
||||
m_devFinder->startWorker();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static QString getCurrentScanDevices()
|
||||
{
|
||||
// QString cmd(BashType);
|
||||
QStringList arglists;
|
||||
|
||||
// arglists << "-c";
|
||||
// arglists << "scanimage";
|
||||
arglists << "-L";
|
||||
|
||||
QProcess *process = new QProcess();
|
||||
process->start("scanimage", arglists);
|
||||
process->waitForFinished();
|
||||
QString devices = QString::fromLocal8Bit(process->readAllStandardOutput());
|
||||
|
||||
KyInfo() << "current Scan devices: " << devices;
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
static int getSubStringNumber(QString src, QString sub)
|
||||
|
@ -461,240 +392,10 @@ static int getSubStringNumber(QString src, QString sub)
|
|||
QStringList srclist = src.split(sub);
|
||||
KyInfo() << "srclist = " << srclist
|
||||
<< "srclist.size = " << srclist.size();
|
||||
|
||||
return srclist.size()-1;
|
||||
}
|
||||
|
||||
void MainWidget::usbAddedOperationSlot(QString recvData)
|
||||
{
|
||||
KyInfo() << "USB Add: " << recvData;
|
||||
|
||||
QProcess *scanList = new QProcess(this);
|
||||
QStringList argvList;
|
||||
argvList.append("-L");
|
||||
scanList->start("scanimage", argvList);
|
||||
|
||||
connect(scanList, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
[ = ](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
|
||||
KyInfo() << "USB Add exitCode = " << exitCode
|
||||
<< "exitStatus = " << exitStatus;
|
||||
|
||||
// m_detectScanDevicesThread.start();
|
||||
if (0 == exitCode) {
|
||||
QString result = QString::fromLocal8Bit(scanList->readAll());
|
||||
KyInfo() << "result = " << result;
|
||||
|
||||
// firstly 'scanimage -L' will failed, so need call it again.
|
||||
QString devices = getCurrentScanDevices();
|
||||
|
||||
QStringList strListDevice;
|
||||
strListDevice =g_sane_object->getSaneNames();
|
||||
KyInfo() << "current sane names: " << strListDevice
|
||||
<< "userInfo.name= " << g_sane_object->userInfo.name
|
||||
<< "size = " << strListDevice.size();
|
||||
|
||||
if (strListDevice.size() == 0 || strListDevice.isEmpty()) {
|
||||
if ((! devices.isEmpty())
|
||||
&& (! devices.contains("No scanners were identified", Qt::CaseSensitive))) {
|
||||
KyInfo() << "Found scan devices: " << devices;
|
||||
if (! m_detectScanDevicesThread.isRunning()) {
|
||||
KyInfo() << "begin detect scan devices.";
|
||||
g_sane_object->saneExit();
|
||||
m_detectScanDevicesThread.start();
|
||||
QString msg = tr("There is a new scanner connect, redetect all scanners, please wait a moment. ");
|
||||
warnMsg(msg);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
count = getSubStringNumber(devices, "is a");
|
||||
KyInfo() << "Fount scanner size: " << count
|
||||
<< "current scanner size: " << strListDevice.size();
|
||||
|
||||
if (count > strListDevice.size()) {
|
||||
if (! m_detectScanDevicesThread.isRunning()) {
|
||||
g_sane_object->saneExit();
|
||||
m_detectScanDevicesThread.start();
|
||||
}
|
||||
|
||||
KyInfo() << "device add";
|
||||
QString msg = tr("There is a new scanner connect, redetect all scanners, please wait a moment. ");
|
||||
warnMsg(msg);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < strListDevice.size(); ++i) {
|
||||
QString str = strListDevice.at(i).toLocal8Bit().constData();
|
||||
KyInfo() << "i=" << i << "str = " << str;
|
||||
|
||||
if (str == tr("No available device")) {
|
||||
break;
|
||||
}
|
||||
|
||||
/// There are two cases that we cannot find scanners throught `scanimage -L`:
|
||||
/// case 1. no this scanner in system, which means this scanner has been disconnect
|
||||
/// case 2. this scanner has been connect in kylin-scanner by sane_init
|
||||
/// case 3. this scanner has been disconnet, but net or usb can be found CaseInsensitive, such as hp:Color LaserJet Pro MFP M281fdw
|
||||
KyInfo() << "judge device add ";
|
||||
if (! devices.contains(str, Qt::CaseSensitive)) {
|
||||
KyInfo() << "judge device add: " << str;
|
||||
|
||||
// current open device name will not search by 'scanimage -L',
|
||||
// such as FUJITSU fi-7140
|
||||
QString currentOpenDeviceName = g_sane_object->openSaneName;
|
||||
if (currentOpenDeviceName == str) {
|
||||
KyInfo() << "current open device name: " << currentOpenDeviceName;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! m_detectScanDevicesThread.isRunning()) {
|
||||
g_sane_object->saneExit();
|
||||
m_detectScanDevicesThread.start();
|
||||
|
||||
}
|
||||
|
||||
KyInfo() << "device add";
|
||||
QString msg = tr("There is a new scanner connect, redetect all scanners, please wait a moment. ");
|
||||
warnMsg(msg);
|
||||
|
||||
return;
|
||||
} else {
|
||||
KyInfo() << "judge device add: " << str;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void MainWidget::usbRemovedOperationSlot(QString recvData)
|
||||
{
|
||||
KyInfo() << "USB Remove: " << recvData;
|
||||
|
||||
|
||||
QProcess *scanList = new QProcess(this);
|
||||
QStringList argvList;
|
||||
argvList.append("-L");
|
||||
scanList->start("scanimage", argvList);
|
||||
|
||||
connect(scanList, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
[ = ](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
|
||||
KyInfo() << "USB Remove exitCode = " << exitCode
|
||||
<< "exitStatus = " << exitStatus;
|
||||
|
||||
if (0 == exitCode) {
|
||||
QString result = QString::fromLocal8Bit(scanList->readAllStandardOutput());
|
||||
KyInfo() << "result = " << result;
|
||||
|
||||
QStringList strListDevice;
|
||||
strListDevice =g_sane_object->getSaneNames();
|
||||
KyInfo() << "current sane names: " << strListDevice
|
||||
<< "userInfo.name= " << g_sane_object->userInfo.name
|
||||
<< "size = " << strListDevice.size();
|
||||
|
||||
|
||||
for (int i = 0; i < strListDevice.size(); ++i) {
|
||||
QString str = strListDevice.at(i).toLocal8Bit().constData();
|
||||
KyInfo() << "i=" << i << "str = " << str;
|
||||
|
||||
if (str == tr("No available device")) {
|
||||
break;
|
||||
}
|
||||
|
||||
int warnFlag = 0;
|
||||
|
||||
/// There are two cases that we cannot find scanners throught `scanimage -L`:
|
||||
/// case 1. no this scanner in system, which means this scanner has been disconnect
|
||||
/// case 2. this scanner has been connect in kylin-scanner by sane_init
|
||||
/// case 3. this scanner has been disconnet, but net or usb can be found CaseInsensitive, such as hp:Color LaserJet Pro MFP M281fdw
|
||||
if (! result.contains(str, Qt::CaseSensitive)) {
|
||||
QString msg;
|
||||
bool retStatus;
|
||||
msg = tr("device ") + str + tr(" has been disconnect.");
|
||||
KyInfo() << "usbRemoved msg: " << msg
|
||||
<< "userInfo.name = " << g_sane_object->userInfo.name
|
||||
<< "str = " << str;
|
||||
|
||||
if (g_sane_object->userInfo.name == str) {
|
||||
KyInfo() << "The user choose device: " << str << "has been disconnect!";
|
||||
|
||||
// get argument again, because it cannot search using scanner while has opened it
|
||||
if (m_scanThread.isRunning()) {
|
||||
KyInfo() << "scanThread is running, so quit it.";
|
||||
m_scanThread.quit();
|
||||
}
|
||||
|
||||
KyInfo() << "begin to open sane device.";
|
||||
g_sane_object->openSaneDeviceForPage(i);
|
||||
|
||||
QString currentOpenDeviceName = g_sane_object->openSaneName;
|
||||
msg = tr("device ") + currentOpenDeviceName + tr(" has been disconnect.");
|
||||
retStatus = g_sane_object->getSaneStatus();
|
||||
|
||||
KyInfo() << "test scanning end, status = " << retStatus;
|
||||
|
||||
if (strListDevice.size() == 1 && str.contains("Pantum DS-230", Qt::CaseSensitive)) {
|
||||
// handle Pantum DS-230 scanners, which still could sane_open true while usb removed
|
||||
KyInfo() << "handle Pantum DS-230 scanners.";
|
||||
warnFlag = 1;
|
||||
}
|
||||
|
||||
if (!retStatus) {
|
||||
warnMsg(msg);
|
||||
|
||||
// Need this before detect devices again, because meet `Error during device I/O`,
|
||||
// which could crash this application.
|
||||
|
||||
if (! m_detectScanDevicesThread.isRunning()) {
|
||||
g_sane_object->saneExit();
|
||||
m_detectScanDevicesThread.start();
|
||||
}
|
||||
|
||||
if (result.contains("No scanners were identified", Qt::CaseInsensitive)) {
|
||||
KyInfo() << "No scanners were identified.";
|
||||
// If not find any scan device
|
||||
// m_displayWidget->showFailedPageSlot();
|
||||
}
|
||||
} else {
|
||||
KyInfo() << "sane_open is true";
|
||||
|
||||
if (warnFlag == 1) {
|
||||
warnMsg(msg);
|
||||
|
||||
// Need this before detect devices again, because meet `Error during device I/O`,
|
||||
// which could crash this application.
|
||||
|
||||
if (! m_detectScanDevicesThread.isRunning()) {
|
||||
g_sane_object->saneExit();
|
||||
m_detectScanDevicesThread.start();
|
||||
}
|
||||
|
||||
if (result.contains("No scanners were identified", Qt::CaseInsensitive)) {
|
||||
KyInfo() << "No scanners were identified.";
|
||||
// If not find any scan device
|
||||
// m_displayWidget->showFailedPageSlot();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}else{
|
||||
//设备仍在
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void MainWidget::startScanOperationSlot()
|
||||
{
|
||||
|
@ -702,7 +403,6 @@ void MainWidget::startScanOperationSlot()
|
|||
|
||||
g_user_signal->exitWindowWithSaveFlag = false;
|
||||
|
||||
isExited = false;
|
||||
g_sane_object->stopSaneRead(false);
|
||||
|
||||
if (m_scanThread.isRunning()) {
|
||||
|
@ -712,33 +412,9 @@ void MainWidget::startScanOperationSlot()
|
|||
}
|
||||
m_scanThread.start();
|
||||
|
||||
#if 0
|
||||
QString pageNumber = g_sane_object->userInfo.pageNumber;
|
||||
int retCompare = QString::compare(pageNumber, tr("Single"), Qt::CaseInsensitive);
|
||||
if (retCompare == 0 ) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
showScanDialogSlot();
|
||||
}
|
||||
|
||||
void MainWidget::stopScanOperationSlot()
|
||||
{
|
||||
isExited = true;
|
||||
// g_sane_object->stopSaneRead(true);
|
||||
// m_scanDialog->updatePageNumberWhileStopScanning();
|
||||
|
||||
|
||||
if (m_detectScanDevicesThread.isRunning()) {
|
||||
KyInfo() << "Quit window, so quit detect scan devices thread ...";
|
||||
// handle usb remove and click scan button crashed error: terminate called without an active exception
|
||||
// m_detectScanDevicesThread.terminate();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MainWidget::showScanDialogSlot()
|
||||
{
|
||||
m_scanDialog = new ScanDialog();
|
||||
|
@ -767,8 +443,9 @@ void MainWidget::scanThreadFinishedSlot(int saneStatus)
|
|||
warnMsg(tr("Invalid argument, please change arguments or switch other scanners.") + tr("error code:") + QString::number(saneStatus));
|
||||
} else if (saneStatus == SANE_STATUS_EOF) {
|
||||
g_sane_object->haveScanSuccessImage = true;
|
||||
|
||||
m_displayWidget->showSuccessImageHandlePageSlot();
|
||||
if(g_sane_object->loadFullScanFileNames.length() != 0){
|
||||
m_displayWidget->showSuccessImageHandlePageSlot();
|
||||
}
|
||||
if(cancelFlag){
|
||||
QString loadPath = g_sane_object->loadFullScanFileName;
|
||||
if(QFile::remove(loadPath)){
|
||||
|
@ -783,8 +460,11 @@ void MainWidget::scanThreadFinishedSlot(int saneStatus)
|
|||
emit g_user_signal->changeToConnectuccessPageSignal();
|
||||
}
|
||||
}else{
|
||||
g_user_signal->scanThreadFinishedImageLoad(g_sane_object->loadFullScanFileNames, g_sane_object->saveFullScanFileNames);
|
||||
ThumbnailWidget::scanPictureIsEmpty = false;
|
||||
if(g_sane_object->loadFullScanFileNames.length() != 0){
|
||||
g_sane_object->scanPageNumber = g_sane_object->saveFullScanFileNames.length();
|
||||
g_user_signal->scanThreadFinishedImageLoad(g_sane_object->loadFullScanFileNames, g_sane_object->saveFullScanFileNames);
|
||||
ThumbnailWidget::scanPictureIsEmpty = false;
|
||||
}
|
||||
}
|
||||
qDebug() << "no more file to read!";
|
||||
|
||||
|
@ -796,15 +476,12 @@ void MainWidget::scanThreadFinishedSlot(int saneStatus)
|
|||
warnMsg(tr("Document feeder out of documents, please place papers and scan again.") + tr("error code:") + QString::number(saneStatus));
|
||||
} else if(saneStatus == SANE_STATUS_CANCELLED) {
|
||||
closeScanDialogSlot();
|
||||
warnMsg(tr("Scan operation has been cancelled.") + tr("error code:") + QString::number(saneStatus));
|
||||
warnMsg(tr("Scan operation has been cancelled."));
|
||||
cancelFlag = false;
|
||||
} else {
|
||||
qDebug() << "met error! saneStatus:" << saneStatus;
|
||||
warnMsg(tr("Scan failed, please check your scanner or switch other scanners. If you want to continue using the scanner, click Options, refresh the list to restart the device.") + tr("error code:") + QString::number(saneStatus));
|
||||
}
|
||||
|
||||
isExited = true;
|
||||
g_user_signal->stopScanOperation();
|
||||
|
||||
} else {
|
||||
g_sane_object->haveScanSuccessImage = true;
|
||||
|
||||
|
@ -823,23 +500,17 @@ void MainWidget::scanThreadFinishedSlot(int saneStatus)
|
|||
emit g_user_signal->changeToConnectuccessPageSignal();
|
||||
}
|
||||
}else{
|
||||
g_sane_object->scanPageNumber = g_sane_object->saveFullScanFileNames.length();
|
||||
g_user_signal->scanThreadFinishedImageLoad(g_sane_object->loadFullScanFileNames, g_sane_object->saveFullScanFileNames);
|
||||
ThumbnailWidget::scanPictureIsEmpty = false;
|
||||
}
|
||||
// to do: update thumbtailwidget icon to current filepath
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::cancelScanningSlot(){
|
||||
cancelFlag = true;
|
||||
g_sane_object->stopSaneReadFlag = true;
|
||||
// m_scanThread.quit();
|
||||
// while(1){
|
||||
// if(m_scanThread.isFinished()){
|
||||
// isExited = true;
|
||||
// sane_cancel(g_sane_object->handle);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void MainWidget::onPrepareForSleep(bool isSleep)
|
||||
|
@ -850,6 +521,9 @@ void MainWidget::onPrepareForSleep(bool isSleep)
|
|||
} else //唤醒分支
|
||||
{
|
||||
qDebug() << "唤醒!!!";
|
||||
// 提示用户 检测到用户手动休眠,请检测扫描仪状态,若未继续扫描,需手动点击取消或刷新列表恢复设备扫描功能
|
||||
QString msg = tr("Detected user manual hibernation. Please check the scanner status. If scanning does not continue, you need to manually click cancel or refresh the list to resume device scanning function.");
|
||||
g_user_signal->warnMsg(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -876,6 +550,24 @@ void MainWidget::startHotPlutSlot()
|
|||
m_usbHotplugThread.start();
|
||||
}
|
||||
|
||||
void MainWidget::showNewDeviceListPageSuccessSlot()
|
||||
{
|
||||
qDebug() << "Install succeed";
|
||||
m_waittingDialog->close();
|
||||
// 初始化页面并,解析内容并展示
|
||||
m_noDriverDevices.clear();
|
||||
m_noDriverDevices = m_devFinder->getList();
|
||||
if(m_noDriverDevices.length() != 0){
|
||||
m_deviceListPage = new newDeviceListPage(m_noDriverDevices, this);
|
||||
}
|
||||
m_devFinder->finished();
|
||||
}
|
||||
|
||||
void MainWidget::showNewDeviceListPageFailSlot()
|
||||
{
|
||||
qDebug() << "Install failed";
|
||||
}
|
||||
|
||||
void MainWidget::showBeautyRunningDialog()
|
||||
{
|
||||
m_beautyRunningDialog = new RunningDialog(this, tr("Running beauty ..."));
|
||||
|
@ -948,7 +640,7 @@ void DetectScanDevicesThread::run()
|
|||
{
|
||||
KyInfo() << "FindScanDevicesThread begin";
|
||||
|
||||
bool res = g_sane_object->detectSaneDeviceForPage();
|
||||
bool res = g_sane_object->detectSaneDevices();
|
||||
|
||||
if (! res) {
|
||||
emit detectScanDevicesFinishedSignal(false);
|
||||
|
@ -965,7 +657,6 @@ void DetectScanDevicesThread::run()
|
|||
void ScanThread::run()
|
||||
{
|
||||
g_sane_object->isOnScanning = true;
|
||||
int sleepTime = 0;
|
||||
int ret = 0;
|
||||
|
||||
g_sane_object->scanPageNumber = 0;
|
||||
|
@ -980,80 +671,18 @@ void ScanThread::run()
|
|||
ret = g_sane_object->startScanning(g_sane_object->userInfo);
|
||||
KyInfo() << "start_scanning end, status = " << ret;
|
||||
|
||||
// if(ret != SANE_STATUS_GOOD){
|
||||
// ;
|
||||
// }
|
||||
|
||||
int saneStatus = ret;
|
||||
|
||||
g_user_signal->scanThreadFinished(ret);
|
||||
|
||||
emit g_user_signal->dbusUnInhabitSignal();
|
||||
|
||||
KyInfo() << "sleep end."
|
||||
<< "scanPageNumber = " << g_sane_object->scanPageNumber;
|
||||
|
||||
emit g_user_signal->cancelOprationOKSignal();
|
||||
g_sane_object->isOnScanning = false;
|
||||
quit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ScanThread::getSleepTime(QString &time)
|
||||
{
|
||||
if (QString::compare(time, "3s", Qt::CaseInsensitive) == 0
|
||||
|| QString::compare(time, tr("3s"), Qt::CaseInsensitive) == 0) {
|
||||
return 3;
|
||||
} else if (QString::compare(time, "5s", Qt::CaseInsensitive) == 0
|
||||
|| QString::compare(time, tr("5s"), Qt::CaseInsensitive) == 0) {
|
||||
return 5;
|
||||
} else if (QString::compare(time, "7s", Qt::CaseInsensitive) == 0
|
||||
|| QString::compare(time, tr("7s"), Qt::CaseInsensitive) == 0) {
|
||||
return 7;
|
||||
} else if (QString::compare(time, "10s", Qt::CaseInsensitive) == 0
|
||||
|| QString::compare(time, tr("10s"), Qt::CaseInsensitive) == 0) {
|
||||
return 10;
|
||||
} else if (QString::compare(time, "15s", Qt::CaseInsensitive) == 0
|
||||
|| QString::compare(time, tr("15s"), Qt::CaseInsensitive) == 0) {
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
|
||||
BeautyThread::BeautyThread(QObject *parent)
|
||||
: QThread(parent)
|
||||
{
|
||||
KyInfo() << "Create beauty thread.";
|
||||
|
||||
}
|
||||
|
||||
BeautyThread::~BeautyThread()
|
||||
{
|
||||
}
|
||||
|
||||
void BeautyThread::run()
|
||||
{
|
||||
KyInfo() << "begin to run beauty thread.";
|
||||
|
||||
oneClickBeauty(ScanningPicture);
|
||||
|
||||
KyInfo() << "end oneClickBeauty()";
|
||||
|
||||
g_user_signal->doBeautyOperationFinished();
|
||||
|
||||
}
|
||||
|
||||
void BeautyThread::beautyThreadStop()
|
||||
{
|
||||
KyInfo() << "beauty thread stop";
|
||||
if(isRunning())
|
||||
{
|
||||
terminate();
|
||||
wait();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RectifyThread::RectifyThread(QObject *parent)
|
||||
: QThread(parent)
|
||||
{
|
||||
|
@ -1066,19 +695,6 @@ RectifyThread::~RectifyThread()
|
|||
|
||||
void RectifyThread::run()
|
||||
{
|
||||
// KyInfo() << "begin to run rectify thread.";
|
||||
|
||||
// int res = 0;
|
||||
// res = ImageRectify(ScanningPicture);
|
||||
|
||||
// KyInfo() << "end ImageRectify(), res = " << res;
|
||||
|
||||
// if (0 == res) {
|
||||
// g_user_signal->doRectifyOperationFinished(true);
|
||||
// } else {
|
||||
// g_user_signal->doRectifyOperationFinished(false);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
void RectifyThread::rectifyThreadStop()
|
||||
|
|
|
@ -41,8 +41,6 @@
|
|||
#include <QWidget>
|
||||
#include <QX11Info>
|
||||
#include <QThread>
|
||||
#include <tesseract/baseapi.h>
|
||||
#include <leptonica/allheaders.h>
|
||||
#include <QInputDialog>
|
||||
#include <qmath.h>
|
||||
#include "utils/HorizontalOrVerticalMode.h"
|
||||
|
@ -61,14 +59,12 @@
|
|||
#include "titlebar/titlebar.h"
|
||||
#include "globalsignal.h"
|
||||
#include "usb.h"
|
||||
#include "beauty.h"
|
||||
#include "rectify.h"
|
||||
#include <kylin_system/session_management.hpp>
|
||||
#include "usbhotplugthread.h"
|
||||
#include "utils/rotatechangeinfo.h"
|
||||
|
||||
#include <sane/sane.h>
|
||||
|
||||
#include "waittingdialog.h"
|
||||
#include "deviceFinder.h"
|
||||
#include "newdevicelistpage.h"
|
||||
|
||||
class ScanThread : public QThread
|
||||
{
|
||||
|
@ -77,8 +73,6 @@ class ScanThread : public QThread
|
|||
protected:
|
||||
void run() Q_DECL_OVERRIDE;
|
||||
|
||||
int getSleepTime(QString &time);
|
||||
|
||||
Q_SIGNALS:
|
||||
void scanThreadFinishedSignal(int);
|
||||
};
|
||||
|
@ -95,18 +89,6 @@ Q_SIGNALS:
|
|||
};
|
||||
|
||||
|
||||
class BeautyThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BeautyThread(QObject *parent = 0);
|
||||
~BeautyThread();
|
||||
|
||||
void run() Q_DECL_OVERRIDE;
|
||||
|
||||
void beautyThreadStop();
|
||||
|
||||
};
|
||||
|
||||
class RectifyThread : public QThread
|
||||
{
|
||||
|
@ -136,7 +118,6 @@ public:
|
|||
|
||||
void resizeTitleBar();
|
||||
void resizeDisplayWidget();
|
||||
void themeChange();
|
||||
void fontSizeChange();
|
||||
void transparencyChange();
|
||||
|
||||
|
@ -151,63 +132,53 @@ protected:
|
|||
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
|
||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
private:
|
||||
QDBusInterface *server = nullptr;
|
||||
QDBusMessage serverReturnValue;
|
||||
// double m_transparency = 0.60;
|
||||
QStringList m_styleList;
|
||||
|
||||
login1dbusManager *m_dbus = nullptr;
|
||||
quint32 flag;
|
||||
kdk::kabase::SessionManagement sessionManagementTest;
|
||||
RotateChangeInfo rotateInfo;
|
||||
TitleBar *m_titleBar;
|
||||
DisplayWidget *m_displayWidget;
|
||||
// QScrollArea *m_displayScrollArea;
|
||||
|
||||
QVBoxLayout *m_mainWidgetVLayout;
|
||||
TitleBar *m_titleBar = nullptr;
|
||||
DisplayWidget *m_displayWidget = nullptr;
|
||||
|
||||
QVBoxLayout *m_mainWidgetVLayout = nullptr;
|
||||
|
||||
DetectScanDevicesThread m_detectScanDevicesThread;
|
||||
UsbHotplugThread m_usbHotplugThread;
|
||||
|
||||
ScanThread m_scanThread;
|
||||
ScanDialog *m_scanDialog;
|
||||
WatermarkDialog *m_watermarkDialog;
|
||||
ScanDialog *m_scanDialog = nullptr;
|
||||
WatermarkDialog *m_watermarkDialog = nullptr;
|
||||
|
||||
RunningDialog *m_beautyRunningDialog;
|
||||
BeautyThread m_beautyThread;
|
||||
RunningDialog *m_beautyRunningDialog = nullptr;
|
||||
|
||||
RunningDialog *m_rectifyRunningDialog;
|
||||
RunningDialog *m_rectifyRunningDialog = nullptr;
|
||||
RectifyThread m_rectifyThread;
|
||||
|
||||
bool cancelFlag = false;
|
||||
QList<QMessageBox*> m_msgBoxList;
|
||||
|
||||
bool isDarkTheme();
|
||||
WaittingDialog *m_waittingDialog = nullptr;
|
||||
|
||||
deviceFinder *m_devFinder = nullptr;
|
||||
QList<DeviceInformation> m_noDriverDevices;
|
||||
newDeviceListPage *m_deviceListPage = nullptr;
|
||||
|
||||
void showHelpDialog();
|
||||
|
||||
|
||||
// OcrObject *m_ocrObject;
|
||||
// bool m_isOcrInit = false;
|
||||
// QThread *m_ocrThread;
|
||||
|
||||
|
||||
public slots:
|
||||
void rotationChanged(bool isPCMode,int width,int height);
|
||||
void warnMsg(QString msg);
|
||||
void maximizeWindowSlot();
|
||||
void closeWindowSlot();
|
||||
void styleSettingsChanged(QString);
|
||||
|
||||
void detectScanDevicesSlot();
|
||||
void detectScanDeviceThreadFinishedSlot(bool isDetected);
|
||||
|
||||
void usbAddedOperationSlot(QString recvData);
|
||||
void usbRemovedOperationSlot(QString recvData);
|
||||
|
||||
void startScanOperationSlot();
|
||||
void stopScanOperationSlot();
|
||||
void showScanDialogSlot();
|
||||
void closeScanDialogSlot();
|
||||
void scanThreadFinishedSlot(int saneStatus);
|
||||
|
@ -230,5 +201,8 @@ public slots:
|
|||
void startUsbHotPlugThreadSlot();
|
||||
void startHotPlutSlot();
|
||||
|
||||
void showNewDeviceListPageSuccessSlot();
|
||||
void showNewDeviceListPageFailSlot();
|
||||
|
||||
};
|
||||
#endif // MainWidget_H
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
#include "navigator.h"
|
||||
#include "globalsignal.h"
|
||||
Navigator::Navigator(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
this->resize(QSize(130, 133));
|
||||
this->setStyleSheet("QWidget{background-color:rgba(0,0,0,0.4);}");
|
||||
m_bottomImage = new QLabel(this);
|
||||
m_bottomImage->setAlignment(Qt::AlignCenter);
|
||||
m_bottomImage->resize(this->width(), this->height());
|
||||
m_bottomImage->move(0, 0);
|
||||
m_bottomImage->setMouseTracking(true);
|
||||
this->setMouseTracking(true);
|
||||
//此处绑定信号和槽
|
||||
connect(this, &Navigator::posChange, g_user_signal, &GlobalUserSignal::posChange);
|
||||
}
|
||||
//显示导航器
|
||||
void Navigator::showNavigation(QPixmap pix)
|
||||
{
|
||||
if (pix.isNull()) {
|
||||
this->hide();
|
||||
return;
|
||||
}
|
||||
m_bottomImage->setPixmap(pix);
|
||||
if (this->isHidden()) {
|
||||
this->show();
|
||||
Q_EMIT naviChange();
|
||||
}
|
||||
}
|
||||
//发送鼠标移动坐标
|
||||
void Navigator::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPoint currpos = this->mapFromGlobal(QCursor().pos());
|
||||
|
||||
if (m_isPress) {
|
||||
Q_EMIT posChange(currpos);
|
||||
this->setCursor(Qt::ClosedHandCursor);
|
||||
} else {
|
||||
if ((currpos.x() >= m_startPos.x() && currpos.x() <= m_endPos.x())
|
||||
&& (currpos.y() >= m_startPos.y() && currpos.y() <= m_endPos.y())) {
|
||||
this->setCursor(Qt::ClosedHandCursor);
|
||||
} else {
|
||||
this->unsetCursor();
|
||||
}
|
||||
}
|
||||
|
||||
QWidget::mouseMoveEvent(event);
|
||||
}
|
||||
//发送鼠标按下坐标
|
||||
void Navigator::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
QPoint currpos = this->mapFromGlobal(QCursor().pos());
|
||||
Q_EMIT posChange(currpos);
|
||||
}
|
||||
m_isPress = true;
|
||||
this->setCursor(Qt::ClosedHandCursor);
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void Navigator::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
m_isPress = false;
|
||||
QPoint currpos = this->mapFromGlobal(QCursor().pos());
|
||||
if ((currpos.x() >= m_startPos.x() && currpos.x() <= m_endPos.x())
|
||||
&& (currpos.y() >= m_startPos.y() && currpos.y() <= m_endPos.y())) {
|
||||
this->setCursor(Qt::ClosedHandCursor);
|
||||
} else {
|
||||
this->unsetCursor();
|
||||
}
|
||||
//判断在区域内,鼠标不变,否则,鼠标变化为
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void Navigator::getHighLightRegion(QPoint startPos, QPoint endPos)
|
||||
{
|
||||
m_startPos = startPos;
|
||||
m_endPos = endPos;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef NAVIGATOR_H
|
||||
#define NAVIGATOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QPixmap>
|
||||
#include <QDebug>
|
||||
#include <QMouseEvent>
|
||||
|
||||
class Navigator : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Navigator(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
QLabel *m_bottomImage = nullptr;
|
||||
bool m_isPress = false;
|
||||
QPoint m_startPos = QPoint(-1, -1);
|
||||
QPoint m_endPos = QPoint(-1, -1);
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
|
||||
public:
|
||||
void showNavigation(QPixmap pix);
|
||||
void getHighLightRegion(QPoint startPos, QPoint endPos); //拿起始点和终点
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
void naviChange();
|
||||
void posChange(QPoint pos);
|
||||
};
|
||||
|
||||
#endif // NAVIGATOR_H
|
|
@ -0,0 +1,376 @@
|
|||
#include "newdevicelistpage.h"
|
||||
#include "Qt/windowmanage.hpp"
|
||||
#include <QHeaderView>
|
||||
#include "buriedpoint.hpp"
|
||||
|
||||
newDeviceListPage::newDeviceListPage(QList<DeviceInformation> devInfoList, QWidget *parent)
|
||||
: QDialog(parent),
|
||||
m_VLayout(new QVBoxLayout()),
|
||||
m_titleHLayout(new QHBoxLayout()),
|
||||
m_closeButton(new QPushButton()),
|
||||
m_mainWidget(new QStackedWidget()),
|
||||
m_mainVLayout(new QVBoxLayout()),
|
||||
m_mainVLayout2(new QVBoxLayout()),
|
||||
m_mainVWidget1(new QWidget()),
|
||||
m_mainVWidget2(new QWidget()),
|
||||
m_labelbuttonLayout(new QHBoxLayout()),
|
||||
m_deviceLabel(new QLabel()),
|
||||
m_reDetectButton(new QPushButton()),
|
||||
m_stackDeviceList(new QStackedWidget()),
|
||||
m_noDeviceWidget(new NoDeviceWidget()),
|
||||
m_buttonHLayout(new QHBoxLayout()),
|
||||
m_cancelButton(new QPushButton()),
|
||||
m_nextStepButton(new QPushButton()),
|
||||
m_selectedDeviceName(new QLabel()),
|
||||
m_selectedDriverName(new QLabel()),
|
||||
m_cancelButton2(new QPushButton()),
|
||||
m_beforeButton(new QPushButton()),
|
||||
m_installButton(new QPushButton()),
|
||||
m_buttonHLayout2(new QHBoxLayout()),
|
||||
m_devInfoList(devInfoList)
|
||||
{
|
||||
kabase::WindowManage::removeHeader(this);
|
||||
this->setWindowModality(Qt::ApplicationModal);
|
||||
|
||||
QList<QString> header = {tr("Name"), tr("Symbol")};
|
||||
m_deviceList = new CustomTableWidget(header, this);
|
||||
init();
|
||||
initConnect();
|
||||
handleData();
|
||||
this->show();
|
||||
}
|
||||
|
||||
void newDeviceListPage::init()
|
||||
{
|
||||
m_closeButton->setIcon(QIcon::fromTheme ("window-close-symbolic"));
|
||||
m_closeButton->setToolTip(tr("Close"));
|
||||
m_closeButton->setFixedSize(30, 30);
|
||||
m_closeButton->setIconSize (QSize(16, 16));
|
||||
m_closeButton->setProperty("isWindowButton", 0x2);
|
||||
m_closeButton->setProperty("useIconHighlightEffect", 0x8);
|
||||
m_closeButton->setFlat(true);
|
||||
|
||||
m_titleHLayout->setSpacing(0);
|
||||
m_titleHLayout->addStretch();
|
||||
m_titleHLayout->addWidget(m_closeButton);
|
||||
m_titleHLayout->setContentsMargins(0, 4, 4, 4);
|
||||
m_titleHLayout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
m_deviceLabel->setText(tr("Device List"));
|
||||
m_reDetectButton->setFixedSize(24, 24);
|
||||
m_reDetectButton->setIcon(QIcon::fromTheme("view-refresh-symbolic"));
|
||||
m_reDetectButton->setIconSize(QSize(16, 16));
|
||||
|
||||
m_labelbuttonLayout->addWidget(m_deviceLabel);
|
||||
m_labelbuttonLayout->addStretch();
|
||||
m_labelbuttonLayout->addWidget(m_reDetectButton);
|
||||
|
||||
m_stackDeviceList->addWidget(m_noDeviceWidget);
|
||||
m_stackDeviceList->addWidget(m_deviceList);
|
||||
m_stackDeviceList->setCurrentIndex(0);
|
||||
|
||||
m_cancelButton->setText(tr("Cancel"));
|
||||
m_nextStepButton->setText(tr("Next"));
|
||||
m_nextStepButton->setEnabled(false);
|
||||
|
||||
m_buttonHLayout->addStretch();
|
||||
m_buttonHLayout->addWidget(m_cancelButton);
|
||||
m_buttonHLayout->addSpacing(10);
|
||||
m_buttonHLayout->addWidget(m_nextStepButton);
|
||||
|
||||
m_mainVLayout->setSpacing(0);
|
||||
m_mainVLayout->addLayout(m_labelbuttonLayout);
|
||||
m_mainVLayout->addSpacing(7);
|
||||
m_mainVLayout->addWidget(m_stackDeviceList);
|
||||
m_mainVLayout->addSpacing(24);
|
||||
m_mainVLayout->addLayout(m_buttonHLayout);
|
||||
m_mainVLayout->setContentsMargins(24, 0, 24, 24);
|
||||
m_mainVWidget1->setLayout(m_mainVLayout);
|
||||
|
||||
m_mainWidget->addWidget(m_mainVWidget1);
|
||||
|
||||
m_cancelButton2->setText(tr("Cancel"));
|
||||
m_beforeButton->setText(tr("Before"));
|
||||
m_installButton->setText(tr("Install"));
|
||||
|
||||
m_buttonHLayout2->addStretch();
|
||||
m_buttonHLayout2->addWidget(m_cancelButton2);
|
||||
m_buttonHLayout2->addSpacing(10);
|
||||
m_buttonHLayout2->addWidget(m_beforeButton);
|
||||
m_buttonHLayout2->addSpacing(10);
|
||||
m_buttonHLayout2->addWidget(m_installButton);
|
||||
|
||||
m_mainVLayout2->setSpacing(0);
|
||||
m_mainVLayout2->addWidget(m_selectedDeviceName);
|
||||
m_mainVLayout2->addSpacing(12);
|
||||
m_mainVLayout2->addWidget(m_selectedDriverName);
|
||||
m_mainVLayout2->addSpacing(22);
|
||||
m_mainVLayout2->addLayout(m_buttonHLayout2);
|
||||
m_mainVLayout->setContentsMargins(24, 0, 24, 24);
|
||||
|
||||
m_mainVWidget2->setLayout(m_mainVLayout2);
|
||||
m_mainWidget->addWidget(m_mainVWidget2);
|
||||
m_mainWidget->setCurrentIndex(0);
|
||||
|
||||
m_VLayout->addLayout(m_titleHLayout);
|
||||
m_VLayout->addSpacing(6);
|
||||
m_VLayout->addWidget(m_mainWidget);
|
||||
|
||||
this->setLayout(m_VLayout);
|
||||
this->setFixedSize(560, 420);
|
||||
}
|
||||
|
||||
void newDeviceListPage::initConnect()
|
||||
{
|
||||
connect(m_cancelButton, &QPushButton::clicked, this, &newDeviceListPage::close);
|
||||
connect(m_cancelButton, &QPushButton::clicked, this, &newDeviceListPage::deleteLater);
|
||||
connect(m_closeButton, &QPushButton::clicked, m_cancelButton, &QPushButton::click);
|
||||
connect(m_cancelButton2, &QPushButton::clicked, this, &newDeviceListPage::close);
|
||||
connect(m_cancelButton2, &QPushButton::clicked, this, &newDeviceListPage::deleteLater);
|
||||
connect(m_deviceList, &CustomTableWidget::itemSelectionChanged, this, [=](){m_nextStepButton->setEnabled(true);});
|
||||
connect(m_beforeButton, &QPushButton::clicked, this, [=]()
|
||||
{
|
||||
m_mainWidget->setCurrentIndex(0);
|
||||
this->setFixedSize(560, 420);
|
||||
});
|
||||
connect(m_nextStepButton, &QPushButton::clicked, this, &newDeviceListPage::nextButtonClickSlot);
|
||||
connect(m_installButton, &QPushButton::clicked, this, &newDeviceListPage::installDriverSlot);
|
||||
connect(m_reDetectButton, &QPushButton::clicked, this, &newDeviceListPage::reDetectDevicesSlot);
|
||||
}
|
||||
|
||||
void newDeviceListPage::handleData()
|
||||
{
|
||||
for(int i = 0; i < m_devInfoList.length(); ++i)
|
||||
{
|
||||
QString name = m_devInfoList.at(i).vendor + " " + m_devInfoList.at(i).model;
|
||||
QString symbol;
|
||||
if(m_devInfoList.at(i).serial != ""){
|
||||
symbol = m_devInfoList.at(i).serial;
|
||||
}else{
|
||||
symbol = m_devInfoList.at(i).host;
|
||||
}
|
||||
QStringList content = QStringList() << name << symbol;
|
||||
m_deviceList->insertItem(i, content);
|
||||
m_stackDeviceList->setCurrentIndex(1);
|
||||
}
|
||||
}
|
||||
|
||||
void newDeviceListPage::nextButtonClickSlot()
|
||||
{
|
||||
QStringList names = m_deviceList->getSelectedRow();
|
||||
QString devName = QString(tr("Device Name:")) + names.at(0);
|
||||
m_selectedDeviceName->setText(devName);
|
||||
bool hasDriver = false;
|
||||
QString driverName = QString(tr("Driver Name:")) ;
|
||||
// 判断该设备在云端是否有驱动可以自动安装
|
||||
for(int i = 0; i < m_devInfoList.length(); ++i)
|
||||
{
|
||||
if(names.at(1) == m_devInfoList.at(i).serial || names.at(1) == m_devInfoList.at(i).host)
|
||||
{
|
||||
if(m_devInfoList.at(i).packageNameList.length() == 0){
|
||||
break;
|
||||
}
|
||||
if(m_devInfoList.at(i).packageNameList.at(0) != "")
|
||||
{
|
||||
hasDriver = true;
|
||||
m_waitForInstallOne = m_devInfoList.at(i);
|
||||
for(int j = 0; j < m_devInfoList.at(i).packageNameList.length(); j++)
|
||||
{
|
||||
driverName += m_devInfoList.at(i).packageNameList.at(j) + "; ";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 运行驱动寻找程序
|
||||
if(hasDriver)
|
||||
{
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerDriverCanAutoInstall)));
|
||||
buried_data.insert(std::make_pair("action", "has driver, auto install"));
|
||||
buried_data.insert(std::make_pair("function", "in newdevicelistpage.cpp function nextButtonClickSlot()"));
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
|
||||
// 找到了对应驱动
|
||||
m_selectedDriverName->setText(driverName);
|
||||
m_mainWidget->setCurrentIndex(1);
|
||||
this->setFixedSize(425, 210);
|
||||
}else
|
||||
{
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerNoDriver)));
|
||||
buried_data.insert(std::make_pair("action", "no driver, manual install"));
|
||||
buried_data.insert(std::make_pair("function", "in newdevicelistpage.cpp function nextButtonClickSlot()"));
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
// 未找到对应驱动程序
|
||||
m_msg = new QMessageBox();
|
||||
m_msg->setFixedSize(450, 210);
|
||||
this->close();
|
||||
QString tipsStr = tr("No available drivers, do you want to manually add drivers?");
|
||||
m_msg->setText(tipsStr);
|
||||
m_msg->setIcon(QMessageBox::Warning);
|
||||
QPushButton *addButton = new QPushButton(m_msg);
|
||||
addButton->setText(tr("Add"));
|
||||
addButton->setProperty("isImportant", true);
|
||||
m_msg->addButton(tr("Cancel"), QMessageBox::RejectRole);
|
||||
m_msg->addButton(addButton, QMessageBox::AcceptRole);
|
||||
|
||||
connect(m_msg, &QMessageBox::accepted, this, &newDeviceListPage::installHandlerSlot);
|
||||
connect(m_msg, &QMessageBox::rejected, [=](){this->close();});
|
||||
m_msg->show();
|
||||
|
||||
QWidget *widget = nullptr;
|
||||
QWidgetList widgetList = QApplication::allWidgets();
|
||||
for (int i=0; i<widgetList.length(); ++i) {
|
||||
if (widgetList.at(i)->objectName() == "MainWindow") {
|
||||
widget = widgetList.at(i);
|
||||
}
|
||||
}
|
||||
if (widget) {
|
||||
QRect rect = widget->geometry();
|
||||
int x = rect.x() + rect.width()/2 - m_msg->width()/2;
|
||||
int y = rect.y() + rect.height()/2 - m_msg->height()/2;
|
||||
m_msg->move(x,y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void newDeviceListPage::installDriverSlot()
|
||||
{
|
||||
QWidget *widget = nullptr;
|
||||
QWidgetList widgetList = QApplication::allWidgets();
|
||||
for (int i=0; i<widgetList.length(); ++i) {
|
||||
if (widgetList.at(i)->objectName() == "MainWindow") {
|
||||
widget = widgetList.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
m_waittingDialog = new WaittingDialog(widget);
|
||||
this->close();
|
||||
m_waittingDialog->setText(tr("Installing driver..."));
|
||||
m_waittingDialog->show();
|
||||
m_aptHelper = new AptUtilHelper(DeviceInformation(m_waitForInstallOne));
|
||||
|
||||
QObject::connect(m_aptHelper, &AptUtilHelper::succeed, this, &newDeviceListPage::showSuccessDialog);
|
||||
QObject::connect(m_aptHelper, &AptUtilHelper::failed, this, &newDeviceListPage::showFailDialog);
|
||||
|
||||
m_aptHelper->startWorker();
|
||||
}
|
||||
|
||||
void newDeviceListPage::showSuccessDialog()
|
||||
{
|
||||
m_waittingDialog->close();
|
||||
qDebug() << "Install succeed";
|
||||
|
||||
m_msg = new QMessageBox();
|
||||
m_msg->setFixedSize(450, 210);
|
||||
QString tipsStr = tr("Installation successful. Do you want to use this scanner now?");
|
||||
m_msg->setText(tipsStr);
|
||||
m_msg->setIcon(QMessageBox::Icon::Information);
|
||||
// m_msg->setIconPixmap(QPixmap::fromImage(QImage::from));
|
||||
m_msg->addButton(tr("Cancel"), QMessageBox::RejectRole);
|
||||
m_msg->addButton(tr("Use"), QMessageBox::AcceptRole);
|
||||
connect(m_msg, &QMessageBox::accepted, [=](){emit g_user_signal->refreshListInFilePage();});
|
||||
m_msg->show();
|
||||
|
||||
QWidget *widget = nullptr;
|
||||
QWidgetList widgetList = QApplication::allWidgets();
|
||||
for (int i=0; i<widgetList.length(); ++i) {
|
||||
if (widgetList.at(i)->objectName() == "MainWindow") {
|
||||
widget = widgetList.at(i);
|
||||
}
|
||||
}
|
||||
if (widget) {
|
||||
QRect rect = widget->geometry();
|
||||
int x = rect.x() + rect.width()/2 - m_msg->width()/2;
|
||||
int y = rect.y() + rect.height()/2 - m_msg->height()/2;
|
||||
m_msg->move(x,y);
|
||||
}
|
||||
}
|
||||
|
||||
void newDeviceListPage::showFailDialog(QString err)
|
||||
{
|
||||
m_waittingDialog->close();
|
||||
qDebug() << "Install failed";
|
||||
|
||||
m_msg = new QMessageBox();
|
||||
m_msg->setFixedSize(450, 210);
|
||||
QString tipsStr = tr("Installation failed.") + "\n" + err;
|
||||
m_msg->setText(tipsStr);
|
||||
m_msg->setIcon(QMessageBox::Critical);
|
||||
m_msg->addButton(tr("Ok"), QMessageBox::AcceptRole);
|
||||
connect(m_msg, &QMessageBox::accepted, [=](){this->close();m_msg->deleteLater();});
|
||||
m_msg->show();
|
||||
|
||||
QWidget *widget = nullptr;
|
||||
QWidgetList widgetList = QApplication::allWidgets();
|
||||
for (int i=0; i<widgetList.length(); ++i) {
|
||||
if (widgetList.at(i)->objectName() == "MainWindow") {
|
||||
widget = widgetList.at(i);
|
||||
}
|
||||
}
|
||||
if (widget) {
|
||||
QRect rect = widget->geometry();
|
||||
qDebug() << "!!!!!!!!!!!!!!rect: " <<rect;
|
||||
int x = rect.x() + rect.width()/2 - m_msg->width()/2;
|
||||
int y = rect.y() + rect.height()/2 - m_msg->height()/2;
|
||||
qDebug() << "!!!!!!!!!!!!!!msg_size: " << m_msg->size();
|
||||
qDebug() << "x,y :" << x << " / "<< y;
|
||||
m_msg->move(x,y);
|
||||
}
|
||||
}
|
||||
|
||||
void newDeviceListPage::reDetectDevicesSlot()
|
||||
{
|
||||
this->close();
|
||||
m_waittingDialog = new WaittingDialog(this);
|
||||
m_waittingDialog->show();
|
||||
|
||||
m_deviceFinder = new deviceFinder();
|
||||
QObject::connect(m_deviceFinder, &deviceFinder::succeed, [=](){
|
||||
m_devInfoList = m_deviceFinder->getList();
|
||||
m_deviceList->clear();
|
||||
m_waittingDialog->close();
|
||||
handleData();
|
||||
this->show();
|
||||
});
|
||||
m_deviceFinder->startWorker();
|
||||
}
|
||||
|
||||
void newDeviceListPage::installHandlerSlot()
|
||||
{
|
||||
QString dlgTitle = tr("Select a directory");
|
||||
QString userRootDIr = QDir::homePath();
|
||||
QString selectedDir = QFileDialog::getOpenFileName(this, dlgTitle, userRootDIr, "*.deb");
|
||||
|
||||
m_waittingDialog = new WaittingDialog();
|
||||
this->close();
|
||||
m_waittingDialog->setText(tr("Installing driver..."));
|
||||
m_waittingDialog->show();
|
||||
|
||||
QWidget *widget = nullptr;
|
||||
QWidgetList widgetList = QApplication::allWidgets();
|
||||
for (int i=0; i<widgetList.length(); ++i) {
|
||||
if (widgetList.at(i)->objectName() == "MainWindow") {
|
||||
widget = widgetList.at(i);
|
||||
}
|
||||
}
|
||||
if (widget) {
|
||||
QRect rect = widget->geometry();
|
||||
int x = rect.x() + rect.width()/2 - m_waittingDialog->width()/2;
|
||||
int y = rect.y() + rect.height()/2 - m_waittingDialog->height()/2;
|
||||
m_waittingDialog->move(x,y);
|
||||
}
|
||||
|
||||
m_debHelper = new DebUtilHelper(selectedDir);
|
||||
QObject::connect(m_debHelper, &DebUtilHelper::succeed, this, &newDeviceListPage::showSuccessDialog);
|
||||
QObject::connect(m_debHelper, &DebUtilHelper::failed, this, &newDeviceListPage::showFailDialog);
|
||||
m_debHelper->startWorker();
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef NEWDEVICELISTPAGE_H
|
||||
#define NEWDEVICELISTPAGE_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QStackedWidget>
|
||||
#include <QTableWidget>
|
||||
#include <QTableWidgetItem>
|
||||
#include <QMessageBox>
|
||||
#include <QIcon>
|
||||
#include <kmessagebox.h>
|
||||
#include <QFileDialog>
|
||||
#include <kmessagebox.h>
|
||||
|
||||
#include "nodevicewidget.h"
|
||||
#include "waittingdialog.h"
|
||||
#include "custom_push_button.h"
|
||||
#include "include/theme.h"
|
||||
#include "customtablewidget.h"
|
||||
#include "device_information.h"
|
||||
#include "ukui_apt.h"
|
||||
#include "globalsignal.h"
|
||||
#include "deviceFinder.h"
|
||||
|
||||
class newDeviceListPage : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit newDeviceListPage(QList<DeviceInformation> devInfoList,QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
QVBoxLayout *m_VLayout = nullptr; // 整体layout
|
||||
QHBoxLayout *m_titleHLayout = nullptr; // 标题栏 layout
|
||||
QPushButton *m_closeButton = nullptr;
|
||||
|
||||
QStackedWidget * m_mainWidget = nullptr;
|
||||
QVBoxLayout *m_mainVLayout = nullptr; // 除标题栏外主体layout
|
||||
QWidget *m_mainVWidget1 = nullptr; // 用于存放mainVlayout的widget
|
||||
QVBoxLayout *m_mainVLayout2 = nullptr; // 除标题栏外主体layout
|
||||
QWidget *m_mainVWidget2 = nullptr; // 用于存放mainVlayout的widget
|
||||
|
||||
// mainVlayout 的内容
|
||||
QHBoxLayout *m_labelbuttonLayout = nullptr; // 设备列表/重新检测按钮布局
|
||||
QLabel *m_deviceLabel = nullptr;
|
||||
QPushButton *m_reDetectButton = nullptr;
|
||||
QStackedWidget *m_stackDeviceList = nullptr;
|
||||
NoDeviceWidget *m_noDeviceWidget = nullptr;
|
||||
CustomTableWidget *m_deviceList = nullptr;
|
||||
QHBoxLayout *m_buttonHLayout = nullptr;
|
||||
QPushButton *m_cancelButton = nullptr;
|
||||
QPushButton *m_nextStepButton = nullptr;
|
||||
|
||||
// mainVlayout2 的内容
|
||||
QLabel *m_selectedDeviceName = nullptr;
|
||||
QLabel *m_selectedDriverName = nullptr;
|
||||
QPushButton *m_cancelButton2 = nullptr;
|
||||
QPushButton *m_beforeButton = nullptr;
|
||||
QPushButton *m_installButton = nullptr;
|
||||
|
||||
QHBoxLayout *m_buttonHLayout2 = nullptr;
|
||||
|
||||
WaittingDialog *m_waittingDialog = nullptr;
|
||||
|
||||
deviceFinder *m_deviceFinder = nullptr;
|
||||
QList<DeviceInformation> m_devInfoList;
|
||||
DeviceInformation m_waitForInstallOne;
|
||||
AptUtilHelper* m_aptHelper = nullptr;
|
||||
DebUtilHelper *m_debHelper = nullptr;
|
||||
QMessageBox *m_msg;
|
||||
|
||||
void init();
|
||||
void initConnect();
|
||||
void handleData();
|
||||
|
||||
private Q_SLOTS:
|
||||
void nextButtonClickSlot();
|
||||
void installDriverSlot();
|
||||
|
||||
void showSuccessDialog();
|
||||
void showFailDialog(QString err);
|
||||
void reDetectDevicesSlot();
|
||||
void installHandlerSlot();
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // NEWDEVICELISTPAGE_H
|
|
@ -0,0 +1,39 @@
|
|||
#include "nodevicewidget.h"
|
||||
#include <QPainter>
|
||||
|
||||
NoDeviceWidget::NoDeviceWidget(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_PageIcon(new QLabel()),
|
||||
m_PageText(new QLabel()),
|
||||
m_pageVLayout(new QVBoxLayout())
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void NoDeviceWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(this);
|
||||
QPen pen;
|
||||
pen.setColor(QColor("#8C8C8C"));
|
||||
pen.setStyle(Qt::SolidLine);
|
||||
painter.setPen(pen);
|
||||
painter.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||
}
|
||||
|
||||
void NoDeviceWidget::init()
|
||||
{
|
||||
m_PageIcon->setPixmap(QPixmap(":/default-connect-page/detect_fail_light.svg"));
|
||||
m_PageText->setText(tr("Scanner not detected"));
|
||||
m_PageText->setEnabled(false);
|
||||
|
||||
|
||||
m_pageVLayout->setSpacing(0);
|
||||
m_pageVLayout->addStretch();
|
||||
m_pageVLayout->addWidget(m_PageIcon, 0, Qt::AlignCenter);
|
||||
m_pageVLayout->addSpacing(8);
|
||||
m_pageVLayout->addWidget(m_PageText, 0, Qt::AlignCenter);
|
||||
m_pageVLayout->addStretch();
|
||||
m_pageVLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
this->setLayout(m_pageVLayout);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef NODEVICEWIDGET_H
|
||||
#define NODEVICEWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QPaintEvent>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class NoDeviceWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NoDeviceWidget(QWidget *parent = nullptr);
|
||||
|
||||
QLabel *m_PageIcon = nullptr;
|
||||
QLabel *m_PageText = nullptr;
|
||||
QVBoxLayout *m_pageVLayout = nullptr;
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
};
|
||||
|
||||
#endif // NODEVICEWIDGET_H
|
|
@ -1,50 +0,0 @@
|
|||
#include "ocrobject.h"
|
||||
|
||||
OcrObject::OcrObject(QObject *parent) : QObject(parent)
|
||||
{
|
||||
doOcr();
|
||||
|
||||
}
|
||||
|
||||
void OcrObject::doOcr()
|
||||
{
|
||||
KyInfo() << "begin to run ocr thread !\n";
|
||||
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
|
||||
|
||||
if (api->Init(NULL, "chi_sim")) {
|
||||
KyInfo() << "Could not initialize tesseract.\n";
|
||||
g_sane_object->ocrOutputText = tr("Unable to read text");
|
||||
|
||||
g_user_signal->toolbarOcrOperationFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
KyInfo() << "before pixRead.";
|
||||
Pix *image = pixRead(ScanningPicture);
|
||||
if (! image) {
|
||||
KyInfo() << "pixRead error!";
|
||||
g_sane_object->ocrOutputText = tr("Unable to read text");
|
||||
if (api)
|
||||
api->End();
|
||||
|
||||
g_user_signal->toolbarOcrOperationFinished();
|
||||
|
||||
return;
|
||||
}
|
||||
if (image) {
|
||||
KyInfo() << "before setImage.";
|
||||
api->SetImage(image);
|
||||
g_sane_object->ocrOutputText = api->GetUTF8Text();
|
||||
}
|
||||
|
||||
KyInfo() << "before destroy image.";
|
||||
if (api) {
|
||||
api->End();
|
||||
}
|
||||
if (image) {
|
||||
pixDestroy(&image);
|
||||
}
|
||||
|
||||
g_user_signal->toolbarOcrOperationFinished();
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef OCROBJECT_H
|
||||
#define OCROBJECT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
|
||||
#include <tesseract/baseapi.h>
|
||||
#include <leptonica/allheaders.h>
|
||||
#include <ukui-log4qt.h>
|
||||
|
||||
#include "globalsignal.h"
|
||||
#include "saneobject.h"
|
||||
#include "include/common.h"
|
||||
|
||||
class OcrObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OcrObject(QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void doOcr();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
};
|
||||
|
||||
#endif // OCROBJECT_H
|
320
src/rectify.cpp
320
src/rectify.cpp
|
@ -20,269 +20,113 @@
|
|||
|
||||
#include <ukui-log4qt.h>
|
||||
|
||||
double DegreeTrans(double theta)
|
||||
int ImageRectify(QImage *src)
|
||||
{
|
||||
double res = theta / CV_PI * 180;
|
||||
return res;
|
||||
}
|
||||
|
||||
int rotateImage(Mat src, Mat &img_rotate, double degree)
|
||||
{
|
||||
Point2f center;
|
||||
center.x = float(src.cols / 2.0);
|
||||
center.y = float(src.rows / 2.0);
|
||||
KyInfo() << "center.x" << center.x;
|
||||
KyInfo() << "center.y" << center.y;
|
||||
QTransform transform;
|
||||
double angle = caculateSkewAngle(src);
|
||||
qDebug() << "角度:" << angle;
|
||||
transform.rotate(angle);
|
||||
QImage correctedImage = src->transformed(transform).scaled(src->size(),Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
correctedImage.save(ScanningPicture);
|
||||
|
||||
int length = 0;
|
||||
length = sqrt(src.cols * src.cols + src.rows * src.rows);
|
||||
KyInfo() << "length = " << length;
|
||||
|
||||
Mat M = getRotationMatrix2D(center, degree, 1);
|
||||
// warpAffine(src, img_rotate, M, Size(length, length), 1, 0, Scalar(255,255,255));//仿射变换,背景色填充为白色
|
||||
|
||||
// src.release(); // handle crash problems
|
||||
if (src.cols <= 0 || src.rows <= 0) {
|
||||
KyInfo() << "src.cols = " << src.cols
|
||||
<< "src.rows = " << src.rows;
|
||||
return -1;
|
||||
}
|
||||
|
||||
warpAffine(src, img_rotate, M, img_rotate.size(), 1, 0, Scalar(255, 255, 255));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CalcDegree 通过霍夫变换计算角度
|
||||
* 接近水平[0-5度]和接近垂直[175-185度]都不进行纠偏
|
||||
*
|
||||
* 算法思想:
|
||||
* 1. 读取原始图并转换成灰度图,采用边缘检测算子(如Canny)转换成二值化边缘图像
|
||||
* 2. 对该图像进行霍夫变换
|
||||
*
|
||||
* 只选角度最小的作为旋转角度
|
||||
* 角度为正时以左上角为支点逆时针旋转,
|
||||
* 角度为负时已左上角为支点顺时针旋转
|
||||
* @param srcImage
|
||||
* @param dst
|
||||
* @return
|
||||
*/
|
||||
double CalcDegree(const Mat &srcImage, Mat &dst)
|
||||
double caculateSkewAngle(QImage *src)
|
||||
{
|
||||
Mat midImage;
|
||||
Mat dstImage;
|
||||
int Threshold = 300;
|
||||
int sizeLineBefore;
|
||||
int sizeLineAfter;
|
||||
// 将图像转换为灰度图
|
||||
QImage grayImage = src->convertToFormat(QImage::Format_Grayscale8);
|
||||
|
||||
Canny(srcImage, midImage, 50, 200, 3);
|
||||
cvtColor(midImage, dstImage, COLOR_GRAY2BGR);
|
||||
// 计算水平和垂直梯度
|
||||
QVector<double> horizontalGradient;
|
||||
QVector<double> verticalGradient;
|
||||
|
||||
//通过霍夫变换检测直线
|
||||
// 600 dpi: Threshold = 750
|
||||
std::vector<Vec2f> lines;
|
||||
HoughLines(midImage, lines, 1, CV_PI / 180, Threshold, 0,
|
||||
0);//第5个参数就是阈值,阈值越大,检测精度越高
|
||||
//KyInfo() << lines.size() ;
|
||||
int width = grayImage.width();
|
||||
int height = grayImage.height();
|
||||
|
||||
KyInfo() << "Begin to found good threshold.";
|
||||
// 由于图像不同,阈值不好设定,因为阈值设定过高导致无法检测直线,阈值过低直线太多,速度很慢
|
||||
// 所以根据阈值由大到小设置了三个阈值(300, 200, 100),如果经过大量试验后,可以固定一个适合的阈值。
|
||||
// While Threshold is too small, lines will be large(>5000).
|
||||
// this will make rectify process slower,
|
||||
// so we should judge lines.size();
|
||||
while (lines.size() > 100 || lines.size() < 10) {
|
||||
if (lines.size() >100)
|
||||
Threshold += 300;
|
||||
else if (lines.size() < 10)
|
||||
Threshold -= 50;
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
QRgb pixel = grayImage.pixel(x, y);
|
||||
|
||||
sizeLineBefore = lines.size();
|
||||
if (x == 0 || x == width - 1 || y == 0 || y == height - 1)
|
||||
{
|
||||
horizontalGradient.append(0);
|
||||
verticalGradient.append(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int leftPixel = qGray(grayImage.pixel(x - 1, y));
|
||||
int rightPixel = qGray(grayImage.pixel(x + 1, y));
|
||||
int topPixel = qGray(grayImage.pixel(x, y - 1));
|
||||
int bottomPixel = qGray(grayImage.pixel(x, y + 1));
|
||||
|
||||
KyInfo() << "Threshold = " << Threshold << "lines.size = " << lines.size();
|
||||
HoughLines(midImage, lines, 1, CV_PI / 180, Threshold, 0, 0);
|
||||
double gx = (rightPixel - leftPixel) / 2.0;
|
||||
double gy = (bottomPixel - topPixel) / 2.0;
|
||||
|
||||
sizeLineAfter = lines.size();
|
||||
|
||||
if ((sizeLineBefore > 100) && (sizeLineAfter < 10)) {
|
||||
// break this loop
|
||||
Threshold += 50;
|
||||
HoughLines(midImage, lines, 1, CV_PI / 180, Threshold, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Threshold <= 0) {
|
||||
KyInfo() << "没有检测到直线!" ;
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
KyInfo() << "after while, Threshold = " << Threshold
|
||||
<< "lines.size() = " << lines.size();
|
||||
|
||||
// 由于上述的判断可能会导致获取的线条为0,此时需要重新进行定位阈值范围
|
||||
if (lines.size() == 0 || lines.size() < 50) {
|
||||
KyInfo() << "Threshold = 300 " << "lines = " << lines.size();
|
||||
HoughLines(midImage, lines, 1, CV_PI / 180, 300, 0, 0);
|
||||
|
||||
if (lines.size() == 0) {
|
||||
KyInfo() << "Threshold = 200 " << "lines = " << lines.size();
|
||||
HoughLines(midImage, lines, 1, CV_PI / 180, 200, 0, 0);
|
||||
|
||||
if (lines.size() == 0) {
|
||||
KyInfo() << "Threshold = 100 " << "lines = " << lines.size();
|
||||
HoughLines(midImage, lines, 1, CV_PI / 180, 100, 0, 0);
|
||||
horizontalGradient.append(gx);
|
||||
verticalGradient.append(gy);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float sum = 0;
|
||||
int n = 0;
|
||||
//依次画出每条线段
|
||||
size_t i = 0;
|
||||
|
||||
int loop = 300;
|
||||
if (lines.size() > loop) {
|
||||
loop = 300;
|
||||
} else {
|
||||
loop = lines.size();
|
||||
}
|
||||
KyInfo() << "lines.size = " << lines.size ()
|
||||
<< "draw line loop = " << loop;
|
||||
|
||||
int num180 = 0;
|
||||
int num0 = 0;
|
||||
int num90 = 0;
|
||||
|
||||
//for (i = 0; i < lines.size(); ++i) {
|
||||
for (i = 0; i < loop; ++i) {
|
||||
float rho = lines[i][0];
|
||||
float theta = lines[i][1];
|
||||
Point pt1, pt2;
|
||||
double a = cos(theta), b = sin(theta);
|
||||
double x0 = a * rho, y0 = b * rho;
|
||||
pt1.x = cvRound(x0 + 1000 * (-b));
|
||||
pt1.y = cvRound(y0 + 1000 * (a));
|
||||
pt2.x = cvRound(x0 - 1000 * (-b));
|
||||
pt2.y = cvRound(y0 - 1000 * (a));
|
||||
//KyInfo() << i << ", " << "DegreeTrans() = " << DegreeTrans (theta);
|
||||
|
||||
// 时常会遇到角度为5度返回内的图片,此时处理机制为默认已经高度校正,过滤该线条角度
|
||||
// 不应该为了追求效率,导致过滤掉大量高度矫正的线条,导致本就纠正的图片变歪
|
||||
/*
|
||||
if (((DegreeTrans(theta) >= 85) && (DegreeTrans(theta) <= 95))
|
||||
|| (DegreeTrans(theta) >= 178.5)
|
||||
|| (DegreeTrans(theta) <= 5 )) {
|
||||
n += 1;
|
||||
continue;
|
||||
// 计算累积角度
|
||||
QVector<double> angles;
|
||||
for (int i = 0; i < horizontalGradient.size(); ++i)
|
||||
{
|
||||
double degrees = qAtan2(verticalGradient[i], horizontalGradient[i]);
|
||||
if(verticalGradient[i]==0 && horizontalGradient[i]==0){
|
||||
degrees = 0;
|
||||
}
|
||||
*/
|
||||
if (DegreeTrans(theta) <= 5) {
|
||||
++num0;
|
||||
} else if (DegreeTrans(theta) >= 175 && DegreeTrans(theta) <= 185) {
|
||||
++num180;
|
||||
} else if (DegreeTrans(theta) >= 85 && DegreeTrans(theta) <= 95) {
|
||||
++num90;
|
||||
double angle = qRadiansToDegrees(degrees);
|
||||
angles.append(angle);
|
||||
}
|
||||
|
||||
// 求解主方向
|
||||
int binSize = 300; // 直方图中每个bin的大小,可以根据实际情况调整
|
||||
int numBins = 360 / binSize;
|
||||
QVector<int> histogram(numBins, 0); // 初始化直方图为0
|
||||
|
||||
for (double angle : angles)
|
||||
{
|
||||
int bin = qRound(angle / binSize);
|
||||
if (bin >= 0 && bin < histogram.size()) {
|
||||
histogram[bin]++;
|
||||
}
|
||||
|
||||
KyInfo() << "theta = " << theta
|
||||
<< "degree(theta) = " << DegreeTrans(theta);
|
||||
|
||||
sum += theta;
|
||||
//KyInfo() << "sum = " << sum;
|
||||
line(dstImage, pt1, pt2, Scalar(55, 100, 195), 1, LINE_AA); //Scalar函数用于调节线段颜色
|
||||
// mirror picture for deskew(rectify)
|
||||
imwrite("/tmp/scanner/mirror.png", dstImage);
|
||||
}
|
||||
|
||||
// 找到最大的直方图bin
|
||||
int maxBinIndex = 0;
|
||||
int maxBinValue = 0;
|
||||
|
||||
KyInfo() << "sum = " << sum << "lines.size()" << lines.size () << "n = " << n;
|
||||
if (lines.size () - n == 0 || sum == 0)
|
||||
return 0.0;
|
||||
|
||||
//对所有角度求平均,这样做旋转效果会更好
|
||||
//float average = sum / (lines.size() - n);
|
||||
|
||||
// sum = 182.352 lines.size() 181
|
||||
// 这种情况会将已经垂直的图片纠偏歪了
|
||||
float average = sum / loop;
|
||||
|
||||
double angle = DegreeTrans(average);
|
||||
KyInfo() << "angle = " << angle;
|
||||
|
||||
// angel < 0: clockwise rotation
|
||||
// 经过多次反复测试,此处应该减90,整个线条接近水平,之后可以旋转进行校正。
|
||||
|
||||
KyInfo() << "num0 = " << num0
|
||||
<< "num180 = " << num180
|
||||
<< "num90 = " << num90
|
||||
<< "loop = " << loop;
|
||||
|
||||
if (num0 + num180 > loop * 0.90) {
|
||||
// 接近垂直,故需要旋转90度,但是不清楚是正方向还是反方向,同时还有图片的大小问题,故不纠偏
|
||||
// angle = 90;
|
||||
angle = 0;
|
||||
} else if (num90 >= loop * 0.90) {
|
||||
// 接近水平,故不矫正
|
||||
angle = 0;
|
||||
} else {
|
||||
angle = angle - 90;
|
||||
for (int i = 0; i < numBins; ++i)
|
||||
{
|
||||
if (histogram[i] > maxBinValue)
|
||||
{
|
||||
maxBinValue = histogram[i];
|
||||
maxBinIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (angle >= 135)
|
||||
angle = angle - 180;
|
||||
else if (angle >= 90)
|
||||
angle =angle - 90;
|
||||
else if (angle >= 45)
|
||||
angle = angle - 90;
|
||||
*/
|
||||
// 计算平均角度
|
||||
double totalAngle = 0;
|
||||
int count = 0;
|
||||
|
||||
KyInfo() << "angle = " << angle;
|
||||
for (double angle : angles)
|
||||
{
|
||||
int bin = qRound(angle / binSize);
|
||||
|
||||
int res = 0;
|
||||
res = rotateImage(dstImage, dst, angle);
|
||||
if (0 != res) {
|
||||
return ERROR;
|
||||
if (bin == maxBinIndex)
|
||||
{
|
||||
totalAngle += angle;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
//int ImageRectify(const char *pInFileName)
|
||||
int ImageRectify(cv::Mat *src)
|
||||
{
|
||||
double degree = 0.0;
|
||||
int res = 0;
|
||||
Mat src_1 = *src;
|
||||
|
||||
// Mat src = imread(pInFileName);
|
||||
if (!src_1.data) {
|
||||
// Avoid crash after click btnBeauty duplicately
|
||||
KyInfo() << "cannot read this image: ";// << pInFileName;
|
||||
return -1;
|
||||
}
|
||||
Mat dst;
|
||||
|
||||
KyInfo() << "before calcDegree(): inFilename = "; //<< pInFileName;
|
||||
degree = CalcDegree(src_1, dst);
|
||||
KyInfo() << "degree = " << degree;
|
||||
|
||||
if (fabs (degree - ERROR) < 1e-15) {
|
||||
KyInfo() << "rectify failed !" ;
|
||||
return -1;
|
||||
}
|
||||
if (fabs(degree) < 1e-15 + 0.4) {
|
||||
KyInfo() << "already right, so return straight!";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Mat src_2 = *src;
|
||||
// src = imread(pInFileName);
|
||||
|
||||
res = rotateImage(src_2, dst, degree);
|
||||
if (0 != res) {
|
||||
return -1;
|
||||
}
|
||||
imwrite(ScanningPicture, dst);
|
||||
return 0;
|
||||
|
||||
double averageAngle = totalAngle / count;
|
||||
|
||||
// 返回平均角度作为纠偏角度
|
||||
return averageAngle;
|
||||
}
|
||||
|
|
|
@ -19,22 +19,16 @@
|
|||
#ifndef RECTIFY_H
|
||||
#define RECTIFY_H
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
#include <QVector>
|
||||
|
||||
using namespace cv;
|
||||
//using namespace std;
|
||||
#include <QImage>
|
||||
#include <qmath.h>
|
||||
#include <QTransform>
|
||||
|
||||
#include "include/common.h"
|
||||
|
||||
#define ERROR 1234
|
||||
|
||||
int ImageRectify(QImage *src);
|
||||
|
||||
int ImageRectify(cv::Mat *src);
|
||||
double caculateSkewAngle(QImage *src);
|
||||
|
||||
#endif // RECTIFY_H
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
*/
|
||||
|
||||
#include "runningdialog.h"
|
||||
#include <gsettings.hpp>
|
||||
#include "kabase/Qt/windowmanage.hpp"
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
#include "Qt/windowmanage.hpp"
|
||||
|
||||
RunningDialog::RunningDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
|
@ -29,13 +29,13 @@ RunningDialog::RunningDialog(QWidget *parent)
|
|||
, waitImage (new QLabel())
|
||||
, waitText (new QLabel())
|
||||
, hLayoutInfo (new QHBoxLayout())
|
||||
, btnCancel (new QPushButton())
|
||||
, btnCancel (new CustomPushButton())
|
||||
, hLayoutCancel (new QHBoxLayout())
|
||||
, vLayout (new QVBoxLayout())
|
||||
{
|
||||
setWindowModality(Qt::ApplicationModal);
|
||||
/* 移除标题栏 */
|
||||
::kabase::WindowManage::removeHeader(this);
|
||||
kabase::WindowManage::removeHeader(this);
|
||||
|
||||
|
||||
setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
|
||||
|
@ -51,7 +51,7 @@ RunningDialog::RunningDialog(QWidget *parent)
|
|||
setPalette(pal);
|
||||
}
|
||||
|
||||
m_closeButton->setIcon (QIcon::fromTheme ("window-close-symbolic"));
|
||||
m_closeButton->setIcon(QIcon::fromTheme ("window-close-symbolic"));
|
||||
m_closeButton->setToolTip(tr("Close"));
|
||||
m_closeButton->setFixedSize(30, 30);
|
||||
m_closeButton->setIconSize (QSize(16, 16));
|
||||
|
@ -60,7 +60,6 @@ RunningDialog::RunningDialog(QWidget *parent)
|
|||
m_closeButton->setFlat(true);
|
||||
|
||||
m_titleHBoxLayout->setSpacing(0);
|
||||
// m_titleHBoxLayout->addWidget(m_titleLabel);
|
||||
m_titleHBoxLayout->addStretch();
|
||||
m_titleHBoxLayout->addWidget(m_closeButton);
|
||||
m_titleHBoxLayout->setContentsMargins(0, 4, 4, 4);
|
||||
|
@ -104,7 +103,7 @@ RunningDialog::RunningDialog(QWidget *parent)
|
|||
connect(time, SIGNAL(timeout()), this, SLOT(showPictures()));
|
||||
connect(m_closeButton, &QPushButton::clicked, this, &RunningDialog::accept);
|
||||
// connect(btnCancel, SIGNAL(clicked()), this, SLOT(accepted()));
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &RunningDialog::runningDialogStyleChanged);
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemThemeChange, this, &RunningDialog::runningDialogStyleChanged);
|
||||
}
|
||||
|
||||
RunningDialog::RunningDialog(QWidget *parent, QString text)
|
||||
|
@ -116,15 +115,14 @@ RunningDialog::RunningDialog(QWidget *parent, QString text)
|
|||
, waitImage (new QLabel())
|
||||
, waitText (new QLabel())
|
||||
, hLayoutInfo (new QHBoxLayout())
|
||||
, btnCancel (new QPushButton())
|
||||
, btnCancel (new CustomPushButton())
|
||||
, hLayoutCancel (new QHBoxLayout())
|
||||
, vLayout (new QVBoxLayout())
|
||||
|
||||
{
|
||||
kabase::WindowManage::removeHeader(this);
|
||||
setWindowModality(Qt::ApplicationModal);
|
||||
|
||||
::kabase::WindowManage::removeHeader(this);
|
||||
|
||||
setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
|
||||
if (isDarkTheme()) {
|
||||
|
@ -148,7 +146,6 @@ RunningDialog::RunningDialog(QWidget *parent, QString text)
|
|||
m_closeButton->setFlat(true);
|
||||
|
||||
m_titleHBoxLayout->setSpacing(0);
|
||||
// m_titleHBoxLayout->addWidget(m_titleLabel);
|
||||
m_titleHBoxLayout->addStretch();
|
||||
m_titleHBoxLayout->addWidget(m_closeButton);
|
||||
m_titleHBoxLayout->setContentsMargins(0, 4, 4, 4);
|
||||
|
@ -194,11 +191,12 @@ RunningDialog::RunningDialog(QWidget *parent, QString text)
|
|||
connect(time, SIGNAL(timeout()), this, SLOT(showPictures()));
|
||||
connect(m_closeButton, &QPushButton::clicked, this, &RunningDialog::reject);
|
||||
connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &RunningDialog::runningDialogStyleChanged);
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemThemeChange, this, &RunningDialog::runningDialogStyleChanged);
|
||||
}
|
||||
|
||||
bool RunningDialog::isDarkTheme()
|
||||
{
|
||||
QString systemTheme = kdk::kabase::Gsettings::getSystemTheme().toString();
|
||||
QString systemTheme = kdk::GsettingMonitor::getSystemTheme().toString();
|
||||
|
||||
if (systemTheme == STYLE_NAME_KEY_DARK || systemTheme == STYLE_NAME_KEY_BLACK) {
|
||||
return true;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "include/common.h"
|
||||
#include "include/theme.h"
|
||||
#include "svghandler.h"
|
||||
#include "custom_push_button.h"
|
||||
|
||||
#define WINDOW_WIDTH 380
|
||||
#define WINDOW_HEIGHT 162
|
||||
|
@ -43,8 +44,8 @@ class RunningDialog : public QDialog
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QPushButton *btnCancel;
|
||||
QPushButton *m_closeButton;
|
||||
CustomPushButton *btnCancel = nullptr;
|
||||
QPushButton *m_closeButton = nullptr;
|
||||
explicit RunningDialog(QWidget *parent = nullptr);
|
||||
explicit RunningDialog(QWidget *parent = nullptr, QString text="");
|
||||
|
||||
|
@ -58,25 +59,23 @@ private:
|
|||
int num = 0;
|
||||
int count = 0;
|
||||
|
||||
SVGHandler *svghandler;
|
||||
SVGHandler *svghandler = nullptr;
|
||||
|
||||
QFileInfo fileinfo;
|
||||
QString path;
|
||||
QTimer *time;
|
||||
QTimer *time = nullptr;
|
||||
|
||||
// QLabel *m_titleLabel;
|
||||
QHBoxLayout *m_titleHBoxLayout = nullptr;
|
||||
|
||||
QHBoxLayout *m_titleHBoxLayout;
|
||||
|
||||
QLabel *waitImage;
|
||||
QLabel *waitText;
|
||||
QHBoxLayout *hLayoutInfo;
|
||||
QLabel *waitImage = nullptr;
|
||||
QLabel *waitText = nullptr;
|
||||
QHBoxLayout *hLayoutInfo = nullptr;
|
||||
|
||||
QString waitMsgText;
|
||||
|
||||
QHBoxLayout *hLayoutCancel;
|
||||
QHBoxLayout *hLayoutCancel = nullptr;
|
||||
|
||||
QVBoxLayout *vLayout;
|
||||
QVBoxLayout *vLayout = nullptr;
|
||||
|
||||
bool isDarkTheme();
|
||||
|
||||
|
|
|
@ -58,51 +58,12 @@ static SANE_Byte *g_buf;
|
|||
static SANE_Int g_BufSize;
|
||||
static SANE_Device *g_saneDevice = nullptr;
|
||||
|
||||
static bool stopSaneExceptionFlag = false;
|
||||
|
||||
#define SET_1_BIT(n,i) ((1<<(i))|(n))
|
||||
#define SET_0_BIT(n,i) ((~(1<<(i)))&(n))
|
||||
#define SET_R_BIT(n,i) ((n)^(1<<(i)))
|
||||
#define GET_i_BIT(n,i) (((n)>>(i))&1)
|
||||
|
||||
|
||||
#if HAVE_LIBJPEG
|
||||
static void
|
||||
write_jpeg_header (SANE_Frame format, int width, int height, int dpi, FILE *ofp, struct jpeg_compress_struct *cinfo, struct jpeg_error_mgr *jerr)
|
||||
{
|
||||
cinfo->err = jpeg_std_error(jerr);
|
||||
jpeg_create_compress(cinfo);
|
||||
jpeg_stdio_dest(cinfo, ofp);
|
||||
|
||||
cinfo->image_width = width;
|
||||
cinfo->image_height = height;
|
||||
switch (format)
|
||||
{
|
||||
case SANE_FRAME_RED:
|
||||
case SANE_FRAME_GREEN:
|
||||
case SANE_FRAME_BLUE:
|
||||
case SANE_FRAME_RGB:
|
||||
cinfo->in_color_space = JCS_RGB;
|
||||
cinfo->input_components = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
cinfo->in_color_space = JCS_GRAYSCALE;
|
||||
cinfo->input_components = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
jpeg_set_defaults(cinfo);
|
||||
/* jpeg_set_defaults overrides density, be careful. */
|
||||
cinfo->density_unit = 1; /* Inches */
|
||||
cinfo->X_density = cinfo->Y_density = dpi;
|
||||
cinfo->write_JFIF_header = TRUE;
|
||||
|
||||
jpeg_set_quality(cinfo, 75, TRUE);
|
||||
// jpeg_start_compress(cinfo, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void writePnmHeader (SANE_Frame format, int width, int height, int depth, FILE *ofp)
|
||||
{
|
||||
switch (format) {
|
||||
|
@ -164,339 +125,258 @@ static void *advance (Image *image)
|
|||
static SANE_Status onScanning(FILE *ofp)
|
||||
{
|
||||
int i = 0, offset = 0, must_buffer = 0, hundred_percent = 1;
|
||||
SANE_Int len;
|
||||
bool first_frame = true;
|
||||
SANE_Byte min = 0xff, max = 0;
|
||||
SANE_Parameters parm;
|
||||
SANE_Status status;
|
||||
Image image = { nullptr, 0, 0, 0, 0 };
|
||||
SANE_Word total_bytes = 0;
|
||||
SANE_Int hang_over = -1;
|
||||
SANE_Int len;
|
||||
bool first_frame = true;
|
||||
SANE_Byte min = 0xff, max = 0;
|
||||
SANE_Parameters parm;
|
||||
SANE_Status status;
|
||||
Image image = { nullptr, 0, 0, 0, 0 };
|
||||
SANE_Word total_bytes = 0;
|
||||
SANE_Int hang_over = -1;
|
||||
do {
|
||||
if (!first_frame) {
|
||||
qDebug() << "sane start!";
|
||||
status = sane_start(g_device);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
int resolution_value = g_sane_object->resolution_value;
|
||||
// int resolution_value = 75;
|
||||
qDebug()<<"sane get parameter";
|
||||
status = sane_get_parameters(g_device, &parm);
|
||||
KyInfo() << "Parm : status = " << sane_strstatus(status)
|
||||
<< "format = " << parm.format
|
||||
<< "last_frame = " << parm.last_frame
|
||||
<< "bytes_per_line = " << parm.bytes_per_line
|
||||
<< "pixels_per_line = " << parm.pixels_per_line
|
||||
<< "lines = " << parm.lines
|
||||
<< "depth = " << parm.depth;
|
||||
|
||||
#if HAVE_LIBJPEG
|
||||
int jpegrow = 0;
|
||||
JSAMPLE *jpegbuf = NULL;
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
#endif
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
goto cleanup;
|
||||
|
||||
do {
|
||||
if (!first_frame) {
|
||||
qDebug() << "sane start!";
|
||||
status = sane_start (g_device);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
goto cleanup;
|
||||
}
|
||||
if (first_frame) {
|
||||
if (parm.lines >= 0) {
|
||||
KyInfo() << "Image's size(pixels): " << parm.pixels_per_line << parm.lines
|
||||
<< "Bits/pixel: " << parm.depth * (SANE_FRAME_RGB == parm.format ? 3 : 1);
|
||||
} else {
|
||||
KyInfo() << "Image's wide pixels: " << parm.pixels_per_line
|
||||
<< "Height for bits/pixel: " << parm.depth * (SANE_FRAME_RGB == parm.format ? 3 : 1);
|
||||
}
|
||||
|
||||
qDebug()<<"sane get parameter";
|
||||
status = sane_get_parameters (g_device, &parm);
|
||||
KyInfo() << "Parm : status = " << sane_strstatus(status)
|
||||
<< "format = " << parm.format
|
||||
<< "last_frame = " << parm.last_frame
|
||||
<< "bytes_per_line = " << parm.bytes_per_line
|
||||
<< "pixels_per_line = " << parm.pixels_per_line
|
||||
<< "lines = " << parm.lines
|
||||
<< "depth = " << parm.depth;
|
||||
switch (parm.format) {
|
||||
case SANE_FRAME_RED:
|
||||
case SANE_FRAME_GREEN:
|
||||
case SANE_FRAME_BLUE:
|
||||
assert (parm.depth == 8);
|
||||
must_buffer = 1;
|
||||
offset = parm.format - SANE_FRAME_RED;
|
||||
break;
|
||||
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
goto cleanup;
|
||||
case SANE_FRAME_RGB:
|
||||
case SANE_FRAME_GRAY:
|
||||
assert ((parm.depth == 1) || (parm.depth == 8) || (parm.depth == 16));
|
||||
if (parm.lines < 0) {
|
||||
must_buffer = 1;
|
||||
offset = 0;
|
||||
} else {
|
||||
switch(g_sane_object->output_format)
|
||||
{
|
||||
case OUTPUT_PNM:
|
||||
qDebug()<<"start write file!";
|
||||
writePnmHeader(parm.format, parm.pixels_per_line, parm.lines, parm.depth, ofp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (first_frame) {
|
||||
if (parm.lines >= 0) {
|
||||
KyInfo() << "Image's size(pixels): " << parm.pixels_per_line << parm.lines
|
||||
<< "Bits/pixel: " << parm.depth * (SANE_FRAME_RGB == parm.format ? 3 : 1);
|
||||
} else {
|
||||
KyInfo() << "Image's wide pixels: " << parm.pixels_per_line
|
||||
<< "Height for bits/pixel: " << parm.depth * (SANE_FRAME_RGB == parm.format ? 3 : 1);
|
||||
}
|
||||
if (must_buffer) {
|
||||
/**
|
||||
* We're either scanning a multi-frame image or the
|
||||
* scanner doesn't know what the eventual image height
|
||||
* will be (common for hand-held scanners). In either
|
||||
* case, we need to buffer all data before we can write
|
||||
* the image.
|
||||
*/
|
||||
image.width = parm.bytes_per_line;
|
||||
if (parm.lines >= 0) {
|
||||
image.height = parm.lines - STRIP_HEIGHT + 1;
|
||||
} else {
|
||||
image.height = 0;
|
||||
}
|
||||
|
||||
switch (parm.format) {
|
||||
case SANE_FRAME_RED:
|
||||
case SANE_FRAME_GREEN:
|
||||
case SANE_FRAME_BLUE:
|
||||
assert (parm.depth == 8);
|
||||
must_buffer = 1;
|
||||
offset = parm.format - SANE_FRAME_RED;
|
||||
break;
|
||||
image.x = image.width - 1;
|
||||
image.y = -1;
|
||||
if (!advance (&image)) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert (parm.format >= SANE_FRAME_RED && parm.format <= SANE_FRAME_BLUE);
|
||||
offset = parm.format - SANE_FRAME_RED;
|
||||
image.x = image.y = 0;
|
||||
}
|
||||
|
||||
case SANE_FRAME_RGB:
|
||||
//assert ((parm.depth == 8) || (parm.depth == 16));
|
||||
hundred_percent = parm.bytes_per_line * parm.lines * ((parm.format == SANE_FRAME_RGB || parm.format == SANE_FRAME_GRAY) ? 1 : 3);
|
||||
while (status == SANE_STATUS_GOOD) {
|
||||
static int i =0;
|
||||
double progr;
|
||||
qDebug()<< "read file!" << i++;
|
||||
status = sane_read(g_device, g_buf, g_BufSize, &len);
|
||||
|
||||
case SANE_FRAME_GRAY:
|
||||
assert ((parm.depth == 1) || (parm.depth == 8) || (parm.depth == 16));
|
||||
if (parm.lines < 0) {
|
||||
must_buffer = 1;
|
||||
offset = 0;
|
||||
} else {
|
||||
switch(g_sane_object->output_format)
|
||||
{
|
||||
case OUTPUT_PNM:
|
||||
qDebug()<<"start write file!";
|
||||
writePnmHeader (parm.format, parm.pixels_per_line, parm.lines, parm.depth, ofp);
|
||||
break;
|
||||
#if HAVE_LIBJPEG
|
||||
case OUTPUT_JPEG:
|
||||
write_jpeg_header (parm.format, parm.pixels_per_line,
|
||||
parm.lines, resolution_value,
|
||||
ofp, &cinfo, &jerr);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if HAVE_LIBJPEG
|
||||
if(g_sane_object->output_format == OUTPUT_JPEG)
|
||||
jpegbuf = static_cast<JSAMPLE *>(malloc(parm.bytes_per_line));
|
||||
#endif
|
||||
|
||||
if (must_buffer) {
|
||||
/**
|
||||
* We're either scanning a multi-frame image or the
|
||||
* scanner doesn't know what the eventual image height
|
||||
* will be (common for hand-held scanners). In either
|
||||
* case, we need to buffer all data before we can write
|
||||
* the image.
|
||||
*/
|
||||
image.width = parm.bytes_per_line;
|
||||
if (parm.lines >= 0) {
|
||||
image.height = parm.lines - STRIP_HEIGHT + 1;
|
||||
} else {
|
||||
image.height = 0;
|
||||
}
|
||||
|
||||
image.x = image.width - 1;
|
||||
image.y = -1;
|
||||
if (!advance (&image)) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert (parm.format >= SANE_FRAME_RED && parm.format <= SANE_FRAME_BLUE);
|
||||
offset = parm.format - SANE_FRAME_RED;
|
||||
image.x = image.y = 0;
|
||||
}
|
||||
|
||||
hundred_percent = parm.bytes_per_line * parm.lines \
|
||||
*((parm.format == SANE_FRAME_RGB || parm.format == SANE_FRAME_GRAY) ? 1 : 3);
|
||||
while (status == SANE_STATUS_GOOD && g_sane_object->stopSaneReadFlag == false) {
|
||||
static int i =0;
|
||||
double progr;
|
||||
qDebug()<<"read file!" << i++;
|
||||
status = sane_read (g_device, g_buf, g_BufSize, &len);
|
||||
total_bytes += (SANE_Word) len;
|
||||
if(hundred_percent == 0){
|
||||
hundred_percent = 1;
|
||||
}
|
||||
progr = ((total_bytes * 100.) / (double) hundred_percent);
|
||||
if (progr > 100.)
|
||||
progr = 100.;
|
||||
total_bytes += (SANE_Word) len;
|
||||
if(hundred_percent == 0){
|
||||
hundred_percent = 1;
|
||||
}
|
||||
progr = ((total_bytes * 100.) / (double) hundred_percent);
|
||||
if (progr > 100.)
|
||||
progr = 100.;
|
||||
|
||||
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
if (status != SANE_STATUS_EOF) {
|
||||
goto cleanup;
|
||||
// return status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
if (status != SANE_STATUS_EOF) {
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (must_buffer) {
|
||||
KyInfo() << "must_buffer = " << must_buffer;
|
||||
switch (parm.format) {
|
||||
case SANE_FRAME_RED:
|
||||
case SANE_FRAME_GREEN:
|
||||
case SANE_FRAME_BLUE:
|
||||
for (i = 0; i < len; ++i) {
|
||||
image.data[offset + 3 * i] = g_buf[i];
|
||||
if (!advance (&image)) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
offset += 3 * len;
|
||||
break;
|
||||
case SANE_FRAME_RGB:
|
||||
for (i = 0; i < len; ++i) {
|
||||
image.data[offset + i] = g_buf[i];
|
||||
if (!advance (&image)) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
offset += len;
|
||||
break;
|
||||
case SANE_FRAME_GRAY:
|
||||
for (i = 0; i < len; ++i) {
|
||||
image.data[offset + i] = g_buf[i];
|
||||
if (!advance (&image)) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
offset += len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else { /* ! must_buffer */
|
||||
#if HAVE_LIBJPEG
|
||||
KyInfo() << "end scanning status: " << status;
|
||||
if (g_sane_object->output_format == OUTPUT_JPEG)
|
||||
{
|
||||
int i = 0;
|
||||
int left = len;
|
||||
while(jpegrow + left >= parm.bytes_per_line)
|
||||
{
|
||||
memcpy(jpegbuf + jpegrow, g_buf + i, parm.bytes_per_line - jpegrow);
|
||||
if(parm.depth == 1)
|
||||
{
|
||||
int col1, col8;
|
||||
JSAMPLE *buf8 = static_cast<JSAMPLE *>(malloc(parm.bytes_per_line * 8));
|
||||
for(col1 = 0; col1 < parm.bytes_per_line; col1++)
|
||||
for(col8 = 0; col8 < 8; col8++)
|
||||
buf8[col1 * 8 + col8] = jpegbuf[col1] & (1 << (8 - col8 - 1)) ? 0 : 0xff;
|
||||
jpeg_write_scanlines(&cinfo, &buf8, 1);
|
||||
free(buf8);
|
||||
} else {
|
||||
jpeg_write_scanlines(&cinfo, &jpegbuf, 1);
|
||||
}
|
||||
i += parm.bytes_per_line - jpegrow;
|
||||
left -= parm.bytes_per_line - jpegrow;
|
||||
jpegrow = 0;
|
||||
}
|
||||
memcpy(jpegbuf + jpegrow, g_buf + i, left);
|
||||
jpegrow += left;
|
||||
}
|
||||
#endif
|
||||
if ((parm.depth != 16)) {
|
||||
fwrite (g_buf, 1, len, ofp);
|
||||
} else {
|
||||
#if !defined(WORDS_BIGENDIAN)
|
||||
int start = 0;
|
||||
/* check if we have saved one byte from the last sane_read */
|
||||
if (hang_over > -1) {
|
||||
if (len > 0) {
|
||||
fwrite (g_buf, 1, 1, ofp);
|
||||
g_buf[0] = (SANE_Byte) hang_over;
|
||||
hang_over = -1;
|
||||
start = 1;
|
||||
}
|
||||
}
|
||||
/* now do the byte-swapping */
|
||||
for (i = start; i < (len - 1); i += 2) {
|
||||
unsigned char LSB;
|
||||
LSB = g_buf[i];
|
||||
g_buf[i] = g_buf[i + 1];
|
||||
g_buf[i + 1] = LSB;
|
||||
}
|
||||
/* check if we have an odd number of bytes */
|
||||
if (((len - start) % 2) != 0) {
|
||||
hang_over = g_buf[len - 1];
|
||||
len--;
|
||||
}
|
||||
#endif
|
||||
fwrite (g_buf, 1, len, ofp);
|
||||
}
|
||||
}
|
||||
if (must_buffer) {
|
||||
KyInfo() << "must_buffer = " << must_buffer;
|
||||
switch (parm.format) {
|
||||
case SANE_FRAME_RED:
|
||||
case SANE_FRAME_GREEN:
|
||||
case SANE_FRAME_BLUE:
|
||||
for (i = 0; i < len; ++i) {
|
||||
image.data[offset + 3 * i] = g_buf[i];
|
||||
if (!advance (&image)) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
offset += 3 * len;
|
||||
break;
|
||||
case SANE_FRAME_RGB:
|
||||
for (i = 0; i < len; ++i) {
|
||||
image.data[offset + i] = g_buf[i];
|
||||
if (!advance (&image)) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
offset += len;
|
||||
break;
|
||||
case SANE_FRAME_GRAY:
|
||||
for (i = 0; i < len; ++i) {
|
||||
image.data[offset + i] = g_buf[i];
|
||||
if (!advance (&image)) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
offset += len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else { /* ! must_buffer */
|
||||
if ((parm.depth != 16)) {
|
||||
fwrite (g_buf, 1, len, ofp);
|
||||
} else {
|
||||
#if !defined(WORDS_BIGENDIAN)
|
||||
int start = 0;
|
||||
/* check if we have saved one byte from the last sane_read */
|
||||
if (hang_over > -1) {
|
||||
if (len > 0) {
|
||||
fwrite (g_buf, 1, 1, ofp);
|
||||
g_buf[0] = (SANE_Byte) hang_over;
|
||||
hang_over = -1;
|
||||
start = 1;
|
||||
}
|
||||
}
|
||||
/* now do the byte-swapping */
|
||||
for (i = start; i < (len - 1); i += 2) {
|
||||
unsigned char LSB;
|
||||
LSB = g_buf[i];
|
||||
g_buf[i] = g_buf[i + 1];
|
||||
g_buf[i + 1] = LSB;
|
||||
}
|
||||
/* check if we have an odd number of bytes */
|
||||
if (((len - start) % 2) != 0) {
|
||||
hang_over = g_buf[len - 1];
|
||||
len--;
|
||||
}
|
||||
#endif
|
||||
fwrite (g_buf, 1, len, ofp);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_verbose && parm.depth == 8) {
|
||||
for (i = 0; i < len; ++i)
|
||||
if (g_buf[i] >= max) {
|
||||
max = g_buf[i];
|
||||
} else if (g_buf[i] < min) {
|
||||
min = g_buf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(g_sane_object->stopSaneReadFlag == true){
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
fflush(ofp);
|
||||
first_frame = 0;
|
||||
qDebug()<< "0531info: first_frame value has changed:" << first_frame;
|
||||
qDebug()<< "0531info: parm.last_frame value:" << parm.last_frame;
|
||||
} while (!parm.last_frame);
|
||||
if (g_verbose && parm.depth == 8) {
|
||||
for (i = 0; i < len; ++i)
|
||||
if (g_buf[i] >= max) {
|
||||
max = g_buf[i];
|
||||
} else if (g_buf[i] < min) {
|
||||
min = g_buf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(g_sane_object->stopSaneReadFlag == true){
|
||||
if(g_sane_object->userInfo.type.compare(QApplication::tr("ADF Duplex"), Qt::CaseInsensitive) == 0){
|
||||
status = status = sane_start(g_device);
|
||||
while(status == SANE_STATUS_GOOD){
|
||||
status = sane_read(g_device, g_buf, g_BufSize, &len);
|
||||
}
|
||||
}
|
||||
|
||||
if (must_buffer) {
|
||||
KyInfo() << "must_buffer = " << must_buffer;
|
||||
image.height = image.y;
|
||||
status = SANE_STATUS_CANCELLED;
|
||||
goto cleanup;
|
||||
}
|
||||
fflush(ofp);
|
||||
first_frame = 0;
|
||||
qDebug() << "0531info: first_frame value has changed:" << first_frame;
|
||||
qDebug() << "0531info: parm.last_frame value:" << parm.last_frame;
|
||||
} while (!parm.last_frame);
|
||||
|
||||
switch(g_sane_object->output_format) {
|
||||
case OUTPUT_PNM:
|
||||
writePnmHeader(parm.format, parm.pixels_per_line,
|
||||
image.height, parm.depth, ofp);
|
||||
break;
|
||||
#if HAVE_LIBJPEG
|
||||
case OUTPUT_JPEG:
|
||||
write_jpeg_header (parm.format, parm.pixels_per_line,
|
||||
parm.lines, resolution_value,
|
||||
ofp, &cinfo, &jerr);
|
||||
KyInfo() << "end scanning status: " << status;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (must_buffer) {
|
||||
KyInfo() << "must_buffer = " << must_buffer;
|
||||
image.height = image.y;
|
||||
|
||||
writePnmHeader (parm.format, parm.pixels_per_line, image.height, parm.depth, ofp);
|
||||
switch(g_sane_object->output_format) {
|
||||
case OUTPUT_PNM:
|
||||
writePnmHeader(parm.format, parm.pixels_per_line,
|
||||
image.height, parm.depth, ofp);
|
||||
break;
|
||||
}
|
||||
|
||||
#if !defined(WORDS_BIGENDIAN)
|
||||
if (parm.depth == 16) {
|
||||
for (i = 0; i < image.height * image.width; i += 2) {
|
||||
unsigned char LSB;
|
||||
LSB = image.data[i];
|
||||
image.data[i] = image.data[i + 1];
|
||||
image.data[i + 1] = LSB;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
KyInfo() << "end scanning status: " << status;
|
||||
fwrite (image.data, 1, image.height * image.width, ofp);
|
||||
}
|
||||
writePnmHeader (parm.format, parm.pixels_per_line, image.height, parm.depth, ofp);
|
||||
|
||||
#if HAVE_LIBJPEG
|
||||
if(g_sane_object->output_format == OUTPUT_JPEG) {
|
||||
KyInfo() << "end scanning status: " << status;
|
||||
// jpeg_finish_compress(&cinfo);
|
||||
}
|
||||
#endif
|
||||
KyInfo() << "end scanning status: " << status;
|
||||
#if !defined(WORDS_BIGENDIAN)
|
||||
if (parm.depth == 16) {
|
||||
for (i = 0; i < image.height * image.width; i += 2) {
|
||||
unsigned char LSB;
|
||||
LSB = image.data[i];
|
||||
image.data[i] = image.data[i + 1];
|
||||
image.data[i + 1] = LSB;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
KyInfo() << "end scanning status: " << status;
|
||||
fwrite (image.data, 1, image.height * image.width, ofp);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
#if HAVE_LIBJPEG
|
||||
if(g_sane_object->output_format == OUTPUT_JPEG) {
|
||||
KyInfo() << "end scanning status: " << status;
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
free(jpegbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (image.data) {
|
||||
KyInfo() << "free image data!";
|
||||
free (image.data);
|
||||
}
|
||||
KyInfo() << "end scanning status: " << sane_strstatus(status);
|
||||
return status;
|
||||
}
|
||||
void SaneObject::stopSaneWhenEndThisCircle(){
|
||||
if (g_sane_object->getSaneHaveHandle()) {
|
||||
if (g_sane_object->getSaneHaveHandle()) {
|
||||
g_sane_object->setSaneHaveHandle(false);
|
||||
KyInfo() << "end scanning status: " << status;
|
||||
|
||||
KyInfo() << "sane_cancel and sane_close";
|
||||
cleanup:
|
||||
if (image.data) {
|
||||
KyInfo() << "free image data!";
|
||||
free (image.data);
|
||||
}
|
||||
KyInfo() << "end scanning status: " << sane_strstatus(status);
|
||||
return status;
|
||||
|
||||
sane_cancel(g_sane_object->handle);
|
||||
sane_close(g_sane_object->handle);
|
||||
}
|
||||
}
|
||||
SANE_Status status = SANE_STATUS_CANCELLED;
|
||||
g_user_signal->scanThreadFinished(status);
|
||||
}
|
||||
|
||||
static void authCallback (SANE_String_Const resource, SANE_Char *username, SANE_Char *password)
|
||||
|
@ -536,27 +416,6 @@ void SaneObject::refreshListSlots()
|
|||
g_user_signal->warnMsg(msg);
|
||||
}
|
||||
|
||||
void SaneObject::stopSaneForException(){
|
||||
stopSaneExceptionFlag = true;
|
||||
}
|
||||
|
||||
SANE_Status getSaneParameters(SANE_Handle device)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_INVAL;
|
||||
SANE_Parameters parm;
|
||||
|
||||
status = sane_get_parameters (device, &parm);
|
||||
KyInfo() << "Parm : status = " << sane_strstatus(status)
|
||||
<< "format = " << parm.format
|
||||
<< "last_frame = " << parm.last_frame
|
||||
<< "bytes_per_line = " << parm.bytes_per_line
|
||||
<< "pixels_per_line = " << parm.pixels_per_line
|
||||
<< "lines = " << parm.lines
|
||||
<< "depth = " << parm.depth;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status doScan(const char *fileName)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
|
@ -574,14 +433,14 @@ SANE_Status doScan(const char *fileName)
|
|||
QString path;
|
||||
QString part_path;
|
||||
QString save_path;
|
||||
g_BufSize = 1024 * 32;
|
||||
g_BufSize = (32 * 1024);
|
||||
g_buf = static_cast<SANE_Byte*>(malloc(g_BufSize));
|
||||
bool multiscan = 0;
|
||||
int pagecount = 1;
|
||||
while (status == SANE_STATUS_GOOD || (status == 5 && multiscan)){
|
||||
path = fileName;
|
||||
QFileInfo pathinfo(path);
|
||||
if(text.compare("Multiple", Qt::CaseInsensitive) == 0 || text.compare("多页扫描", Qt::CaseInsensitive) == 0 || text2.compare("ADF Duplex", Qt::CaseInsensitive) == 0 ||text2.compare("ADF 双面", Qt::CaseInsensitive) == 0){
|
||||
if(text.compare(QApplication::tr("Multiple"), Qt::CaseInsensitive) == 0 || text.compare("多页扫描", Qt::CaseInsensitive) == 0 || text2.compare(QApplication::tr("ADF Duplex"), Qt::CaseInsensitive) == 0 ||text2.compare("ADF 双面", Qt::CaseInsensitive) == 0){
|
||||
multiscan = 1;
|
||||
part_path = pathinfo.absolutePath() + "/" + pathinfo.baseName() + "[" + QString::number(pagecount) + "]" + suffix + ".part";
|
||||
path = pathinfo.absolutePath() + "/" + pathinfo.baseName() + "[" + QString::number(pagecount) + "]" + suffix;
|
||||
|
@ -589,7 +448,7 @@ SANE_Status doScan(const char *fileName)
|
|||
|
||||
g_sane_object->loadFullScanFileNames.append(path);
|
||||
g_sane_object->saveFullScanFileNames.append(save_path);
|
||||
pagecount++;
|
||||
pagecount++;
|
||||
}else{
|
||||
part_path = pathinfo.absolutePath() + "/" + pathinfo.baseName() + suffix + ".part";
|
||||
path = pathinfo.absolutePath() + "/" + pathinfo.baseName() + suffix;
|
||||
|
@ -615,7 +474,6 @@ SANE_Status doScan(const char *fileName)
|
|||
KyInfo() << "`sane_start` status: " << sane_strstatus(status);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
KyInfo() << "Cannot start scan devices, sane_status = " << status;
|
||||
// g_sane_object->setSaneStatus(false);
|
||||
g_user_signal->closeScanDialog();
|
||||
break;
|
||||
}
|
||||
|
@ -633,15 +491,9 @@ SANE_Status doScan(const char *fileName)
|
|||
switch(status) {
|
||||
case SANE_STATUS_GOOD:
|
||||
case SANE_STATUS_EOF: {
|
||||
// status = SANE_STATUS_GOOD;
|
||||
if (!ofp || (0 != fclose(ofp))) {
|
||||
status = SANE_STATUS_ACCESS_DENIED;
|
||||
break;
|
||||
} else {
|
||||
ofp = nullptr;
|
||||
if (rename (part_path.toLocal8Bit().data(), path.toLocal8Bit().data())) {
|
||||
if(QFile(part_path).exists()){
|
||||
if (rename(part_path.toLocal8Bit().data(), path.toLocal8Bit().data())) {
|
||||
status = SANE_STATUS_ACCESS_DENIED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -650,24 +502,24 @@ SANE_Status doScan(const char *fileName)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(multiscan == 1 && g_sane_object->scanPageNumber != 1 && status !=SANE_STATUS_CANCELLED){
|
||||
if(multiscan == 1 && status !=SANE_STATUS_CANCELLED){
|
||||
g_sane_object->loadFullScanFileNames.removeLast();
|
||||
g_sane_object->saveFullScanFileNames.removeLast();
|
||||
g_sane_object->scanPageNumber -= 1;
|
||||
if(g_sane_object->scanPageNumber != 1){
|
||||
g_sane_object->scanPageNumber -= 1;
|
||||
}
|
||||
status = SANE_STATUS_EOF;
|
||||
}
|
||||
|
||||
KyInfo() << "sane_cancel";
|
||||
|
||||
|
||||
if (ofp) {
|
||||
fclose (ofp);
|
||||
ofp = nullptr;
|
||||
fclose (ofp);
|
||||
ofp = nullptr;
|
||||
}
|
||||
|
||||
if (g_buf) {
|
||||
free (g_buf);
|
||||
g_buf = nullptr;
|
||||
free (g_buf);
|
||||
g_buf = nullptr;
|
||||
}
|
||||
sane_cancel(g_device);
|
||||
return status;
|
||||
|
@ -717,21 +569,14 @@ SANE_Status saneOpen(SANE_Device *device, SANE_Handle *sane_handle)
|
|||
|
||||
KyInfo() << "Open device name: " <<g_sane_object->openSaneName;
|
||||
|
||||
/// Filter HP scanners: hpaio:/net/hp_laserjet_pro_mfp_m226dw?ip=192.168.195.5&queue=false
|
||||
/// This scanner will `sane_open` not stop forever, so we reture error immediately
|
||||
if (device->name) {
|
||||
if (strstr(device->name, "hpaio:/net/hp_laserjet_pro_mfp_m226dw?ip=192")) {
|
||||
KyInfo() << device->name << " cannot scan, so we just return SANE_STATUS_INVAL.";
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = sane_open(device->name, sane_handle);
|
||||
|
||||
if (status) {
|
||||
/// status = Error during device I/O: can be this scanner connected by usb is error,
|
||||
/// so check usb connected.
|
||||
KyInfo() << "status = " << sane_strstatus(status);
|
||||
QString message = QApplication::tr("Fail to open the scanner, error code ") + QString::number(status);
|
||||
QTimer::singleShot(1000, [=](){g_user_signal->warnMsg(message);});
|
||||
}else{
|
||||
KyInfo() << "Open scanner success";
|
||||
}
|
||||
|
@ -1247,11 +1092,6 @@ static const SANE_Option_Descriptor *getOptdescByName(SANE_Handle device, const
|
|||
const SANE_Option_Descriptor *opt;
|
||||
|
||||
opt = sane_get_option_descriptor (device, *option_num);
|
||||
|
||||
if (opt->name) {
|
||||
// KyInfo() << opt->name;
|
||||
}
|
||||
|
||||
if (opt->name && strcmp(opt->name, name) == 0) {
|
||||
KyInfo() << "Get option desc for " << *option_num << "opt->name = " << opt->name << "name" << name;
|
||||
return (opt);
|
||||
|
@ -1358,20 +1198,14 @@ SANE_Status setOptionSizesAll(SANE_Handle sane_handle, int type)
|
|||
return status;
|
||||
}
|
||||
|
||||
#define GUARDS_SIZE 4
|
||||
#define GUARD1 ((SANE_Word)0x5abf8ea5)
|
||||
#define GUARD2 ((SANE_Word)0xa58ebf5a)
|
||||
|
||||
static void *guardsMalloc(size_t size)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
|
||||
size += 2 * GUARDS_SIZE;
|
||||
ptr = static_cast<unsigned char *>(malloc(size));
|
||||
|
||||
assert(ptr);
|
||||
|
||||
ptr += GUARDS_SIZE;
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
@ -1379,8 +1213,6 @@ static void *guardsMalloc(size_t size)
|
|||
static void guardsFree(void *ptr)
|
||||
{
|
||||
unsigned char *p = static_cast<unsigned char *>(ptr);
|
||||
|
||||
p -= GUARDS_SIZE;
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
@ -1421,8 +1253,7 @@ static SANE_Status getOptionValue(SANE_Handle device, const char *option_name)
|
|||
void *optval;
|
||||
optval = guardsMalloc(opt->size);
|
||||
/* Get default optval(different format) */
|
||||
status = sane_control_option (device, optnum,
|
||||
SANE_ACTION_GET_VALUE, optval, nullptr);
|
||||
status = sane_control_option (device, optnum, SANE_ACTION_GET_VALUE, optval, nullptr);
|
||||
|
||||
if (opt->desc) {
|
||||
KyInfo() << opt->desc;
|
||||
|
@ -1783,21 +1614,6 @@ static SANE_Status showAllSaneParameters(SANE_Handle device)
|
|||
return status;
|
||||
}
|
||||
|
||||
static SANE_Status startSaneScan(SANE_Handle sane_handle, SANE_String_Const fileName)
|
||||
{
|
||||
g_device = sane_handle;
|
||||
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
status = doScan(fileName);
|
||||
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
KyInfo() << "start scan error, status = " << status;
|
||||
}
|
||||
// sane_cancel(sane_handle);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void SaneObject::saneCancel(SANE_Handle sane_handle)
|
||||
{
|
||||
KyInfo() << "saneCancel()";
|
||||
|
@ -1945,7 +1761,6 @@ SaneObject::SaneObject(QObject *parent) : QObject(parent)
|
|||
devicesInfo.resolution << "";
|
||||
devicesInfo.size << "";
|
||||
|
||||
connect(g_user_signal, &GlobalUserSignal::saneCancelSignal, this, &SaneObject::stopSaneForException);
|
||||
connect(g_user_signal, &GlobalUserSignal::saneRestartSignal, this, &SaneObject::restartSaneForException);
|
||||
connect(g_user_signal, &GlobalUserSignal::openDeviceSignal,this,&SaneObject::openSaneDeviceForPage);
|
||||
connect(g_user_signal, &GlobalUserSignal::refreshListSignal, this, &SaneObject::refreshListSlots);
|
||||
|
@ -2114,9 +1929,7 @@ void SaneObject::dumpScannerOptions()
|
|||
void SaneObject::setSaneAllParametersByUser()
|
||||
{
|
||||
dumpScannerOptions();
|
||||
setSaneNameByUser();
|
||||
setSanePageNumberByUser();
|
||||
setSaneTimeByUser();
|
||||
setSaneTypeByUser();
|
||||
setSaneColorByUser();
|
||||
setSaneResolutionByUser();
|
||||
|
@ -2124,11 +1937,6 @@ void SaneObject::setSaneAllParametersByUser()
|
|||
setSaneFormatByUser();
|
||||
}
|
||||
|
||||
void SaneObject::setSaneNameByUser()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SaneObject::setSanePageNumberByUser()
|
||||
{
|
||||
if(g_sane_object->devicemodel == "HW-3130"){
|
||||
|
@ -2141,11 +1949,6 @@ void SaneObject::setSanePageNumberByUser()
|
|||
}
|
||||
}
|
||||
|
||||
void SaneObject::setSaneTimeByUser()
|
||||
{
|
||||
// used in ScanThread run(), so we not set hear
|
||||
}
|
||||
|
||||
void SaneObject::setSaneTypeByUser()
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
|
@ -2345,12 +2148,7 @@ QString SaneObject::getSaneTmpSaveDirectory()
|
|||
return tmpSaveDirectory;
|
||||
}
|
||||
|
||||
bool SaneObject::detectSaneDeviceForPage()
|
||||
{
|
||||
return detectSaneDevices();
|
||||
}
|
||||
void SaneObject::restartSaneForException(){
|
||||
stopSaneExceptionFlag = false;
|
||||
openSaneDevice(openDeviceIndex);
|
||||
}
|
||||
|
||||
|
@ -2403,38 +2201,24 @@ QString SaneObject::getFullScanFileNameExceptFormatForPnmLoad()
|
|||
*/
|
||||
int SaneObject::startScanning(UserSelectedInfo info)
|
||||
{
|
||||
if(stopSaneExceptionFlag){
|
||||
qDebug()<< "stopSaneExceptionFlag exec!";
|
||||
stopSaneWhenEndThisCircle();
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
KyInfo() << "startScanning";
|
||||
// openSaneDevice(g_sane_object->openDeviceIndex);
|
||||
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
if(!g_sane_object->m_ParametersHaveSeted){
|
||||
KyInfo() << "Setting Parameter...";
|
||||
setSaneAllParametersByUser();
|
||||
g_sane_object->m_ParametersHaveSeted = true;
|
||||
}
|
||||
|
||||
QString saveFullName = getFullScanFileNameExceptFormatForSave();
|
||||
QString loadFullName = getFullScanFileNameExceptFormatForPnmLoad();
|
||||
|
||||
loadFullScanFileName = loadFullName;
|
||||
|
||||
saveFullScanFileName = saveFullName;
|
||||
saveFullScanFileName = getFullScanFileNameExceptFormatForSave();
|
||||
loadFullScanFileName = getFullScanFileNameExceptFormatForPnmLoad();
|
||||
|
||||
KyInfo() << "Start scanning, please waiting ...";
|
||||
status = startSaneScan(g_sane_object->handle, loadFullScanFileName.toStdString().c_str());
|
||||
KyInfo() << "Stop scanning, check status: " << status
|
||||
<< "getSaneHaveHandle: " << g_sane_object->getSaneHaveHandle();
|
||||
g_device = g_sane_object->handle;
|
||||
status = doScan(loadFullScanFileName.toStdString().c_str());
|
||||
|
||||
KyInfo() << "Scan Finish, check status: " << status;
|
||||
|
||||
// if (g_sane_object->getSaneHaveHandle()) {
|
||||
// sane_cancel(g_sane_object->handle);
|
||||
// }
|
||||
KyInfo() << "saveText nowSaveName = " << nowSaveName;
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sane/sane.h>
|
||||
#include <sane/saneopts.h>
|
||||
#include <iostream>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
|
@ -41,7 +39,17 @@
|
|||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
#include <QFileInfo>
|
||||
//using namespace std;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "sane/sane.h"
|
||||
#include "sane/saneopts.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "globalsignal.h"
|
||||
#include <QMap>
|
||||
|
@ -49,26 +57,12 @@
|
|||
#define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBJPEG
|
||||
#define HAVE_LIBJEEG 0
|
||||
#undef HAVE_LIBJPEG // jpeg format cannot work
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if HAVE_LIBJPEG
|
||||
#include <jpeglib.h>
|
||||
#include <jmorecfg.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define OUTPUT_UNKNOWN 0
|
||||
#define OUTPUT_PNM 1
|
||||
#define OUTPUT_TIFF 2
|
||||
#define OUTPUT_PNG 3
|
||||
#define OUTPUT_JPEG 4
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ScanDeviceInfo struct
|
||||
* Parameters getted from specific scanner device, which could set in scansetting page
|
||||
|
@ -144,9 +138,7 @@ public:
|
|||
void saneClose();
|
||||
|
||||
void setSaneAllParametersByUser();
|
||||
void setSaneNameByUser();
|
||||
void setSanePageNumberByUser();
|
||||
void setSaneTimeByUser();
|
||||
void setSaneTypeByUser();
|
||||
QString getSaneTypeByUser(QString type);
|
||||
void setSaneColorByUser();
|
||||
|
@ -160,8 +152,6 @@ public:
|
|||
QString getSaneSaveDirectoryByUser();
|
||||
QString getSaneTmpSaveDirectory();
|
||||
|
||||
|
||||
bool detectSaneDeviceForPage();
|
||||
void openSaneDeviceForPage(int index);
|
||||
QString getFullScanFileNameExceptFormatForSave();
|
||||
QString getFullScanFileNameExceptFormatForPnmLoad();
|
||||
|
@ -228,9 +218,7 @@ private:
|
|||
void dumpScannerOptions();
|
||||
public slots:
|
||||
void stopSaneRead(bool isStoped);
|
||||
void stopSaneForException();
|
||||
void restartSaneForException();
|
||||
void stopSaneWhenEndThisCircle();
|
||||
void refreshListSlots();
|
||||
signals:
|
||||
void updatePageNum();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "scandialog.h"
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
#include "Qt/windowmanage.hpp"
|
||||
#include "./utils/xatom-helper.h"
|
||||
#include "globalsignal.h"
|
||||
#include "kabase/Qt/windowmanage.hpp"
|
||||
#include <gsettings.hpp>
|
||||
#include "include/theme.h"
|
||||
|
||||
ScanDialog::ScanDialog(QWidget *parent) : QDialog(parent),
|
||||
|
@ -10,7 +10,7 @@ ScanDialog::ScanDialog(QWidget *parent) : QDialog(parent),
|
|||
m_closeButton(new QPushButton()),
|
||||
m_iconLabel(new QLabel()),
|
||||
m_msgLabel(new QLabel()),
|
||||
m_cancelButton(new QPushButton()),
|
||||
m_cancelButton(new CustomPushButton()),
|
||||
m_titleWidget(new QWidget(this)),
|
||||
m_titleHBoxLayout(new QHBoxLayout(m_titleWidget)),
|
||||
m_msgWidget(new QWidget(this)),
|
||||
|
@ -25,10 +25,8 @@ ScanDialog::ScanDialog(QWidget *parent) : QDialog(parent),
|
|||
|
||||
void ScanDialog::setupGui()
|
||||
{
|
||||
::kabase::WindowManage::removeHeader(this);
|
||||
|
||||
kabase::WindowManage::removeHeader(this);
|
||||
setWindowModality(Qt::ApplicationModal);
|
||||
// setWindowIcon(QIcon::fromTheme("kylin-scanner"));
|
||||
this->setWindowTitle(tr("Scanner"));
|
||||
this->setFixedSize(ScanDialogWindowSize);
|
||||
|
||||
|
@ -100,13 +98,11 @@ void ScanDialog::setupGui()
|
|||
|
||||
|
||||
this->setLayout(m_mainVBoxLayout);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool ScanDialog::isDarkTheme()
|
||||
{
|
||||
QString systemTheme = kdk::kabase::Gsettings::getSystemTheme().toString();
|
||||
QString systemTheme = kdk::GsettingMonitor::getSystemTheme().toString();
|
||||
|
||||
if (systemTheme == STYLE_NAME_KEY_DARK || systemTheme == STYLE_NAME_KEY_BLACK) {
|
||||
return true;
|
||||
|
@ -116,30 +112,21 @@ bool ScanDialog::isDarkTheme()
|
|||
}
|
||||
void ScanDialog::initConnect()
|
||||
{
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, [=]{
|
||||
connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemThemeChange, this, [=]{
|
||||
if(isDarkTheme()){
|
||||
QPalette pal(palette());
|
||||
pal.setColor(QPalette::Background, QColor(0, 0, 0));
|
||||
setAutoFillBackground(true);
|
||||
setPalette(pal);
|
||||
this->setStyleSheet("background: #262626;");
|
||||
}else{
|
||||
QPalette pal(palette());
|
||||
pal.setColor(QPalette::Background, QColor(255, 255, 255));
|
||||
setAutoFillBackground(true);
|
||||
setPalette(pal);
|
||||
this->setStyleSheet("background: #FFFFFF;");
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_closeButton, &QPushButton::clicked, this, [=](){
|
||||
this->reject();
|
||||
// g_user_signal->stopScanOperation();
|
||||
});
|
||||
|
||||
connect(m_cancelButton, &QPushButton::clicked, this, [=]{
|
||||
//this->reject();
|
||||
cancelOpration();
|
||||
emit g_user_signal->cancelScanning();
|
||||
// g_user_signal->stopScanOperation();
|
||||
|
||||
});
|
||||
connect(g_sane_object, &SaneObject::updatePageNum, this, &ScanDialog::updatePageNumberWhileScanning);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define ScanDialogButtonSize QSize(96, 36)
|
||||
|
||||
#include "saneobject.h"
|
||||
#include "custom_push_button.h"
|
||||
|
||||
class ScanDialog : public QDialog
|
||||
{
|
||||
|
@ -49,7 +50,7 @@ private:
|
|||
QPushButton *m_closeButton = nullptr;
|
||||
QLabel *m_iconLabel = nullptr;
|
||||
QLabel *m_msgLabel = nullptr;
|
||||
QPushButton *m_cancelButton = nullptr;
|
||||
CustomPushButton *m_cancelButton = nullptr;
|
||||
|
||||
QWidget *m_titleWidget = nullptr;
|
||||
QHBoxLayout *m_titleHBoxLayout = nullptr;
|
||||
|
|
|
@ -29,24 +29,27 @@
|
|||
#include <QStandardItem>
|
||||
#include <QStandardItemModel>
|
||||
#include <QDateTime>
|
||||
#include <buried_point.hpp>
|
||||
#include <gsettings.hpp>
|
||||
#include <buriedpoint.hpp>
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
#include <QPalette>
|
||||
#include "include/theme.h"
|
||||
#include "thumbnailwidget.h"
|
||||
#include "newdevicelistpage.h"
|
||||
|
||||
ScanSettingsWidget::ScanSettingsWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
scanButtonLeftLabel(new QLabel()),
|
||||
scanButtonRightLabel(new QLabel()),
|
||||
scanButtonHLayout(new QHBoxLayout()),
|
||||
m_scanButton(new QPushButton()),
|
||||
scanButtonLeftLabel(new QLabel(m_scanButton)),
|
||||
scanButtonRightLabel(new QLabel(m_scanButton)),
|
||||
scanButtonHLayout(new QHBoxLayout(m_scanButton)),
|
||||
m_deviceSettingsLabel(new QLabel()),
|
||||
m_deviceLabel(new QLabel()),
|
||||
m_deviceComboBox(new QComboBox()),
|
||||
m_deviceAddButton(new kdk::KPushButton()),
|
||||
m_deviceHLayout(new QHBoxLayout()),
|
||||
m_deviceWidget(new QWidget()),
|
||||
m_pageNumberLabel(new QLabel()),
|
||||
m_pageNumberComboBox(new QComboBox()),
|
||||
m_timeLabel(new QLabel()),
|
||||
m_timeComboBox(new QComboBox()),
|
||||
m_typeLabel(new QLabel()),
|
||||
m_typeComboBox(new QComboBox()),
|
||||
m_colorLabel(new QLabel()),
|
||||
|
@ -65,35 +68,29 @@ ScanSettingsWidget::ScanSettingsWidget(QWidget *parent) :
|
|||
m_saveDirectoryButtonLayout(new QHBoxLayout()),
|
||||
m_saveDirectoryButton(new QLineEdit()),
|
||||
m_settingsFormLayout(new QFormLayout()),
|
||||
m_sendMailButton(new QPushButton()),
|
||||
m_SaveAsButton(new QPushButton()),
|
||||
m_sendMailButton(new CustomPushButton()),
|
||||
m_SaveAsButton(new CustomPushButton()),
|
||||
m_buttonsHLayout(new QHBoxLayout()),
|
||||
m_mainScrollArea (new QScrollArea()),
|
||||
m_mainVLayout(new QVBoxLayout(this))
|
||||
m_mainVLayout(new QVBoxLayout(this)),
|
||||
dialog(new SendMailDialog(this))
|
||||
{
|
||||
m_themeData = new QGSettings(UKUI_THEME_GSETTING_PATH);
|
||||
setupGui();
|
||||
// initTheme();
|
||||
initConnect();
|
||||
}
|
||||
void ScanSettingsWidget::initTheme(){
|
||||
// QPalette pal(palette());
|
||||
// if (isDarkTheme()) {
|
||||
// pal.setColor(QPalette::Background, QColor(18, 18, 18));
|
||||
// } else {
|
||||
// pal.setColor(QPalette::Background, QColor(255, 255, 255));
|
||||
// }
|
||||
// setAutoFillBackground(true);
|
||||
// setPalette(pal);
|
||||
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::setScanIconDisable()
|
||||
{
|
||||
m_scanButton->setEnabled(false);
|
||||
// QPalette pe;
|
||||
// pe.setColor(QPalette::Text, Qt::gray);
|
||||
// scanButtonRightLabel->setPalette(pe);
|
||||
scanButtonRightLabel->setStyleSheet("color:grey;");
|
||||
m_deviceComboBox->setEnabled(false);
|
||||
m_pageNumberComboBox->setEnabled(false);
|
||||
m_typeComboBox->setEnabled(false);
|
||||
m_colorComboBox->setEnabled(false);
|
||||
m_resolutionComboBox->setEnabled(false);
|
||||
m_sizeComboBox->setEnabled(false);
|
||||
m_formatComboBox->setEnabled(false);
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::paintEvent(QPaintEvent *event)
|
||||
|
@ -110,6 +107,7 @@ void ScanSettingsWidget::paintEvent(QPaintEvent *event)
|
|||
mainColor = opt.palette.color(QPalette::Base);
|
||||
|
||||
p.fillPath(rectPath,QBrush(mainColor));
|
||||
p.end();
|
||||
}
|
||||
void ScanSettingsWidget::selectSaveDirectorySlot()
|
||||
{
|
||||
|
@ -155,7 +153,7 @@ void ScanSettingsWidget::deviceCurrentTextChangedSlot(QString text)
|
|||
if(text == ""){
|
||||
return;
|
||||
}
|
||||
KyInfo() << "Sane device name: " << g_sane_object->userInfo.name << "current devece name: " << m_deviceComboBox->currentText();
|
||||
KyInfo() << "Sane device name: " << g_sane_object->userInfo.name << "current deviece name: " << m_deviceComboBox->currentText();
|
||||
|
||||
if (g_sane_object->userInfo.name.isEmpty()) {
|
||||
g_sane_object->userInfo.name = text;
|
||||
|
@ -169,7 +167,7 @@ void ScanSettingsWidget::deviceCurrentTextChangedSlot(QString text)
|
|||
|
||||
int curTextLen = m_deviceComboBox->currentText().length();
|
||||
|
||||
if ( curTextLen >= 20) {
|
||||
if (curTextLen >= 20){
|
||||
m_deviceComboBox->setToolTip(m_deviceComboBox->currentText());
|
||||
} else {
|
||||
m_deviceComboBox->setToolTip("");
|
||||
|
@ -183,7 +181,9 @@ void ScanSettingsWidget::deviceCurrentTextChangedSlot(QString text)
|
|||
|
||||
g_sane_object->userInfo.deviceNameIndex = index;
|
||||
|
||||
g_sane_object->saneClose();
|
||||
if(g_sane_object->getSaneHaveHandle()){
|
||||
g_sane_object->saneClose();
|
||||
}
|
||||
|
||||
// while switch scan device, we should open the scan device to get some parameters
|
||||
g_sane_object->openDeviceIndex = index;
|
||||
|
@ -208,22 +208,30 @@ void ScanSettingsWidget::pageNumberCurrentTextChangedSlot(QString text)
|
|||
return;
|
||||
}
|
||||
g_sane_object->userInfo.pageNumber = tr("Multiple");
|
||||
m_saveNameEdit->setMaxLength(235);
|
||||
// m_saveNameEdit->setMaxLength(234);
|
||||
|
||||
// Avoid SANE_STATUS_NO_DOC Error to set time not enable.
|
||||
g_sane_object->setSaneStatus(true);
|
||||
// 还未删掉showTimeRow()
|
||||
// showTimeRow();
|
||||
kdk::kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerMultiPageScan)) {
|
||||
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerMultiPageScan)));
|
||||
buried_data.insert(std::make_pair("action", "multipage scan"));
|
||||
buried_data.insert(std::make_pair("function", "in scansettingswidget.cpp function pageNumberCurrentTextChangedSlot()"));
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
|
||||
} else {
|
||||
g_sane_object->userInfo.pageNumber = tr("Single");
|
||||
m_saveNameEdit->setMaxLength(230);
|
||||
// hideTimeRow();
|
||||
kdk::kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerSinglePageScan)) {
|
||||
// m_saveNameEdit->setMaxLength(237);
|
||||
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerSinglePageScan)));
|
||||
buried_data.insert(std::make_pair("action", "SinglePage scan"));
|
||||
buried_data.insert(std::make_pair("function", "in scansettingswidget.cpp function pageNumberCurrentTextChangedSlot()"));
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
}
|
||||
|
@ -238,20 +246,12 @@ void ScanSettingsWidget::timeCurrentTextChangedSlot(QString text)
|
|||
|
||||
void ScanSettingsWidget::typeCurrentTextChangedSlot(QString text)
|
||||
{
|
||||
// if (0 == QString::compare(text, tr("ADF Back"), Qt::CaseInsensitive)) {
|
||||
// g_sane_object->userInfo.type = "ADF Back";
|
||||
// } else if(0 == QString::compare(text, tr("ADF Front"), Qt::CaseInsensitive)) {
|
||||
// g_sane_object->userInfo.type = "ADF Front";
|
||||
// } else if(0 == QString::compare(text, tr("ADF Duplex"), Qt::CaseInsensitive)) {
|
||||
// g_sane_object->userInfo.type = "ADF Duplex";
|
||||
// }
|
||||
if(QString::compare(text, tr("Flatbed"), Qt::CaseInsensitive) == 0){
|
||||
m_pageNumberComboBox->setCurrentText(tr("Single"));
|
||||
}
|
||||
|
||||
g_sane_object->m_ParametersHaveSeted = false;
|
||||
g_sane_object->userInfo.type = text;
|
||||
|
||||
KyInfo() << "userInfo.type = " << text;
|
||||
}
|
||||
|
||||
|
@ -314,14 +314,17 @@ void ScanSettingsWidget::nameCurrentTextChangedSlot(QString text)
|
|||
m_saveNameEdit->cursorBackward(true, 1);
|
||||
m_saveNameEdit->del();
|
||||
}
|
||||
|
||||
QString saveNameEditStr = m_saveNameEdit->text();
|
||||
int len = strlen(saveNameEditStr.toLocal8Bit());
|
||||
qDebug() << "name length:"<<len;
|
||||
while(len > 240){
|
||||
saveNameEditStr = saveNameEditStr.left(saveNameEditStr.size() - 1);
|
||||
len = strlen(saveNameEditStr.toLocal8Bit());
|
||||
long length = g_utf8_strlen(saveNameEditStr.toUtf8().data(), -1); // 当前内容长度
|
||||
if (length > 236) {
|
||||
char *buff = new char[236 * 4 +1];
|
||||
memset(buff, '\0', 236 * 4 +1);
|
||||
g_utf8_strncpy(buff, saveNameEditStr.toUtf8().data(), 236); // 截取指定长度
|
||||
saveNameEditStr = QString::fromUtf8(buff);
|
||||
delete buff;
|
||||
m_saveNameEdit->setText(saveNameEditStr);
|
||||
}
|
||||
m_saveNameEdit->setText(saveNameEditStr);
|
||||
|
||||
g_sane_object->userInfo.saveName = m_saveNameEdit->text();
|
||||
KyInfo() << "saveName = " << g_sane_object->userInfo.saveName;
|
||||
|
@ -330,9 +333,13 @@ void ScanSettingsWidget::nameCurrentTextChangedSlot(QString text)
|
|||
}
|
||||
|
||||
void ScanSettingsWidget::sendMailButtonClickedSlot()
|
||||
{
|
||||
kdk::kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerSendMail)) {
|
||||
{
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerSendMail)));
|
||||
buried_data.insert(std::make_pair("action", "Send Mail"));
|
||||
buried_data.insert(std::make_pair("function", "in scansettingswidget.cpp function sendMailButtonClickedSlot()"));
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
int retDialog;
|
||||
|
@ -361,10 +368,15 @@ void ScanSettingsWidget::sendMailButtonClickedSlot()
|
|||
g_user_signal->sendMailButtonClicked();
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::saveAsButtonClickedSlot()
|
||||
void ScanSettingsWidget::saveAsButtonClickedSlot(bool exitApp)
|
||||
{
|
||||
kdk::kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerSaveAs)) {
|
||||
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerSaveAs)));
|
||||
buried_data.insert(std::make_pair("action", "save in user designed path"));
|
||||
buried_data.insert(std::make_pair("function", "in scansettingswidget.cpp function saveAsButtonClickedSlot()"));
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
|
||||
|
@ -458,6 +470,9 @@ void ScanSettingsWidget::saveAsButtonClickedSlot()
|
|||
// }
|
||||
g_user_signal->saveAsButtonClicked(path);
|
||||
g_user_signal->exitWindowWithSaveFlag = false;
|
||||
if(exitApp){
|
||||
g_user_signal->exitApplication();
|
||||
}
|
||||
}
|
||||
bool ScanSettingsWidget::showRunningDialog()
|
||||
{
|
||||
|
@ -465,17 +480,17 @@ bool ScanSettingsWidget::showRunningDialog()
|
|||
QString path = currentSaveDirectory;
|
||||
QString format = m_formatComboBox->currentText();
|
||||
QString filePath;
|
||||
if(g_sane_object->userInfo.pageNumber.compare(QApplication::tr("Multiple"), Qt::CaseInsensitive) == 0){
|
||||
if(g_sane_object->userInfo.pageNumber.compare(QApplication::tr("Multiple"), Qt::CaseInsensitive) == 0 || g_sane_object->userInfo.type.compare(QApplication::tr("ADF Duplex"), Qt::CaseInsensitive) == 0){
|
||||
if(format != "tiff"){
|
||||
filePath = path + "/" + fileName + "[1]" + "." + format;
|
||||
}else{
|
||||
filePath = path + "/" + fileName + "." + "tif";
|
||||
filePath = path + "/" + fileName + "." + "tiff";
|
||||
}
|
||||
}else{
|
||||
if(format != "tiff"){
|
||||
filePath = path + "/" + fileName + "." + format;
|
||||
}else{
|
||||
filePath = path + "/" + fileName + "." + "tif";
|
||||
filePath = path + "/" + fileName + "." + "tiff";
|
||||
}
|
||||
}
|
||||
QFileInfo file(filePath);
|
||||
|
@ -484,8 +499,8 @@ bool ScanSettingsWidget::showRunningDialog()
|
|||
QString tipsStr1 = tr("The file ");
|
||||
QString tipsStr2 = tr(" already exists, do you want to overwrite it? If you are performing a multi page scan, it may cause multiple files to be overwritten. Please be cautious!");
|
||||
QString tipsStr = tipsStr1 + file.fileName() + tipsStr2;
|
||||
box = QMessageBox::question(this->parentWidget(),tr("tips"),tipsStr,QMessageBox::Yes|QMessageBox::No);
|
||||
if(box == QMessageBox::Yes){
|
||||
box = QMessageBox::question(this->parentWidget(),tr("tips"),tipsStr,QMessageBox::Ok|QMessageBox::Cancel);
|
||||
if(box == QMessageBox::Ok){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
|
@ -510,7 +525,6 @@ void ScanSettingsWidget::fontSizeChanged()
|
|||
{
|
||||
setLabelAttributes(m_deviceLabel, tr("Device"));
|
||||
setLabelAttributes(m_pageNumberLabel, tr("Pages"));
|
||||
setLabelAttributes(m_timeLabel, tr("Time"));
|
||||
setLabelAttributes(m_typeLabel, tr("Type"));
|
||||
setLabelAttributes(m_colorLabel, tr("Colour"));
|
||||
setLabelAttributes(m_resolutionLabel, tr("Resolution"));
|
||||
|
@ -521,6 +535,9 @@ void ScanSettingsWidget::fontSizeChanged()
|
|||
|
||||
setSaveButtonLabelAttributes(m_saveDirectoryButtonLabel, currentSaveDirectory, ScanSettingsButtonElideWidth);
|
||||
|
||||
m_deviceAddButton->setIcon(QIcon::fromTheme("list-add-symbolic"));
|
||||
m_deviceAddButton->setIconSize(QSize(24, 24));
|
||||
|
||||
m_sendMailButton->adjustSize();
|
||||
m_sendMailButton->setText(tr("Mail to"));
|
||||
m_sendMailButton->setToolTip(tr("Mail to"));
|
||||
|
@ -533,7 +550,7 @@ void ScanSettingsWidget::fontSizeChanged()
|
|||
|
||||
void ScanSettingsWidget::fontSizeChangedSlot()
|
||||
{
|
||||
float systemFontSize = kdk::kabase::Gsettings::getSystemFontSize().toFloat();
|
||||
float systemFontSize = kdk::GsettingMonitor::getSystemFontSize().toFloat();
|
||||
QString fontType = m_themeData->get("systemFont").toString();
|
||||
QFont font(fontType, systemFontSize);
|
||||
scanButtonRightLabel->setFont(font);
|
||||
|
@ -544,9 +561,62 @@ void ScanSettingsWidget::setDeviceBoxDisableSlot()
|
|||
{
|
||||
m_deviceComboBox->setEnabled(false);
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::showWaittingDialogSlot()
|
||||
{
|
||||
QWidget *widget = nullptr;
|
||||
QWidgetList widgetList = QApplication::allWidgets();
|
||||
for (int i=0; i<widgetList.length(); ++i) {
|
||||
if (widgetList.at(i)->objectName() == "MainWindow") {
|
||||
widget = widgetList.at(i);
|
||||
}
|
||||
}
|
||||
m_waittingDialog = new WaittingDialog(widget);
|
||||
m_waittingDialog->show();
|
||||
|
||||
std::map<std::string, std::string> buried_data;
|
||||
buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerFindNoDriverDevice)));
|
||||
buried_data.insert(std::make_pair("action", "Show waitting dialog and make deviceFinder start work."));
|
||||
buried_data.insert(std::make_pair("function", "in scansettingswidget.cpp function ShowWaittingDialogSlot()"));
|
||||
|
||||
kabase::BuriedPoint buriedPointTest;
|
||||
if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) {
|
||||
qCritical() << "Error : buried point fail !";
|
||||
};
|
||||
|
||||
m_devFinder = new deviceFinder();
|
||||
QObject::connect(m_devFinder, &deviceFinder::succeed, this, &ScanSettingsWidget::showNewDeviceListPageSuccessSlot);
|
||||
QObject::connect(m_devFinder, &deviceFinder::failed, this, &ScanSettingsWidget::showNewDeviceListPageFailSlot);
|
||||
m_devFinder->startWorker();
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::showNewDeviceListPageSuccessSlot()
|
||||
{
|
||||
QWidget *widget = nullptr;
|
||||
QWidgetList widgetList = QApplication::allWidgets();
|
||||
for (int i=0; i<widgetList.length(); ++i) {
|
||||
if (widgetList.at(i)->objectName() == "MainWindow") {
|
||||
widget = widgetList.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "Install succeed";
|
||||
m_waittingDialog->close();
|
||||
// 初始化页面并,解析内容并展示
|
||||
m_noDriverDevices.clear();
|
||||
m_noDriverDevices = m_devFinder->getList();
|
||||
m_deviceListPage = new newDeviceListPage(m_noDriverDevices, widget);
|
||||
m_devFinder->finished();
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::showNewDeviceListPageFailSlot()
|
||||
{
|
||||
qDebug() << "Install failed";
|
||||
}
|
||||
|
||||
bool ScanSettingsWidget::isDarkTheme()
|
||||
{
|
||||
QString systemTheme = kdk::kabase::Gsettings::getSystemTheme().toString();
|
||||
QString systemTheme = kdk::GsettingMonitor::getSystemTheme().toString();
|
||||
|
||||
if (systemTheme == STYLE_NAME_KEY_DARK || systemTheme == STYLE_NAME_KEY_BLACK) {
|
||||
return true;
|
||||
|
@ -617,8 +687,15 @@ void ScanSettingsWidget::setupGui()
|
|||
|
||||
currentSaveAsDirectory = tr("Save as");
|
||||
fontSizeChanged();
|
||||
m_deviceAddButton->setFixedSize(36, 36);
|
||||
m_deviceHLayout->setSpacing(0);
|
||||
m_deviceHLayout->addWidget(m_deviceComboBox);
|
||||
m_deviceHLayout->addSpacing(8);
|
||||
m_deviceHLayout->addWidget(m_deviceAddButton);
|
||||
m_deviceHLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_deviceWidget->setLayout(m_deviceHLayout);
|
||||
|
||||
|
||||
// m_settingsFormLayout->setSpacing(0);
|
||||
m_settingsFormLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
|
||||
m_settingsFormLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
|
||||
m_settingsFormLayout->setFormAlignment(Qt::AlignHCenter | Qt::AlignTop);
|
||||
|
@ -626,7 +703,7 @@ void ScanSettingsWidget::setupGui()
|
|||
m_settingsFormLayout->setHorizontalSpacing(7);
|
||||
m_settingsFormLayout->setVerticalSpacing(8);
|
||||
m_settingsFormLayout->addRow(m_deviceSettingsLabel);
|
||||
m_settingsFormLayout->addRow(m_deviceLabel, m_deviceComboBox);
|
||||
m_settingsFormLayout->addRow(m_deviceLabel, m_deviceWidget);
|
||||
m_settingsFormLayout->addRow(m_pageNumberLabel, m_pageNumberComboBox);
|
||||
m_settingsFormLayout->addRow(m_typeLabel, m_typeComboBox);
|
||||
m_settingsFormLayout->addRow(m_colorLabel, m_colorComboBox);
|
||||
|
@ -668,10 +745,10 @@ void ScanSettingsWidget::initConnect()
|
|||
{
|
||||
connect(m_scanButton, &QPushButton::clicked, this, &ScanSettingsWidget::scanButtonClickedSlot);
|
||||
connect(GlobalUserSignal::getInstance(), &GlobalUserSignal::scanStart, m_scanButton, &QPushButton::click);
|
||||
|
||||
connect(m_scanButton, &QPushButton::clicked, g_user_signal, &GlobalUserSignal::exitOcrWhenScanSignal);
|
||||
connect(m_deviceComboBox, &QComboBox::currentTextChanged, this, &ScanSettingsWidget::deviceCurrentTextChangedSlot);
|
||||
connect(m_deviceAddButton, &kdk::KPushButton::clicked, this, &ScanSettingsWidget::showWaittingDialogSlot);
|
||||
connect(m_pageNumberComboBox, &QComboBox::currentTextChanged, this, &ScanSettingsWidget::pageNumberCurrentTextChangedSlot);
|
||||
connect(m_timeComboBox, &QComboBox::currentTextChanged, this, &ScanSettingsWidget::timeCurrentTextChangedSlot);
|
||||
connect(m_typeComboBox, &QComboBox::currentTextChanged, this, &ScanSettingsWidget::typeCurrentTextChangedSlot);
|
||||
connect(m_colorComboBox, &QComboBox::currentTextChanged, this, &ScanSettingsWidget::colorCurrentTextChangedSlot);
|
||||
connect(m_resolutionComboBox, &QComboBox::currentTextChanged, this, &ScanSettingsWidget::resolutionCurrentTextChangedSlot);
|
||||
|
@ -723,49 +800,15 @@ void ScanSettingsWidget::rotateChangedSlot(bool isPCMode){
|
|||
m_saveDirectoryButton->setFixedHeight(48);
|
||||
}
|
||||
}
|
||||
void ScanSettingsWidget::showTimeRow()
|
||||
{
|
||||
int countRow = m_settingsFormLayout->rowCount();
|
||||
KyInfo() << "countRow = " << countRow;
|
||||
|
||||
if (countRow == 11) {
|
||||
if (m_timeLabel) {
|
||||
m_timeLabel = new QLabel;
|
||||
setLabelAttributes(m_timeLabel, tr("Time"));
|
||||
}
|
||||
if (m_timeComboBox) {
|
||||
m_timeComboBox = new QComboBox;
|
||||
connect(m_timeComboBox, &QComboBox::currentTextChanged, this, &ScanSettingsWidget::timeCurrentTextChangedSlot);
|
||||
}
|
||||
m_settingsFormLayout->insertRow(3, m_timeLabel, m_timeComboBox);
|
||||
|
||||
updateTimeSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::hideTimeRow()
|
||||
{
|
||||
int countRow = m_settingsFormLayout->rowCount();
|
||||
KyInfo() << "countRow = " << countRow;
|
||||
|
||||
if (countRow == 12) {
|
||||
m_settingsFormLayout->removeRow(3);
|
||||
}
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::updateScanButtonSettings()
|
||||
{
|
||||
bool saneStatus = g_sane_object->getSaneStatus();
|
||||
|
||||
m_scanButton->setEnabled(saneStatus);
|
||||
if(saneStatus == true){
|
||||
// QPalette pe;
|
||||
// pe.setColor(QPalette::Text, Qt::white);
|
||||
// scanButtonRightLabel->setPalette(pe);
|
||||
scanButtonRightLabel->setStyleSheet("color:white;");
|
||||
}else{
|
||||
// QPalette pe;
|
||||
// pe.setColor(QPalette::Text, Qt::gray);
|
||||
// scanButtonRightLabel->setPalette(pe);
|
||||
scanButtonRightLabel->setStyleSheet("color:grey;");
|
||||
}
|
||||
}
|
||||
|
@ -820,23 +863,6 @@ void ScanSettingsWidget::updatePageNumberSettings()
|
|||
setComboboxAttributes(m_pageNumberComboBox, pageNumberStringList);
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::updateTimeSettings()
|
||||
{
|
||||
QStringList timerStringList;
|
||||
|
||||
bool saneStatus = g_sane_object->getSaneStatus();
|
||||
|
||||
timerStringList << tr("3s") << tr("5s") << tr("7s") << tr("10s") << tr("15s");
|
||||
|
||||
KyInfo() << "Timer : " << timerStringList;
|
||||
|
||||
if(!m_timeComboBox->isHidden()){
|
||||
m_timeComboBox->setEnabled(saneStatus);
|
||||
}
|
||||
|
||||
setComboboxAttributes(m_timeComboBox, timerStringList);
|
||||
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::updateTypeSettings()
|
||||
{
|
||||
|
@ -951,9 +977,10 @@ void ScanSettingsWidget::updateFormatSettings()
|
|||
|
||||
bool saneStatus = g_sane_object->getSaneStatus();
|
||||
|
||||
formatStringList << "jpg" << "png" << "pdf" << "bmp";
|
||||
formatStringList << "jpg" << "png" << "pdf" << "bmp" << "tiff";
|
||||
|
||||
m_formatComboBox->setEnabled(saneStatus);
|
||||
|
||||
setComboboxAttributes(m_formatComboBox, formatStringList);
|
||||
|
||||
}
|
||||
|
@ -1030,9 +1057,13 @@ void ScanSettingsWidget::updateSettingsForDetectDevices()
|
|||
updateFormatSettings();
|
||||
updateSaveNameTextSettings();
|
||||
updateSaveDirectorySettings();
|
||||
|
||||
m_sendMailButton->setEnabled(false);
|
||||
m_SaveAsButton->setEnabled(false);
|
||||
if(ThumbnailWidget::scanPictureIsEmpty){
|
||||
m_sendMailButton->setEnabled(false);
|
||||
m_SaveAsButton->setEnabled(false);
|
||||
}else{
|
||||
m_sendMailButton->setEnabled(true);
|
||||
m_SaveAsButton->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::updateSettingsForSwitchDevices()
|
||||
|
@ -1046,18 +1077,19 @@ void ScanSettingsWidget::updateSettingsForSwitchDevices()
|
|||
updateFormatSettings();
|
||||
updateSaveNameTextSettings();
|
||||
updateSaveDirectorySettings();
|
||||
|
||||
// updateSendMailSettings();
|
||||
// updateSaveAsSettings();
|
||||
|
||||
m_sendMailButton->setEnabled(false);
|
||||
m_SaveAsButton->setEnabled(false);
|
||||
if(ThumbnailWidget::scanPictureIsEmpty){
|
||||
m_sendMailButton->setEnabled(false);
|
||||
m_SaveAsButton->setEnabled(false);
|
||||
}else{
|
||||
m_sendMailButton->setEnabled(true);
|
||||
m_SaveAsButton->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ScanSettingsWidget::updateSettingsStatusForStartScan()
|
||||
{
|
||||
m_scanButton->setEnabled(false);
|
||||
// m_deviceComboBox->setEnabled(false);
|
||||
scanButtonRightLabel->setStyleSheet("color:grey;");
|
||||
m_pageNumberComboBox->setEnabled(false);
|
||||
m_typeComboBox->setEnabled(false);
|
||||
m_colorComboBox->setEnabled(false);
|
||||
|
@ -1080,11 +1112,9 @@ void ScanSettingsWidget::updateSettingsStatusForEndScan(int saneStatus)
|
|||
|| saneStatus == SANE_STATUS_CANCELLED) {
|
||||
|
||||
m_scanButton->setEnabled(true);
|
||||
scanButtonRightLabel->setStyleSheet("color:white;");
|
||||
|
||||
m_pageNumberComboBox->setEnabled(true);
|
||||
int countRow = m_settingsFormLayout->rowCount();
|
||||
if (countRow == 12) {
|
||||
m_timeComboBox->setEnabled(true);
|
||||
}
|
||||
m_typeComboBox->setEnabled(true);
|
||||
m_colorComboBox->setEnabled(true);
|
||||
m_resolutionComboBox->setEnabled(true);
|
||||
|
@ -1097,17 +1127,8 @@ void ScanSettingsWidget::updateSettingsStatusForEndScan(int saneStatus)
|
|||
|
||||
} else if (saneStatus == SANE_STATUS_INVAL) {
|
||||
m_scanButton->setEnabled(true);
|
||||
// QPalette pe;
|
||||
// pe.setColor(QPalette::Text, Qt::white);
|
||||
// scanButtonRightLabel->setPalette(pe);
|
||||
scanButtonRightLabel->setStyleSheet("color:white;");
|
||||
m_pageNumberComboBox->setEnabled(true);
|
||||
|
||||
int countRow = m_settingsFormLayout->rowCount();
|
||||
if (countRow == 12) {
|
||||
m_timeComboBox->setEnabled(true);
|
||||
}
|
||||
|
||||
m_typeComboBox->setEnabled(true);
|
||||
m_colorComboBox->setEnabled(true);
|
||||
m_resolutionComboBox->setEnabled(true);
|
||||
|
@ -1127,23 +1148,12 @@ void ScanSettingsWidget::updateSettingsStatusForEndScan(int saneStatus)
|
|||
}
|
||||
m_scanButton->setEnabled(saneStatusBool);
|
||||
if(saneStatusBool == true){
|
||||
// QPalette pe;
|
||||
// pe.setColor(QPalette::Text, Qt::white);
|
||||
// scanButtonRightLabel->setPalette(pe);
|
||||
scanButtonRightLabel->setStyleSheet("color:white;");
|
||||
}else{
|
||||
// QPalette pe;
|
||||
// pe.setColor(QPalette::Text, Qt::gray);
|
||||
// scanButtonRightLabel->setPalette(pe);
|
||||
scanButtonRightLabel->setStyleSheet("color:grey;");
|
||||
}
|
||||
|
||||
m_pageNumberComboBox->setEnabled(saneStatusBool);
|
||||
|
||||
int countRow = m_settingsFormLayout->rowCount();
|
||||
if (countRow == 12) {
|
||||
m_timeComboBox->setEnabled(saneStatusBool);
|
||||
}
|
||||
m_typeComboBox->setEnabled(saneStatusBool);
|
||||
m_colorComboBox->setEnabled(saneStatusBool);
|
||||
m_resolutionComboBox->setEnabled(saneStatusBool);
|
||||
|
@ -1243,7 +1253,6 @@ void ScanSettingsWidget::warnMsg(QString msg)
|
|||
|
||||
msgBox->setText(msg);
|
||||
msgBox->setIcon(QMessageBox::Warning);
|
||||
// msgBox->setWindowIcon(QIcon::fromTheme("kylin-scanner"));
|
||||
msgBox->setWindowTitle(tr("Scanner"));
|
||||
msgBox->setStandardButtons(QMessageBox::Yes);
|
||||
msgBox->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
|
|
|
@ -49,7 +49,10 @@
|
|||
#include <QScrollBar>
|
||||
#include <QSizePolicy>
|
||||
#include "runningdialog.h"
|
||||
|
||||
#include "custom_push_button.h"
|
||||
#include "waittingdialog.h"
|
||||
#include "deviceFinder.h"
|
||||
#include "newdevicelistpage.h"
|
||||
|
||||
class ScanSettingsWidget : public QWidget
|
||||
{
|
||||
|
@ -61,14 +64,10 @@ public:
|
|||
void setupGui();
|
||||
void initConnect();
|
||||
|
||||
void showTimeRow();
|
||||
void hideTimeRow();
|
||||
|
||||
/// update scan settings throught sane api
|
||||
void updateScanButtonSettings();
|
||||
void updateDeviceSettings();
|
||||
void updatePageNumberSettings();
|
||||
void updateTimeSettings();
|
||||
void updateTypeSettings();
|
||||
void updateColorSettings();
|
||||
void updateResolutionSettings(bool DetectedDevices);
|
||||
|
@ -122,77 +121,85 @@ public slots:
|
|||
void nameCurrentTextChangedSlot(QString text);
|
||||
|
||||
void sendMailButtonClickedSlot();
|
||||
void saveAsButtonClickedSlot();
|
||||
void saveAsButtonClickedSlot(bool exitApp = false);
|
||||
|
||||
void scanButtonClickedSlot();
|
||||
|
||||
void fontSizeChanged();
|
||||
void fontSizeChangedSlot();
|
||||
void setDeviceBoxDisableSlot();
|
||||
void showWaittingDialogSlot();
|
||||
private:
|
||||
RunningDialog *m_runningDialog = nullptr;
|
||||
WaittingDialog *m_waittingDialog = nullptr;
|
||||
|
||||
QString currentSaveDirectory;
|
||||
QString currentSaveAsDirectory;
|
||||
|
||||
QLabel *scanButtonLeftLabel;
|
||||
QLabel *scanButtonRightLabel;
|
||||
QHBoxLayout *scanButtonHLayout;
|
||||
QPushButton *m_scanButton;
|
||||
QHBoxLayout *scanButtonCrapLayout;
|
||||
QPushButton *m_scanButton = nullptr;
|
||||
QLabel *scanButtonLeftLabel = nullptr;
|
||||
QLabel *scanButtonRightLabel = nullptr;
|
||||
QHBoxLayout *scanButtonHLayout = nullptr;
|
||||
|
||||
QLabel *m_deviceSettingsLabel;
|
||||
QHBoxLayout *scanButtonCrapLayout = nullptr;
|
||||
|
||||
QLabel *m_deviceLabel;
|
||||
QComboBox *m_deviceComboBox;
|
||||
QLabel *m_deviceSettingsLabel = nullptr;
|
||||
|
||||
QLabel *m_pageNumberLabel;
|
||||
QComboBox *m_pageNumberComboBox;
|
||||
QLabel *m_deviceLabel = nullptr;
|
||||
QComboBox *m_deviceComboBox = nullptr;
|
||||
kdk::KPushButton *m_deviceAddButton = nullptr;
|
||||
QHBoxLayout *m_deviceHLayout = nullptr;
|
||||
QWidget *m_deviceWidget = nullptr;
|
||||
|
||||
QLabel *m_timeLabel;
|
||||
QComboBox *m_timeComboBox;
|
||||
QLabel *m_pageNumberLabel = nullptr;
|
||||
QComboBox *m_pageNumberComboBox = nullptr;
|
||||
|
||||
QLabel *m_typeLabel;
|
||||
QComboBox *m_typeComboBox;
|
||||
QLabel *m_typeLabel = nullptr;
|
||||
QComboBox *m_typeComboBox = nullptr;
|
||||
|
||||
QLabel *m_colorLabel;
|
||||
QComboBox *m_colorComboBox;
|
||||
QLabel *m_colorLabel = nullptr;
|
||||
QComboBox *m_colorComboBox = nullptr;
|
||||
|
||||
QLabel *m_resolutionLabel;
|
||||
QComboBox *m_resolutionComboBox;
|
||||
QLabel *m_resolutionLabel = nullptr;
|
||||
QComboBox *m_resolutionComboBox = nullptr;
|
||||
|
||||
QLabel *m_fileSettingsLabel;
|
||||
QLabel *m_fileSettingsLabel = nullptr;
|
||||
|
||||
QLabel *m_sizeLabel;
|
||||
QComboBox *m_sizeComboBox;
|
||||
QLabel *m_sizeLabel = nullptr;
|
||||
QComboBox *m_sizeComboBox = nullptr;
|
||||
|
||||
QLabel *m_formatLabel;
|
||||
QComboBox *m_formatComboBox;
|
||||
QLabel *m_formatLabel = nullptr;
|
||||
QComboBox *m_formatComboBox = nullptr;
|
||||
|
||||
QLabel *m_saveNameLabel;
|
||||
QLineEdit *m_saveNameEdit;
|
||||
QLabel *m_saveNameLabel = nullptr;
|
||||
QLineEdit *m_saveNameEdit = nullptr;
|
||||
|
||||
QLabel *m_saveDirectoryLabel;
|
||||
QLabel *m_saveDirectoryButtonLabel;
|
||||
QHBoxLayout *m_saveDirectoryButtonLayout;
|
||||
QLineEdit *m_saveDirectoryButton;
|
||||
QLabel *m_saveDirectoryLabel = nullptr;
|
||||
QLabel *m_saveDirectoryButtonLabel = nullptr;
|
||||
QHBoxLayout *m_saveDirectoryButtonLayout = nullptr;
|
||||
QLineEdit *m_saveDirectoryButton = nullptr;
|
||||
|
||||
QFormLayout *m_settingsFormLayout;
|
||||
QFormLayout *m_settingsFormLayout = nullptr;
|
||||
|
||||
QPushButton *m_sendMailButton;
|
||||
QPushButton *m_SaveAsButton;
|
||||
QHBoxLayout *m_buttonsHLayout;
|
||||
CustomPushButton *m_sendMailButton = nullptr;
|
||||
CustomPushButton *m_SaveAsButton = nullptr;
|
||||
QHBoxLayout *m_buttonsHLayout = nullptr;
|
||||
|
||||
QScrollArea *m_mainScrollArea;
|
||||
|
||||
QVBoxLayout *m_mainVLayout;
|
||||
QVBoxLayout *m_mainVLayout = nullptr;
|
||||
|
||||
QGSettings *m_themeData = nullptr;
|
||||
|
||||
SendMailDialog *dialog = nullptr;
|
||||
deviceFinder *m_devFinder = nullptr;
|
||||
QList<DeviceInformation> m_noDriverDevices;
|
||||
newDeviceListPage *m_deviceListPage = nullptr;
|
||||
|
||||
bool isDarkTheme();
|
||||
bool showRunningDialog();
|
||||
private slots:
|
||||
void initTheme();
|
||||
void setScanIconDisable();
|
||||
void showNewDeviceListPageSuccessSlot();
|
||||
void showNewDeviceListPageFailSlot();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -15,25 +15,26 @@
|
|||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
|
||||
#include "sendmail.h"
|
||||
#include <kylin_system/window_management.hpp>
|
||||
#include "kabase/Qt/windowmanage.hpp"
|
||||
#include "Qt/windowmanage.hpp"
|
||||
|
||||
NoMailDialog::NoMailDialog(QWidget *parent) : QDialog(parent)
|
||||
, m_noMailTitleTextLabel (new QLabel())
|
||||
, m_noMailCloseButton (new QPushButton())
|
||||
, m_noMailTitleHBoxLayout (new QHBoxLayout())
|
||||
, m_noMaillogoLabel (new QLabel())
|
||||
, m_noMailtitleLabel (new QLabel())
|
||||
, m_noMailLogoTitleHBoxLayout (new QHBoxLayout())
|
||||
, m_noMailInfoLabel (new QLabel())
|
||||
, m_noMailInfoLabel (new QTextBrowser())
|
||||
, m_noMailInfoHBoxLayout (new QHBoxLayout())
|
||||
, m_cancelButton (new QPushButton())
|
||||
, m_installButton (new QPushButton())
|
||||
, m_cancelButton (new kdk::KPushButton())
|
||||
, m_installButton (new kdk::KPushButton())
|
||||
, m_noMailButtonsHBoxLayout (new QHBoxLayout())
|
||||
, m_mainVBoxLayout (new QVBoxLayout())
|
||||
{
|
||||
m_themeData = new QGSettings(UKUI_THEME_GSETTING_PATH);
|
||||
|
||||
initWindow();
|
||||
|
||||
initLayout();
|
||||
|
@ -48,16 +49,14 @@ NoMailDialog::~NoMailDialog()
|
|||
|
||||
void NoMailDialog::initWindow()
|
||||
{
|
||||
::kabase::WindowManage::removeHeader(this);
|
||||
kabase::WindowManage::removeHeader(this);
|
||||
|
||||
setWindowTitle (tr("No email client"));
|
||||
setWindowTitle(tr("No email client"));
|
||||
setFixedSize(NoMailWindowWidth, NoMainWindowHeight);
|
||||
}
|
||||
|
||||
void NoMailDialog::initLayout()
|
||||
{
|
||||
m_noMailTitleTextLabel->setText(tr("Scanner"));
|
||||
|
||||
m_noMailCloseButton->setIcon (QIcon::fromTheme (ICON_THEME_CLOSE));
|
||||
m_noMailCloseButton->setToolTip(tr("Close"));
|
||||
m_noMailCloseButton->setFixedSize(30, 30);
|
||||
|
@ -66,9 +65,6 @@ void NoMailDialog::initLayout()
|
|||
m_noMailCloseButton->setProperty("useIconHighlightEffect", 0x8);
|
||||
m_noMailCloseButton->setFlat(true);
|
||||
|
||||
m_noMailTitleHBoxLayout->setSpacing(0);
|
||||
m_noMailTitleHBoxLayout->addSpacing(12);
|
||||
m_noMailTitleHBoxLayout->addWidget(m_noMailTitleTextLabel);
|
||||
m_noMailTitleHBoxLayout->addStretch();
|
||||
m_noMailTitleHBoxLayout->addWidget(m_noMailCloseButton);
|
||||
m_noMailTitleHBoxLayout->setAlignment(Qt::AlignCenter);
|
||||
|
@ -78,58 +74,47 @@ void NoMailDialog::initLayout()
|
|||
m_noMaillogoLabel->setFixedSize(QSize(24, 24));
|
||||
m_noMaillogoLabel->setPixmap(pix);
|
||||
|
||||
QFont ft;
|
||||
ft.setPixelSize(14);
|
||||
ft.setBold(true);
|
||||
m_noMailtitleLabel->setFont(ft);
|
||||
m_noMailtitleLabel->setText(tr("No email client"));
|
||||
m_noMailtitleLabel->setToolTip(tr("No email client"));
|
||||
m_noMailtitleLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
m_noMailLogoTitleHBoxLayout->setSpacing(0);
|
||||
m_noMailLogoTitleHBoxLayout->addSpacing(24);
|
||||
m_noMailLogoTitleHBoxLayout->addSpacing(20);
|
||||
m_noMailLogoTitleHBoxLayout->addWidget(m_noMaillogoLabel);
|
||||
m_noMailLogoTitleHBoxLayout->addSpacing(8);
|
||||
m_noMailLogoTitleHBoxLayout->addWidget(m_noMailtitleLabel);
|
||||
m_noMailLogoTitleHBoxLayout->addStretch();
|
||||
m_noMailLogoTitleHBoxLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
QFont ft1;
|
||||
ft1.setPixelSize(14);
|
||||
m_noMailInfoLabel->setFont(ft1);
|
||||
m_noMailInfoLabel->setText(tr("Not find email client in the system, please install email client firstly."));
|
||||
m_noMailInfoLabel->setFixedSize(QSize(296, 44));
|
||||
m_noMailInfoLabel->setWordWrap(true);
|
||||
m_noMailInfoLabel->setFixedSize(QSize(296, 70));
|
||||
m_noMailInfoLabel->setFrameShape(QTextBrowser::NoFrame);
|
||||
m_noMailInfoLabel->setStyleSheet(".QTextBrowser{background:transparent;}");
|
||||
|
||||
|
||||
m_noMailInfoHBoxLayout->setSpacing(0);
|
||||
m_noMailInfoHBoxLayout->addSpacing(56);
|
||||
m_noMailInfoHBoxLayout->addSpacing(40);
|
||||
m_noMailInfoHBoxLayout->addWidget(m_noMailInfoLabel);
|
||||
m_noMailInfoHBoxLayout->addSpacing(28);
|
||||
m_noMailInfoHBoxLayout->addSpacing(18);
|
||||
m_noMailInfoHBoxLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
|
||||
|
||||
m_cancelButton->setText(tr("Cancel"));
|
||||
m_cancelButton->setToolTip(tr("Cancel"));
|
||||
m_cancelButton->setFixedSize(96, 36);
|
||||
|
||||
m_cancelButton->setMinimumSize(96, 36);
|
||||
m_installButton->setText(tr("Install"));
|
||||
m_installButton->setToolTip(tr("Install"));
|
||||
m_installButton->setFixedSize(96, 36);
|
||||
|
||||
m_installButton->setFocus();
|
||||
m_installButton->setDefault(true);
|
||||
m_installButton->setStyleSheet("color:white;");
|
||||
m_installButton->setMinimumSize(96, 36);
|
||||
m_installButton->setBackgroundColorHighlight(true);
|
||||
|
||||
m_noMailButtonsHBoxLayout->setSpacing(0);
|
||||
m_noMailButtonsHBoxLayout->addSpacing(152);
|
||||
m_noMailButtonsHBoxLayout->addWidget(m_cancelButton);
|
||||
m_noMailButtonsHBoxLayout->addSpacing(12);
|
||||
m_noMailButtonsHBoxLayout->addWidget(m_installButton);
|
||||
m_noMailButtonsHBoxLayout->setAlignment(Qt::AlignRight);
|
||||
m_noMailButtonsHBoxLayout->setContentsMargins(0, 0, 24, 24);
|
||||
|
||||
m_mainVBoxLayout->setSpacing(0);
|
||||
m_mainVBoxLayout->addLayout(m_noMailTitleHBoxLayout);
|
||||
m_mainVBoxLayout->addSpacing(16);
|
||||
m_mainVBoxLayout->addSpacing(5);
|
||||
m_mainVBoxLayout->addLayout(m_noMailLogoTitleHBoxLayout);
|
||||
m_mainVBoxLayout->addSpacing(8);
|
||||
m_mainVBoxLayout->addLayout(m_noMailInfoHBoxLayout);
|
||||
|
@ -144,22 +129,7 @@ void NoMailDialog::initConnect()
|
|||
connect(m_installButton, &QPushButton::clicked, this, &NoMailDialog::accept);
|
||||
connect(m_cancelButton, &QPushButton::clicked, this, &NoMailDialog::closeNoMailWindow);
|
||||
connect(m_noMailCloseButton, &QPushButton::clicked, this, &NoMailDialog::closeNoMailWindow);
|
||||
}
|
||||
|
||||
void NoMailDialog::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
QPainterPath rectPath;
|
||||
rectPath.addRoundedRect(this->rect(), 0, 0);
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
|
||||
QColor mainColor;
|
||||
mainColor = opt.palette.color(QPalette::Window);
|
||||
|
||||
p.fillPath(rectPath,QBrush(mainColor));
|
||||
connect(m_themeData, &QGSettings::changed, this, &NoMailDialog::fontSizeChangedSlot);
|
||||
}
|
||||
|
||||
|
||||
|
@ -189,6 +159,15 @@ void NoMailDialog::closeNoMailWindow()
|
|||
// emit noMailWindowClose();
|
||||
}
|
||||
|
||||
void NoMailDialog::fontSizeChangedSlot()
|
||||
{
|
||||
float systemFontSize = kdk::GsettingMonitor::getSystemFontSize().toFloat();
|
||||
QString fontType = m_themeData->get("systemFont").toString();
|
||||
QFont font(fontType, systemFontSize);
|
||||
m_noMailInfoLabel->setFont(font);
|
||||
m_installButton->setFont(font);
|
||||
}
|
||||
|
||||
SendMailDialog::SendMailDialog(QWidget *parent) : QDialog(parent)
|
||||
, m_titleTextLabel(new QLabel())
|
||||
, m_closeButton (new QPushButton())
|
||||
|
@ -196,8 +175,8 @@ SendMailDialog::SendMailDialog(QWidget *parent) : QDialog(parent)
|
|||
, m_mailSelectLabel (new QLabel())
|
||||
, m_mailSelectCombobox (new QComboBox())
|
||||
, m_mailSelectHBoxLayout (new QHBoxLayout())
|
||||
, m_cancelButton (new QPushButton())
|
||||
, m_confirmButton (new QPushButton())
|
||||
, m_cancelButton (new CustomPushButton())
|
||||
, m_confirmButton (new CustomPushButton())
|
||||
, m_buttonsHBoxLayout (new QHBoxLayout)
|
||||
, m_mainVBoxLayout (new QVBoxLayout())
|
||||
{
|
||||
|
@ -215,7 +194,7 @@ SendMailDialog::~SendMailDialog()
|
|||
|
||||
void SendMailDialog::initWindow()
|
||||
{
|
||||
::kabase::WindowManage::removeHeader(this);
|
||||
kabase::WindowManage::removeHeader(this);
|
||||
|
||||
setWindowTitle (tr("Select email client"));
|
||||
setFixedSize(SendMailWindowWidth, SendMainWindowHeight);
|
||||
|
@ -405,6 +384,7 @@ void SendMailDialog::paintEvent(QPaintEvent *event)
|
|||
mainColor = opt.palette.color(QPalette::Window);
|
||||
|
||||
p.fillPath(rectPath,QBrush(mainColor));
|
||||
p.end();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,14 +41,14 @@
|
|||
#include <QFileInfo>
|
||||
#include <QFileIconProvider>
|
||||
#include <qmath.h>
|
||||
|
||||
#include <QTextBrowser>
|
||||
#include <ukui-log4qt.h>
|
||||
|
||||
#include "utils/xatom-helper.h"
|
||||
#include "globalsignal.h"
|
||||
#include "include/common.h"
|
||||
#include "include/theme.h"
|
||||
|
||||
#include "custom_push_button.h"
|
||||
#ifdef signals
|
||||
#undef signals
|
||||
#endif
|
||||
|
@ -67,6 +67,7 @@ extern "C" {
|
|||
|
||||
#define SendMailWindowWidth 380
|
||||
#define SendMainWindowHeight 176
|
||||
#define UKUI_THEME_GSETTING_PATH "org.ukui.style"
|
||||
|
||||
|
||||
typedef struct _Applist {
|
||||
|
@ -90,26 +91,23 @@ public:
|
|||
void initLayout();
|
||||
void initConnect();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QLabel *m_noMailTitleTextLabel;
|
||||
QPushButton *m_noMailCloseButton;
|
||||
QHBoxLayout *m_noMailTitleHBoxLayout;
|
||||
QPushButton *m_noMailCloseButton = nullptr;
|
||||
QHBoxLayout *m_noMailTitleHBoxLayout = nullptr;
|
||||
|
||||
QLabel *m_noMaillogoLabel;
|
||||
QLabel *m_noMailtitleLabel;
|
||||
QHBoxLayout *m_noMailLogoTitleHBoxLayout;
|
||||
QLabel *m_noMaillogoLabel = nullptr;
|
||||
QLabel *m_noMailtitleLabel = nullptr;
|
||||
QHBoxLayout *m_noMailLogoTitleHBoxLayout = nullptr;
|
||||
|
||||
QLabel *m_noMailInfoLabel;
|
||||
QHBoxLayout *m_noMailInfoHBoxLayout;
|
||||
QTextBrowser *m_noMailInfoLabel = nullptr;
|
||||
QHBoxLayout *m_noMailInfoHBoxLayout = nullptr;
|
||||
|
||||
QPushButton *m_cancelButton;
|
||||
QPushButton *m_installButton;
|
||||
QHBoxLayout *m_noMailButtonsHBoxLayout;
|
||||
kdk::KPushButton *m_cancelButton = nullptr;
|
||||
kdk::KPushButton *m_installButton = nullptr;
|
||||
QHBoxLayout *m_noMailButtonsHBoxLayout = nullptr;
|
||||
|
||||
QVBoxLayout *m_mainVBoxLayout;
|
||||
QVBoxLayout *m_mainVBoxLayout = nullptr;
|
||||
QGSettings *m_themeData = nullptr;
|
||||
|
||||
Q_SIGNALS:
|
||||
void noMailWindowClose();
|
||||
|
@ -120,6 +118,7 @@ private slots:
|
|||
void themeChangedBlack();
|
||||
|
||||
void closeNoMailWindow();
|
||||
void fontSizeChangedSlot();
|
||||
};
|
||||
|
||||
class SendMailDialog : public QDialog
|
||||
|
@ -140,19 +139,19 @@ protected:
|
|||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QLabel *m_titleTextLabel;
|
||||
QPushButton *m_closeButton;
|
||||
QHBoxLayout *m_titleHBoxLayout;
|
||||
QLabel *m_titleTextLabel = nullptr;
|
||||
QPushButton *m_closeButton = nullptr;
|
||||
QHBoxLayout *m_titleHBoxLayout = nullptr;
|
||||
|
||||
QLabel *m_mailSelectLabel;
|
||||
QComboBox *m_mailSelectCombobox;
|
||||
QHBoxLayout *m_mailSelectHBoxLayout;
|
||||
QLabel *m_mailSelectLabel = nullptr;
|
||||
QComboBox *m_mailSelectCombobox = nullptr;
|
||||
QHBoxLayout *m_mailSelectHBoxLayout = nullptr;
|
||||
|
||||
QPushButton *m_cancelButton;
|
||||
QPushButton *m_confirmButton;
|
||||
QHBoxLayout *m_buttonsHBoxLayout;
|
||||
CustomPushButton *m_cancelButton = nullptr;
|
||||
CustomPushButton *m_confirmButton = nullptr;
|
||||
QHBoxLayout *m_buttonsHBoxLayout = nullptr;
|
||||
|
||||
QVBoxLayout *m_mainVBoxLayout;
|
||||
QVBoxLayout *m_mainVBoxLayout = nullptr;
|
||||
|
||||
QList<QString> m_desktopName;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <ukui-log4qt.h>
|
||||
#include <KWindowEffects>
|
||||
#include <gsettings.hpp>
|
||||
#include <kysdk/applications/gsettingmonitor.h>
|
||||
#include "utils/copyoperation.h"
|
||||
#include "imageOp/imageoperationbeauty.h"
|
||||
#include "imageOp/imageoperationmirror.h"
|
||||
|
@ -10,8 +11,6 @@
|
|||
#include "imageOp/imageoperationwatermark.h"
|
||||
#include "imageOp/imageoperationrotate.h"
|
||||
|
||||
|
||||
|
||||
ShowImageWidget::ShowImageWidget(QWidget *parent) : QWidget(parent)
|
||||
, m_stackImage (new QImage())
|
||||
, m_editImage (new QImage())
|
||||
|
@ -27,6 +26,7 @@ ShowImageWidget::ShowImageWidget(QWidget *parent) : QWidget(parent)
|
|||
, m_toolbarWidget (new ToolBarWidget())
|
||||
, m_mainVLayout (new QVBoxLayout())
|
||||
, scannerImagePath(g_config_signal->m_scannerImagePath)
|
||||
, m_navigator(new Navigator(this))
|
||||
{
|
||||
loadImg = new LoadImage;
|
||||
loadImg->moveToThread(&loadImgOP);
|
||||
|
@ -55,7 +55,7 @@ void ShowImageWidget::setupGui()
|
|||
|
||||
m_okButton->setFixedSize(QSize(20, 20));
|
||||
m_okButton->setIconSize(QSize(20, 20));
|
||||
m_okButton->setToolTip(tr("Cancel"));
|
||||
m_okButton->setToolTip(tr("Ok"));
|
||||
m_okButton->setFocusPolicy(Qt::NoFocus);
|
||||
m_okButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; border-image:url(:/ok-button.png);}"
|
||||
"QPushButton::hover{border:0px; border-radius: 6px; background:transparent; border-image:url(:/ok-button-hover.png);}"
|
||||
|
@ -107,13 +107,12 @@ void ShowImageWidget::setupGui()
|
|||
m_loadingMovie = new QMovie(":/loadgif.gif");
|
||||
|
||||
this->setLayout(m_mainVLayout);
|
||||
// drawShadow();
|
||||
themeChangedSlot();
|
||||
m_navigator->move(this->width() - 7 - m_navigator->width(), this->height() - 52 - m_navigator->height());
|
||||
m_navigator->hide();
|
||||
}
|
||||
|
||||
void ShowImageWidget::initConnect()
|
||||
{
|
||||
connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &ShowImageWidget::themeChangedSlot);
|
||||
connect(g_user_signal, &GlobalUserSignal::scanThreadFinishedImageLoadSignal, this, &ShowImageWidget::showNormalImageAfterScan, Qt::QueuedConnection);
|
||||
|
||||
connect(g_user_signal, &GlobalUserSignal::showImageAfterClickedThumbnailSignal, this, &ShowImageWidget::showImageAfterClickedThumbnail);
|
||||
|
@ -136,14 +135,19 @@ void ShowImageWidget::initConnect()
|
|||
|
||||
connect(g_user_signal, &GlobalUserSignal::toolbarOcrOperationStartSignal, this, &ShowImageWidget::ocrStartSlot);
|
||||
|
||||
//connect(g_user_signal,&GlobalUserSignal::cropOpSig,this,&ShowImageWidget::cropOp);
|
||||
//connect(g_user_signal,&GlobalUserSignal::rollBackOperationSig,this,&ShowImageWidget::rollBackOperation);
|
||||
|
||||
connect(g_user_signal, &GlobalUserSignal::cancleCorpSignal, m_cancelButton, &QPushButton::click);
|
||||
connect(m_cancelButton, &QPushButton::clicked, this, &ShowImageWidget::cropCancelSlot);
|
||||
connect(m_okButton, &QPushButton::clicked, this, &ShowImageWidget::cropCompleteSlot);
|
||||
|
||||
connect(m_cropLabel, &CropLabel::paintCompleteSignal, this, &ShowImageWidget::setCancelWidgetPositon);
|
||||
connect(m_cropLabel, &CropLabel::hideCancelOkWidget, this, [=](){m_cancelOkWidget->hide();});
|
||||
|
||||
connect(this, &ShowImageWidget::showNavigation, m_navigator, &Navigator::showNavigation);
|
||||
connect(m_navigator, &Navigator::naviChange, this, &ShowImageWidget::naviChange);
|
||||
connect(this, &ShowImageWidget::sendHightlightPos, m_navigator, &Navigator::getHighLightRegion);
|
||||
connect(g_user_signal, &GlobalUserSignal::posChange, this, &ShowImageWidget::clickNavigation);
|
||||
connect(g_user_signal, &GlobalUserSignal::resetNavigatorsignal, this, &ShowImageWidget::resetNavigator);
|
||||
|
||||
}
|
||||
|
||||
constexpr inline int U(const char *str)
|
||||
|
@ -221,6 +225,7 @@ void ShowImageWidget::saveToPdf(QImage img, QString pathname)
|
|||
QPixmap pixmap = QPixmap::fromImage(img);
|
||||
pdfPainter->drawPixmap(xCurrentP, yCurrentP, pixmap.width(), pixmap.height(), pixmap);
|
||||
|
||||
pdfPainter->end();
|
||||
delete pdfPainter;
|
||||
delete pdfWriter;
|
||||
pdfFile.close();
|
||||
|
@ -283,11 +288,80 @@ QString ShowImageWidget::setPixmapScaled(QImage img, QLabel *lab, double scale)
|
|||
|
||||
}
|
||||
|
||||
|
||||
proportionForPercentage = proportion;
|
||||
|
||||
QPixmap pixmap = QPixmap::fromImage(img);
|
||||
QPixmap fitpixmap = resizePix(pixmap, img.size()*proportion);
|
||||
m_nowImage = pixmap;
|
||||
QPixmap fitpixmap = pixmap.scaled(img.size()*proportion, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
if(fitpixmap.width() > labWidth || fitpixmap.height() > labHeight){
|
||||
createNavigation();
|
||||
|
||||
int proportionInt = qRound(proportionForPercentage * 100);
|
||||
QString proportionString = QString("%1").arg(proportionInt) + "%";
|
||||
|
||||
return proportionString;
|
||||
}else{
|
||||
lab->setPixmap(fitpixmap);
|
||||
lab->setFixedSize(QSize(fitpixmap.size()));
|
||||
lab->setScaledContents(true);
|
||||
lab->setAlignment(Qt::AlignCenter | Qt::AlignCenter | Qt::AlignCenter);
|
||||
m_navigator->hide();
|
||||
|
||||
KyInfo() << "proportion: " << proportion << "proportionForPercentage: " << proportionForPercentage;
|
||||
|
||||
int proportionInt = qRound(proportionForPercentage * 100);
|
||||
|
||||
KyInfo() << "proportionInt: " << proportionInt;
|
||||
QString proportionString = QString("%1").arg(proportionInt) + "%";
|
||||
|
||||
KyInfo() << "proportionString: " << proportionString;
|
||||
g_sane_object->percentage = proportionString;
|
||||
|
||||
g_user_signal->toolbarPercentageChanged();
|
||||
|
||||
return proportionString;
|
||||
}
|
||||
}
|
||||
|
||||
QString ShowImageWidget::setCropPixmapScaled(QImage img, QLabel *lab, double scale)
|
||||
{
|
||||
if (img.isNull()) {
|
||||
KyWarning() << "image is null.";
|
||||
return "";
|
||||
}
|
||||
double labWidth = this->width() - 2*ShowImageWidgetSpacing - AddWidthForLargeFontSize;
|
||||
double labHeight = this->height() - 24 -24 - 36 -16;
|
||||
|
||||
double imgWidth = defaultScanImageSize.width();
|
||||
double imgHeight = defaultScanImageSize.height();
|
||||
|
||||
if(rotationFlag){
|
||||
std::swap(imgWidth,imgHeight);
|
||||
}
|
||||
|
||||
qDebug() << "label size: " << lab->size()
|
||||
<< "this size: " << this->size()
|
||||
<< "this labsize: " << labWidth << labHeight
|
||||
<< "defaultImage size: " << defaultScanImageSize
|
||||
<< "scale: " << scale
|
||||
<< "image size: " << img.size();
|
||||
|
||||
if (! qFuzzyCompare(scale, 1.0)) {
|
||||
proportion = scale;
|
||||
} else {
|
||||
if ((labWidth / imgWidth) <= (labHeight / imgHeight)) {
|
||||
proportion = labWidth / imgWidth;
|
||||
} else {
|
||||
proportion = labHeight / imgHeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
proportionForPercentage = proportion;
|
||||
|
||||
QPixmap pixmap = QPixmap::fromImage(img);
|
||||
QPixmap fitpixmap = pixmap.scaled(img.size()*proportion, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
lab->setPixmap(fitpixmap);
|
||||
lab->setFixedSize(QSize(fitpixmap.size()));
|
||||
|
@ -309,7 +383,92 @@ QString ShowImageWidget::setPixmapScaled(QImage img, QLabel *lab, double scale)
|
|||
|
||||
g_user_signal->toolbarPercentageChanged();
|
||||
|
||||
return proportionString;
|
||||
return proportionString;
|
||||
|
||||
}
|
||||
|
||||
QImage ShowImageWidget::pictureDeepen(const QImage &img, const QSize &hightlightSize, const QPoint &point)
|
||||
{
|
||||
QImage image = img.copy();
|
||||
int key = 50;
|
||||
int left = point.x();
|
||||
int right = point.x() + hightlightSize.width();
|
||||
int top = point.y();
|
||||
//边界值限定
|
||||
int bottom = point.y() + hightlightSize.height();
|
||||
right = boundaryJudg(img.width(), right);
|
||||
bottom = boundaryJudg(img.height(), bottom);
|
||||
//如果有透明通道
|
||||
bool hasAlpha = false;
|
||||
if (image.format() == QImage::Format_ARGB32 || image.format() == QImage::Format_ARGB32_Premultiplied) {
|
||||
hasAlpha = true;
|
||||
}
|
||||
|
||||
for (int j = 0; j < image.height(); ++j) {
|
||||
for (int i = 0; i < image.width(); ++i) {
|
||||
if (i >= left && i < right && j >= top && j < bottom) {
|
||||
continue; //高亮区域不处理
|
||||
}
|
||||
QColor color(image.pixel(i, j));
|
||||
if (hasAlpha && color.red() + color.green() + color.blue() == 0) { //透明区域40%透明度的黑色
|
||||
color.setAlphaF(0.4);
|
||||
image.setPixel(i, j, color.rgba());
|
||||
continue;
|
||||
}
|
||||
color.setRed(minNumIsZero(color.red(), key));
|
||||
color.setGreen(minNumIsZero(color.green(), key));
|
||||
color.setBlue(minNumIsZero(color.blue(), key));
|
||||
image.setPixel(i, j, color.rgb());
|
||||
}
|
||||
}
|
||||
//绘制边框-画内边界
|
||||
for (int i = left; i < right; ++i) {
|
||||
i = boundaryJudg(right, i);
|
||||
QColor colorDown(img.pixel(i, top));
|
||||
colorDown.setRed(255);
|
||||
colorDown.setGreen(255);
|
||||
colorDown.setBlue(255);
|
||||
image.setPixel(i, top, colorDown.rgb());
|
||||
QColor colorTop(img.pixel(i, bottom - 1));
|
||||
colorTop.setRed(255);
|
||||
colorTop.setGreen(255);
|
||||
colorTop.setBlue(255);
|
||||
image.setPixel(i, bottom - 1, colorTop.rgb());
|
||||
}
|
||||
for (int k = top; k < bottom; ++k) {
|
||||
k = boundaryJudg(bottom, k);
|
||||
QColor colorLeft(img.pixel(left, k));
|
||||
colorLeft.setRed(255);
|
||||
colorLeft.setGreen(255);
|
||||
colorLeft.setBlue(255);
|
||||
image.setPixel(left, k, colorLeft.rgb());
|
||||
QColor colorRight(img.pixel(right - 1, k));
|
||||
colorRight.setRed(255);
|
||||
colorRight.setGreen(255);
|
||||
colorRight.setBlue(255);
|
||||
image.setPixel(right - 1, k, colorRight.rgb());
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
int ShowImageWidget::boundaryJudg(int max, int point)
|
||||
{
|
||||
if (point < 0) {
|
||||
point = 0;
|
||||
}
|
||||
if (point > max) {
|
||||
point = max;
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
int ShowImageWidget::minNumIsZero(const int &num1, const int &num2)
|
||||
{
|
||||
int num = num1 - num2;
|
||||
if (num < 0) {
|
||||
return 0;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
void ShowImageWidget::setPixmapScaledByProportion(double scaledNumber)
|
||||
|
@ -428,10 +587,10 @@ void ShowImageWidget::rollBackOperation(){
|
|||
|
||||
if (m_showImageAndCropWidget->currentWidget() == m_cropLabel) {
|
||||
*m_editImage = m_imageStack.pop();
|
||||
setPixmapScaled(*m_editImage, m_cropLabel);
|
||||
setCropPixmapScaled(*m_editImage, m_cropLabel);
|
||||
|
||||
*m_normalImage = m_editImage->copy();
|
||||
setPixmapScaled(*m_normalImage, m_showImageLabel);
|
||||
setCropPixmapScaled(*m_normalImage, m_showImageLabel);
|
||||
|
||||
m_showImageAndCropWidget->setCurrentWidget(m_labelWidget);
|
||||
g_sane_object->cropFlag = 0;
|
||||
|
@ -441,10 +600,14 @@ void ShowImageWidget::rollBackOperation(){
|
|||
|
||||
*m_normalImage = m_editImage->copy();
|
||||
setPixmapScaled(*m_normalImage, m_showImageLabel);
|
||||
|
||||
m_showImageAndCropWidget->setCurrentWidget(m_showImageLabel);
|
||||
g_sane_object->cropFlag = 0;
|
||||
}
|
||||
}
|
||||
if(m_imageStack.isEmpty()){
|
||||
g_user_signal->exitWindowWithSaveFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowImageWidget::keyPressEvent(QKeyEvent *event)
|
||||
|
@ -484,17 +647,6 @@ void ShowImageWidget::keyPressEvent(QKeyEvent *event)
|
|||
m_cancelOkWidget->hide();
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Escape:
|
||||
// KyInfo() << "pressed key(Esc): " << event->key();
|
||||
// if (! m_imageStack.isEmpty()) {
|
||||
// *m_editImage = m_imageStack.pop();
|
||||
// setPixmapScaled(*m_editImage, m_showImageLabel);
|
||||
|
||||
// *m_normalImage = m_editImage->copy();
|
||||
// setPixmapScaled(*m_normalImage, m_showImageLabel);
|
||||
// }
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
KyInfo() << "pressed key: " << event->key();
|
||||
|
@ -543,10 +695,6 @@ void ShowImageWidget::showNormalImageAfterScan(QStringList loadFileName, QString
|
|||
}
|
||||
}
|
||||
|
||||
QPixmap ShowImageWidget::resizePix(const QPixmap &pixmap, const QSize &size)
|
||||
{
|
||||
return pixmap.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
void ShowImageWidget::imageNUll(bool res)
|
||||
{
|
||||
if (res) {
|
||||
|
@ -565,7 +713,10 @@ void ShowImageWidget::imageNUll(bool res)
|
|||
void ShowImageWidget::setCancelWidgetPositon()
|
||||
{
|
||||
m_cancelOkWidget->show();
|
||||
m_cancelOkWidget->move(int(this->width() / 2 - ThumbnailWidgetMinimumWidth + 16), m_showImageLabel->height());
|
||||
qDebug() << "this height: " << this->height();
|
||||
qDebug() << "m_showImageLabel height: " << m_showImageLabel->height();
|
||||
|
||||
m_cancelOkWidget->move(int(this->width() / 2 - ThumbnailWidgetMinimumWidth + 16), (this->height()-150));
|
||||
}
|
||||
|
||||
void ShowImageWidget::drawShadow()
|
||||
|
@ -576,6 +727,110 @@ void ShowImageWidget::drawShadow()
|
|||
effect->setBlurRadius(8); //设定阴影的模糊半径,数值越大越模糊
|
||||
m_cancelOkWidget->setGraphicsEffect(effect);
|
||||
}
|
||||
|
||||
void ShowImageWidget::createNavigation()
|
||||
{
|
||||
// 缩略图大小
|
||||
QSize navigationSize = QSize(130, 133);
|
||||
m_navigationImage = m_nowImage.scaled(navigationSize, Qt::KeepAspectRatio, Qt::SmoothTransformation).toImage();
|
||||
|
||||
//记录空白区域
|
||||
m_spaceWidth = (navigationSize.width() - m_navigationImage.width()) / 2;
|
||||
m_spaceHeight = (navigationSize.height() - m_navigationImage.height()) / 2;
|
||||
|
||||
//待显示图
|
||||
m_tmpSize = m_nowImage.size() * qRound(proportionForPercentage * 100) / 100;
|
||||
|
||||
double labWidth = this->width() - 2*ShowImageWidgetSpacing - AddWidthForLargeFontSize;
|
||||
double labHeight = this->height() - 24 -24 - 36 -16;
|
||||
|
||||
//高亮区域大小
|
||||
m_hightlightSize.setWidth(m_navigationImage.width() * labWidth / m_tmpSize.width());
|
||||
m_hightlightSize.setHeight(m_navigationImage.height() * labHeight / m_tmpSize.height());
|
||||
if (m_hightlightSize.width() > m_navigationImage.width()) {
|
||||
m_hightlightSize.setWidth(m_navigationImage.width());
|
||||
}
|
||||
if (m_hightlightSize.height() > m_navigationImage.height()) {
|
||||
m_hightlightSize.setHeight(m_navigationImage.height());
|
||||
}
|
||||
|
||||
clickNavigation(m_clickBeforePosition);
|
||||
}
|
||||
|
||||
void ShowImageWidget::clickNavigation(const QPoint &point)
|
||||
{
|
||||
bool hasArg = true;
|
||||
//无参输入则使用上次的位置
|
||||
if (point == QPoint(-1, -1)) {
|
||||
hasArg = false;
|
||||
}
|
||||
//有参则记录,无参使用上一次的点
|
||||
if (hasArg) {
|
||||
m_clickBeforePosition = point;
|
||||
}
|
||||
|
||||
QPoint startPoint(m_clickBeforePosition.x() - m_hightlightSize.width() / 2 - m_spaceWidth,
|
||||
m_clickBeforePosition.y() - m_hightlightSize.height() / 2 - m_spaceHeight);
|
||||
int right = m_navigationImage.width() - m_hightlightSize.width(); //右侧边缘
|
||||
int bottom = m_navigationImage.height() - m_hightlightSize.height(); //下侧边缘
|
||||
|
||||
//过滤无效区域
|
||||
if (startPoint.x() < 0) {
|
||||
startPoint.setX(0);
|
||||
}
|
||||
if (startPoint.y() < 0) {
|
||||
startPoint.setY(0);
|
||||
}
|
||||
if (startPoint.x() > right) {
|
||||
startPoint.setX(right);
|
||||
}
|
||||
if (startPoint.y() > bottom) {
|
||||
startPoint.setY(bottom);
|
||||
}
|
||||
|
||||
QImage deepenImg = pictureDeepen(m_navigationImage, m_hightlightSize, startPoint);
|
||||
|
||||
// 发送到导航器
|
||||
Q_EMIT showNavigation(QPixmap::fromImage(deepenImg));
|
||||
// 发送到导航器设置
|
||||
Q_EMIT sendHightlightPos(QPoint(startPoint.x() + m_spaceWidth, startPoint.y() + m_spaceHeight),
|
||||
QPoint(startPoint.x() + m_hightlightSize.width() + m_spaceWidth,
|
||||
startPoint.y() + m_hightlightSize.height() + m_spaceHeight));
|
||||
|
||||
double labWidth = this->width() - 2 * ShowImageWidgetSpacing - AddWidthForLargeFontSize;
|
||||
double labHeight = this->height() - 24 - 24 - 36 -16;
|
||||
|
||||
QSize m_size(labWidth, labHeight);
|
||||
|
||||
QPoint startShowPoint = startPoint * m_tmpSize.width() / m_navigationImage.width();
|
||||
QPixmap result = localAmplification(m_nowImage, m_tmpSize, startShowPoint, m_size);
|
||||
m_showImageLabel->setPixmap(result);
|
||||
m_showImageLabel->setFixedSize(QSize(result.size()));
|
||||
m_showImageLabel->setScaledContents(true);
|
||||
m_showImageLabel->setAlignment(Qt::AlignCenter | Qt::AlignCenter | Qt::AlignCenter);
|
||||
|
||||
KyInfo() << "proportion: " << proportion << "proportionForPercentage: " << proportionForPercentage;
|
||||
|
||||
int proportionInt = qRound(proportionForPercentage * 100);
|
||||
|
||||
KyInfo() << "proportionInt: " << proportionInt;
|
||||
QString proportionString = QString("%1").arg(proportionInt) + "%";
|
||||
|
||||
KyInfo() << "proportionString: " << proportionString;
|
||||
g_sane_object->percentage = proportionString;
|
||||
}
|
||||
|
||||
QPixmap ShowImageWidget::localAmplification(const QPixmap &orgPix, QSize showSize, QPoint local, QSize widSize)
|
||||
{
|
||||
// orgPix——原图 showSize——目标大小 local——基于showSize的起始坐标 widSize——窗口尺寸
|
||||
double proportion = double(showSize.width()) / double(orgPix.width());
|
||||
QPoint locaPoint(local.rx() / proportion, local.ry() / proportion);
|
||||
QSize locaSize(widSize.width() / proportion, widSize.height() / proportion);
|
||||
QPixmap localPix = orgPix.copy(locaPoint.rx(), locaPoint.ry(), locaSize.width(), locaSize.height());
|
||||
|
||||
return localPix.scaled(widSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
void ShowImageWidget::showImageAfterClickedThumbnail(QString loadPath)
|
||||
{
|
||||
m_imageStack.clear();
|
||||
|
@ -663,7 +918,7 @@ void ShowImageWidget::cropSlot()
|
|||
|
||||
zoomCurrentNormalImage();
|
||||
|
||||
m_cropLabel->initCropSettings();
|
||||
m_cropLabel->initCropSettings(m_showImageLabel->width(), m_showImageLabel->height());
|
||||
m_showImageAndCropWidget->setCurrentWidget(m_cropLabel);
|
||||
|
||||
*m_editImage = m_normalImage->copy();
|
||||
|
@ -671,7 +926,7 @@ void ShowImageWidget::cropSlot()
|
|||
*m_stackImage = m_normalImage->copy();
|
||||
m_imageStack.push(*m_stackImage);
|
||||
|
||||
setPixmapScaled(*m_editImage, m_cropLabel);
|
||||
setCropPixmapScaled(*m_editImage, m_cropLabel);
|
||||
}else{
|
||||
rollBackOperation();
|
||||
m_cancelOkWidget->hide();
|
||||
|
@ -841,8 +1096,8 @@ void ShowImageWidget::zoomCurrentNormalImage()
|
|||
{
|
||||
double scale = getCurrentPercentage();
|
||||
|
||||
setPixmapScaled(*m_normalImage, m_showImageLabel, scale);
|
||||
setPixmapScaled(*m_normalImage, m_cropLabel, scale);
|
||||
setCropPixmapScaled(*m_normalImage, m_showImageLabel, scale);
|
||||
setCropPixmapScaled(*m_normalImage, m_cropLabel, scale);
|
||||
|
||||
updatePercentageByZoom(scale);
|
||||
}
|
||||
|
@ -867,7 +1122,7 @@ void ShowImageWidget::showBeautyRunningDialog(QString text)
|
|||
m_beautyRunningDialog->hideCancelButton();
|
||||
m_beautyRunningDialog->setWaitText(tr("Canceling...Please waiting..."));
|
||||
});
|
||||
connect(g_user_signal, &GlobalUserSignal::exitOCR, this, &ShowImageWidget::cancelImageOperationSlot);
|
||||
connect(g_user_signal, &GlobalUserSignal::exitOCR, this, &ShowImageWidget::ocrStopSlot);
|
||||
}
|
||||
void ShowImageWidget::cancelImageOperationSlot(){
|
||||
if(imageOpThread->isRunning()){
|
||||
|
@ -900,6 +1155,7 @@ void ShowImageWidget::beautyFinished(){
|
|||
imageOp = nullptr;
|
||||
imageOpThread->quit();
|
||||
qDebug() << "image operation complete!";
|
||||
emit g_user_signal->mutexUnlockSignal();
|
||||
}
|
||||
void ShowImageWidget::beautyStopSlot()
|
||||
{
|
||||
|
@ -929,20 +1185,24 @@ void ShowImageWidget::rectifyStopSlot(bool isTrue)
|
|||
|
||||
void ShowImageWidget::ocrStartSlot()
|
||||
{
|
||||
imageOp = new ImageOperationOCR(&(*m_normalImage));
|
||||
imageOpThread = new QThread;
|
||||
imageOp->moveToThread(imageOpThread);
|
||||
imageOpThread->start();
|
||||
connect(this,&ShowImageWidget::OCRSignal,imageOp,&ImageOperationBase::ImageOP);
|
||||
connect(imageOp,&ImageOperationBase::finished,this,&ShowImageWidget::ocrStopSlot);
|
||||
QString realLoadPathDelayUpdate = QFileInfo(m_loadPathDelayUpdate).absolutePath() + "/" + QFileInfo(m_loadPathDelayUpdate).baseName() + "_temp" + ".jpg";
|
||||
m_normalImage->save(realLoadPathDelayUpdate);
|
||||
emit g_user_signal->showScanWidgetSignal(realLoadPathDelayUpdate);
|
||||
imageOpOcr = new ImageOperationOCR(m_normalImage, realLoadPathDelayUpdate);
|
||||
imageOpOcrThread = new QThread();
|
||||
imageOpOcr->moveToThread(imageOpOcrThread);
|
||||
imageOpOcrThread->start();
|
||||
connect(this, &ShowImageWidget::OCRSignal, imageOpOcr, &ImageOperationBase::ImageOP);
|
||||
connect(imageOpOcr, &ImageOperationBase::finished, this, &ShowImageWidget::ocrStopSlot);
|
||||
emit OCRSignal();
|
||||
}
|
||||
|
||||
void ShowImageWidget::ocrStopSlot()
|
||||
{
|
||||
delete imageOp;
|
||||
imageOp = nullptr;
|
||||
imageOpThread->quit();
|
||||
// disconnect(imageOpOcr,&ImageOperationBase::finished,this,&ShowImageWidget::ocrStopSlot);
|
||||
// imageOpOcrThread->terminate();
|
||||
imageOpOcr = nullptr;
|
||||
imageOpOcrThread = nullptr;
|
||||
}
|
||||
|
||||
void ShowImageWidget::saveCurrentPicture()
|
||||
|
@ -956,19 +1216,6 @@ void ShowImageWidget::loadAfterBROPicture()
|
|||
setPixmapScaled(*m_normalImage, m_showImageLabel);
|
||||
}
|
||||
|
||||
void ShowImageWidget::themeChangedSlot()
|
||||
{
|
||||
QString systemTheme = kdk::kabase::Gsettings::getSystemTheme().toString();
|
||||
|
||||
if (systemTheme == STYLE_NAME_KEY_DARK || systemTheme == STYLE_NAME_KEY_BLACK) {
|
||||
KyInfo() << "dark theme";
|
||||
m_cancelOkWidget->setStyleSheet("background: rgba(64, 64, 64, 0.8); box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15); border-radius: 6px; filter: blur(18px);");
|
||||
} else {
|
||||
KyInfo() << "white theme";
|
||||
m_cancelOkWidget->setStyleSheet("background: rgba(249, 249, 249, 0.8); box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.8); border-radius: 6px; filter: blur(18px);");
|
||||
}
|
||||
}
|
||||
|
||||
void ShowImageWidget::cropCancelSlot()
|
||||
{
|
||||
KyInfo() << "pressed cancel: " ;
|
||||
|
@ -1000,3 +1247,17 @@ void ShowImageWidget::cropCompleteSlot()
|
|||
|
||||
m_cancelOkWidget->hide();
|
||||
}
|
||||
|
||||
void ShowImageWidget::naviChange()
|
||||
{
|
||||
if (m_navigator->isHidden()) {
|
||||
return;
|
||||
}
|
||||
m_navigator->move(this->width() - 7 - m_navigator->width(), this->height() - 52 - m_navigator->height());
|
||||
}
|
||||
|
||||
void ShowImageWidget::resetNavigator()
|
||||
{
|
||||
m_navigator->hide();
|
||||
m_clickBeforePosition = QPoint(0, 0);
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue