diff --git a/AUTHORS b/AUTHORS index 45792df..9067917 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,3 @@ yushuoqi zhaoyuzhen +fanyuchen \ No newline at end of file diff --git a/README.md b/README.md index 56df7b9..4ca0370 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/README_CN.md b/README_CN.md index e17c6b6..10a7f0c 100644 --- a/README_CN.md +++ b/README_CN.md @@ -5,8 +5,6 @@ ![Main Picture](docs/scanner.png) -## 作者博客页面 -:point_right: [Franklin-Qi](https://github.com/Franklin-Qi) ## 功能列表 - [x] 正常扫描(根据不同的设备类型,分辨率,尺寸,色彩模式,保存格式) diff --git a/debian/changelog b/debian/changelog index d8d5b06..489d715 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +kylin-scanner (3.2.1-0k2.0) yangtze; urgency=medium + + * BUG号:无 + * 需求号:#22628 扫描仪自动安装驱动需求 + * 其他改动说明: 同步最新功能代码,添加扫描仪驱动自动安装功能,pdf多页扫描保存为一个pdf文件功能,剔除OpenCV相关代码(一键美化和智能纠偏算法改变),OCR改用SDK提供的开源算法。 + * 其他改动影响域:无 + + -- fanyuchen Sat, 23 Sep 2023 14:59:40 +0800 + kylin-scanner (3.2.1-0k1.3) yangtze; urgency=medium * BUG号:#I5XFGZ 【平板模式】【扫描】已扫描多张图片,左侧预览图可以左右拖动 diff --git a/kylin-scanner.pro b/kylin-scanner.pro index 261fba6..b06b6d3 100644 --- a/kylin-scanner.pro +++ b/kylin-scanner.pro @@ -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/)) diff --git a/src/beauty.cpp b/src/beauty.cpp deleted file mode 100644 index 745bdf3..0000000 --- a/src/beauty.cpp +++ /dev/null @@ -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 - -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_(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(val); - - val = srcHSL[j * chns + 1] + saturation; - if ( val < 0) - val = 0; - if ( val > 255 ) - val = 255; - srcHSL[j * chns + 1] = static_cast(val); - - val = srcHSL[j * chns + 2] + lumination; - if ( val < 0) - val = 0; - if ( val > 255 ) - val = 255; - srcHSL[j * chns + 2] = static_cast(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(i, j)[c] = - saturate_cast( alpha * (src.at(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 (row, col)[2]; - uchar g = src.at (row, col)[1]; - uchar b = src.at (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 (row, col)[0] = new_b; - new_img.at (row, col)[1] = new_g; - new_img.at (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 (row, col)[0] = new_b; - KyInfo() << "3"; - new_img.at (row, col)[1] = new_g; - KyInfo() << "4"; - new_img.at (row, col)[2] = new_r; - KyInfo() << "5"; - } - } - - dst = new_img.clone(); - KyInfo() << "saturation() end"; -} - - -void histogramEqualizationCV(Mat src, Mat &dst) -{ - std::vector 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_(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(i, j)[0] = log1p(src.at(i, j)[0]); - imageLog.at(i, j)[1] = log1p(src.at(i, j)[1]); - imageLog.at(i, j)[2] = log1p(src.at(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(i, j)[0] = (src.at(i, j)[0]) * (src.at(i, - j)[0]) * (src.at(i, j)[0]); - imageGamma.at(i, j)[1] = (src.at(i, j)[1]) * (src.at(i, - j)[1]) * (src.at(i, j)[1]); - imageGamma.at(i, j)[2] = (src.at(i, j)[2]) * (src.at(i, - j)[2]) * (src.at(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); -} diff --git a/src/beauty.h b/src/beauty.h deleted file mode 100644 index 3d419a3..0000000 --- a/src/beauty.h +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -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 diff --git a/src/crop.cpp b/src/crop.cpp index ec76ebe..9fbbd71 100644 --- a/src/crop.cpp +++ b/src/crop.cpp @@ -46,7 +46,7 @@ void CropLabel::paintEvent(QPaintEvent *event) { QLabel::paintEvent(event); // draw label background -// QPainter painter(this); + QPainter painter(this); painter.begin(this); QPen pen(QColor(55, 144, 250), 1); painter.setPen(pen); @@ -55,25 +55,42 @@ void CropLabel::paintEvent(QPaintEvent *event) borderPath.setFillRule(Qt::WindingFill); borderPath.addRect(0, 0, this->width(), this->height()); // need judge -// int W = m_endX - m_startX; -// int H = m_endY - m_startY; - int W = m_endX - m_beginX; int H = m_endY - m_beginY; m_beginPoint.setX(m_beginX); m_beginPoint.setY(m_beginY); m_endPoint.setX(m_endX); m_endPoint.setY(m_endY); + m_currentSelectRect = getRect(m_beginPoint, m_endPoint); QPainterPath cropPath; cropPath.addRect(m_currentSelectRect); - // draw different pixmap - if(!(H == 0 && W == 0)){ - drawPixmapBorder(m_currentSelectRect, W, H); - } + painter.drawPixmap(m_currentSelectRect.x()-m_leftTopPixmapSize.width()/2, m_currentSelectRect.y()-m_leftTopPixmapSize.height()/2, + m_leftTopPixmapSize.width(), m_leftTopPixmapSize.height(), m_leftTopPixmap); + + painter.drawPixmap(m_currentSelectRect.x()+W/2-m_topPixmapSize.width()/2, m_currentSelectRect.y()-m_topPixmapSize.height()/2, + m_topPixmapSize.width(), m_topPixmapSize.height(), m_topPixmap); + + painter.drawPixmap(m_currentSelectRect.x()+W-m_rightTopPixmapSize.width()/2, m_currentSelectRect.y()-m_rightTopPixmapSize.height()/2, + m_rightTopPixmapSize.width(), m_rightTopPixmapSize.height(), m_rightTopPixmap); + + painter.drawPixmap(m_currentSelectRect.x()+W-m_rightPixmapSize.width()/2, m_currentSelectRect.y()+H/2-m_rightPixmapSize.height()/2, + m_rightPixmapSize.width(), m_rightPixmapSize.height(), m_rightPixmap); + + painter.drawPixmap(m_currentSelectRect.x()+W-m_rightBottomPixmapSize.width()/2, m_currentSelectRect.y()+H-m_rightBottomPixmapSize.height()/2, + m_rightBottomPixmapSize.width(), m_rightBottomPixmapSize.height(), m_rightBottomPixmap); + + painter.drawPixmap(m_currentSelectRect.x()+W/2-m_bottomPixmapSize.width()/2, m_currentSelectRect.y()+H-m_bottomPixmapSize.height()/2, + m_bottomPixmapSize.width(), m_bottomPixmapSize.height(), m_bottomPixmap); + + painter.drawPixmap(m_currentSelectRect.x()-m_leftBottomPixmapSize.width()/2, m_currentSelectRect.y()+H-m_leftBottomPixmapSize.height()/2, + m_leftBottomPixmapSize.width(), m_leftBottomPixmapSize.height(), m_leftBottomPixmap); + + painter.drawPixmap(m_currentSelectRect.x()-m_leftPixmapSize.width()/2, m_currentSelectRect.y()+H/2-m_leftPixmapSize.height()/2, + m_leftPixmapSize.width(), m_leftPixmapSize.height(), m_leftPixmap); // draw crop rect path painter.drawPath(cropPath); @@ -84,7 +101,7 @@ void CropLabel::paintEvent(QPaintEvent *event) painter.setRenderHint(QPainter::Antialiasing, true); painter.fillPath(outPath, QColor(0, 0, 0, 100)); - painter.end(); + if(!(H == 0 && W == 0)){ emit paintCompleteSignal(); } @@ -123,7 +140,6 @@ void CropLabel::calculateDetectRegion(){ void CropLabel::mousePressEvent(QMouseEvent *event) { -// QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor)); m_isPressed = true; if (event->button() == Qt::LeftButton) { //判断按下的手柄的区域位置 @@ -222,6 +238,7 @@ void CropLabel::mouseMoveEvent(QMouseEvent *event) m_beginY = judgePosition(m_beginY,0,m_origRect.height()); m_endX = judgePosition(m_endX,0,m_origRect.width()); m_endY = judgePosition(m_endY,0,m_origRect.height()); + m_beginPoint.setX(m_beginX); m_beginPoint.setY(m_beginY); m_endPoint.setX(m_endX); @@ -299,35 +316,6 @@ bool CropLabel::isPressPointInCropRegion(QPoint mousePressPoint) return true; } -bool CropLabel::drawPixmapBorder(QRect rect, int W, int H) -{ - painter.drawPixmap(rect.x()-m_leftTopPixmapSize.width()/2, rect.y()-m_leftTopPixmapSize.height()/2, - m_leftTopPixmapSize.width(), m_leftTopPixmapSize.height(), m_leftTopPixmap); - - painter.drawPixmap(rect.x()+W/2-m_topPixmapSize.width()/2, rect.y()-m_topPixmapSize.height()/2, - m_topPixmapSize.width(), m_topPixmapSize.height(), m_topPixmap); - - painter.drawPixmap(rect.x()+W-m_rightTopPixmapSize.width()/2, rect.y()-m_rightTopPixmapSize.height()/2, - m_rightTopPixmapSize.width(), m_rightTopPixmapSize.height(), m_rightTopPixmap); - - painter.drawPixmap(rect.x()+W-m_rightPixmapSize.width()/2, rect.y()+H/2-m_rightPixmapSize.height()/2, - m_rightPixmapSize.width(), m_rightPixmapSize.height(), m_rightPixmap); - - painter.drawPixmap(rect.x()+W-m_rightBottomPixmapSize.width()/2, rect.y()+H-m_rightBottomPixmapSize.height()/2, - m_rightBottomPixmapSize.width(), m_rightBottomPixmapSize.height(), m_rightBottomPixmap); - - painter.drawPixmap(rect.x()+W/2-m_bottomPixmapSize.width()/2, rect.y()+H-m_bottomPixmapSize.height()/2, - m_bottomPixmapSize.width(), m_bottomPixmapSize.height(), m_bottomPixmap); - - painter.drawPixmap(rect.x()-m_leftBottomPixmapSize.width()/2, rect.y()+H-m_leftBottomPixmapSize.height()/2, - m_leftBottomPixmapSize.width(), m_leftBottomPixmapSize.height(), m_leftBottomPixmap); - - painter.drawPixmap(rect.x()-m_leftPixmapSize.width()/2, rect.y()+H/2-m_leftPixmapSize.height()/2, - m_leftPixmapSize.width(), m_leftPixmapSize.height(), m_leftPixmap); - - return true; -} - QRect CropLabel::getRect(const QPoint &m_beginPoint, const QPoint &m_endPoint) { int W = m_endPoint.x() - m_beginPoint.x(); @@ -340,20 +328,26 @@ QRect CropLabel::getRect(const QPoint &m_beginPoint, const QPoint &m_endPoint) } -void CropLabel::initCropSettings() +void CropLabel::initCropSettings(int width, int height) { // Not show crop box in first crop operation m_origRect.setRect(0,0,this->width(),this->height()); m_beginX = 0; m_beginY = 0; - m_endX = m_origRect.width(); - m_endY = m_origRect.height(); + if(width == 0 || height == 0){ + m_endX = m_origRect.width()-1; + m_endY = m_origRect.height()-1; + }else{ + m_endX = width-1; + m_endY = height-1; + } m_beginPoint = QPoint(m_beginX, m_beginY); m_endPoint = QPoint(m_endX, m_endY); update(); calculateDetectRegion(); m_hasCropRegion = false; + } void CropLabel::loadAllPixmaps() diff --git a/src/crop.h b/src/crop.h index ac60116..fb8e956 100644 --- a/src/crop.h +++ b/src/crop.h @@ -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 { diff --git a/src/custom_push_button.cpp b/src/custom_push_button.cpp new file mode 100644 index 0000000..31ea9f9 --- /dev/null +++ b/src/custom_push_button.cpp @@ -0,0 +1,69 @@ +#include "custom_push_button.h" +#include + +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(""); + } +} diff --git a/src/custom_push_button.h b/src/custom_push_button.h new file mode 100644 index 0000000..0560a4a --- /dev/null +++ b/src/custom_push_button.h @@ -0,0 +1,27 @@ +#ifndef CUSTOM_PUSH_BUTTON_H +#define CUSTOM_PUSH_BUTTON_H + +#include +#include + +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 diff --git a/src/customtablewidget.cpp b/src/customtablewidget.cpp new file mode 100644 index 0000000..ae6d882 --- /dev/null +++ b/src/customtablewidget.cpp @@ -0,0 +1,48 @@ +#include "customtablewidget.h" + +CustomTableWidget::CustomTableWidget(QList 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 items = this->selectedItems(); + QStringList contents; + for(int i = 0; i < items.length(); i++){ + for(int j = 0; j columnCount(); j++){ + contents.append(items.at(i)->text(j)); + } + } + return contents; +} diff --git a/src/customtablewidget.h b/src/customtablewidget.h new file mode 100644 index 0000000..a7c1c7b --- /dev/null +++ b/src/customtablewidget.h @@ -0,0 +1,20 @@ +#ifndef CUSTOMTABLEWIDGET_H +#define CUSTOMTABLEWIDGET_H + +#include +#include +#include +#include +#include + +class CustomTableWidget : public QTreeWidget +{ + Q_OBJECT +public: + CustomTableWidget(QList header, QWidget *parent = nullptr); + + void insertItem(int i, QStringList content); + QStringList getSelectedRow(); +}; + +#endif // CUSTOMTABLEWIDGET_H diff --git a/src/detectpagewidget.cpp b/src/detectpagewidget.cpp index 1f274ca..5f1dd82 100644 --- a/src/detectpagewidget.cpp +++ b/src/detectpagewidget.cpp @@ -16,30 +16,34 @@ * */ #include "detectpagewidget.h" -#include +#include + #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; diff --git a/src/detectpagewidget.h b/src/detectpagewidget.h index 77bfbe2..485cb1a 100644 --- a/src/detectpagewidget.h +++ b/src/detectpagewidget.h @@ -32,12 +32,13 @@ #include #include #include - +#include #include #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; }; diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt new file mode 100644 index 0000000..d4a16dc --- /dev/null +++ b/src/device/CMakeLists.txt @@ -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") diff --git a/src/device/avahi_qt/qt_watch.cpp b/src/device/avahi_qt/qt_watch.cpp new file mode 100644 index 0000000..a42bc3b --- /dev/null +++ b/src/device/avahi_qt/qt_watch.cpp @@ -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 +#include +#include +#include + +#include + +#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; +} + diff --git a/src/device/avahi_qt/qt_watch.h b/src/device/avahi_qt/qt_watch.h new file mode 100644 index 0000000..c56ba30 --- /dev/null +++ b/src/device/avahi_qt/qt_watch.h @@ -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 +#include +#include + +#include +#include + +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 diff --git a/src/device/base_info.cpp b/src/device/base_info.cpp new file mode 100644 index 0000000..a1674dc --- /dev/null +++ b/src/device/base_info.cpp @@ -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; +} diff --git a/src/device/base_info.h b/src/device/base_info.h new file mode 100644 index 0000000..deef86e --- /dev/null +++ b/src/device/base_info.h @@ -0,0 +1,28 @@ +#ifndef BASEINFO_H +#define BASEINFO_H + +#include +#include +#include "singleton.h" + +class BaseInfo : public QObject, + public Singleton +{ + Q_OBJECT + friend class Singleton; +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 diff --git a/src/device/common.cpp b/src/device/common.cpp new file mode 100644 index 0000000..a22dd0d --- /dev/null +++ b/src/device/common.cpp @@ -0,0 +1,192 @@ +#include +#include +#include + +#include +#include +#include +#include + +#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::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; +} diff --git a/src/device/common.h b/src/device/common.h new file mode 100644 index 0000000..4d8d7b6 --- /dev/null +++ b/src/device/common.h @@ -0,0 +1,72 @@ +#ifndef KYLIN_PRINTER_COMMON_H +#define KYLIN_PRINTER_COMMON_H + +#include +#include +#include +#include + +#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 mfgConvertMap = { + std::map::value_type("Lenovo Image", "Lenovo"), + std::map::value_type("Fuji Xerox", "Fuji-Xerox"), + std::map::value_type("INDEX BRAILLE", "INDEX-BRAILLE"), + std::map::value_type("KONICA MINOLTA", "KONICA-MINOLTA"), + std::map::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 diff --git a/src/device/connect.cpp b/src/device/connect.cpp new file mode 100644 index 0000000..0d3452f --- /dev/null +++ b/src/device/connect.cpp @@ -0,0 +1,54 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "connect.h" + +#include + + +// 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(); +} \ No newline at end of file diff --git a/src/device/connect.h b/src/device/connect.h new file mode 100644 index 0000000..baceed3 --- /dev/null +++ b/src/device/connect.h @@ -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 \ No newline at end of file diff --git a/src/device/deviceFinder.cpp b/src/device/deviceFinder.cpp new file mode 100644 index 0000000..8c19fd0 --- /dev/null +++ b/src/device/deviceFinder.cpp @@ -0,0 +1,215 @@ +// +// Created by oubayasho on 2023/6/6. +// + +#include "deviceFinder.h" +#include "usbFinder.h" +#include "snmpFinder.h" +#include +#include +#include "common.h" +#include "connect.h" +#include +#include +#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 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 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 deviceFinder::getList() +{ + return m_infoList; +} + +void deviceFinder::doPackageWork() +{ + this->succeed(); +} + +void deviceFinder::buriedDeviceInfomation(QList list) +{ + for(int i = 0; i < list.size(); i++){ + std::map 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 !"; + }; + } +} diff --git a/src/device/deviceFinder.h b/src/device/deviceFinder.h new file mode 100644 index 0000000..a2f60ae --- /dev/null +++ b/src/device/deviceFinder.h @@ -0,0 +1,43 @@ +// +// Created by oubayasho on 2023/6/6. +// + +#ifndef UNTITLED6_DEVICEFINDER_H +#define UNTITLED6_DEVICEFINDER_H + +#include +#include "device_information.h" +//#include "network_device_detector.h" +#include +#include + +class deviceFinder : public QObject +{ + Q_OBJECT +public: + deviceFinder(QObject *parent = nullptr); + ~deviceFinder(); + QList 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 list); + QThread *m_thread{nullptr}; + QList m_infoList; + QList m_saneInfoList; + bool m_isServerAddressConnected{false}; +}; + + +#endif//UNTITLED6_DEVICEFINDER_H diff --git a/src/device/device_information.cpp b/src/device/device_information.cpp new file mode 100644 index 0000000..efb4f81 --- /dev/null +++ b/src/device/device_information.cpp @@ -0,0 +1,196 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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"< 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 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 !"; + }; + +} diff --git a/src/device/device_information.h b/src/device/device_information.h new file mode 100644 index 0000000..308e25d --- /dev/null +++ b/src/device/device_information.h @@ -0,0 +1,88 @@ +#ifndef DEVICE_INFORMATION_H +#define DEVICE_INFORMATION_H + +#include +#include +#include +#include +#include + +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 protocolMap = { + std::map::value_type("none", ProtocolType::NONE), + std::map::value_type("lpd", ProtocolType::LPD), + std::map::value_type("ipp", ProtocolType::IPP), + std::map::value_type("http", ProtocolType::HTTP), + std::map::value_type("socket", ProtocolType::SOCKET), + std::map::value_type("dnssd", ProtocolType::DNSSD), + std::map::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 diff --git a/src/device/main.cpp b/src/device/main.cpp new file mode 100644 index 0000000..b64e7e9 --- /dev/null +++ b/src/device/main.cpp @@ -0,0 +1,55 @@ +#include +#include +#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(); +} diff --git a/src/device/network_device_detector.cpp b/src/device/network_device_detector.cpp new file mode 100644 index 0000000..f20d71c --- /dev/null +++ b/src/device/network_device_detector.cpp @@ -0,0 +1,178 @@ +#include + +#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 oids = { + { ckey }, + }; + + + std::vector hosts = { + { cname, "public" }, + }; + + std::vector 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 ; +} diff --git a/src/device/network_device_detector.h b/src/device/network_device_detector.h new file mode 100644 index 0000000..5010e2f --- /dev/null +++ b/src/device/network_device_detector.h @@ -0,0 +1,49 @@ +#ifndef NETWORK_DEVICE_DETECTOR_H +#define NETWORK_DEVICE_DETECTOR_H + +#include + +#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 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 diff --git a/src/device/qt_zeroconf/zconfservice.cpp b/src/device/qt_zeroconf/zconfservice.cpp new file mode 100644 index 0000000..be35446 --- /dev/null +++ b/src/device/qt_zeroconf/zconfservice.cpp @@ -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 +#include +#include +#include +#include +#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(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); +} diff --git a/src/device/qt_zeroconf/zconfservice.h b/src/device/qt_zeroconf/zconfservice.h new file mode 100644 index 0000000..fc190a1 --- /dev/null +++ b/src/device/qt_zeroconf/zconfservice.h @@ -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 +#include + +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 diff --git a/src/device/qt_zeroconf/zconfservicebrowser.cpp b/src/device/qt_zeroconf/zconfservicebrowser.cpp new file mode 100644 index 0000000..ecdf520 --- /dev/null +++ b/src/device/qt_zeroconf/zconfservicebrowser.cpp @@ -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 +#include +#include +#include +#include +#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(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(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 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; +} \ No newline at end of file diff --git a/src/device/qt_zeroconf/zconfservicebrowser.h b/src/device/qt_zeroconf/zconfservicebrowser.h new file mode 100644 index 0000000..e39ab65 --- /dev/null +++ b/src/device/qt_zeroconf/zconfservicebrowser.h @@ -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 +#include +#include + +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 diff --git a/src/device/qt_zeroconf/zconfserviceclient.cpp b/src/device/qt_zeroconf/zconfserviceclient.cpp new file mode 100644 index 0000000..f35036d --- /dev/null +++ b/src/device/qt_zeroconf/zconfserviceclient.cpp @@ -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 +#include "qt_watch.h" +#include +#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(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 + } +} diff --git a/src/device/qt_zeroconf/zconfserviceclient.h b/src/device/qt_zeroconf/zconfserviceclient.h new file mode 100644 index 0000000..0578550 --- /dev/null +++ b/src/device/qt_zeroconf/zconfserviceclient.h @@ -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 +#include + +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 diff --git a/src/device/singleton.h b/src/device/singleton.h new file mode 100644 index 0000000..90a6fdc --- /dev/null +++ b/src/device/singleton.h @@ -0,0 +1,18 @@ +#pragma once + +template +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; +}; diff --git a/src/device/snmpFinder.cpp b/src/device/snmpFinder.cpp new file mode 100644 index 0000000..096e446 --- /dev/null +++ b/src/device/snmpFinder.cpp @@ -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 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); +} diff --git a/src/device/snmpFinder.h b/src/device/snmpFinder.h new file mode 100644 index 0000000..dae91f4 --- /dev/null +++ b/src/device/snmpFinder.h @@ -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 getList(); + +private: + QList m_snmpInfoList; + void parseSnmpInfo(QString &info); +}; + +#endif // DEVICE_SNMPFINDER_H diff --git a/src/device/snmpwalk_browser.cpp b/src/device/snmpwalk_browser.cpp new file mode 100644 index 0000000..347b11e --- /dev/null +++ b/src/device/snmpwalk_browser.cpp @@ -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 + +#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 &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 &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 &buf, + const std::vector &hosts, + std::vector &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 &oids) +{ + return initialize(oids); +} + +int snmpwalkBrowser_synchronous(std::vector &buf, + const std::vector &hosts, + std::vector &oids) +{ + if (hosts.size() != 1) { + return -1; + } + int res = 0; + // std::cout << hosts[0].name << ' ' < +#include +#include +#include + +/* + * 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 &oids); + +int snmpwalkBrowser_synchronous(std::vector &buf, + const std::vector &hosts, + std::vector &oids); + +#endif // SNMPWALK_BROWSER_H \ No newline at end of file diff --git a/src/device/ukui_apt.cpp b/src/device/ukui_apt.cpp new file mode 100644 index 0000000..cb1bba8 --- /dev/null +++ b/src/device/ukui_apt.cpp @@ -0,0 +1,142 @@ +#include "ukui_apt.h" +#include +#include +#include +#include +#include + +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()); +} diff --git a/src/device/ukui_apt.h b/src/device/ukui_apt.h new file mode 100644 index 0000000..9a9bb0c --- /dev/null +++ b/src/device/ukui_apt.h @@ -0,0 +1,98 @@ +#ifndef UKUI_APT_H +#define UKUI_APT_H +// Use QObject +#include +#include +#include +// Use libqapt as apt interface +//#include +//#include +//#include +//#include +// +#include "device_information.h" +#include + +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 diff --git a/src/device/usbFinder.cpp b/src/device/usbFinder.cpp new file mode 100644 index 0000000..675e27e --- /dev/null +++ b/src/device/usbFinder.cpp @@ -0,0 +1,312 @@ +// +// Created by oubayasho on 2023/6/5. +// + +#include "usbFinder.h" +#include +#include +#include +#include +#include "common.h" +#include +#include + + +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 usbFinder::getList() +{ + return m_usbInfoList; +} diff --git a/src/device/usbFinder.h b/src/device/usbFinder.h new file mode 100644 index 0000000..5856f69 --- /dev/null +++ b/src/device/usbFinder.h @@ -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 getList(); +private: + QList m_usbInfoList; +}; + + +#endif//UNTITLED6_USBFINDER_H diff --git a/src/displaywidget.cpp b/src/displaywidget.cpp index ea85e28..2670137 100644 --- a/src/displaywidget.cpp +++ b/src/displaywidget.cpp @@ -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(); } diff --git a/src/displaywidget.h b/src/displaywidget.h index 6fbbe64..5de36f4 100644 --- a/src/displaywidget.h +++ b/src/displaywidget.h @@ -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; }; diff --git a/src/failedpagewidget.cpp b/src/failedpagewidget.cpp index 9ee48ad..3500d02 100644 --- a/src/failedpagewidget.cpp +++ b/src/failedpagewidget.cpp @@ -1,14 +1,18 @@ #include "failedpagewidget.h" #include -#include +#include + +#include +#include +#include #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); diff --git a/src/failedpagewidget.h b/src/failedpagewidget.h index 6ea4acf..e83710b 100644 --- a/src/failedpagewidget.h +++ b/src/failedpagewidget.h @@ -16,7 +16,7 @@ #include #include -#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 diff --git a/src/global.cpp b/src/global.cpp index 8a16f76..012e302 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -23,7 +23,6 @@ void Global::global_init() { { g_settings->setValue("General/display_env", "x11"); } -// isWayland = (g_settings->value("General/display_env").toString() == "wayland"); } diff --git a/src/globalsignal.cpp b/src/globalsignal.cpp index 71dd564..82e7ecc 100644 --- a/src/globalsignal.cpp +++ b/src/globalsignal.cpp @@ -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"; diff --git a/src/globalsignal.h b/src/globalsignal.h index 59f669a..84f4da5 100644 --- a/src/globalsignal.h +++ b/src/globalsignal.h @@ -43,6 +43,7 @@ public: void setCurrentMode(bool isPCMode); bool exitWindowWithSaveFlag = false; + void setDeviceList(const SANE_Device **list); QList 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; diff --git a/src/imageBaseOP/loadimage.cpp b/src/imageBaseOP/loadimage.cpp index 7be610e..e85cb90 100644 --- a/src/imageBaseOP/loadimage.cpp +++ b/src/imageBaseOP/loadimage.cpp @@ -2,7 +2,7 @@ #include #include #include - +#include 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 img(loadPath.toLocal8Bit().data()); + if(!QFile(newLoadPath).exists()){ + img.save_jpeg(newLoadPath.toLocal8Bit().data()); + } +} + diff --git a/src/imageBaseOP/loadimage.h b/src/imageBaseOP/loadimage.h index 7412f88..f944751 100644 --- a/src/imageBaseOP/loadimage.h +++ b/src/imageBaseOP/loadimage.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include 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); diff --git a/src/imageBaseOP/pngsaver.cpp b/src/imageBaseOP/pngsaver.cpp new file mode 100644 index 0000000..10bdc54 --- /dev/null +++ b/src/imageBaseOP/pngsaver.cpp @@ -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); +} diff --git a/src/imageBaseOP/pngsaver.h b/src/imageBaseOP/pngsaver.h new file mode 100644 index 0000000..a8e03f6 --- /dev/null +++ b/src/imageBaseOP/pngsaver.h @@ -0,0 +1,22 @@ +#ifndef PNGSAVER_H +#define PNGSAVER_H + +#include +#include +#include + +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 diff --git a/src/imageBaseOP/savefilebase.cpp b/src/imageBaseOP/savefilebase.cpp index 5e4c3a9..8a3cf55 100644 --- a/src/imageBaseOP/savefilebase.cpp +++ b/src/imageBaseOP/savefilebase.cpp @@ -1,11 +1,13 @@ #include "savefilebase.h" #include -#include #include "../saneobject.h" #include #include #include #include +#include +#include "pngsaver.h" +#include 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(); } } diff --git a/src/imageBaseOP/savefilebase.h b/src/imageBaseOP/savefilebase.h index 38fddba..69bf9a9 100644 --- a/src/imageBaseOP/savefilebase.h +++ b/src/imageBaseOP/savefilebase.h @@ -4,13 +4,11 @@ #include #include #include -#include -#include -#include #include #include #include #include +#include class SaveFileBase : public QObject { @@ -29,6 +27,8 @@ private: QList m_tiffImageList; QStringList m_fileImages; QList m_filist; + int m_pdfCount = 0; + QStringList m_pdfName; signals: }; diff --git a/src/imageOp/imageoperationbase.h b/src/imageOp/imageoperationbase.h index 0ee93e9..9fc823b 100644 --- a/src/imageOp/imageoperationbase.h +++ b/src/imageOp/imageoperationbase.h @@ -12,7 +12,7 @@ public: QImage *m_origin; QStack *m_stackImage; - bool isInterupt; + bool isInterupt = false; QImage imageCopy(QImage *origin, QStack *stackImage); bool getIsInterrupt(); void interuptOp(); diff --git a/src/imageOp/imageoperationbeauty.cpp b/src/imageOp/imageoperationbeauty.cpp index 06ff71e..ff95b83 100644 --- a/src/imageOp/imageoperationbeauty.cpp +++ b/src/imageOp/imageoperationbeauty.cpp @@ -1,5 +1,4 @@ #include "imageoperationbeauty.h" -#include "../beauty.h" #include "../include/common.h" #include @@ -10,64 +9,85 @@ ImageOperationBeauty::ImageOperationBeauty(QImage *origin, QStack *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(img->bits()),static_cast(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((centerGray - brightness) * usmAmount); + brightness = qBound(0, usmGray, 255); + + // 增强对比度 + float contrastAmount = 1.5; + brightness = qBound(0, static_cast((brightness -128) * contrastAmount) + 128, 255); + + // 更新像素值 + outputImage.setPixel(x, y, qRgb(brightness, brightness, brightness)); + } + } + + outputImage.save(ScanningPicture); } + diff --git a/src/imageOp/imageoperationbeauty.h b/src/imageOp/imageoperationbeauty.h index e193898..4e503b8 100644 --- a/src/imageOp/imageoperationbeauty.h +++ b/src/imageOp/imageoperationbeauty.h @@ -2,10 +2,7 @@ #define IMAGEOPERATIONBEAUTY_H #include "imageoperationbase.h" -#include -#include -#include -using namespace cv; + #include "../runningdialog.h" class ImageOperationBeauty : public ImageOperationBase @@ -14,8 +11,7 @@ public: ImageOperationBeauty(QImage *origin, QStack *stackImage); virtual void ImageOP(); private: - void beauty(cv::Mat); - cv::Mat Image2Mat(QImage *img); + void beauty(const QImage inputImage); void showBeautyRunningDialog(); }; diff --git a/src/imageOp/imageoperationocr.cpp b/src/imageOp/imageoperationocr.cpp index f069de4..4677bc4 100644 --- a/src/imageOp/imageoperationocr.cpp +++ b/src/imageOp/imageoperationocr.cpp @@ -1,61 +1,35 @@ #include "imageoperationocr.h" -#include -#include "../src/saneobject.h" -#include +#include "../saneobject.h" #include "../include/common.h" #include +#include +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 result; + kdk::kdkOCR OCR; + std::vector 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); - } -} diff --git a/src/imageOp/imageoperationocr.h b/src/imageOp/imageoperationocr.h index 30445ce..1191063 100644 --- a/src/imageOp/imageoperationocr.h +++ b/src/imageOp/imageoperationocr.h @@ -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 diff --git a/src/imageOp/imageoperationrectify.cpp b/src/imageOp/imageoperationrectify.cpp index a5a2fac..339cb66 100644 --- a/src/imageOp/imageoperationrectify.cpp +++ b/src/imageOp/imageoperationrectify.cpp @@ -1,61 +1,24 @@ #include "imageoperationrectify.h" -#include "../src/rectify.h" +#include "../rectify.h" #include - +#include ImageOperationRectify::ImageOperationRectify(QImage *origin, QStack *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(img->bits()),static_cast(img->bytesPerLine())); - cvtColor(res,res,CV_BGR2RGB); - } - return res; -} - diff --git a/src/imageOp/imageoperationrectify.h b/src/imageOp/imageoperationrectify.h index 4ac1331..eec78d1 100644 --- a/src/imageOp/imageoperationrectify.h +++ b/src/imageOp/imageoperationrectify.h @@ -4,20 +4,12 @@ #include "imageoperationbase.h" #include "imageoperationbase.h" #include -#include -#include -#include -#include - -using namespace cv; class ImageOperationRectify : public ImageOperationBase { public: ImageOperationRectify(QImage *origin, QStack *stackImage); virtual void ImageOP(); -private: - cv::Mat Image2Mat(QImage *img); }; #endif // IMAGEOPERATIONRECTIFY_H diff --git a/src/imageOp/imageoperationwatermark.cpp b/src/imageOp/imageoperationwatermark.cpp index 03df956..84fcde7 100644 --- a/src/imageOp/imageoperationwatermark.cpp +++ b/src/imageOp/imageoperationwatermark.cpp @@ -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; diff --git a/src/include/common.h b/src/include/common.h index a376b23..ac06523 100644 --- a/src/include/common.h +++ b/src/include/common.h @@ -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) diff --git a/kabase/Qt/kabaselog.hpp b/src/kabase/Qt/log.hpp similarity index 94% rename from kabase/Qt/kabaselog.hpp rename to src/kabase/Qt/log.hpp index 5bef3c0..a0ccd88 100644 --- a/kabase/Qt/kabaselog.hpp +++ b/src/kabase/Qt/log.hpp @@ -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 \ No newline at end of file diff --git a/kabase/Qt/windowmanage.hpp b/src/kabase/Qt/windowmanage.hpp similarity index 100% rename from kabase/Qt/windowmanage.hpp rename to src/kabase/Qt/windowmanage.hpp diff --git a/kabase/buriedpoint.hpp b/src/kabase/buriedpoint.hpp similarity index 94% rename from kabase/buriedpoint.hpp rename to src/kabase/buriedpoint.hpp index 1413571..590bd8b 100644 --- a/kabase/buriedpoint.hpp +++ b/src/kabase/buriedpoint.hpp @@ -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 \ No newline at end of file +#endif diff --git a/kabase/utils.hpp b/src/kabase/utils.hpp similarity index 100% rename from kabase/utils.hpp rename to src/kabase/utils.hpp diff --git a/src/leftimagehandlesuccesspagewidget.cpp b/src/leftimagehandlesuccesspagewidget.cpp index f9078df..a31e202 100644 --- a/src/leftimagehandlesuccesspagewidget.cpp +++ b/src/leftimagehandlesuccesspagewidget.cpp @@ -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(); +} diff --git a/src/leftimagehandlesuccesspagewidget.h b/src/leftimagehandlesuccesspagewidget.h index 0766647..63323bd 100644 --- a/src/leftimagehandlesuccesspagewidget.h +++ b/src/leftimagehandlesuccesspagewidget.h @@ -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 diff --git a/src/leftsuccesspagewidget.cpp b/src/leftsuccesspagewidget.cpp index 7e06bdf..5ca50dc 100644 --- a/src/leftsuccesspagewidget.cpp +++ b/src/leftsuccesspagewidget.cpp @@ -17,7 +17,8 @@ */ #include "leftsuccesspagewidget.h" #include "include/theme.h" -#include +#include +#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); diff --git a/src/leftsuccesspagewidget.h b/src/leftsuccesspagewidget.h index 0f3b937..9a07475 100644 --- a/src/leftsuccesspagewidget.h +++ b/src/leftsuccesspagewidget.h @@ -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 diff --git a/src/main.cpp b/src/main.cpp index cc97a1e..e9caead 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,12 +15,7 @@ * along with this program; if not, see #include #include @@ -38,15 +33,17 @@ #include #include #include -#include "kabaselog.hpp" +#include +#include #include "windowmanage.hpp" -#include -#include +#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" <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 } } diff --git a/src/mainwidget.cpp b/src/mainwidget.cpp index 9d59df3..6838584 100644 --- a/src/mainwidget.cpp +++ b/src/mainwidget.cpp @@ -21,32 +21,26 @@ #include #include #include -#include -#include -#include +#include +#include "Qt/windowmanage.hpp" +#include #include +#include +#include +#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::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::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() diff --git a/src/mainwidget.h b/src/mainwidget.h index 2394b53..afbc6fa 100644 --- a/src/mainwidget.h +++ b/src/mainwidget.h @@ -41,8 +41,6 @@ #include #include #include -#include -#include #include #include #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 #include "usbhotplugthread.h" -#include "utils/rotatechangeinfo.h" - #include - +#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 m_msgBoxList; - bool isDarkTheme(); + WaittingDialog *m_waittingDialog = nullptr; + + deviceFinder *m_devFinder = nullptr; + QList 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 diff --git a/src/navigator.cpp b/src/navigator.cpp new file mode 100644 index 0000000..c357037 --- /dev/null +++ b/src/navigator.cpp @@ -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; +} diff --git a/src/navigator.h b/src/navigator.h new file mode 100644 index 0000000..8ea8483 --- /dev/null +++ b/src/navigator.h @@ -0,0 +1,38 @@ +#ifndef NAVIGATOR_H +#define NAVIGATOR_H + +#include +#include +#include +#include +#include +#include + +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 diff --git a/src/newdevicelistpage.cpp b/src/newdevicelistpage.cpp new file mode 100644 index 0000000..e345211 --- /dev/null +++ b/src/newdevicelistpage.cpp @@ -0,0 +1,376 @@ +#include "newdevicelistpage.h" +#include "Qt/windowmanage.hpp" +#include +#include "buriedpoint.hpp" + +newDeviceListPage::newDeviceListPage(QList 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 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 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 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; iobjectName() == "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; iobjectName() == "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; iobjectName() == "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; iobjectName() == "MainWindow") { + widget = widgetList.at(i); + } + } + if (widget) { + QRect rect = widget->geometry(); + qDebug() << "!!!!!!!!!!!!!!rect: " <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; iobjectName() == "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(); +} + diff --git a/src/newdevicelistpage.h b/src/newdevicelistpage.h new file mode 100644 index 0000000..79f8211 --- /dev/null +++ b/src/newdevicelistpage.h @@ -0,0 +1,93 @@ +#ifndef NEWDEVICELISTPAGE_H +#define NEWDEVICELISTPAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 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 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 diff --git a/src/nodevicewidget.cpp b/src/nodevicewidget.cpp new file mode 100644 index 0000000..d5f35c3 --- /dev/null +++ b/src/nodevicewidget.cpp @@ -0,0 +1,39 @@ +#include "nodevicewidget.h" +#include + +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); +} diff --git a/src/nodevicewidget.h b/src/nodevicewidget.h new file mode 100644 index 0000000..2158a2e --- /dev/null +++ b/src/nodevicewidget.h @@ -0,0 +1,26 @@ +#ifndef NODEVICEWIDGET_H +#define NODEVICEWIDGET_H + +#include +#include +#include +#include + +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 diff --git a/src/ocrobject.cpp b/src/ocrobject.cpp deleted file mode 100644 index 2c53c81..0000000 --- a/src/ocrobject.cpp +++ /dev/null @@ -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(); - -} diff --git a/src/ocrobject.h b/src/ocrobject.h deleted file mode 100644 index e14063c..0000000 --- a/src/ocrobject.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef OCROBJECT_H -#define OCROBJECT_H - -#include -#include - -#include -#include -#include - -#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 diff --git a/src/rectify.cpp b/src/rectify.cpp index b117602..d7968cd 100644 --- a/src/rectify.cpp +++ b/src/rectify.cpp @@ -20,269 +20,113 @@ #include -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 horizontalGradient; + QVector verticalGradient; - //通过霍夫变换检测直线 - // 600 dpi: Threshold = 750 - std::vector 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 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 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; } diff --git a/src/rectify.h b/src/rectify.h index 9e02bad..b3b809a 100644 --- a/src/rectify.h +++ b/src/rectify.h @@ -19,22 +19,16 @@ #ifndef RECTIFY_H #define RECTIFY_H -#include -#include -#include -#include -#include -#include -#include -using namespace cv; -//using namespace std; +#include +#include +#include #include "include/common.h" -#define ERROR 1234 +int ImageRectify(QImage *src); -int ImageRectify(cv::Mat *src); +double caculateSkewAngle(QImage *src); #endif // RECTIFY_H diff --git a/src/runningdialog.cpp b/src/runningdialog.cpp index 1063ab6..2b294f0 100644 --- a/src/runningdialog.cpp +++ b/src/runningdialog.cpp @@ -17,8 +17,8 @@ */ #include "runningdialog.h" -#include -#include "kabase/Qt/windowmanage.hpp" +#include +#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; diff --git a/src/runningdialog.h b/src/runningdialog.h index 0d9b60d..37f438f 100644 --- a/src/runningdialog.h +++ b/src/runningdialog.h @@ -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(); diff --git a/src/saneobject.cpp b/src/saneobject.cpp index 9020a0a..1a9a600 100644 --- a/src/saneobject.cpp +++ b/src/saneobject.cpp @@ -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(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(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(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: " <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(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(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; } diff --git a/src/saneobject.h b/src/saneobject.h index 91d7d52..0b3d126 100644 --- a/src/saneobject.h +++ b/src/saneobject.h @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include @@ -41,7 +39,17 @@ #include #include #include -//using namespace std; + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sane/sane.h" +#include "sane/saneopts.h" + +#ifdef __cplusplus +} +#endif #include "globalsignal.h" #include @@ -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 -#include -#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(); diff --git a/src/scandialog.cpp b/src/scandialog.cpp index 191bc65..10c5edd 100644 --- a/src/scandialog.cpp +++ b/src/scandialog.cpp @@ -1,8 +1,8 @@ #include "scandialog.h" +#include +#include "Qt/windowmanage.hpp" #include "./utils/xatom-helper.h" #include "globalsignal.h" -#include "kabase/Qt/windowmanage.hpp" -#include #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); diff --git a/src/scandialog.h b/src/scandialog.h index 87742ba..6bb38f3 100644 --- a/src/scandialog.h +++ b/src/scandialog.h @@ -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; diff --git a/src/scansettingswidget.cpp b/src/scansettingswidget.cpp index a6c12b2..68c5b25 100644 --- a/src/scansettingswidget.cpp +++ b/src/scansettingswidget.cpp @@ -29,24 +29,27 @@ #include #include #include -#include -#include +#include +#include #include #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 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 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:"< 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 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 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; iobjectName() == "MainWindow") { + widget = widgetList.at(i); + } + } + m_waittingDialog = new WaittingDialog(widget); + m_waittingDialog->show(); + + std::map 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; iobjectName() == "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); diff --git a/src/scansettingswidget.h b/src/scansettingswidget.h index c1870fa..b53dd67 100644 --- a/src/scansettingswidget.h +++ b/src/scansettingswidget.h @@ -49,7 +49,10 @@ #include #include #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 m_noDriverDevices; + newDeviceListPage *m_deviceListPage = nullptr; + bool isDarkTheme(); bool showRunningDialog(); private slots: - void initTheme(); void setScanIconDisable(); + void showNewDeviceListPageSuccessSlot(); + void showNewDeviceListPageFailSlot(); }; diff --git a/src/sendmail.cpp b/src/sendmail.cpp index 9cb59c1..643b29a 100644 --- a/src/sendmail.cpp +++ b/src/sendmail.cpp @@ -15,25 +15,26 @@ * along with this program; if not, see #include "sendmail.h" -#include -#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(); } diff --git a/src/sendmail.h b/src/sendmail.h index 87475ce..071c07f 100644 --- a/src/sendmail.h +++ b/src/sendmail.h @@ -41,14 +41,14 @@ #include #include #include - +#include #include #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 m_desktopName; diff --git a/src/showimagewidget.cpp b/src/showimagewidget.cpp index 2253048..b599515 100644 --- a/src/showimagewidget.cpp +++ b/src/showimagewidget.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #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); +} diff --git a/src/showimagewidget.h b/src/showimagewidget.h index 4305473..6b56a70 100644 --- a/src/showimagewidget.h +++ b/src/showimagewidget.h @@ -23,25 +23,18 @@ #include #include -#include -#include -#include -using namespace cv; - -//#include - #include "globalsignal.h" #include "saneobject.h" #include "toolbarwidget.h" #include "watermarkdialog.h" #include "crop.h" -#include "beauty.h" #include "rectify.h" #include "include/common.h" #include "utils/copyoperation.h" #include "imageOp/imageoperationbase.h" #include "imageBaseOP/savefilebase.h" #include +#include "navigator.h" #define ShowImageWidgetMinimumSize QSize(387, 536) #define CancelOkWidgetFixedSize QSize(92, 36) @@ -63,9 +56,19 @@ public: void setPdfSize(QPdfWriter *pdfWriter, QString size); void saveToPdf(QImage img, QString pathname); - QImage *imageSave(QString filename); + QImage m_navigationImage; //导航栏背景 + int m_spaceWidth = 0; //导航栏窗口与缩略图左边缘距离 + int m_spaceHeight = 0; //导航栏窗口与缩略图上边缘距离 + QSize m_hightlightSize; //高亮区域大小; + QSize m_tmpSize; //按比例缩放后的图片大小 + QPoint m_clickBeforePosition = QPoint(0, 0); //记录上次点击区域,用于提升体验 + QImage *imageSave(QString filename); QString setPixmapScaled(QImage img, QLabel *lab, double scale = 1.0); + QString setCropPixmapScaled(QImage img, QLabel *lab, double scale = 1.0); + QImage pictureDeepen(const QImage &img, const QSize &hightlightSize, const QPoint &point); //图片加深 + int boundaryJudg(int max, int point); + int minNumIsZero(const int &num1, const int &num2); void setPixmapScaledByProportion(double scaledNumber); @@ -85,13 +88,13 @@ public: const int defaultImageLableHeight = 536; QSize defaultScanImageSize; - QImage *m_stackImage; - QImage *m_editImage; - QImage *m_normalImage; + QImage *m_stackImage = nullptr; + QImage *m_editImage = nullptr; + QImage *m_normalImage = nullptr; QList m_normalImageList; QPixmap m_normalPixmap; QStack m_imageStack; - + QPixmap m_nowImage; protected: void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; @@ -104,8 +107,6 @@ public slots: void loadImageFinishedSlot(QString, double, QImage); void showNormalImageAfterScan(QStringList, QStringList); - QPixmap resizePix(const QPixmap &pixmap , const QSize &size); - void showImageAfterClickedThumbnail(QString loadPath); void saveImage(QString filename); @@ -127,11 +128,12 @@ public slots: void saveCurrentPicture(); void loadAfterBROPicture(); - - void themeChangedSlot(); void cropCancelSlot(); void cropCompleteSlot(); + void naviChange(); //改变导航栏位置 + void resetNavigator(); + private: QString m_loadPathDelayUpdate; QString m_savePathDelayUpdate; @@ -144,43 +146,53 @@ private: double proportion = 1.0; double proportionForPercentage = 1.0; - Mat matImage; - QLabel *m_showImageLabel = nullptr; QLabel *m_waitingImageLabel = nullptr; QStackedLayout *m_stackedLayout = nullptr; QWidget *m_labelWidget = nullptr; - CropLabel *m_cropLabel; - QStackedWidget *m_showImageAndCropWidget; - QHBoxLayout *m_showImageHLayout; + CropLabel *m_cropLabel = nullptr; + QStackedWidget *m_showImageAndCropWidget = nullptr; + QHBoxLayout *m_showImageHLayout = nullptr; - QWidget *m_cancelOkWidget; - QHBoxLayout *m_cancelOkLayout; - QPushButton *m_cancelButton; - QPushButton *m_okButton; + QWidget *m_cancelOkWidget = nullptr; + QHBoxLayout *m_cancelOkLayout = nullptr; + QPushButton *m_cancelButton = nullptr; + QPushButton *m_okButton = nullptr; - ToolBarWidget *m_toolbarWidget; + ToolBarWidget *m_toolbarWidget = nullptr; CopyOperation *toolObject = nullptr; - QVBoxLayout *m_mainVLayout; + QVBoxLayout *m_mainVLayout = nullptr; ImageOperationBase *imageOp = nullptr; QThread *imageOpThread = nullptr; + ImageOperationBase *imageOpOcr = nullptr; + QThread *imageOpOcrThread = nullptr; + + LoadImage *loadImg = nullptr; QThread loadImgOP; QMovie *m_loadingMovie = nullptr; SaveFileBase m_saveFileBase; + Navigator *m_navigator = nullptr; + void setCancelWidgetPositon(); void drawShadow(); + void createNavigation(); + void clickNavigation(const QPoint &point = QPoint(-1, -1)); + QPixmap localAmplification(const QPixmap &orgPix, QSize showSize, QPoint local, QSize widSize); + signals: void beautySignal(); void rectifySignal(); void OCRSignal(); void rotateSignal(); void mirrorSignal(); + void showNavigation(QPixmap pix); //操作导航器 + void sendHightlightPos(QPoint startPos, QPoint endPos); //给前端发送导航器高亮区域范围 void loadImgSignal(QString loadPath, QString savePath, QImage *img, QLabel *container,double scale, bool rotationFlag,QSize labSize); diff --git a/src/showocrwidget.cpp b/src/showocrwidget.cpp index 836fcb2..0f8aee3 100644 --- a/src/showocrwidget.cpp +++ b/src/showocrwidget.cpp @@ -1,6 +1,8 @@ #include "showocrwidget.h" #include #include +#include +#include showOcrWidget::showOcrWidget(QWidget *parent) : QLabel(parent) , m_ocrImageLabel (new QLabel()) @@ -29,33 +31,25 @@ void showOcrWidget::setupGui() m_ocrTextEdit->setText(tr("The document is in character recognition ...")); m_ocrTextEdit->setReadOnly(true); -// m_ocrTextEdit->setMinimumSize(QSize(612-AddWidthForLargeFontSize, 398)); m_ocrTextEdit->setMinimumSize(QSize(580-AddWidthForLargeFontSize, 370)); -// m_ocrTextEditHLayout->setSpacing(0); -// m_ocrTextEditHLayout->addStretch(); - m_ocrTextEditHLayout->addWidget(m_ocrTextEdit, 0, Qt::AlignCenter | Qt::AlignVCenter |Qt::AlignHCenter); -// m_ocrTextEditHLayout->addStretch(); + m_ocrTextEditHLayout->addWidget(m_ocrTextEdit, 0, Qt::AlignCenter | Qt::AlignVCenter |Qt::AlignHCenter); m_ocrTextEditHLayout->setContentsMargins(12, 12, 12, 12); m_ocrTextEditContainer->setLayout(m_ocrTextEditHLayout); style_changed(); m_toolbarWidget->ocrOtherIconState(true); - m_ocrVLayout->setSpacing(0); m_ocrVLayout->addSpacing(12); m_ocrVLayout->addLayout(m_ocrImageHLayout); -// m_ocrVLayout->addWidget(m_ocrImageLabel, 0, Qt::AlignCenter | Qt::AlignVCenter |Qt::AlignHCenter); m_ocrVLayout->addSpacing(12); m_ocrVLayout->addStretch(); m_ocrVLayout->addWidget(m_ocrTextEditContainer); -// m_ocrVLayout->addWidget(m_ocrTextEdit, 0, Qt::AlignCenter |Qt::AlignVCenter |Qt::AlignHCenter); m_ocrVLayout->addSpacing(12); m_ocrVLayout->addStretch(); m_ocrVLayout->addWidget(m_toolbarWidget, 0, Qt::AlignCenter |Qt::AlignVCenter |Qt::AlignHCenter); m_ocrVLayout->addSpacing(17); -// m_ocrVLayout->addStretch(); m_ocrVLayout->setContentsMargins(20, 0, 20, 0); this->setLayout(m_ocrVLayout); @@ -66,7 +60,7 @@ void showOcrWidget::setupGui() bool showOcrWidget::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; @@ -77,12 +71,10 @@ bool showOcrWidget::isDarkTheme() void showOcrWidget::initConnect() { - connect(g_user_signal, &GlobalUserSignal::toolbarOcrOperationStartSignal, this, &showOcrWidget::startScanSlot); + connect(g_user_signal, &GlobalUserSignal::showScanWidgetSignal, this, &showOcrWidget::startScanSlot); connect(g_user_signal, &GlobalUserSignal::toolbarOcrOperationFinishedSignal, this, &showOcrWidget::updateOcrTextEdit); - -// connect(g_user_signal, &GlobalUserSignal::startScanOperationSignal, this, &showOcrWidget::stopScanStop); connect(g_user_signal, &GlobalUserSignal::stopOcrTimerSignal, this, &showOcrWidget::stopScanStop); - connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &showOcrWidget::style_changed); + connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemThemeChange, this, &showOcrWidget::style_changed); } void showOcrWidget::style_changed(){ QPalette pal(m_ocrTextEditContainer->palette()); @@ -97,6 +89,11 @@ void showOcrWidget::style_changed(){ } +void showOcrWidget::setOcrText() +{ + m_ocrTextEdit->setText(g_sane_object->ocrOutputText); +} + void showOcrWidget::resizeEvent(QResizeEvent *event) { // todo: auto update size of m_ocrImageLabel, m_ocrTextEdit, m_toolbarWidget @@ -112,16 +109,12 @@ void showOcrWidget::showScanLine() scanHeight = 0; } - QPixmap pix; - QString pixFileName = QString(ScanningPicture); - - QPixmap pixScan(":/scan-line.png"); - pix.load(pixFileName); pix = pix.scaled(m_ocrImageLabel->width(), m_ocrImageLabel->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); m_ocrImageLabel->setPixmap(pix); + QPixmap pixScan(":/scan-line.png"); QPainter painter(&pix); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(Qt::transparent); @@ -133,19 +126,17 @@ void showOcrWidget::showScanLine() void showOcrWidget::loadScanningPicture() { QPixmap pix; - QString pixFileName = QString(ScanningPicture); - pix.load(pixFileName); pix = pix.scaled(m_ocrImageLabel->width(), m_ocrImageLabel->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); m_ocrImageLabel->setPixmap(pix); - } -void showOcrWidget::startScanSlot() +void showOcrWidget::startScanSlot(QString pic_path) { if (g_sane_object->cropFlag == 1) { return; } + pixFileName = pic_path; KyInfo() << "start ocr scan"; m_ocrTextEdit->setText(tr("The document is in character recognition ...")); timer->start(10); @@ -170,6 +161,7 @@ void showOcrWidget::updateOcrTextEdit() loadScanningPicture(); - m_ocrTextEdit->setText(g_sane_object->ocrOutputText); + emit updateTextEdit(); +// m_ocrTextEdit->setText(g_sane_object->ocrOutputText); } diff --git a/src/showocrwidget.h b/src/showocrwidget.h index 4d996e6..f593214 100644 --- a/src/showocrwidget.h +++ b/src/showocrwidget.h @@ -33,27 +33,31 @@ public slots: void showScanLine(); void loadScanningPicture(); - void startScanSlot(); + void startScanSlot(QString pic_path); void stopScanStop(); void updateOcrTextEdit(); void style_changed(); + void setOcrText(); +signals: + void updateTextEdit(); private: - QLabel *m_ocrImageLabel; - QHBoxLayout *m_ocrImageHLayout; + QLabel *m_ocrImageLabel = nullptr; + QHBoxLayout *m_ocrImageHLayout = nullptr; - QTextEdit *m_ocrTextEdit; - QHBoxLayout *m_ocrTextEditHLayout; + QTextEdit *m_ocrTextEdit = nullptr; + QHBoxLayout *m_ocrTextEditHLayout = nullptr; - QWidget *m_ocrTextEditContainer; + QWidget *m_ocrTextEditContainer = nullptr; - ToolBarWidget *m_toolbarWidget; + ToolBarWidget *m_toolbarWidget = nullptr; - QVBoxLayout *m_ocrVLayout; + QVBoxLayout *m_ocrVLayout = nullptr; - QTimer *timer; + QTimer *timer = nullptr; int scanHeight = 0; + QString pixFileName; bool isDarkTheme(); diff --git a/src/singleapplication.h b/src/singleapplication.h index 5141580..dc9fbbd 100644 --- a/src/singleapplication.h +++ b/src/singleapplication.h @@ -33,7 +33,7 @@ public: bool isRunning(); bool isExitWindow(); - MainWidget *w; + MainWidget *w = nullptr; private slots: void _newLocalConnection(); @@ -45,7 +45,7 @@ private: bool _isRunning; bool _isExitWindow; - QLocalServer *_localServer; + QLocalServer *_localServer = nullptr; QString _serverName; }; diff --git a/src/successpagewidget.cpp b/src/successpagewidget.cpp index 1a1947e..5cd0a9a 100644 --- a/src/successpagewidget.cpp +++ b/src/successpagewidget.cpp @@ -20,14 +20,12 @@ SuccessPageWidget::SuccessPageWidget(QWidget *parent) : QWidget(parent), - m_leftStackSuccessPageWidget(new QStackedWidget), - m_scanSettingsWidget(new ScanSettingsWidget()), - m_scanSettingsSrollArea(new QScrollArea()), - m_leftImageHandleSuccessPageWidget(new LeftImageHandleSuccessPageWidget()), -// m_leftImageHandleSuccssPageScrollArea(new QScrollArea()), - m_leftSuccessPageWidget(new LeftSuccessPageWidget()), -// m_leftSuccessPageScrollArea(new QScrollArea()), - m_successPageHLayout(new QHBoxLayout()) + m_leftStackSuccessPageWidget(new QStackedWidget(this)), + m_scanSettingsWidget(new ScanSettingsWidget(this)), + m_scanSettingsSrollArea(new QScrollArea(this)), + m_leftImageHandleSuccessPageWidget(new LeftImageHandleSuccessPageWidget(this)), + m_leftSuccessPageWidget(new LeftSuccessPageWidget(this)), + m_successPageHLayout(new QHBoxLayout(this)) { setupGui(); initConnect(); @@ -35,32 +33,10 @@ SuccessPageWidget::SuccessPageWidget(QWidget *parent) : void SuccessPageWidget::setupGui() { -// m_leftImageHandleSuccssPageScrollArea->setWidget(m_leftImageHandleSuccessPageWidget); -// m_leftImageHandleSuccssPageScrollArea->setWidgetResizable(true); -// m_leftImageHandleSuccssPageScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -// m_leftImageHandleSuccssPageScrollArea->setFrameShape(QFrame::NoFrame); -// m_leftImageHandleSuccessPageWidget->adjustSize(); -// m_leftImageHandleSuccssPageScrollArea->setMinimumWidth(LeftImageHandleSuccessPageWidth); - - -// m_leftSuccessPageScrollArea->setWidget(m_leftSuccessPageWidget); -// m_leftSuccessPageScrollArea->setWidgetResizable(true); -// m_leftSuccessPageScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -// m_leftSuccessPageScrollArea->setFrameShape(QFrame::NoFrame); -// m_leftSuccessPageWidget->adjustSize(); -// m_leftSuccessPageScrollArea->setMinimumWidth(LeftSuccessPageWidth); - -// m_leftStackSuccessPageWidget->addWidget(m_leftImageHandleSuccssPageScrollArea); -// m_leftStackSuccessPageWidget->addWidget(m_leftSuccessPageScrollArea); -// m_leftStackSuccessPageWidget->setCurrentWidget(m_leftSuccessPageScrollArea); m_leftStackSuccessPageWidget->addWidget(m_leftImageHandleSuccessPageWidget); m_leftStackSuccessPageWidget->addWidget(m_leftSuccessPageWidget); m_leftStackSuccessPageWidget->setCurrentWidget(m_leftSuccessPageWidget); - if (g_config_signal->m_hideScanSettingsWidget) { - m_scanSettingsWidget->hide(); - } - m_scanSettingsSrollArea->setWidget(m_scanSettingsWidget); m_scanSettingsSrollArea->setWidgetResizable(true); m_scanSettingsSrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -73,7 +49,7 @@ void SuccessPageWidget::setupGui() m_successPageHLayout->addWidget(m_scanSettingsSrollArea); m_successPageHLayout->setContentsMargins(0, 0, 0, 0); - setLayout(m_successPageHLayout); + this->setLayout(m_successPageHLayout); } void SuccessPageWidget::initConnect() diff --git a/src/successpagewidget.h b/src/successpagewidget.h index dc0ea6d..2375cb7 100644 --- a/src/successpagewidget.h +++ b/src/successpagewidget.h @@ -48,18 +48,12 @@ public slots: private: - QStackedWidget *m_leftStackSuccessPageWidget; - - ScanSettingsWidget *m_scanSettingsWidget; - QScrollArea *m_scanSettingsSrollArea; - - LeftImageHandleSuccessPageWidget *m_leftImageHandleSuccessPageWidget; -// QScrollArea *m_leftImageHandleSuccssPageScrollArea; - - LeftSuccessPageWidget *m_leftSuccessPageWidget; -// QScrollArea *m_leftSuccessPageScrollArea; - - QHBoxLayout *m_successPageHLayout; + QStackedWidget *m_leftStackSuccessPageWidget = nullptr; + ScanSettingsWidget *m_scanSettingsWidget = nullptr; + QScrollArea *m_scanSettingsSrollArea = nullptr; + LeftImageHandleSuccessPageWidget *m_leftImageHandleSuccessPageWidget = nullptr; + LeftSuccessPageWidget *m_leftSuccessPageWidget = nullptr; + QHBoxLayout *m_successPageHLayout = nullptr; }; diff --git a/src/thumbnaildelegate.h b/src/thumbnaildelegate.h index bca7fd2..5d60b17 100644 --- a/src/thumbnaildelegate.h +++ b/src/thumbnaildelegate.h @@ -16,8 +16,6 @@ public: QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; -signals: - }; #endif // THUMBNAILDELEGATE_H diff --git a/src/thumbnailwidget.cpp b/src/thumbnailwidget.cpp index 3b9486b..e460e6f 100644 --- a/src/thumbnailwidget.cpp +++ b/src/thumbnailwidget.cpp @@ -1,6 +1,8 @@ #include "thumbnailwidget.h" #include #include +#include +#include #include "include/theme.h" int ThumbnailWidget::scanPictureCount = 0; @@ -13,7 +15,6 @@ ThumbnailWidget::ThumbnailWidget(QWidget *parent) : QListView(parent) themeChange(); } - void ThumbnailWidget::setupGui() { setAutoFillBackground(true); @@ -39,7 +40,7 @@ void ThumbnailWidget::setupGui() setAcceptDrops(false); setFocusPolicy(Qt::NoFocus); - this->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } @@ -48,16 +49,18 @@ void ThumbnailWidget::initConnect() connect(g_user_signal, &GlobalUserSignal::scanThreadFinishedImageLoadSignal, this, &ThumbnailWidget::showNormalImagesAfterScan); connect(this, &ThumbnailWidget::clicked, this, &ThumbnailWidget::clickedItemSlot); - connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &ThumbnailWidget::themeChange); + connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemThemeChange, this, &ThumbnailWidget::themeChange); } + void ThumbnailWidget::themeChange() { } + bool ThumbnailWidget::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; @@ -107,10 +110,13 @@ void ThumbnailWidget::showNormalImageAfterScan(QString loadPath, QString savePat int rowcount = m_thumbnailItemModel->rowCount(); KyInfo() << "rowcount = " << rowcount << "scanFullName = " << scanFullName; - QImage iconImage(loadPath); - QPixmap pixmap = QPixmap::fromImage(iconImage); + QString newScanFullName = QFileInfo(scanFullName).absolutePath() + "/" + QFileInfo(scanFullName).baseName() + ".jpg"; - QPixmap fitpixmap = pixmap.scaled(QSize(40, 40), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + cimg_library::CImg img(scanFullName.toLocal8Bit().data()); + img.save_jpeg(newScanFullName.toLocal8Bit().data()); + QPixmap iconPix(newScanFullName); + + QPixmap fitpixmap = iconPix.scaled(QSize(40, 40), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); qDebug() << "image mesg:" << fitpixmap; ScanStandardItem *item = new ScanStandardItem(); @@ -139,6 +145,10 @@ void ThumbnailWidget::showNormalImagesAfterScan(QStringList loadPathes, QStringL void ThumbnailWidget::clickedItemSlot(const QModelIndex &index) { + if(g_sane_object->cropFlag == 1){ + g_user_signal->cancleCorpSignal(); + } + ScanStandardItem *item = dynamic_cast(m_thumbnailItemModel->itemFromIndex(index)); if (item) { int scanIconNumber = item->getRowCountLocation(); @@ -146,9 +156,10 @@ void ThumbnailWidget::clickedItemSlot(const QModelIndex &index) KyInfo() << "scanIconPath = " << scanIconNumber << loadPath; - g_user_signal->showImageAfterClickedThumbnail(loadPath); - + g_user_signal->showImageAfterClickedThumbnail(loadPath); + g_user_signal->resetNavigatorsignal(); } + g_user_signal->exitWindowWithSaveFlag = false; } diff --git a/src/thumbnailwidget.h b/src/thumbnailwidget.h index 6c89342..03e1674 100644 --- a/src/thumbnailwidget.h +++ b/src/thumbnailwidget.h @@ -26,11 +26,6 @@ #include #include -#include -#include -#include -using namespace cv; - class ScanStandardItem: public QStandardItem { @@ -67,10 +62,9 @@ protected: private: - ThumbnailDelegate *m_thumbnailDelegate; - QStandardItemModel *m_thumbnailItemModel; + ThumbnailDelegate *m_thumbnailDelegate = nullptr; + QStandardItemModel *m_thumbnailItemModel = nullptr; -signals: public slots: void showThumbnailIcon(); diff --git a/src/titlebar/titlebar.cpp b/src/titlebar/titlebar.cpp index 9fed8f1..6b2749a 100644 --- a/src/titlebar/titlebar.cpp +++ b/src/titlebar/titlebar.cpp @@ -18,8 +18,9 @@ #include "titlebar.h" #include "ui_titlebar.h" #include -#include -#include +#include +#include +#include TitleBar::TitleBar(QWidget *parent) : QWidget(parent), @@ -27,10 +28,12 @@ TitleBar::TitleBar(QWidget *parent) : m_menu(new QMenu(this)) { ui->setupUi(this); - ui->m_logoBtn->setFlat(true); - ui->m_logoBtn->setCheckable(false); ui->m_logoBtn->setProperty("useIconHighlightEffect", 0x0); ui->m_logoBtn->setAttribute(Qt::WA_TransparentForMouseEvents, true); + ui->m_logoBtn->setFlat(true); + ui->m_logoBtn->setCheckable(false); + ui->m_logoBtn->setStyleSheet("QPushButton{border:0px; border-radius:4px; background:transparent;}"); + setAutoFillBackground(true); setBackgroundRole(QPalette::Base); this->setWindowTitle("Scanner"); @@ -63,8 +66,7 @@ TitleBar::TitleBar(QWidget *parent) : showHelpDialog(); });//, QKeySequence(Qt::Key_F1) - m_menu->addAction(tr("About"), this, [ = ]() { -// g_user_signal->showAboutDialog(); + m_menu->addAction(tr("About"), this, [=]() { using namespace kdk; m_aboutWindow = new KAboutDialog(this,QIcon::fromTheme("kylin-scanner"),tr(appShowingName.toLocal8Bit()),tr("Version: ") + appVersion); m_aboutWindow->setBodyText(tr("Message provides text chat and file transfer functions in the LAN. " @@ -83,16 +85,15 @@ TitleBar::TitleBar(QWidget *parent) : int saveFlag = warnCloseWindow(); if (saveFlag == 1) { KyInfo() << "close window save as"; - g_user_signal->closeWindowSaveAs(); + g_user_signal->closeWindowSaveAs(true); } } - g_user_signal->exitApplication(); } ); ui->m_OptionBtn->setMenu(m_menu); bool isPCMode = GlobalUserSignal::getInstance()->getCurrentMode(); rotateChangedSlot(isPCMode); -// connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemFontSizeChange, this, &TitleBar::fontSizeChanged); +// connect(kdk::kabase::Gsettings::getPoint(), &kdk::GsettingMonitor::systemFontSizeChange, this, &TitleBar::fontSizeChanged); connect(m_themeData, &QGSettings::changed, this, &TitleBar::fontSizeChanged); } @@ -148,6 +149,7 @@ void TitleBar::paintEvent(QPaintEvent *event) QColor mainColor; mainColor = opt.palette.color(QPalette::Base); p.fillPath(rectPath,QBrush(mainColor)); + p.end(); } void TitleBar::updateMaxButtonStatus(bool isMax) @@ -188,28 +190,21 @@ void TitleBar::on_m_closeBtn_clicked() int saveFlag = warnCloseWindow(); if (saveFlag == 1) { KyInfo() << "close window save as"; - g_user_signal->closeWindowSaveAs(); + g_user_signal->closeWindowSaveAs(true); } + }else{ + g_user_signal->exitApplication(); } - g_user_signal->exitApplication(); } void TitleBar::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; -// QString appName = "kylin-scanner"; -// KYCDaemonDbusObject *ipcDbus = new KYCDaemonDbusObject(); - -// if (!ipcDbus->daemonIsNotRunning()) { -// ipcDbus->showGuide(appName); -// } else { -// KyInfo() << "Guide is Running."; -// } } int TitleBar::warnCloseWindow() @@ -218,16 +213,12 @@ int TitleBar::warnCloseWindow() QMessageBox *msgBox = new QMessageBox(); msgBox->setModal(Qt::WindowModal); msgBox->setAttribute(Qt::WA_ShowModal, true); - - msgBox->setText(tr("The current document is not saved. Do you want to save it?")); + connect(msgBox, &QMessageBox::accepted, msgBox, &QMessageBox::deleteLater); + msgBox->setText(tr("The current file is not saved. Do you want to save it?")); msgBox->setIcon(QMessageBox::Warning); -// msgBox->setWindowIcon(QIcon::fromTheme("kylin-scanner")); msgBox->setWindowTitle(tr("Scanner")); -// msgBox->setStandardButtons(QMessageBox::Yes); msgBox->setContextMenuPolicy(Qt::NoContextMenu); -// msgBox->button(QMessageBox::Yes)->setText(tr("Yes")); QAbstractButton *noButton = (QAbstractButton *)msgBox->addButton(tr("Straight &Exit"), QMessageBox::NoRole); -// QAbstractButton *thinkButton = (QAbstractButton *)msgBox->addButton(QString(tr("Save &Not exit")), QMessageBox::NoRole); QAbstractButton *yesButton = (QAbstractButton *)msgBox->addButton(tr("&Save Exit"), QMessageBox::YesRole); msgBox->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); @@ -247,31 +238,27 @@ int TitleBar::warnCloseWindow() msgBox->move(x,y); } - msgBox->exec(); -#if 0 - QTimer* timer = new QTimer(); - timer->start(3000); - timer->setSingleShot(true); - - connect(timer, &QTimer::timeout, msgBox, &QMessageBox::hide); -#endif - if (msgBox->clickedButton() == yesButton) { + msgBox->deleteLater(); KyInfo() << "Accepeted !"; return 1; - } else { + } else if (msgBox->clickedButton() == noButton) { + g_user_signal->exitApplication(); + msgBox->deleteLater(); KyInfo() << "Rejected !"; return 0; } + return 0; } void TitleBar::fontSizeChanged() { - float systemFontSize = kdk::kabase::Gsettings::getSystemFontSize().toFloat(); + float systemFontSize = kdk::GsettingMonitor::getSystemFontSize().toFloat(); QString fontType = m_themeData->get("systemFont").toString(); QFont font(fontType, systemFontSize); ui->m_appnameLabel->setFont(font); } + diff --git a/src/titlebar/titlebar.h b/src/titlebar/titlebar.h index 5d5bbfa..a560107 100644 --- a/src/titlebar/titlebar.h +++ b/src/titlebar/titlebar.h @@ -35,7 +35,7 @@ #include #include "../utils/HorizontalOrVerticalMode.h" #include "../saneobject.h" -#include "../globalsignal.h" +//#include "../globalsignal.h" namespace Ui { class TitleBar; @@ -84,7 +84,7 @@ private: Ui::TitleBar *ui; QMenu *m_menu = nullptr; kdk::KAboutDialog *m_aboutWindow = nullptr; // 关于界面 - QString appShowingName = tr("kylin-scanner"); + QString appShowingName = tr("Scanner"); QString appVersion = qApp->applicationVersion(); QGSettings *m_themeData = nullptr; }; diff --git a/src/toolbarwidget.cpp b/src/toolbarwidget.cpp index 87bca36..273a134 100644 --- a/src/toolbarwidget.cpp +++ b/src/toolbarwidget.cpp @@ -1,9 +1,12 @@ #include "toolbarwidget.h" #include #include +#include #include "include/theme.h" #include #include +#include "globalsignal.h" +#include "buriedpoint.hpp" ToolBarWidget::ToolBarWidget(QWidget *parent) : QWidget(parent), m_beautyButton(new kdk::KBorderlessButton), @@ -18,6 +21,7 @@ ToolBarWidget::ToolBarWidget(QWidget *parent) : QWidget(parent), m_zoomOutButton(new kdk::KBorderlessButton), m_percentageLabel(new QLabel), m_zoomInButton(new kdk::KBorderlessButton), + m_mutex(new QMutex()), m_mainHLayout(new QHBoxLayout(this)) { setupGui(); @@ -223,28 +227,27 @@ void ToolBarWidget::setupGui() } drawFrame(); - themeChangedSlot(); KyInfo() << "toolbarwidget size: " << this->size(); - -// QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect(this); -// effect->setOffset(0, 0); // set direction of shadow effect, especially (0,0) is on behave of spread around -// effect->setColor(QColor(220, 220, 220)); // set shadow color -// effect->setBlurRadius(20); // set blur of shadow, which means the large the radius, the more blurred -// this->setGraphicsEffect(effect); - } void ToolBarWidget::initConnect() { - connect(kdk::kabase::Gsettings::getPoint(), &kdk::kabase::Gsettings::systemThemeChange, this, &ToolBarWidget::themeChangedSlot); - connect(g_user_signal, &GlobalUserSignal::toolbarPercentageChangedSignel, this, &ToolBarWidget::percentageChangedSlot); connect(m_beautyButton, &QPushButton::clicked, this, &ToolBarWidget::beautyButtonClickedSlot); - connect(m_rectifyButton, &QPushButton::clicked, this, &ToolBarWidget::rectifyButtonClickedSlot); + connect(m_rectifyButton, &QPushButton::clicked, [=](){ + m_mutex->lock(); + rectifyButtonClickedSlot(); + m_rectifyButton->setEnabled(false); + }); + connect(g_user_signal, &GlobalUserSignal::mutexUnlockSignal, [=](){ + m_mutex->unlock(); + m_rectifyButton->setEnabled(true); + }); connect(m_ocrButton, &QPushButton::clicked, this, &ToolBarWidget::ocrButtonClickedSlot); connect(m_cropButton, &QPushButton::clicked, this, &ToolBarWidget::cropButtonClickedSlot); + connect(m_cropButton, &QPushButton::clicked, this, &ToolBarWidget::cropDoubleClickedSlot); connect(m_rotateButton, &QPushButton::clicked, this, &ToolBarWidget::rotateButtonClickedSlot); connect(m_mirrorButton, &QPushButton::clicked, this, &ToolBarWidget::mirrorButtonClickedSlot); connect(m_watermarkButton, &QPushButton::clicked, this, &ToolBarWidget::watermarkButtonClickedSlot); @@ -252,17 +255,6 @@ void ToolBarWidget::initConnect() connect(m_zoomInButton, &QPushButton::clicked, this, &ToolBarWidget::zoominButtonClickedSlot); connect(GlobalUserSignal::getInstance(), &GlobalUserSignal::rotationChangedSig, this, &ToolBarWidget::rotateChangedSlot); } -void ToolBarWidget::themeChangedSlot(){ - QString systemTheme = kdk::kabase::Gsettings::getSystemTheme().toString(); - - if (systemTheme == STYLE_NAME_KEY_DARK || systemTheme == STYLE_NAME_KEY_BLACK) { - KyInfo() << "dark theme"; - this->setStyleSheet("background: rgba(38, 38, 38, 1); box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15); border-radius: 6px; filter: blur(18px);"); - } else { - KyInfo() << "white theme"; - this->setStyleSheet("background: rgba(249, 249, 249, 0.8); box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15); border-radius: 6px; filter: blur(18px);"); - } -} void ToolBarWidget::rotateChangedSlot(bool isPCMode) { @@ -372,13 +364,18 @@ void ToolBarWidget::ocrOtherIconState(bool flag) */ void ToolBarWidget::paintEvent(QPaintEvent *event) { + Q_UNUSED(event); QStyleOption opt; opt.init(this); QPainter painter(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this); - QWidget::paintEvent(event); - + QColor mainColor; + mainColor = opt.palette.color(QPalette::Base); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect(), 0, 0); + painter.fillPath(rectPath,QBrush(mainColor)); + painter.end(); } void ToolBarWidget::keyPressEvent(QKeyEvent *event) @@ -395,97 +392,6 @@ void ToolBarWidget::keyReleaseEvent(QKeyEvent *event) return; } -void ToolBarWidget::themeChangedWhiteSlot() -{ - - -// themeChangedIconWhiteSettings(); - - this->setStyleSheet("background: rgba(249, 249, 249, 0.8); box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15); border-radius: 6px; filter: blur(18px);"); - -// m_leftFrame->setStyleSheet("background: #B3B3B3; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15);"); -// m_rightFrame->setStyleSheet("background: #B3B3B3; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15);"); - - -// m_beautyButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/beauty.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/beauty-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/beauty-blue.svg);}"); - -// m_rectifyButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rectify.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rectify-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rectify-blue.svg);}"); - -// m_ocrButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/ocr.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/ocr-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/ocr-blue.svg);}"); - -// m_cropButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/crop.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/crop-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/crop-blue.svg);}"); - -// m_rotateButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rotate.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rotate-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rotate-blue.svg);}"); - -// m_mirrorButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/mirror.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/mirror-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/mirror-blue.svg);}"); - -// m_watermarkButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/watermark.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/watermark-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/watermark-blue.svg);}"); - - -// m_zoomOutButton->setStyleSheet("background: #FFFFFF; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15); border-radius: 10px;"); -// m_percentageLabel->setStyleSheet("width: 32px; height: 18px; color: #262626;"); -// m_zoomInButton->setStyleSheet("background: #FFFFFF; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15); border-radius: 10px;"); -} - -void ToolBarWidget::themeChangedBlackSlot() -{ -// themeChangedIconBlackSettings(); - - this->setStyleSheet("background: rgba(38, 38, 38, 1); box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15); border-radius: 6px; filter: blur(18px);"); - -// m_leftFrame->setStyleSheet("background: #B3B3B3; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15);"); -// m_rightFrame->setStyleSheet("background: #B3B3B3; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15);"); - -// m_beautyButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/beauty-white.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/beauty-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/beauty-blue.svg);}"); - -// m_rectifyButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rectify-white.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rectify-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rectify-blue.svg);}"); - -// m_ocrButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/ocr-white.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/ocr-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/ocr-blue.svg);}"); - -// m_cropButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/crop-white.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/crop-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/crop-blue.svg);}"); - -// m_rotateButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rotate-white.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rotate-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/rotate-blue.svg);}"); - -// m_mirrorButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/mirror-white.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/mirror-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/mirror-blue.svg);}"); - -// m_watermarkButton->setStyleSheet("QPushButton{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/watermark-white.svg);}" -// "QPushButton::hover{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/watermark-blue.svg);}" -// "QPushButton::pressed{border:0px; border-radius: 6px; background:transparent; background-image:url(:/toolbar/watermark-blue.svg);}"); - - - -// m_zoomOutButton->setStyleSheet("background: #373738; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15); border-radius: 10px;"); -// m_percentageLabel->setStyleSheet("width: 32px; height: 18px; color: #D9D9D9;"); -// m_zoomInButton->setStyleSheet("background: #373738; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.15); border-radius: 10px;"); - -} - void ToolBarWidget::percentageChangedSlot() { KyInfo() << "percentage = " << g_sane_object->percentage; @@ -505,9 +411,12 @@ void ToolBarWidget::beautyButtonClickedSlot() qDebug() << "show beauty dialog!"; qDebug() << "continue!"; - kdk::kabase::BuriedPoint buriedPointTest; - - if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerOneClickBeautification)) { + std::map buried_data; + buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerOneClickBeautification))); + buried_data.insert(std::make_pair("action", "beauty image")); + buried_data.insert(std::make_pair("function", "in toolbarwidget.cpp function beautyButtonClickedSlots()")); + kabase::BuriedPoint buriedPointTest; + if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) { qCritical() << "Error : buried point fail !"; }; } @@ -521,11 +430,16 @@ void ToolBarWidget::rectifyButtonClickedSlot() } g_user_signal->exitWindowWithSaveFlag = true; g_user_signal->toolbarRectifyOperationStart(); - kdk::kabase::BuriedPoint buriedPointTest; - if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerRectification)) { + std::map buried_data; + buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerRectification))); + buried_data.insert(std::make_pair("action", "image rectify")); + buried_data.insert(std::make_pair("function", "in toolbarwidget.cpp function rectifyButtonClickedSlot()")); + kabase::BuriedPoint buriedPointTest; + if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) { qCritical() << "Error : buried point fail !"; - }; + } + } void ToolBarWidget::ocrButtonClickedSlot() @@ -537,18 +451,24 @@ void ToolBarWidget::ocrButtonClickedSlot() return; } emit g_user_signal->switchPageSig(); - if(g_sane_object->ocrFlag){ - ocrOtherIconState(true); + if(g_sane_object->ocrFlag){ qDebug() << "exit OCR page..."; emit g_user_signal->exitOCR(); g_sane_object->ocrFlag = 0; + ocrOtherIconState(true); + }else{ + std::map buried_data; + buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerTextRecognition))); + buried_data.insert(std::make_pair("action", "OCR")); + buried_data.insert(std::make_pair("function", "in toolbarwidget.cpp function ocrButtonClickedSlot()")); + kabase::BuriedPoint buriedPointTest; + if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) { + qCritical() << "Error : buried point fail !"; + } + ocrOtherIconState(false); g_user_signal->toolbarOcrOperationStart(); - kdk::kabase::BuriedPoint buriedPointTest; - if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerTextRecognition)) { - qCritical() << "Error : buried point fail !"; - }; g_sane_object->ocrFlag = 1; } } @@ -564,11 +484,22 @@ void ToolBarWidget::cropButtonClickedSlot() g_user_signal->exitWindowWithSaveFlag = true; g_user_signal->toolbarCropOperation(); - kdk::kabase::BuriedPoint buriedPointTest; - if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerCutting)) { + std::map buried_data; + buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerCutting))); + buried_data.insert(std::make_pair("action", "image cutting")); + buried_data.insert(std::make_pair("function", "in toolbarwidget.cpp function cropButtonClickedSlot()")); + kabase::BuriedPoint buriedPointTest; + if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) { qCritical() << "Error : buried point fail !"; - }; + } + +} + +void ToolBarWidget::cropDoubleClickedSlot() +{ + g_user_signal->toolbarCropOperation(); + g_user_signal->toolbarCropOperation(); } void ToolBarWidget::rotateButtonClickedSlot() @@ -582,11 +513,15 @@ void ToolBarWidget::rotateButtonClickedSlot() g_user_signal->exitWindowWithSaveFlag = true; g_user_signal->toolbarRotateOperation(); - kdk::kabase::BuriedPoint buriedPointTest; - if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerRotate)) { + std::map buried_data; + buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerRotate))); + buried_data.insert(std::make_pair("action", "image rotate")); + buried_data.insert(std::make_pair("function", "in toolbarwidget.cpp function rotateButtonClickedSlot()")); + kabase::BuriedPoint buriedPointTest; + if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) { qCritical() << "Error : buried point fail !"; - }; + } } void ToolBarWidget::mirrorButtonClickedSlot() @@ -600,11 +535,15 @@ void ToolBarWidget::mirrorButtonClickedSlot() g_user_signal->exitWindowWithSaveFlag = true; g_user_signal->toolbarMirrorOperation(); - kdk::kabase::BuriedPoint buriedPointTest; - if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerImage)) { + std::map buried_data; + buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerMirror))); + buried_data.insert(std::make_pair("action", "image mirror")); + buried_data.insert(std::make_pair("function", "in toolbarwidget.cpp function mirrorButtonClickedSlot()")); + kabase::BuriedPoint buriedPointTest; + if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) { qCritical() << "Error : buried point fail !"; - }; + } } void ToolBarWidget::watermarkButtonClickedSlot() @@ -618,11 +557,15 @@ void ToolBarWidget::watermarkButtonClickedSlot() g_user_signal->exitWindowWithSaveFlag = true; g_user_signal->toolbarWatermarkOperation(); - kdk::kabase::BuriedPoint buriedPointTest; - if (buriedPointTest.functionBuriedPoint(kdk::kabase::AppName::KylinScanner , kdk::kabase::BuriedPoint::PT::KylinScannerAddWatermark)) { + std::map buried_data; + buried_data.insert(std::make_pair("FunctionName", kabase::BuriedPoint::convertPTtoString(kabase::BuriedPoint::PT::KylinScannerAddWatermark))); + buried_data.insert(std::make_pair("action", "image add watermark")); + buried_data.insert(std::make_pair("function", "in toolbarwidget.cpp function watermarkButtonClickedSlot()")); + kabase::BuriedPoint buriedPointTest; + if (buriedPointTest.buriedPoint(kabase::AppName::KylinScanner, kabase::BuriedPoint::BuriedPointType::FunctionType, buried_data)) { qCritical() << "Error : buried point fail !"; - }; + } } void ToolBarWidget::zoomoutButtonClickedSlot() @@ -648,3 +591,16 @@ void ToolBarWidget::zoominButtonClickedSlot() g_user_signal->toolbarZoominOperation(); } + +void ToolBarWidget::initTimer() +{ + m_timer = new QTimer; + connect(m_timer, SIGNAL(timeout()), this, SLOT(setRectifyButtonEnable())); + m_timer->start(1500); +} + +void ToolBarWidget::setRectifyButtonEnable() +{ + m_timer->stop(); + m_rectifyButton->setEnabled(true); +} diff --git a/src/toolbarwidget.h b/src/toolbarwidget.h index a5708c9..ce66be7 100644 --- a/src/toolbarwidget.h +++ b/src/toolbarwidget.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "runningdialog.h" #include "utils/HorizontalOrVerticalMode.h" #define ToolBarWidgetColor QColor(249, 249, 249, 0.8*255) @@ -57,46 +58,47 @@ protected: public slots: - void themeChangedWhiteSlot(); - void themeChangedBlackSlot(); - void percentageChangedSlot(); void beautyButtonClickedSlot(); void rectifyButtonClickedSlot(); void ocrButtonClickedSlot(); void cropButtonClickedSlot(); + void cropDoubleClickedSlot(); void rotateButtonClickedSlot(); void mirrorButtonClickedSlot(); void watermarkButtonClickedSlot(); void zoomoutButtonClickedSlot(); void zoominButtonClickedSlot(); - void themeChangedSlot(); + void initTimer(); + void setRectifyButtonEnable(); void rotateChangedSlot(bool isPCMode); - + private: - kdk::KBorderlessButton *m_beautyButton; - kdk::KBorderlessButton *m_rectifyButton; - kdk::KBorderlessButton *m_ocrButton; + kdk::KBorderlessButton *m_beautyButton = nullptr; + kdk::KBorderlessButton *m_rectifyButton = nullptr; + kdk::KBorderlessButton *m_ocrButton = nullptr; - QFrame *m_leftFrame; + QFrame *m_leftFrame = nullptr; - kdk::KBorderlessButton *m_cropButton; - kdk::KBorderlessButton *m_rotateButton; - kdk::KBorderlessButton *m_mirrorButton; - kdk::KBorderlessButton *m_watermarkButton; + kdk::KBorderlessButton *m_cropButton = nullptr; + kdk::KBorderlessButton *m_rotateButton = nullptr; + kdk::KBorderlessButton *m_mirrorButton = nullptr; + kdk::KBorderlessButton *m_watermarkButton = nullptr; - QFrame *m_rightFrame; + QFrame *m_rightFrame = nullptr; - kdk::KBorderlessButton *m_zoomOutButton; // Make small - QLabel *m_percentageLabel; - kdk::KBorderlessButton *m_zoomInButton; // Make large + kdk::KBorderlessButton *m_zoomOutButton = nullptr; // Make small + QLabel *m_percentageLabel = nullptr; + kdk::KBorderlessButton *m_zoomInButton = nullptr; // Make large - QHBoxLayout *m_mainHLayout; + QHBoxLayout *m_mainHLayout = nullptr; RunningDialog *beautyRunningDialog = nullptr; - HorizontalOrVerticalMode m_mode; - + QTimer *m_timer = nullptr; + QMutex *m_mutex = nullptr; + HorizontalOrVerticalMode m_mode; + void drawFrame(); }; diff --git a/src/usb.cpp b/src/usb.cpp index fb89250..14bd3ac 100644 --- a/src/usb.cpp +++ b/src/usb.cpp @@ -27,6 +27,7 @@ int init_hotplug_sock() snl.nl_family = AF_NETLINK; snl.nl_pid = getpid(); snl.nl_groups = 1; +// setsockopt(SO_REUSEADDR); int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (s == -1) { perror("socket"); diff --git a/src/usbhotplugthread.cpp b/src/usbhotplugthread.cpp index ccde7a2..fa70434 100644 --- a/src/usbhotplugthread.cpp +++ b/src/usbhotplugthread.cpp @@ -14,49 +14,46 @@ static SANE_Device *g_saneDeviceusb = nullptr; void UsbHotplugThread::run() { qDebug() << "read device list complete!"; -// hotplug_sock = init_hotplug_sock(); - USBdeviceList = getConnectedScanner(); - connect(g_user_signal, &GlobalUserSignal::setExitFlagTrueSignal, this, &UsbHotplugThread::setExitFlagTrue); - connect(g_user_signal, &GlobalUserSignal::setExitFlagFalseSignal, this, &UsbHotplugThread::setExitFlagFalse); - do { - /* Netlink message buffer */ - char buf[UEVENT_BUFFER_SIZE * 2] = {0}; - recv(g_sane_object->hotplug_sock, &buf, sizeof(buf), 0); + USBdeviceList = getConnectedScanner(); + USBdeviceList.append(getConnectedScanner2()); + connect(g_user_signal, &GlobalUserSignal::setExitFlagTrueSignal, this, &UsbHotplugThread::setExitFlagTrue); + connect(g_user_signal, &GlobalUserSignal::setExitFlagFalseSignal, this, &UsbHotplugThread::setExitFlagFalse); + do { + /* Netlink message buffer */ + char buf[UEVENT_BUFFER_SIZE * 2] = {0}; + recv(g_sane_object->hotplug_sock, &buf, sizeof(buf), 0); - QString recvData = QString(buf); - - if (recvData.contains("add@", Qt::CaseInsensitive) - && recvData.contains("devices", Qt::CaseInsensitive) - && recvData.contains("usb", Qt::CaseInsensitive) - && recvData.endsWith(":1.0", Qt::CaseInsensitive)) { - // ":1.0" means each usb device first directory, which is must -// emit usbAdd(recvData); - if(usbDeviceIdentify(recvData)){ - while(1){ - if(!g_sane_object->usbRemoveSlotIsRunning){ - usbAddSlot(recvData); - break; - } - } - } - } else if (recvData.contains("remove@", Qt::CaseInsensitive) - && recvData.contains("devices", Qt::CaseInsensitive) - && recvData.contains("usb", Qt::CaseInsensitive) - && recvData.endsWith(":1.0", Qt::CaseInsensitive)) { -// emit usbRemove(recvData); - if(isRemoveScanner(recvData)){ - while(1){ - if(!g_sane_object->usbAddSlotIsRunning){ - removeToDeviceList(recvData); - usbRemoveSlot(); - break; - } + QString recvData = QString(buf); + if (recvData.contains("add@", Qt::CaseInsensitive) + && recvData.contains("devices", Qt::CaseInsensitive) + && recvData.contains("usb", Qt::CaseInsensitive) + && recvData.endsWith(":1.0", Qt::CaseInsensitive)){ + // ":1.0" means each usb device first directory, which is must + if(usbDeviceIdentify(recvData)){ + while(1){ + if(!g_sane_object->usbRemoveSlotIsRunning){ + usbAddSlot(recvData); + break; } } } - } while (! exitWindowFlag); - quit(); + } else if (recvData.contains("remove@", Qt::CaseInsensitive) + && recvData.contains("devices", Qt::CaseInsensitive) + && recvData.contains("usb", Qt::CaseInsensitive) + && recvData.endsWith(":1.0", Qt::CaseInsensitive)){ + if(isRemoveScanner(recvData)){ + while(1){ + if(!g_sane_object->usbAddSlotIsRunning){ + removeToDeviceList(recvData); + usbRemoveSlot(); + break; + } + } + } + } + } while (! exitWindowFlag); + quit(); } void UsbHotplugThread::setExitFlagTrue() @@ -72,6 +69,7 @@ void UsbHotplugThread::setExitFlagFalse() void UsbHotplugThread::usbAddSlot(QString qstr){ g_sane_object->usbAddSlotIsRunning = true; qDebug() << "新的usb插入了"; + while(1){ // 不在运行时再对设备列表进行刷新 if(!g_sane_object->isOnScanning){ @@ -85,6 +83,14 @@ void UsbHotplugThread::usbAddSlot(QString qstr){ } initSane(); + + QList current = GlobalUserSignal::getInstance()->getDeviceList(); + if(current.size() != 0){ + g_user_signal->updateConnectSuccessTextSignal(true); + }else{ + emit g_user_signal->hotPlugScanCompleteSignal(); + } + //todo:更新UI设备列表 qDebug() << "a new scanner may joined!"; @@ -104,32 +110,26 @@ void UsbHotplugThread::usbRemoveSlot(){ // 检测到有扫描仪断开链接,如果您断开的是正在扫描的扫描仪,请点击取消扫描或者等待扫描仪报错信息。 QString msg = tr("A scanner is disconnected. If you disconnect the scanner is on scanning, click Cancel Scan or wait for the scanner to report an error message."); g_user_signal->warnMsg(msg); - while(1){ if(!g_sane_object->isOnScanning){ // 扫描仪断开链接,刷新扫描仪列表,请稍等... QString msg = tr("Scanner is disconnect,refreshing scanner list. Please waitting..."); g_user_signal->warnMsg(msg); g_user_signal->setScanIconDisableSignal(); + initSane(); QList current = GlobalUserSignal::getInstance()->getDeviceList(); - g_sane_object->setSaneHaveHandle(false); if(current.size() == 0){ - qDebug() << "no avilable scanner!"; - //todo:禁止操作右边设置栏 - g_sane_object->setSaneStatus(false); - QStringList tmp; - tmp.clear(); - g_sane_object->setSaneNames(tmp); -// g_sane_object->setSaneHaveHandle(false); - g_user_signal->updateSetting(); - g_sane_object->hotPlugScanCompleteSlot(); - }else{ - qDebug() << "have another scanner to open!"; - //todo:打开列表中一个默认设备,更新ui -// g_sane_object->openSaneDeviceForPage(0); - g_user_signal->updateSetting(); + g_user_signal->updateConnectSuccessTextSignal(false); + emit g_user_signal->hotPlugScanCompleteSignal(); } + //todo:禁止操作右边设置栏 + g_sane_object->setSaneStatus(false); + g_sane_object->setSaneHaveHandle(false); + + g_user_signal->updateSetting(); + msg = tr("Scanner list refresh complete."); + g_user_signal->warnMsg(msg); break; } } @@ -145,10 +145,10 @@ bool UsbHotplugThread::usbDeviceAdd(QString qstr) QString path = QString("/sys") + qstr.right(qstr.size() - 1 - qstr.indexOf('@')); QString deviceType = getDeviceTypeFromPath(path); - if(deviceType != "ff"){ - return false; + if(deviceType == "ff" || deviceType == "06"){ + return true; }else{ - return true; + return false; } } @@ -199,6 +199,48 @@ QStringList UsbHotplugThread::getConnectedScanner() return res; } +QStringList UsbHotplugThread::getConnectedScanner2() +{ + struct udev *udev; + struct udev_enumerate *enumerate; + struct udev_list_entry *devices, *dev_list_entry; + struct udev_device *dev; + QStringList res; + + udev = udev_new(); + if (!udev) { + qDebug("Can't create udev\n"); + return res; + } + + enumerate = udev_enumerate_new(udev); + udev_enumerate_add_match_subsystem(enumerate, "usb"); + udev_enumerate_add_match_sysattr(enumerate, "bInterfaceClass", "06"); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + + udev_list_entry_foreach(dev_list_entry, devices) + { + const char *path; + + path = udev_list_entry_get_name(dev_list_entry); + dev = udev_device_new_from_syspath(udev, path); + dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); + if (!dev) + { + // printf("Unable to find parent usb device."); + continue; + } + res.append(udev_device_get_devpath(dev)); + udev_device_unref(dev); + } + udev_enumerate_unref(enumerate); + + udev_unref(udev); + res = res.toSet().toList(); + return res; +} + QString UsbHotplugThread::getDeviceTypeFromPath(QString path) { QString res; @@ -206,7 +248,7 @@ QString UsbHotplugThread::getDeviceTypeFromPath(QString path) QStringList bInterfaceClassPathList = getRetFromCommand(QStringList{"find", path ,"-name", "bInterfaceClass"}).split("\n"); for (int i = 0; i < bInterfaceClassPathList.size(); i++) { bInterfaceClass = getRetFromCommand(QStringList{"cat", bInterfaceClassPathList.at(i)}); - if (bInterfaceClass != "ff"){ + if (bInterfaceClass != "ff" && bInterfaceClass != "06"){ continue; } res = bInterfaceClass; @@ -270,7 +312,7 @@ bool UsbHotplugThread::isRemoveScanner(QString path) static void authCallback (SANE_String_Const resource, SANE_Char *username, SANE_Char *password) { -// KyInfo() << "auth_callback" << resource << username << password; + // KyInfo() << "auth_callback" << resource << username << password; } static SANE_Status saneGetDevices(const SANE_Device ***device_list) @@ -286,10 +328,8 @@ static SANE_Status saneGetDevices(const SANE_Device ***device_list) KyInfo() << "Get all scan devices, please waiting ..."; - /// This will be crashed unexpectedly, samples can be followed: - /// 1. Caused by specific drives, such as `lenovo-image-g-series_1.0-16_arm64`, so we need Vendor developers to handle it - /// 2. This will take a long time - status = sane_get_devices (device_list, SANE_FALSE); + memset(device_list, 0x00, sizeof(device_list)); + status = sane_get_devices(device_list, SANE_FALSE); if (status) { KyInfo() << "status = " << sane_strstatus(status); @@ -303,12 +343,12 @@ void UsbHotplugThread::initSane(){ SANE_Status sane_status; QString name; //获取扫描设备列表 + sane_status = saneGetDevices(&g_deviceListusb); GlobalUserSignal::getInstance()->setDeviceList(g_deviceListusb); g_sane_object->g_deviceList = g_deviceListusb; if (sane_status) { KyInfo() << "Cannot get scan devices, sane_status = " << sane_status; -// g_sane_object->setSaneStatus(false); return; } diff --git a/src/usbhotplugthread.h b/src/usbhotplugthread.h index 686db7b..1a4c478 100644 --- a/src/usbhotplugthread.h +++ b/src/usbhotplugthread.h @@ -24,6 +24,7 @@ #include #include #include +#include class UsbHotplugThread : public QThread { @@ -46,6 +47,7 @@ private: bool usbDeviceRemove(QString qstr); QStringList getConnectedScanner(); + QStringList getConnectedScanner2(); QString getDeviceTypeFromPath(QString path); QString getRetFromCommand(QStringList command); @@ -54,6 +56,8 @@ private: bool isRemoveScanner(QString path); + QMessageBox::StandardButton box; + Q_SIGNALS: void usbRemove(QString); void usbAdd(QString); diff --git a/src/utils/copyoperation.cpp b/src/utils/copyoperation.cpp index 7b0ce80..b06880e 100644 --- a/src/utils/copyoperation.cpp +++ b/src/utils/copyoperation.cpp @@ -6,129 +6,7 @@ #include -#include -#include -#include -using namespace cv; - - CopyOperation::CopyOperation(QObject *parent) : QObject(parent) { } -//void CopyOperation::matOperation(QString loadPath , QImage *m_normalImage){ - -// Mat matImage = KylinImageCodec::loadImageToMat(loadPath).mat; -// QPixmap pixImage = KylinImageCodec::converFormat(matImage); -// *m_normalImage = pixImage.toImage(); - -// QString savePath = g_sane_object->saveFullScanFileName; -// saveImage(savePath); -// qDebug() << "savePath = " << savePath; -//} -//void CopyOperation::saveImage(QString filename) -//{ -// qDebug() << "Save filename: " << filename; -// QImage *img = NULL; -// img = imageSave(filename); - -// if (img) { -// saveToPdf(*img, filename); -// } -//} -//QImage *CopyOperation::imageSave(QString filename,QImage *imageOp,QImage *imageOrin) -//{ -// qDebug() << "save image: " << filename; -// if (g_sane_object->ocrFlag == 0) { -// *imageOp = imageOrin->copy(); -// if (filename.endsWith(".pdf")) -// return imageOp; -// if (filename.endsWith(".png") || filename.endsWith(".jpg") || filename.endsWith(".bmp")) -// imageOp->save(filename); -// } else { -// if (!filename.endsWith(".txt")) -// filename += ".txt"; -// QFile file(filename); -// file.open(QIODevice::ReadWrite | QIODevice::Text); -// QByteArray str = g_sane_object->ocrOutputText.toUtf8(); -// file.write(str); -// file.close(); -// } -// return NULL; -//} -//void CopyOperation::saveToPdf(QImage img, QString pathname) -//{ -// QFile pdfFile(pathname); -// pdfFile.open(QIODevice::WriteOnly); -// QPdfWriter *pdfWriter = new QPdfWriter(&pdfFile); -// setPdfSize(pdfWriter, g_sane_object->userInfo.size); - -// int resolution = g_sane_object->resolutionValue; -// pdfWriter->setResolution(resolution); - -// int pageMargin = 0; -// pdfWriter->setPageMargins(QMarginsF(pageMargin, pageMargin, pageMargin, pageMargin)); - -// QPainter *pdfPainter = new QPainter(pdfWriter); - -// int yCurrentP = 0; -// int xCurrentP = 0; - -// QPixmap pixmap = QPixmap::fromImage(img); -// pdfPainter->drawPixmap(xCurrentP, yCurrentP, pixmap.width(), pixmap.height(), pixmap); - -// delete pdfPainter; -// delete pdfWriter; -// pdfFile.close(); -//} -//constexpr inline int U(const char *str) -//{ -// return str[0] + (str[1] ? U(str + 1) : 0); -//} - -//int CopyOperation::toUnicode(QString str) -//{ -// char *ch; -// QByteArray ba = str.toLatin1(); -// ch = ba.data(); -// return ch[0] + (ch[1] ? toUnicode(ch + 1) : 0); -//} -//void CopyOperation::setPdfSize(QPdfWriter *pdfWriter, QString size) -//{ -// switch (toUnicode(size)) { -// case U("A0"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A0)); -// break; -// case U("A1"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A1)); -// break; -// case U("A2"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A2)); -// break; -// case U("A3"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A3)); -// break; -// case U("A4"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A4)); -// break; -// case U("A5"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A5)); -// break; -// case U("A6"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A6)); -// break; -// case U("A7"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A7)); -// break; -// case U("A8"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A8)); -// break; -// case U("A9"): -// pdfWriter->setPageSize(QPageSize(QPageSize::A9)); -// break; -// default: -// pdfWriter->setPageSize(QPageSize(QPageSize::A4)); -// break; -// } - -//} diff --git a/src/utils/copyoperation.h b/src/utils/copyoperation.h index a8d78eb..3332c85 100644 --- a/src/utils/copyoperation.h +++ b/src/utils/copyoperation.h @@ -8,14 +8,6 @@ class CopyOperation : public QObject Q_OBJECT public: explicit CopyOperation(QObject *parent = nullptr); -// void matOperation(QString loadPath , QImage *m_normalImage); -//private: -// void saveImage(QString filename); -// QImage *imageSave(QString filename); -// void saveToPdf(QImage img, QString pathname); -// void setPdfSize(QPdfWriter *pdfWriter, QString size); -// int toUnicode(QString str); - signals: diff --git a/src/utils/daemondbus.h b/src/utils/daemondbus.h index b81513a..95237ac 100644 --- a/src/utils/daemondbus.h +++ b/src/utils/daemondbus.h @@ -25,7 +25,7 @@ #define KYLIN_USER_GUIDE_INTERFACE "com.guide.hotel" -#define SERVICE_NAME_SIZE 30 +#define SERVICE_NAME_SIZE 40 #include #include diff --git a/src/waittingdialog.cpp b/src/waittingdialog.cpp new file mode 100644 index 0000000..c8485fa --- /dev/null +++ b/src/waittingdialog.cpp @@ -0,0 +1,68 @@ +#include "waittingdialog.h" +#include "Qt/windowmanage.hpp" + +WaittingDialog::WaittingDialog(QWidget *parent) + : QDialog(parent), + m_layout(new QVBoxLayout()), + m_mainVlayout(new QVBoxLayout()), + m_mainHLayout(new QHBoxLayout()), + m_mainWidget(new QWidget()), + m_titleHBoxLayout(new QHBoxLayout()), + m_closeButton(new QPushButton()), + m_text(new QLabel()), + m_progress(new QProgressBar()) +{ + init(); + initConnect(); + this->setWindowModality(Qt::ApplicationModal); + kabase::WindowManage::removeHeader(this); +} + +void WaittingDialog::init() +{ + m_progress->setOrientation(Qt::Horizontal); + m_progress->setMinimum(0); + m_progress->setMaximum(0); + m_progress->setFixedHeight(16); + + 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_titleHBoxLayout->setSpacing(0); + m_titleHBoxLayout->addStretch(); + m_titleHBoxLayout->addWidget(m_closeButton); + m_titleHBoxLayout->setContentsMargins(0, 4, 4, 4); + m_titleHBoxLayout->setAlignment(Qt::AlignCenter); + + m_text->setText(tr("Searching for scanner...")); + m_mainVlayout->addWidget(m_text); + m_mainVlayout->addSpacing(16); + m_mainVlayout->addWidget(m_progress); + m_mainWidget->setLayout(m_mainVlayout); + + m_mainHLayout->addWidget(m_mainWidget); + m_mainHLayout->setContentsMargins(24, 0, 24, 32); + + m_layout->addLayout(m_titleHBoxLayout); + m_layout->addLayout(m_mainHLayout); + + this->setLayout(m_layout); + this->setFixedSize(450, 170); +} + +void WaittingDialog::initConnect() +{ + connect(m_closeButton, &QPushButton::clicked, this, &WaittingDialog::close); +} + +void WaittingDialog::setText(QString text) +{ + m_text->setText(text); +} + + diff --git a/src/waittingdialog.h b/src/waittingdialog.h new file mode 100644 index 0000000..108e048 --- /dev/null +++ b/src/waittingdialog.h @@ -0,0 +1,36 @@ +#ifndef WAITTINGDIALOG_H +#define WAITTINGDIALOG_H + +#include +#include +#include +#include +#include +#include +#include + +class WaittingDialog : public QDialog +{ + Q_OBJECT +public: + explicit WaittingDialog(QWidget *parent = nullptr); + +private: + QVBoxLayout *m_layout = nullptr; + QHBoxLayout *m_titleHBoxLayout = nullptr; + QVBoxLayout *m_mainVlayout = nullptr; + QHBoxLayout *m_mainHLayout = nullptr; + QWidget *m_mainWidget = nullptr; + QPushButton *m_closeButton = nullptr; + QLabel *m_text = nullptr; + QProgressBar *m_progress = nullptr; + + void init(); + void initConnect(); + +public: + void setText(QString text); + +}; + +#endif // WAITTINGDIALOG_H diff --git a/src/watermarkdialog.cpp b/src/watermarkdialog.cpp index 6c6f86e..3e86c92 100644 --- a/src/watermarkdialog.cpp +++ b/src/watermarkdialog.cpp @@ -1,18 +1,20 @@ #include "watermarkdialog.h" -#include "kabase/Qt/windowmanage.hpp" +#include "Qt/windowmanage.hpp" +#include WatermarkDialog::WatermarkDialog(QWidget *parent) : QDialog(parent) - , m_titleLable (new QLabel()) , m_closeButton (new QPushButton()) , m_titleHBoxLayout (new QHBoxLayout()) , m_infoTextLabel (new QLabel()) , m_watermarkLineEdit (new QLineEdit()) , m_watermarkHBoxLayout (new QHBoxLayout()) - , m_cancelButton (new QPushButton()) - , m_confirmButton (new QPushButton) + , m_cancelButton (new kdk::KPushButton()) + , m_confirmButton (new kdk::KPushButton()) , m_buttonsHBoxLayout (new QHBoxLayout()) , m_mainVBoxLayout (new QVBoxLayout()) { + m_themeData = new QGSettings(UKUI_THEME_GSETTING_PATH); + initWindow(); initLayout(); @@ -22,7 +24,7 @@ WatermarkDialog::WatermarkDialog(QWidget *parent) : QDialog(parent) void WatermarkDialog::initWindow() { - ::kabase::WindowManage::removeHeader(this); + kabase::WindowManage::removeHeader(this); setWindowTitle (tr("Scanner")); setFixedSize(QSize(380, 176)); @@ -30,7 +32,6 @@ void WatermarkDialog::initWindow() void WatermarkDialog::initLayout() { - m_titleLable->setText(tr("Scanner")); m_closeButton->setIcon (QIcon::fromTheme (ICON_THEME_CLOSE)); m_closeButton->setToolTip(tr("Close")); @@ -40,9 +41,6 @@ void WatermarkDialog::initLayout() m_closeButton->setProperty("useIconHighlightEffect", 0x8); m_closeButton->setFlat(true); - m_titleHBoxLayout->setSpacing(0); - m_titleHBoxLayout->addSpacing(12); - m_titleHBoxLayout->addWidget(m_titleLable); m_titleHBoxLayout->addStretch(); m_titleHBoxLayout->addWidget(m_closeButton); m_titleHBoxLayout->setContentsMargins(0, 5, 4, 5); @@ -64,16 +62,18 @@ void WatermarkDialog::initLayout() m_watermarkHBoxLayout->setContentsMargins(0, 0, 24, 0); m_cancelButton->setText(tr("Cancel")); - m_cancelButton->setFixedSize(QSize(96, 36)); + m_cancelButton->setMinimumSize(QSize(96, 36)); m_confirmButton->setText(tr("Confirm")); - m_confirmButton->setFixedSize(QSize(96, 36)); + m_confirmButton->setStyleSheet("color:white;"); + m_confirmButton->setBackgroundColorHighlight(true); + m_confirmButton->setMinimumSize(QSize(96, 36)); m_buttonsHBoxLayout->setSpacing(0); - m_buttonsHBoxLayout->addSpacing(152); m_buttonsHBoxLayout->addWidget(m_cancelButton); m_buttonsHBoxLayout->addSpacing(12); m_buttonsHBoxLayout->addWidget(m_confirmButton); + m_buttonsHBoxLayout->setAlignment(Qt::AlignRight); m_buttonsHBoxLayout->setContentsMargins(0, 0, 24, 24); m_mainVBoxLayout->setSpacing(0); @@ -92,6 +92,7 @@ void WatermarkDialog::initConnect() connect(m_closeButton, &QPushButton::clicked, this, &WatermarkDialog::close); connect(m_cancelButton, &QPushButton::clicked, this, &WatermarkDialog::reject); connect(m_confirmButton, &QPushButton::clicked, this, &WatermarkDialog::confirmButtonClickedSlot); + connect(m_themeData, &QGSettings::changed, this, &WatermarkDialog::fontSizeChangedSlot); } @@ -114,6 +115,7 @@ void WatermarkDialog::paintEvent(QPaintEvent *event) mainColor = opt.palette.color(QPalette::Window); p.fillPath(rectPath, QBrush(mainColor)); + p.end(); } void WatermarkDialog::confirmButtonClickedSlot() @@ -125,3 +127,11 @@ void WatermarkDialog::confirmButtonClickedSlot() } } + +void WatermarkDialog::fontSizeChangedSlot() +{ + float systemFontSize = kdk::GsettingMonitor::getSystemFontSize().toFloat(); + QString fontType = m_themeData->get("systemFont").toString(); + QFont font(fontType, systemFontSize); + m_confirmButton->setFont(font); +} diff --git a/src/watermarkdialog.h b/src/watermarkdialog.h index c2efe2c..c97d5b7 100644 --- a/src/watermarkdialog.h +++ b/src/watermarkdialog.h @@ -19,13 +19,13 @@ #include #include -#include - +#include +#include #include "utils/xatom-helper.h" #include "globalsignal.h" #include "include/common.h" #include "include/theme.h" - +#define UKUI_THEME_GSETTING_PATH "org.ukui.style" class WatermarkDialog : public QDialog { @@ -42,24 +42,23 @@ public: protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - public slots: void confirmButtonClickedSlot(); - + void fontSizeChangedSlot(); private: - QLabel *m_titleLable; - QPushButton *m_closeButton; - QHBoxLayout *m_titleHBoxLayout; + QPushButton *m_closeButton = nullptr; + QHBoxLayout *m_titleHBoxLayout = nullptr; - QLabel *m_infoTextLabel; - QLineEdit *m_watermarkLineEdit; - QHBoxLayout *m_watermarkHBoxLayout; + QLabel *m_infoTextLabel = nullptr; + QLineEdit *m_watermarkLineEdit = nullptr; + QHBoxLayout *m_watermarkHBoxLayout = nullptr; - QPushButton *m_cancelButton; - QPushButton *m_confirmButton; - QHBoxLayout *m_buttonsHBoxLayout; + kdk::KPushButton *m_cancelButton = nullptr; + kdk::KPushButton *m_confirmButton = nullptr; + QHBoxLayout *m_buttonsHBoxLayout = nullptr; - QVBoxLayout *m_mainVBoxLayout; + QVBoxLayout *m_mainVBoxLayout = nullptr; + QGSettings *m_themeData = nullptr; };