更新同步最新代码

This commit is contained in:
fanyuchen 2023-09-23 15:04:03 +08:00
parent bbd9bb0aca
commit 4d5dfb8352
123 changed files with 6233 additions and 3316 deletions

View File

@ -1,2 +1,3 @@
yushuoqi <yushuoqi@kylinos.cn>
zhaoyuzhen <zhaoyuzhen@kylinos.cn>
fanyuchen <fanyuchen@kylinos.cn>

View File

@ -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)

View File

@ -5,8 +5,6 @@
![Main Picture](docs/scanner.png)
## 作者博客页面
:point_right: [Franklin-Qi](https://github.com/Franklin-Qi)
## 功能列表
- [x] 正常扫描(根据不同的设备类型,分辨率,尺寸,色彩模式,保存格式)

9
debian/changelog vendored
View File

@ -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 【平板模式】【扫描】已扫描多张图片,左侧预览图可以左右拖动

View File

@ -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/))

View File

@ -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/&gt;.
*
*/
#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);
}

View File

@ -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/&gt;.
*
*/
#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

View File

@ -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()

View File

@ -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 {

View File

@ -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("");
}
}

27
src/custom_push_button.h Normal file
View File

@ -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

48
src/customtablewidget.cpp Normal file
View File

@ -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;
}

20
src/customtablewidget.h Normal file
View File

@ -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

View File

@ -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;

View File

@ -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;
};

74
src/device/CMakeLists.txt Normal file
View File

@ -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")

View File

@ -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;
}

View File

@ -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

34
src/device/base_info.cpp Normal file
View File

@ -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;
}

28
src/device/base_info.h Normal file
View File

@ -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

192
src/device/common.cpp Normal file
View File

@ -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;
}

72
src/device/common.h Normal file
View File

@ -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

54
src/device/connect.cpp Normal file
View File

@ -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();
}

8
src/device/connect.h Normal file
View File

@ -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

215
src/device/deviceFinder.cpp Normal file
View File

@ -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 !";
};
}
}

43
src/device/deviceFinder.h Normal file
View File

@ -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

View File

@ -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 !";
};
}

View File

@ -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

55
src/device/main.cpp Normal file
View File

@ -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();
}

View File

@ -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 ;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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

18
src/device/singleton.h Normal file
View File

@ -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;
};

114
src/device/snmpFinder.cpp Normal file
View File

@ -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);
}

21
src/device/snmpFinder.h Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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

142
src/device/ukui_apt.cpp Normal file
View File

@ -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());
}

98
src/device/ukui_apt.h Normal file
View File

@ -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

312
src/device/usbFinder.cpp Normal file
View File

@ -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;
}

33
src/device/usbFinder.h Normal file
View File

@ -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

View File

@ -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();
}

View File

@ -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;
};

View File

@ -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);

View File

@ -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

View File

@ -23,7 +23,6 @@ void Global::global_init() {
{
g_settings->setValue("General/display_env", "x11");
}
// isWayland = (g_settings->value("General/display_env").toString() == "wayland");
}

View File

@ -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";

View File

@ -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;

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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:
};

View File

@ -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();

View File

@ -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);
}

View File

@ -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();
};

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -15,12 +15,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/&gt;.
*
*/
#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
}
}

View File

@ -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()

View File

@ -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

79
src/navigator.cpp Normal file
View File

@ -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;
}

38
src/navigator.h Normal file
View File

@ -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

376
src/newdevicelistpage.cpp Normal file
View File

@ -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();
}

93
src/newdevicelistpage.h Normal file
View File

@ -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

39
src/nodevicewidget.cpp Normal file
View File

@ -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);
}

26
src/nodevicewidget.h Normal file
View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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;
}

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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();
};

View File

@ -15,25 +15,26 @@
* along with this program; if not, see <http://www.gnu.org/licenses/&gt;.
*
*/
#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();
}

View File

@ -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;

View File

@ -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