This commit is contained in:
gangphon 2023-04-18 14:14:46 +08:00
parent d441f6fbc1
commit f2f5742ba5
454 changed files with 44213 additions and 52971 deletions

View File

@ -1,51 +1,51 @@
7-Zip 21.07
-----------
7-Zip is a file archiver for Windows.
7-Zip Copyright (C) 1999-2021 Igor Pavlov.
The main features of 7-Zip:
- High compression ratio in the new 7z format
- Supported formats:
- Packing / unpacking: 7z, XZ, BZIP2, GZIP, TAR, ZIP and WIM.
- Unpacking only: AR, ARJ, Base64, CAB, CHM, CPIO, CramFS, DMG, EXT, FAT, GPT, HFS,
IHEX, ISO, LZH, LZMA, MBR, MSI, NSIS, NTFS, QCOW2, RAR,
RPM, SquashFS, UDF, UEFI, VDI, VHD, VHDX, VMDK, XAR and Z.
- Fast compression and decompression
- Self-extracting capability for 7z format
- Strong AES-256 encryption in 7z and ZIP formats
- Integration with Windows Shell
- Powerful File Manager
- Powerful command line version
- Localizations for 90 languages
7-Zip is free software distributed under the GNU LGPL (except for unRar code).
Read License.txt for more information about license.
This distribution package contains the following files:
7zFM.exe - 7-Zip File Manager
7-zip.dll - Plugin for Windows Shell
7-zip32.dll - Plugin for Windows Shell (32-bit plugin for 64-bit system)
7zg.exe - GUI module
7z.exe - Command line version
7z.dll - 7-Zip engine module
7z.sfx - SFX module (Windows version)
7zCon.sfx - SFX module (Console version)
License.txt - License information
readme.txt - This file
History.txt - History of 7-Zip
7-zip.chm - User's Manual in HTML Help format
descript.ion - Description for files
Lang\en.ttt - English (base) localization file
Lang\*.txt - Localization files
---
End of document
7-Zip 21.07
-----------
7-Zip is a file archiver for Windows.
7-Zip Copyright (C) 1999-2021 Igor Pavlov.
The main features of 7-Zip:
- High compression ratio in the new 7z format
- Supported formats:
- Packing / unpacking: 7z, XZ, BZIP2, GZIP, TAR, ZIP and WIM.
- Unpacking only: AR, ARJ, Base64, CAB, CHM, CPIO, CramFS, DMG, EXT, FAT, GPT, HFS,
IHEX, ISO, LZH, LZMA, MBR, MSI, NSIS, NTFS, QCOW2, RAR,
RPM, SquashFS, UDF, UEFI, VDI, VHD, VHDX, VMDK, XAR and Z.
- Fast compression and decompression
- Self-extracting capability for 7z format
- Strong AES-256 encryption in 7z and ZIP formats
- Integration with Windows Shell
- Powerful File Manager
- Powerful command line version
- Localizations for 90 languages
7-Zip is free software distributed under the GNU LGPL (except for unRar code).
Read License.txt for more information about license.
This distribution package contains the following files:
7zFM.exe - 7-Zip File Manager
7-zip.dll - Plugin for Windows Shell
7-zip32.dll - Plugin for Windows Shell (32-bit plugin for 64-bit system)
7zg.exe - GUI module
7z.exe - Command line version
7z.dll - 7-Zip engine module
7z.sfx - SFX module (Windows version)
7zCon.sfx - SFX module (Console version)
License.txt - License information
readme.txt - This file
History.txt - History of 7-Zip
7-zip.chm - User's Manual in HTML Help format
descript.ion - Description for files
Lang\en.ttt - English (base) localization file
Lang\*.txt - Localization files
---
End of document

View File

@ -1,313 +1,300 @@
QT += core gui widgets
QT += multimedia
QT += network
QT += concurrent
QT += serialport
QT += opengl
QT += webenginewidgets
CONFIG += c++20
CONFIG += lrelease
CONFIG += embed_translations
# CONFIG += console
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
TARGET = $$quote(LedOK Express)
VERSION = 1.3.0
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
msvc {
QMAKE_CXXFLAGS += -execution-charset:utf-8
QMAKE_CXXFLAGS += -source-charset:utf-8
CONFIG += force_debug_info
CONFIG += separate_debug_info
}
win* {
LIBS += -lwinmm
LIBS += -lDbghelp
}
win32 {
QMAKE_LFLAGS += /LARGEADDRESSAWARE
#QMAKE_LFLAGS += -Wl,--large-address-aware
}
SOURCES += \
base/aboutdlg.cpp \
base/changepasswordform.cpp \
base/customprogressindicator.cpp \
base/loemptydialog.cpp \
base/pixbmpshowdialog.cpp \
base/qiplineedit.cpp \
base/softconfigdialog.cpp \
base/switchcontrol.cpp \
base/taesclass.cpp \
base/updateledset3dialog.cpp \
base/updaterdialog.cpp \
base/x_checkboxdelegate.cpp \
base/x_spinboxdelegate.cpp \
base/x_timeeditdelegate.cpp \
base/x_uimsgboxok.cpp \
base/extendedgroupbox.cpp \
base/ffutil.cpp \
base/locolorselector.cpp \
base/lodateselector.cpp \
base/loqtitlebar.cpp \
base/loqtreewidget.cpp \
base/table.cpp \
base/waitingdlg.cpp \
basedlg.cpp \
basewin.cpp \
cfg.cpp \
communication/hpptclient.cpp \
communication/taserialthread.cpp \
devicectrlpanel.cpp \
deviceitem.cpp \
devicepanel.cpp \
ffplayer.cpp \
globaldefine.cpp \
main.cpp \
mainwindow.cpp \
mguangyingpinwidget.cpp \
passwordindlg.cpp \
player/digiclock.cpp \
player/eleanaclock.cpp \
player/elebase.cpp \
player/eleborder.cpp \
player/elegif.cpp \
player/eleimg.cpp \
player/elemultipng.cpp \
player/elescroll.cpp \
player/eletimer.cpp \
player/elevideo.cpp \
player/playwin.cpp \
player/posdlg.cpp \
progpanel.cpp \
synctimer.cpp \
tcpsocket.cpp \
test.cpp \
tipdialog.cpp \
tools.cpp \
wDevicesManager/controlencryptwidget.cpp \
wDevicesManager/controlhdmischedule.cpp \
wDevicesManager/controlhdmiwidget.cpp \
wDevicesManager/controlnetconfigwidget.cpp \
wDevicesManager/controlpowermanual.cpp \
wDevicesManager/controlpowerschedule.cpp \
wDevicesManager/controlpowerwidget.cpp \
wDevicesManager/controltestwidget.cpp \
wDevicesManager/controlvolumemanual.cpp \
wDevicesManager/controlvolumeschedule.cpp \
wDevicesManager/controlvolumewidget.cpp \
wDevicesManager/ctrladvancedpanel.cpp \
wDevicesManager/ctrlbrightpanel.cpp \
wDevicesManager/ctrlverifyclockpanel.cpp \
wDevicesManager/ledcard.cpp \
wDevicesManager/threadupgradeapk.cpp \
wDevicesManager/upgradeapkdialog.cpp \
wDevicesManager/wupgradeapkitem.cpp \
wProgramManager/eaclock.cpp \
wProgramManager/eaudio.cpp \
wProgramManager/ebase.cpp \
wProgramManager/edclock.cpp \
wProgramManager/eenviron.cpp \
wProgramManager/egif.cpp \
wProgramManager/emultiwin.cpp \
wProgramManager/ephoto.cpp \
wProgramManager/etext.cpp \
wProgramManager/etimer.cpp \
wProgramManager/evideo.cpp \
wProgramManager/eweb.cpp \
wProgramManager/gentmpthread.cpp \
wProgramManager/pageeditor.cpp \
wProgramManager/pagelistitem.cpp \
wProgramManager/progcreatedlg.cpp \
wProgramManager/progeditorwin.cpp \
wProgramManager/progitem.cpp \
wProgramManager/sendprogramdialog.cpp \
wProgramManager/sendprogthread.cpp \
wProgramManager/threadexportprogrampro.cpp \
wProgramManager/usbdetectdialog.cpp \
wProgramManager/videosplitthread.cpp \
wProgramManager/wexportprogramitem.cpp \
wProgramManager/wplanitem.cpp \
wProgramManager/wplanlist.cpp \
wProgramManager/wprogrampublishitem.cpp \
HEADERS += \
base/aboutdlg.h \
base/changepasswordform.h \
base/customprogressindicator.h \
base/loemptydialog.h \
base/pixbmpshowdialog.h \
base/qiplineedit.h \
base/softconfigdialog.h \
base/switchcontrol.h \
base/taesclass.h \
base/updateledset3dialog.h \
base/updaterdialog.h \
base/x_checkboxdelegate.h \
base/x_spinboxdelegate.h \
base/x_timeeditdelegate.h \
base/x_uimsgboxok.h \
base/extendedgroupbox.h \
base/locolorselector.h \
base/lodateselector.h \
base/loqtitlebar.h \
base/loqtreewidget.h \
base/table.h \
base/waitingdlg.h \
basedlg.h \
basewin.h \
cfg.h \
communication/hpptclient.h \
communication/taserialthread.h \
devicectrlpanel.h \
deviceitem.h \
devicepanel.h \
ffplayer.h \
globaldefine.h \
gqt.h \
mainwindow.h \
mguangyingpinwidget.h \
passwordindlg.h \
player/digiclock.h \
player/eleanaclock.h \
player/elebase.h \
player/eleborder.h \
player/elegif.h \
player/eleimg.h \
player/elemultipng.h \
player/elescroll.h \
player/eletimer.h \
player/elevideo.h \
player/playwin.h \
player/posdlg.h \
progpanel.h \
synctimer.h \
tcpsocket.h \
tipdialog.h \
tools.h \
wDevicesManager/controlencryptwidget.h \
wDevicesManager/controlhdmischedule.h \
wDevicesManager/controlhdmiwidget.h \
wDevicesManager/controlnetconfigwidget.h \
wDevicesManager/controlpowermanual.h \
wDevicesManager/controlpowerschedule.h \
wDevicesManager/controlpowerwidget.h \
wDevicesManager/controltestwidget.h \
wDevicesManager/controlvolumemanual.h \
wDevicesManager/controlvolumeschedule.h \
wDevicesManager/controlvolumewidget.h \
wDevicesManager/ctrladvancedpanel.h \
wDevicesManager/ctrlbrightpanel.h \
wDevicesManager/ctrlverifyclockpanel.h \
wDevicesManager/ledcard.h \
wDevicesManager/threadupgradeapk.h \
wDevicesManager/upgradeapkdialog.h \
wDevicesManager/wupgradeapkitem.h \
wProgramManager/eaclock.h \
wProgramManager/eaudio.h \
wProgramManager/ebase.h \
wProgramManager/edclock.h \
wProgramManager/eenviron.h \
wProgramManager/egif.h \
wProgramManager/emultiwin.h \
wProgramManager/ephoto.h \
wProgramManager/etext.h \
wProgramManager/etimer.h \
wProgramManager/evideo.h \
wProgramManager/eweb.h \
wProgramManager/gentmpthread.h \
wProgramManager/pageeditor.h \
wProgramManager/pagelistitem.h \
wProgramManager/progcreatedlg.h \
wProgramManager/progeditorwin.h \
wProgramManager/progitem.h \
wProgramManager/sendprogramdialog.h \
wProgramManager/sendprogthread.h \
wProgramManager/threadexportprogrampro.h \
wProgramManager/usbdetectdialog.h \
wProgramManager/videosplitthread.h \
wProgramManager/wexportprogramitem.h \
wProgramManager/wplanitem.h \
wProgramManager/wplanlist.h \
wProgramManager/wprogrampublishitem.h \
FORMS += \
base/pixbmpshowdialog.ui \
base/updateledset3dialog.ui \
base/updaterdialog.ui \
base/x_uimsgboxok.ui \
mguangyingpinwidget.ui \
tipdialog.ui \
wDevicesManager/controlencryptwidget.ui \
wDevicesManager/controlhdmischedule.ui \
wDevicesManager/controlpowermanual.ui \
wDevicesManager/controlpowerschedule.ui \
wDevicesManager/controlpowerwidget.ui \
wDevicesManager/controltestwidget.ui \
wDevicesManager/controlvolumemanual.ui \
wDevicesManager/controlvolumeschedule.ui \
wDevicesManager/controlvolumewidget.ui \
wDevicesManager/upgradeapkdialog.ui \
wProgramManager/wplanitem.ui \
TRANSLATIONS += \
translations/app_zh_CN.ts \
translations/app_zh_TW.ts \
translations/app_ja.ts \
translations/app_en.ts
EXTRA_TRANSLATIONS += \
translations/qt_zh_CN.ts \
translations/qt_zh_TW.ts \
translations/qt_ja.ts \
translations/qt_en.ts
RESOURCES += \
res.qrc \
qss.qrc
win32:RC_ICONS = res/Logo.ico
osx:ICON = res/Logo.icns
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
INCLUDEPATH += $$PWD/ffmpeg/include
LIBS += -L$$PWD/ffmpeg/lib/\
-lavcodec \
-lavdevice \
-lavfilter \
-lavformat \
-lavutil \
-lswresample \
-lswscale
copy.files += $$files(ffmpeg/bin/*.dll)
copy.files += ffmpeg/bin/ffmpeg.exe
include(./xlsx/qtxlsx.pri)
include(./QSimpleUpdater/QSimpleUpdater.pri)
# for https requests
copy2.files += $$files(OpenSSL/*.dll)
copy.files += 7z/7z.dll
copy.files += 7z/7z.exe
copy.path = $$OUT_PWD
copy2.path = $$OUT_PWD/release
CONFIG += file_copies
COPIES += copy
COPIES += copy2
QT += core gui widgets
QT += multimedia
QT += network
QT += concurrent
QT += serialport
QT += opengl
QT += webenginewidgets
CONFIG += c++20
CONFIG += lrelease
CONFIG += embed_translations
# CONFIG += console
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
TARGET = $$quote(LedOK Express)
VERSION = 1.3.5
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
msvc {
QMAKE_CXXFLAGS += -execution-charset:utf-8
QMAKE_CXXFLAGS += -source-charset:utf-8
CONFIG += force_debug_info
CONFIG += separate_debug_info
# QMAKE_LFLAGS_RELEASE += /MAP
# QMAKE_CFLAGS_RELEASE += /Zi
# QMAKE_LFLAGS_RELEASE += /debug /opt:ref
# QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
# QMAKE_LFLAGS_RELEASE += $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
LIBS += -lDbgHelp
}
win* {
LIBS += -lwinmm
LIBS += -lDbghelp
}
win32 {
QMAKE_LFLAGS += /LARGEADDRESSAWARE
#QMAKE_LFLAGS += -Wl,--large-address-aware
}
SOURCES += \
base/aboutdlg.cpp \
base/changepasswordform.cpp \
base/customprogressindicator.cpp \
base/loemptydialog.cpp \
base/pixbmpshowdialog.cpp \
base/qiplineedit.cpp \
base/softconfigdialog.cpp \
base/switchcontrol.cpp \
base/taesclass.cpp \
base/updateledset3dialog.cpp \
base/x_checkboxdelegate.cpp \
base/x_spinboxdelegate.cpp \
base/x_timeeditdelegate.cpp \
base/x_uimsgboxok.cpp \
base/extendedgroupbox.cpp \
base/ffutil.cpp \
base/locolorselector.cpp \
base/lodateselector.cpp \
base/loqtitlebar.cpp \
base/loqtreewidget.cpp \
base/waitingdlg.cpp \
basedlg.cpp \
basewin.cpp \
cfg.cpp \
communication/hpptclient.cpp \
communication/taserialthread.cpp \
device/ctrlhdmipanel.cpp \
device/ctrlnetworkpanel.cpp \
device/ctrlpwdpanel.cpp \
devicectrlpanel.cpp \
deviceitem.cpp \
devicepanel.cpp \
ffplayer.cpp \
globaldefine.cpp \
gutil/qgui.cpp \
gutil/qnetwork.cpp \
main.cpp \
mainwindow.cpp \
mguangyingpinwidget.cpp \
passwordindlg.cpp \
player/digiclock.cpp \
player/eleanaclock.cpp \
player/elebase.cpp \
player/eleborder.cpp \
player/elegif.cpp \
player/eleimg.cpp \
player/elemultipng.cpp \
player/elescroll.cpp \
player/eletimer.cpp \
player/elevideo.cpp \
player/playwin.cpp \
player/posdlg.cpp \
progpanel.cpp \
synctimer.cpp \
test.cpp \
tools.cpp \
device/controlpowerschedule.cpp \
device/controlpowerwidget.cpp \
device/controltestwidget.cpp \
device/controlvolumeschedule.cpp \
device/controlvolumewidget.cpp \
device/ctrladvancedpanel.cpp \
device/ctrlbrightpanel.cpp \
device/ctrlverifyclockpanel.cpp \
device/ledcard.cpp \
device/upgradeapkdialog.cpp \
device/wupgradeapkitem.cpp \
program/copydirthread.cpp \
program/eaclock.cpp \
program/eaudio.cpp \
program/ebase.cpp \
program/edclock.cpp \
program/eenviron.cpp \
program/egif.cpp \
program/emultiwin.cpp \
program/ephoto.cpp \
program/etext.cpp \
program/etimer.cpp \
program/evideo.cpp \
program/eweb.cpp \
program/gentmpthread.cpp \
program/pageeditor.cpp \
program/pagelistitem.cpp \
program/progcreatedlg.cpp \
program/progeditorwin.cpp \
program/progitem.cpp \
program/sendprogramdialog.cpp \
program/sendprogthread.cpp \
program/usbdetectdialog.cpp \
program/videosplitthread.cpp \
program/wplanitem.cpp \
program/wplanlist.cpp \
program/wprogrampublishitem.cpp \
HEADERS += \
base/aboutdlg.h \
base/changepasswordform.h \
base/customprogressindicator.h \
base/loemptydialog.h \
base/pixbmpshowdialog.h \
base/qiplineedit.h \
base/softconfigdialog.h \
base/switchcontrol.h \
base/taesclass.h \
base/updateledset3dialog.h \
base/x_checkboxdelegate.h \
base/x_spinboxdelegate.h \
base/x_timeeditdelegate.h \
base/x_uimsgboxok.h \
base/extendedgroupbox.h \
base/locolorselector.h \
base/lodateselector.h \
base/loqtitlebar.h \
base/loqtreewidget.h \
base/waitingdlg.h \
basedlg.h \
basewin.h \
cfg.h \
communication/hpptclient.h \
communication/taserialthread.h \
device/ctrlhdmipanel.h \
device/ctrlnetworkpanel.h \
device/ctrlpwdpanel.h \
devicectrlpanel.h \
deviceitem.h \
devicepanel.h \
ffplayer.h \
globaldefine.h \
gutil/qgui.h \
gutil/qnetwork.h \
mainwindow.h \
mguangyingpinwidget.h \
passwordindlg.h \
player/digiclock.h \
player/eleanaclock.h \
player/elebase.h \
player/eleborder.h \
player/elegif.h \
player/eleimg.h \
player/elemultipng.h \
player/elescroll.h \
player/eletimer.h \
player/elevideo.h \
player/playwin.h \
player/posdlg.h \
progpanel.h \
synctimer.h \
tools.h \
device/controlpowerschedule.h \
device/controlpowerwidget.h \
device/controltestwidget.h \
device/controlvolumeschedule.h \
device/controlvolumewidget.h \
device/ctrladvancedpanel.h \
device/ctrlbrightpanel.h \
device/ctrlverifyclockpanel.h \
device/ledcard.h \
device/upgradeapkdialog.h \
device/wupgradeapkitem.h \
program/copydirthread.h \
program/eaclock.h \
program/eaudio.h \
program/ebase.h \
program/edclock.h \
program/eenviron.h \
program/egif.h \
program/emultiwin.h \
program/ephoto.h \
program/etext.h \
program/etimer.h \
program/evideo.h \
program/eweb.h \
program/gentmpthread.h \
program/pageeditor.h \
program/pagelistitem.h \
program/progcreatedlg.h \
program/progeditorwin.h \
program/progitem.h \
program/sendprogramdialog.h \
program/sendprogthread.h \
program/usbdetectdialog.h \
program/videosplitthread.h \
program/wplanitem.h \
program/wplanlist.h \
program/wprogrampublishitem.h \
FORMS += \
base/pixbmpshowdialog.ui \
base/updateledset3dialog.ui \
base/x_uimsgboxok.ui \
mguangyingpinwidget.ui \
device/controlpowerschedule.ui \
device/controltestwidget.ui \
device/controlvolumeschedule.ui \
program/wplanitem.ui \
TRANSLATIONS += \
translations/app_zh_CN.ts \
translations/app_zh_TW.ts \
translations/app_ja.ts \
translations/app_en.ts
EXTRA_TRANSLATIONS += \
translations/qt_zh_CN.ts \
translations/qt_zh_TW.ts \
translations/qt_ja.ts \
translations/qt_en.ts
RESOURCES += res.qrc
win32:RC_ICONS = res/Logo.ico
osx:ICON = res/Logo.icns
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
INCLUDEPATH += $$PWD/ffmpeg/include
LIBS += -L$$PWD/ffmpeg/lib/\
-lavcodec \
-lavdevice \
-lavfilter \
-lavformat \
-lavutil \
-lswresample \
-lswscale
copy.files += $$files(ffmpeg/bin/*.dll)
copy.files += ffmpeg/bin/ffmpeg.exe
include(./xlsx/qtxlsx.pri)
include(./QSimpleUpdater/QSimpleUpdater.pri)
# for https requests
copy2.files += $$files(OpenSSL/*.dll)
copy.files += 7z/7z.dll
copy.files += 7z/7z.exe
copy.path = $$OUT_PWD
copy2.path = $$OUT_PWD/release
copy3.files += $$quote(y50 param)
copy3.path = $$OUT_PWD/release
CONFIG += file_copies
COPIES += copy
COPIES += copy2
COPIES += copy3

View File

@ -1,5 +1,5 @@
<RCC>
<qresource prefix="/icons">
<file alias="update.png">update.png</file>
</qresource>
</RCC>
<RCC>
<qresource prefix="/icons">
<file alias="update.png">update.png</file>
</qresource>
</RCC>

View File

@ -1,20 +1,20 @@
:: Description: This script changes the style format of
:: all the source code of the project.
:: Setup the command line
@echo off
title Code Formatter
:: Go to the directory where the script is run
cd /d %~dp0
:: Style and format the source code recursively
astyle --style=linux --indent=spaces --align-pointer=type --indent-preproc-block --indent-preproc-define --indent-col1-comments --pad-first-paren-out --pad-oper --attach-namespaces --remove-brackets --convert-tabs --close-templates --max-code-length=100 --max-instatement-indent=50 --lineend=windows --suffix=none --recursive ../../*.h ../../*.cpp ../../*.c
:: Notify the user that we have finished
echo.
echo Code styling complete!
echo.
:: Let the user see the output
pause
:: Description: This script changes the style format of
:: all the source code of the project.
:: Setup the command line
@echo off
title Code Formatter
:: Go to the directory where the script is run
cd /d %~dp0
:: Style and format the source code recursively
astyle --style=linux --indent=spaces --align-pointer=type --indent-preproc-block --indent-preproc-define --indent-col1-comments --pad-first-paren-out --pad-oper --attach-namespaces --remove-brackets --convert-tabs --close-templates --max-code-length=100 --max-instatement-indent=50 --lineend=windows --suffix=none --recursive ../../*.h ../../*.cpp ../../*.c
:: Notify the user that we have finished
echo.
echo Code styling complete!
echo.
:: Let the user see the output
pause

View File

@ -1,2 +1,2 @@
# Style and format recursively
astyle --style=linux --indent=spaces --align-pointer=type --indent-preproc-block --indent-preproc-define --indent-col1-comments --pad-first-paren-out --pad-oper --attach-namespaces --remove-brackets --convert-tabs --close-templates --max-code-length=100 --max-instatement-indent=50 --lineend=windows --suffix=none --recursive ../../*.h ../../*.cpp ../../*.cc
# Style and format recursively
astyle --style=linux --indent=spaces --align-pointer=type --indent-preproc-block --indent-preproc-define --indent-col1-comments --pad-first-paren-out --pad-oper --attach-namespaces --remove-brackets --convert-tabs --close-templates --max-code-length=100 --max-instatement-indent=50 --lineend=windows --suffix=none --recursive ../../*.h ../../*.cpp ../../*.cc

View File

@ -1,119 +1,119 @@
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#ifndef _QSIMPLEUPDATER_MAIN_H
#define _QSIMPLEUPDATER_MAIN_H
#include <QUrl>
#include <QList>
#include <QObject>
#if defined (QSU_SHARED)
#define QSU_DECL Q_DECL_EXPORT
#elif defined (QSU_IMPORT)
#define QSU_DECL Q_DECL_IMPORT
#else
#define QSU_DECL
#endif
class Updater;
/**
* \brief Manages the updater instances
*
* The \c QSimpleUpdater class manages the updater system and allows for
* parallel application modules to check for updates and download them.
*
* The behavior of each updater can be regulated by specifying the update
* definitions URL (from where we download the individual update definitions)
* and defining the desired options by calling the individual "setter"
* functions (e.g. \c setNotifyOnUpdate()).
*
* The \c QSimpleUpdater also implements an integrated downloader.
* If you need to use a custom install procedure/code, just create a function
* that is called when the \c downloadFinished() signal is emitted to
* implement your own install procedures.
*
* By default, the downloader will try to open the file as if you opened it
* from a file manager or a web browser (with the "file:*" url).
*/
class QSU_DECL QSimpleUpdater : public QObject
{
Q_OBJECT
signals:
void checkingFinished (const QString& url);
void appcastDownloaded (const QString& url, const QByteArray& data);
void downloadFinished (const QString& url, const QString& filepath);
public:
static QSimpleUpdater* getInstance();
bool usesCustomAppcast (const QString& url) const;
bool getNotifyOnUpdate (const QString& url) const;
bool getNotifyOnFinish (const QString& url) const;
bool getUpdateAvailable (const QString& url) const;
bool getUpdateSameVersionAvailable (const QString& url) const;
bool getDownloaderEnabled (const QString& url) const;
bool usesCustomInstallProcedures (const QString& url) const;
QString getOpenUrl (const QString& url) const;
QString getChangelog (const QString& url) const;
QString getModuleName (const QString& url) const;
QString getDownloadUrl (const QString& url) const;
QString getPlatformKey (const QString& url) const;
QString getLatestVersion (const QString& url) const;
QString getModuleVersion (const QString& url) const;
QString getUserAgentString (const QString& url) const;
public slots:
void checkForUpdates (const QString& url);
void setModuleName (const QString& url, const QString& name);
void setNotifyOnUpdate (const QString& url, const bool notify);
void setNotifyOnFinish (const QString& url, const bool notify);
void setPlatformKey (const QString& url, const QString& platform);
void setModuleVersion (const QString& url, const QString& version);
void setDownloaderEnabled (const QString& url, const bool enabled);
void setUserAgentString (const QString& url, const QString& agent);
void setUseCustomAppcast (const QString& url, const bool customAppcast);
void setUseCustomInstallProcedures (const QString& url, const bool custom);
void setNoNotifyDownload (const QString& url, const bool custom);
void setCompareBySameString (const QString& url, const bool custom);
void setMandatoryUpdate (const QString& url, const bool mandatory_update);
protected:
~QSimpleUpdater();
private:
Updater* getUpdater (const QString& url) const;
};
#endif
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#ifndef _QSIMPLEUPDATER_MAIN_H
#define _QSIMPLEUPDATER_MAIN_H
#include <QUrl>
#include <QList>
#include <QObject>
#if defined (QSU_SHARED)
#define QSU_DECL Q_DECL_EXPORT
#elif defined (QSU_IMPORT)
#define QSU_DECL Q_DECL_IMPORT
#else
#define QSU_DECL
#endif
class Updater;
/**
* \brief Manages the updater instances
*
* The \c QSimpleUpdater class manages the updater system and allows for
* parallel application modules to check for updates and download them.
*
* The behavior of each updater can be regulated by specifying the update
* definitions URL (from where we download the individual update definitions)
* and defining the desired options by calling the individual "setter"
* functions (e.g. \c setNotifyOnUpdate()).
*
* The \c QSimpleUpdater also implements an integrated downloader.
* If you need to use a custom install procedure/code, just create a function
* that is called when the \c downloadFinished() signal is emitted to
* implement your own install procedures.
*
* By default, the downloader will try to open the file as if you opened it
* from a file manager or a web browser (with the "file:*" url).
*/
class QSU_DECL QSimpleUpdater : public QObject
{
Q_OBJECT
signals:
void checkingFinished (const QString& url);
void appcastDownloaded (const QString& url, const QByteArray& data);
void downloadFinished (const QString& url, const QString& filepath);
public:
static QSimpleUpdater* getInstance();
bool usesCustomAppcast (const QString& url) const;
bool getNotifyOnUpdate (const QString& url) const;
bool getNotifyOnFinish (const QString& url) const;
bool getUpdateAvailable (const QString& url) const;
bool getUpdateSameVersionAvailable (const QString& url) const;
bool getDownloaderEnabled (const QString& url) const;
bool usesCustomInstallProcedures (const QString& url) const;
QString getOpenUrl (const QString& url) const;
QString getChangelog (const QString& url) const;
QString getModuleName (const QString& url) const;
QString getDownloadUrl (const QString& url) const;
QString getPlatformKey (const QString& url) const;
QString getLatestVersion (const QString& url) const;
QString getModuleVersion (const QString& url) const;
QString getUserAgentString (const QString& url) const;
public slots:
void checkForUpdates (const QString& url);
void setModuleName (const QString& url, const QString& name);
void setNotifyOnUpdate (const QString& url, const bool notify);
void setNotifyOnFinish (const QString& url, const bool notify);
void setPlatformKey (const QString& url, const QString& platform);
void setModuleVersion (const QString& url, const QString& version);
void setDownloaderEnabled (const QString& url, const bool enabled);
void setUserAgentString (const QString& url, const QString& agent);
void setUseCustomAppcast (const QString& url, const bool customAppcast);
void setUseCustomInstallProcedures (const QString& url, const bool custom);
void setNoNotifyDownload (const QString& url, const bool custom);
void setCompareBySameString (const QString& url, const bool custom);
void setMandatoryUpdate (const QString& url, const bool mandatory_update);
protected:
~QSimpleUpdater();
private:
Updater* getUpdater (const QString& url) const;
};
#endif

View File

@ -1,438 +1,438 @@
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
* Copyright (c) 2017 Gilmanov Ildar <https://github.com/gilmanov-ildar>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#include <QDir>
#include <QFile>
#include <QProcess>
#include <QDateTime>
#include <QMessageBox>
#include <QNetworkReply>
#include <QDesktopServices>
#include <QNetworkAccessManager>
#include <math.h>
#include "Downloader.h"
static const QString PARTIAL_DOWN (".part");
extern QWidget *gMainWin;
Downloader::Downloader (QWidget* parent) : QDialog (parent) {
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
m_ui = new Ui::Downloader;
m_ui->setupUi (this);
//m_ui->label->setText(tr("Software update"));
/* Initialize private members */
m_manager = new QNetworkAccessManager();
/* Initialize internal values */
m_url = "";
m_fileName = "";
m_startTime = 0;
m_useCustomProcedures = false;
m_mandatoryUpdate = false;
/* Set download directory */
//m_downloadDir.setPath(QDir::homePath() + "/Downloads/");
m_downloadDir.setPath(QCoreApplication::applicationDirPath() + "/Downloads/");
/* Make the window look like a modal dialog */
// setWindowIcon (QIcon());
// setWindowFlags (Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
/* Configure the appearance and behavior of the buttons */
m_ui->openButton->setEnabled (false);
m_ui->openButton->setVisible (false);
connect (m_ui->stopButton, SIGNAL (clicked()),
this, SLOT (cancelDownload()));
connect (m_ui->openButton, SIGNAL (clicked()),
this, SLOT (installUpdate()));
/* Resize to fit */
setFixedSize (minimumSizeHint());
setStyleSheet("background-color: #D8D8D8");
}
Downloader::~Downloader()
{
delete m_ui;
delete m_reply;
delete m_manager;
}
/**
* Returns \c true if the updater shall not intervene when the download has
* finished (you can use the \c QSimpleUpdater signals to know when the
* download is completed).
*/
bool Downloader::useCustomInstallProcedures() const
{
return m_useCustomProcedures;
}
/**
* Changes the URL, which is used to indentify the downloader dialog
* with an \c Updater instance
*
* \note the \a url parameter is not the download URL, it is the URL of
* the AppCast file
*/
void Downloader::setUrlId (const QString& url)
{
m_url = url;
}
/**
* Begins downloading the file at the given \a url
*/
void Downloader::startDownload (const QUrl& url)
{
/* Reset UI */
m_ui->progressBar->setValue (0);
m_ui->stopButton->setText (tr ("Stop"));
m_ui->downloadLabel->setText (tr ("Downloading updates"));
m_ui->timeLabel->setText (tr ("Time remaining") + ": " + tr ("unknown"));
/* Configure the network request */
QNetworkRequest request (url);
if (!m_userAgentString.isEmpty())
request.setRawHeader ("User-Agent", m_userAgentString.toUtf8());
/* Start download */
m_reply = m_manager->get (request);
m_startTime = QDateTime::currentDateTime().toTime_t();
/* Ensure that downloads directory exists */
if (!m_downloadDir.exists())
m_downloadDir.mkpath(".");
/* Remove old downloads */
QFile::remove (m_downloadDir.filePath (m_fileName));
QFile::remove (m_downloadDir.filePath (m_fileName + PARTIAL_DOWN));
/* Update UI when download progress changes or download finishes */
connect (m_reply, SIGNAL (downloadProgress (qint64, qint64)),
this, SLOT (updateProgress (qint64, qint64)));
connect (m_reply, SIGNAL (finished ()),
this, SLOT (finished ()));
connect (m_reply, SIGNAL (redirected (QUrl)),
this, SLOT (startDownload (QUrl)));
showNormal();
}
/**
* Changes the name of the downloaded file
*/
void Downloader::setFileName (const QString& file)
{
m_fileName = file;
if (m_fileName.isEmpty())
m_fileName = "QSU_Update.bin";
}
/**
* Changes the user-agent string used to communicate with the remote HTTP server
*/
void Downloader::setUserAgentString (const QString& agent)
{
m_userAgentString = agent;
}
void Downloader::finished()
{
/* Rename file */
QFile::rename (m_downloadDir.filePath (m_fileName + PARTIAL_DOWN),
m_downloadDir.filePath (m_fileName));
/* Notify application */
emit downloadFinished (m_url, m_downloadDir.filePath (m_fileName));
/* Install the update */
m_reply->close();
installUpdate();
setVisible (false);
}
/**
* Opens the downloaded file.
* \note If the downloaded file is not found, then the function will alert the
* user about the error.
*/
void Downloader::openDownload() {
if(!m_fileName.isEmpty()) QDesktopServices::openUrl(QUrl::fromLocalFile(m_downloadDir.filePath(m_fileName)));
else QMessageBox::critical (gMainWin, tr("Error"), tr("Cannot find downloaded update!"), QMessageBox::Close);
}
/**
* Instructs the OS to open the downloaded file.
*
* \note If \c useCustomInstallProcedures() returns \c true, the function will
* not instruct the OS to open the downloaded file. You can use the
* signals fired by the \c QSimpleUpdater to install the update with your
* own implementations/code.
*/
void Downloader::installUpdate(){
if (useCustomInstallProcedures()){
return;
}
/* Update labels */
m_ui->stopButton->setText (tr ("Close"));
m_ui->downloadLabel->setText (tr ("Download complete!"));
m_ui->timeLabel->setText (tr ("The installer will open separately")
+ "...");
/* Ask the user to install the download */
// QMessageBox box;
// box.setIcon (QMessageBox::Question);
// box.setDefaultButton (QMessageBox::Ok);
// box.setStandardButtons (QMessageBox::Ok | QMessageBox::Cancel);
// box.setInformativeText (tr ("Click \"OK\" to begin installing the update"));
QString text = m_mandatoryUpdate ? tr("In order to install the update, you may need to quit the application. This is a mandatory update, exiting now will close the application") : tr("In order to install the update ");
auto res = QMessageBox::information(gMainWin, tr("Tip Info"), text, QMessageBox::Ok, QMessageBox::Cancel);
if(m_mandatoryUpdate) QApplication::quit();
if(res == QMessageBox::Ok) {
if(!useCustomInstallProcedures()) openDownload();
} else {
m_ui->openButton->setEnabled (true);
m_ui->openButton->setVisible (true);
m_ui->timeLabel->setText (tr ("Click the \"Open\" button to "
"apply the update"));
}
}
/**
* Prompts the user if he/she wants to cancel the download and cancels the
* download if the user agrees to do that.
*/
void Downloader::cancelDownload()
{
if (!m_reply->isFinished()) {
QMessageBox box;
box.setWindowTitle (tr ("Updater"));
box.setIcon (QMessageBox::Question);
box.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
QString text = tr("Are you sure you want to cancel the download?");
if (m_mandatoryUpdate)
{
text = tr("Are you sure you want to cancel the download? This is a mandatory update, exiting now will close the application");
}
box.setText (text);
if (box.exec() == QMessageBox::Yes) {
hide();
m_reply->abort();
if(m_mandatoryUpdate)
QApplication::quit();
}
}
else
{
if(m_mandatoryUpdate)
QApplication::quit();
hide();
}
}
/**
* Writes the downloaded data to the disk
*/
void Downloader::saveFile (qint64 received, qint64 total)
{
Q_UNUSED (received);
Q_UNUSED (total);
/* Check if we need to redirect */
QUrl url = m_reply->attribute (
QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!url.isEmpty()) {
startDownload (url);
return;
}
/* Save downloaded data to disk */
QFile file (m_downloadDir.filePath (m_fileName + PARTIAL_DOWN));
if (file.open (QIODevice::WriteOnly | QIODevice::Append)) {
file.write (m_reply->readAll());
file.close();
}
}
/**
* Calculates the appropiate size units (bytes, KB or MB) for the received
* data and the total download size. Then, this function proceeds to update the
* dialog controls/UI.
*/
void Downloader::calculateSizes (qint64 received, qint64 total)
{
QString totalSize;
QString receivedSize;
if (total < 1024)
totalSize = tr ("%1 bytes").arg (total);
else if (total < 1048576)
totalSize = tr ("%1 KB").arg (round (total / 1024));
else
totalSize = tr ("%1 MB").arg (round (total / 1048576));
if (received < 1024)
receivedSize = tr ("%1 bytes").arg (received);
else if (received < 1048576)
receivedSize = tr ("%1 KB").arg (received / 1024);
else
receivedSize = tr ("%1 MB").arg (received / 1048576);
m_ui->downloadLabel->setText (tr ("Downloading updates")
+ " (" + receivedSize + " " + tr ("of")
+ " " + totalSize + ")");
}
/**
* Uses the \a received and \a total parameters to get the download progress
* and update the progressbar value on the dialog.
*/
void Downloader::updateProgress (qint64 received, qint64 total)
{
if (total > 0) {
m_ui->progressBar->setMinimum (0);
m_ui->progressBar->setMaximum (100);
m_ui->progressBar->setValue ((received * 100) / total);
calculateSizes (received, total);
calculateTimeRemaining (received, total);
saveFile (received, total);
}
else {
m_ui->progressBar->setMinimum (0);
m_ui->progressBar->setMaximum (0);
m_ui->progressBar->setValue (-1);
m_ui->downloadLabel->setText (tr ("Downloading Updates") + "...");
m_ui->timeLabel->setText (QString ("%1: %2")
.arg (tr ("Time Remaining"))
.arg (tr ("Unknown")));
}
}
/**
* Uses two time samples (from the current time and a previous sample) to
* calculate how many bytes have been downloaded.
*
* Then, this function proceeds to calculate the appropiate units of time
* (hours, minutes or seconds) and constructs a user-friendly string, which
* is displayed in the dialog.
*/
void Downloader::calculateTimeRemaining (qint64 received, qint64 total)
{
uint difference = QDateTime::currentDateTime().toTime_t() - m_startTime;
if (difference > 0) {
QString timeString;
qreal timeRemaining = (total - received) / (received / difference);
if (timeRemaining > 7200) {
timeRemaining /= 3600;
int hours = int (timeRemaining + 0.5);
if (hours > 1)
timeString = tr ("about %1 hours").arg (hours);
else
timeString = tr ("about one hour");
}
else if (timeRemaining > 60) {
timeRemaining /= 60;
int minutes = int (timeRemaining + 0.5);
if (minutes > 1)
timeString = tr ("%1 minutes").arg (minutes);
else
timeString = tr ("1 minute");
}
else if (timeRemaining <= 60) {
int seconds = int (timeRemaining + 0.5);
if (seconds > 1)
timeString = tr ("%1 seconds").arg (seconds);
else
timeString = tr ("1 second");
}
m_ui->timeLabel->setText (tr ("Time remaining") + ": " + timeString);
}
}
/**
* Rounds the given \a input to two decimal places
*/
qreal Downloader::round (const qreal& input)
{
return static_cast<qreal>(roundf (static_cast<float>(input) * 100) / 100);
}
QString Downloader::downloadDir() const
{
return m_downloadDir.absolutePath();
}
void Downloader::setDownloadDir (const QString& downloadDir)
{
if (m_downloadDir.absolutePath() != downloadDir)
m_downloadDir.setPath(downloadDir);
}
/**
* If the \a mandatory_update is set to \c true, the \c Downloader has to download and install the
* update. If the user cancels or exits, the application will close
*/
void Downloader::setMandatoryUpdate(const bool mandatory_update)
{
m_mandatoryUpdate = mandatory_update;
}
/**
* If the \a custom parameter is set to \c true, then the \c Downloader will not
* attempt to open the downloaded file.
*
* Use the signals fired by the \c QSimpleUpdater to implement your own install
* procedures.
*/
void Downloader::setUseCustomInstallProcedures (const bool custom)
{
m_useCustomProcedures = custom;
}
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
* Copyright (c) 2017 Gilmanov Ildar <https://github.com/gilmanov-ildar>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#include <QDir>
#include <QFile>
#include <QProcess>
#include <QDateTime>
#include <QMessageBox>
#include <QNetworkReply>
#include <QDesktopServices>
#include <QNetworkAccessManager>
#include <math.h>
#include "Downloader.h"
static const QString PARTIAL_DOWN (".part");
extern QWidget *gMainWin;
Downloader::Downloader (QWidget* parent) : QDialog (parent) {
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
m_ui = new Ui::Downloader;
m_ui->setupUi (this);
//m_ui->label->setText(tr("Software update"));
/* Initialize private members */
m_manager = new QNetworkAccessManager();
/* Initialize internal values */
m_url = "";
m_fileName = "";
m_startTime = 0;
m_useCustomProcedures = false;
m_mandatoryUpdate = false;
/* Set download directory */
//m_downloadDir.setPath(QDir::homePath() + "/Downloads/");
m_downloadDir.setPath(QCoreApplication::applicationDirPath() + "/Downloads/");
/* Make the window look like a modal dialog */
// setWindowIcon (QIcon());
// setWindowFlags (Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
/* Configure the appearance and behavior of the buttons */
m_ui->openButton->setEnabled (false);
m_ui->openButton->setVisible (false);
connect (m_ui->stopButton, SIGNAL (clicked()),
this, SLOT (cancelDownload()));
connect (m_ui->openButton, SIGNAL (clicked()),
this, SLOT (installUpdate()));
/* Resize to fit */
setFixedSize (minimumSizeHint());
setStyleSheet("background-color: #D8D8D8");
}
Downloader::~Downloader()
{
delete m_ui;
delete m_reply;
delete m_manager;
}
/**
* Returns \c true if the updater shall not intervene when the download has
* finished (you can use the \c QSimpleUpdater signals to know when the
* download is completed).
*/
bool Downloader::useCustomInstallProcedures() const
{
return m_useCustomProcedures;
}
/**
* Changes the URL, which is used to indentify the downloader dialog
* with an \c Updater instance
*
* \note the \a url parameter is not the download URL, it is the URL of
* the AppCast file
*/
void Downloader::setUrlId (const QString& url)
{
m_url = url;
}
/**
* Begins downloading the file at the given \a url
*/
void Downloader::startDownload (const QUrl& url)
{
/* Reset UI */
m_ui->progressBar->setValue (0);
m_ui->stopButton->setText (tr ("Stop"));
m_ui->downloadLabel->setText (tr ("Downloading updates"));
m_ui->timeLabel->setText (tr ("Time remaining") + ": " + tr ("unknown"));
/* Configure the network request */
QNetworkRequest request (url);
if (!m_userAgentString.isEmpty())
request.setRawHeader ("User-Agent", m_userAgentString.toUtf8());
/* Start download */
m_reply = m_manager->get (request);
m_startTime = QDateTime::currentDateTime().toTime_t();
/* Ensure that downloads directory exists */
if (!m_downloadDir.exists())
m_downloadDir.mkpath(".");
/* Remove old downloads */
QFile::remove (m_downloadDir.filePath (m_fileName));
QFile::remove (m_downloadDir.filePath (m_fileName + PARTIAL_DOWN));
/* Update UI when download progress changes or download finishes */
connect (m_reply, SIGNAL (downloadProgress (qint64, qint64)),
this, SLOT (updateProgress (qint64, qint64)));
connect (m_reply, SIGNAL (finished ()),
this, SLOT (finished ()));
connect (m_reply, SIGNAL (redirected (QUrl)),
this, SLOT (startDownload (QUrl)));
showNormal();
}
/**
* Changes the name of the downloaded file
*/
void Downloader::setFileName (const QString& file)
{
m_fileName = file;
if (m_fileName.isEmpty())
m_fileName = "QSU_Update.bin";
}
/**
* Changes the user-agent string used to communicate with the remote HTTP server
*/
void Downloader::setUserAgentString (const QString& agent)
{
m_userAgentString = agent;
}
void Downloader::finished()
{
/* Rename file */
QFile::rename (m_downloadDir.filePath (m_fileName + PARTIAL_DOWN),
m_downloadDir.filePath (m_fileName));
/* Notify application */
emit downloadFinished (m_url, m_downloadDir.filePath (m_fileName));
/* Install the update */
m_reply->close();
installUpdate();
setVisible (false);
}
/**
* Opens the downloaded file.
* \note If the downloaded file is not found, then the function will alert the
* user about the error.
*/
void Downloader::openDownload() {
if(!m_fileName.isEmpty()) QDesktopServices::openUrl(QUrl::fromLocalFile(m_downloadDir.filePath(m_fileName)));
else QMessageBox::critical (gMainWin, tr("Error"), tr("Cannot find downloaded update!"), QMessageBox::Close);
}
/**
* Instructs the OS to open the downloaded file.
*
* \note If \c useCustomInstallProcedures() returns \c true, the function will
* not instruct the OS to open the downloaded file. You can use the
* signals fired by the \c QSimpleUpdater to install the update with your
* own implementations/code.
*/
void Downloader::installUpdate(){
if (useCustomInstallProcedures()){
return;
}
/* Update labels */
m_ui->stopButton->setText (tr ("Close"));
m_ui->downloadLabel->setText (tr ("Download complete!"));
m_ui->timeLabel->setText (tr ("The installer will open separately")
+ "...");
/* Ask the user to install the download */
// QMessageBox box;
// box.setIcon (QMessageBox::Question);
// box.setDefaultButton (QMessageBox::Ok);
// box.setStandardButtons (QMessageBox::Ok | QMessageBox::Cancel);
// box.setInformativeText (tr ("Click \"OK\" to begin installing the update"));
QString text = m_mandatoryUpdate ? tr("In order to install the update, you may need to quit the application. This is a mandatory update, exiting now will close the application") : tr("In order to install the update ");
auto res = QMessageBox::information(gMainWin, tr("Tip Info"), text, QMessageBox::Ok, QMessageBox::Cancel);
if(m_mandatoryUpdate) QApplication::quit();
if(res == QMessageBox::Ok) {
if(!useCustomInstallProcedures()) openDownload();
} else {
m_ui->openButton->setEnabled (true);
m_ui->openButton->setVisible (true);
m_ui->timeLabel->setText (tr ("Click the \"Open\" button to "
"apply the update"));
}
}
/**
* Prompts the user if he/she wants to cancel the download and cancels the
* download if the user agrees to do that.
*/
void Downloader::cancelDownload()
{
if (!m_reply->isFinished()) {
QMessageBox box;
box.setWindowTitle (tr ("Updater"));
box.setIcon (QMessageBox::Question);
box.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
QString text = tr("Are you sure you want to cancel the download?");
if (m_mandatoryUpdate)
{
text = tr("Are you sure you want to cancel the download? This is a mandatory update, exiting now will close the application");
}
box.setText (text);
if (box.exec() == QMessageBox::Yes) {
hide();
m_reply->abort();
if(m_mandatoryUpdate)
QApplication::quit();
}
}
else
{
if(m_mandatoryUpdate)
QApplication::quit();
hide();
}
}
/**
* Writes the downloaded data to the disk
*/
void Downloader::saveFile (qint64 received, qint64 total)
{
Q_UNUSED (received);
Q_UNUSED (total);
/* Check if we need to redirect */
QUrl url = m_reply->attribute (
QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!url.isEmpty()) {
startDownload (url);
return;
}
/* Save downloaded data to disk */
QFile file (m_downloadDir.filePath (m_fileName + PARTIAL_DOWN));
if (file.open (QIODevice::WriteOnly | QIODevice::Append)) {
file.write (m_reply->readAll());
file.close();
}
}
/**
* Calculates the appropiate size units (bytes, KB or MB) for the received
* data and the total download size. Then, this function proceeds to update the
* dialog controls/UI.
*/
void Downloader::calculateSizes (qint64 received, qint64 total)
{
QString totalSize;
QString receivedSize;
if (total < 1024)
totalSize = tr ("%1 bytes").arg (total);
else if (total < 1048576)
totalSize = tr ("%1 KB").arg (round (total / 1024));
else
totalSize = tr ("%1 MB").arg (round (total / 1048576));
if (received < 1024)
receivedSize = tr ("%1 bytes").arg (received);
else if (received < 1048576)
receivedSize = tr ("%1 KB").arg (received / 1024);
else
receivedSize = tr ("%1 MB").arg (received / 1048576);
m_ui->downloadLabel->setText (tr ("Downloading updates")
+ " (" + receivedSize + " " + tr ("of")
+ " " + totalSize + ")");
}
/**
* Uses the \a received and \a total parameters to get the download progress
* and update the progressbar value on the dialog.
*/
void Downloader::updateProgress (qint64 received, qint64 total)
{
if (total > 0) {
m_ui->progressBar->setMinimum (0);
m_ui->progressBar->setMaximum (100);
m_ui->progressBar->setValue ((received * 100) / total);
calculateSizes (received, total);
calculateTimeRemaining (received, total);
saveFile (received, total);
}
else {
m_ui->progressBar->setMinimum (0);
m_ui->progressBar->setMaximum (0);
m_ui->progressBar->setValue (-1);
m_ui->downloadLabel->setText (tr ("Downloading Updates") + "...");
m_ui->timeLabel->setText (QString ("%1: %2")
.arg (tr ("Time Remaining"))
.arg (tr ("Unknown")));
}
}
/**
* Uses two time samples (from the current time and a previous sample) to
* calculate how many bytes have been downloaded.
*
* Then, this function proceeds to calculate the appropiate units of time
* (hours, minutes or seconds) and constructs a user-friendly string, which
* is displayed in the dialog.
*/
void Downloader::calculateTimeRemaining (qint64 received, qint64 total)
{
uint difference = QDateTime::currentDateTime().toTime_t() - m_startTime;
if (difference > 0) {
QString timeString;
qreal timeRemaining = (total - received) / (received / difference);
if (timeRemaining > 7200) {
timeRemaining /= 3600;
int hours = int (timeRemaining + 0.5);
if (hours > 1)
timeString = tr ("about %1 hours").arg (hours);
else
timeString = tr ("about one hour");
}
else if (timeRemaining > 60) {
timeRemaining /= 60;
int minutes = int (timeRemaining + 0.5);
if (minutes > 1)
timeString = tr ("%1 minutes").arg (minutes);
else
timeString = tr ("1 minute");
}
else if (timeRemaining <= 60) {
int seconds = int (timeRemaining + 0.5);
if (seconds > 1)
timeString = tr ("%1 seconds").arg (seconds);
else
timeString = tr ("1 second");
}
m_ui->timeLabel->setText (tr ("Time remaining") + ": " + timeString);
}
}
/**
* Rounds the given \a input to two decimal places
*/
qreal Downloader::round (const qreal& input)
{
return static_cast<qreal>(roundf (static_cast<float>(input) * 100) / 100);
}
QString Downloader::downloadDir() const
{
return m_downloadDir.absolutePath();
}
void Downloader::setDownloadDir (const QString& downloadDir)
{
if (m_downloadDir.absolutePath() != downloadDir)
m_downloadDir.setPath(downloadDir);
}
/**
* If the \a mandatory_update is set to \c true, the \c Downloader has to download and install the
* update. If the user cancels or exits, the application will close
*/
void Downloader::setMandatoryUpdate(const bool mandatory_update)
{
m_mandatoryUpdate = mandatory_update;
}
/**
* If the \a custom parameter is set to \c true, then the \c Downloader will not
* attempt to open the downloaded file.
*
* Use the signals fired by the \c QSimpleUpdater to implement your own install
* procedures.
*/
void Downloader::setUseCustomInstallProcedures (const bool custom)
{
m_useCustomProcedures = custom;
}

View File

@ -1,101 +1,101 @@
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
* Copyright (c) 2017 Gilmanov Ildar <https://github.com/gilmanov-ildar>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#ifndef DOWNLOAD_DIALOG_H
#define DOWNLOAD_DIALOG_H
#include <QDir>
#include <QDialog>
#include <ui_Downloader.h>
namespace Ui {
class Downloader;
}
class QNetworkReply;
class QNetworkAccessManager;
/**
* \brief Implements an integrated file downloader with a nice UI
*/
class Downloader : public QDialog//QWidget
{
Q_OBJECT
signals:
void downloadFinished (const QString& url, const QString& filepath);
public:
explicit Downloader (QWidget* parent = 0);
~Downloader();
bool useCustomInstallProcedures() const;
QString m_strVersion="";
QString downloadDir() const;
void setDownloadDir (const QString& downloadDir);
public slots:
void setUrlId (const QString& url);
void startDownload (const QUrl& url);
void setFileName (const QString& file);
void setUserAgentString (const QString& agent);
void setUseCustomInstallProcedures (const bool custom);
void setMandatoryUpdate (const bool mandatory_update);
private slots:
void finished();
void openDownload();
void installUpdate();
void cancelDownload();
void saveFile (qint64 received, qint64 total);
void calculateSizes (qint64 received, qint64 total);
void updateProgress (qint64 received, qint64 total);
void calculateTimeRemaining (qint64 received, qint64 total);
private:
qreal round (const qreal& input);
private:
QString m_url;
uint m_startTime;
QDir m_downloadDir;
QString m_fileName;
Ui::Downloader* m_ui;
QNetworkReply* m_reply;
QString m_userAgentString;
bool m_useCustomProcedures;
bool m_mandatoryUpdate;
QNetworkAccessManager* m_manager;
};
#endif
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
* Copyright (c) 2017 Gilmanov Ildar <https://github.com/gilmanov-ildar>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#ifndef DOWNLOAD_DIALOG_H
#define DOWNLOAD_DIALOG_H
#include <QDir>
#include <QDialog>
#include <ui_Downloader.h>
namespace Ui {
class Downloader;
}
class QNetworkReply;
class QNetworkAccessManager;
/**
* \brief Implements an integrated file downloader with a nice UI
*/
class Downloader : public QDialog//QWidget
{
Q_OBJECT
signals:
void downloadFinished (const QString& url, const QString& filepath);
public:
explicit Downloader (QWidget* parent = 0);
~Downloader();
bool useCustomInstallProcedures() const;
QString m_strVersion="";
QString downloadDir() const;
void setDownloadDir (const QString& downloadDir);
public slots:
void setUrlId (const QString& url);
void startDownload (const QUrl& url);
void setFileName (const QString& file);
void setUserAgentString (const QString& agent);
void setUseCustomInstallProcedures (const bool custom);
void setMandatoryUpdate (const bool mandatory_update);
private slots:
void finished();
void openDownload();
void installUpdate();
void cancelDownload();
void saveFile (qint64 received, qint64 total);
void calculateSizes (qint64 received, qint64 total);
void updateProgress (qint64 received, qint64 total);
void calculateTimeRemaining (qint64 received, qint64 total);
private:
qreal round (const qreal& input);
private:
QString m_url;
uint m_startTime;
QDir m_downloadDir;
QString m_fileName;
Ui::Downloader* m_ui;
QNetworkReply* m_reply;
QString m_userAgentString;
bool m_useCustomProcedures;
bool m_mandatoryUpdate;
QNetworkAccessManager* m_manager;
};
#endif

View File

@ -1,214 +1,214 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Downloader</class>
<widget class="QWidget" name="Downloader">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>472</width>
<height>227</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Updater</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="maximumSize">
<size>
<width>30</width>
<height>24</height>
</size>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="styleSheet">
<string notr="true">border-top: 2px solid gray; </string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="updater_icon">
<property name="minimumSize">
<size>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../etc/resources/qsimpleupdater.qrc">:/icons/update.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="progressFrame" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="downloadLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Downloading updates</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="minimumSize">
<size>
<width>320</width>
<height>0</height>
</size>
</property>
<property name="value">
<number>0</number>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="timeLabel">
<property name="text">
<string>Time remaining: 0 minutes</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="buttonFrame" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item>
<spacer name="buttonSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="openButton">
<property name="text">
<string>Open</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopButton">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../etc/resources/qsimpleupdater.qrc"/>
</resources>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Downloader</class>
<widget class="QWidget" name="Downloader">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>472</width>
<height>227</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Updater</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="maximumSize">
<size>
<width>30</width>
<height>24</height>
</size>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="styleSheet">
<string notr="true">border-top: 2px solid gray; </string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="updater_icon">
<property name="minimumSize">
<size>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../etc/resources/qsimpleupdater.qrc">:/icons/update.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="progressFrame" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="downloadLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Downloading updates</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="minimumSize">
<size>
<width>320</width>
<height>0</height>
</size>
</property>
<property name="value">
<number>0</number>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="timeLabel">
<property name="text">
<string>Time remaining: 0 minutes</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="buttonFrame" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item>
<spacer name="buttonSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="openButton">
<property name="text">
<string>Open</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopButton">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../etc/resources/qsimpleupdater.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -1,433 +1,433 @@
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#include "Updater.h"
#include "QSimpleUpdater.h"
static QList<QString> URLS;
static QList<Updater*> UPDATERS;
QSimpleUpdater::~QSimpleUpdater()
{
URLS.clear();
foreach (Updater* updater, UPDATERS)
updater->deleteLater();
UPDATERS.clear();
}
/**
* Returns the only instance of the class
*/
QSimpleUpdater* QSimpleUpdater::getInstance()
{
static QSimpleUpdater updater;
return &updater;
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* uses a custom appcast format and/or allows the application to read and
* interpret the downloaded appcast file
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::usesCustomAppcast (const QString& url) const
{
return getUpdater (url)->customAppcast();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* shall notify the user when an update is available.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::getNotifyOnUpdate (const QString& url) const
{
return getUpdater (url)->notifyOnUpdate();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* shall notify the user when it finishes checking for updates.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::getNotifyOnFinish (const QString& url) const
{
return getUpdater (url)->notifyOnFinish();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* has an update available.
*
* \warning You should call \c checkForUpdates() before using this function
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::getUpdateAvailable (const QString& url) const
{
return getUpdater (url)->updateAvailable();
}
bool QSimpleUpdater::getUpdateSameVersionAvailable (const QString& url) const
{
return getUpdater (url)->updateSameVersionAvailable();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* has the integrated downloader enabled.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::getDownloaderEnabled (const QString& url) const
{
return getUpdater (url)->downloaderEnabled();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* shall try to open the downloaded file.
*
* If you want to implement your own way to handle the downloaded file, just
* bind to the \c downloadFinished() signal and disable the integrated
* downloader with the \c setUseCustomInstallProcedures() function.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::usesCustomInstallProcedures (const QString& url) const
{
return getUpdater (url)->useCustomInstallProcedures();
}
/**
* Returns the URL to open in a web browser of the \c Updater instance
* registered with the given \a url.
*
* \note If the module name is empty, then the \c Updater will use the
* application name as its module name.
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getOpenUrl (const QString& url) const
{
return getUpdater (url)->openUrl();
}
/**
* Returns the changelog of the \c Updater instance registered with the given
* \a url.
*
* \warning You should call \c checkForUpdates() before using this function
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getChangelog (const QString& url) const
{
return getUpdater (url)->changelog();
}
/**
* Returns the module name of the \c Updater instance registered with the given
* \a url.
*
* \note If the module name is empty, then the \c Updater will use the
* application name as its module name.
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getModuleName (const QString& url) const
{
return getUpdater (url)->moduleName();
}
/**
* Returns the download URL of the \c Updater instance registered with the given
* \a url.
*
* \warning You should call \c checkForUpdates() before using this function
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getDownloadUrl (const QString& url) const
{
return getUpdater (url)->downloadUrl();
}
/**
* Returns the platform key of the \c Updater registered with the given \a url.
* If you do not define a platform key, the system will assign the following
* platform key:
* - On iOS: \c ios
* - On Mac OSX: \c osx
* - On Android: \c android
* - On GNU/Linux: \c linux
* - On Microsoft Windows: \c windows
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getPlatformKey (const QString& url) const
{
return getUpdater (url)->platformKey();
}
/**
* Returns the remote module version of the \c Updater instance registered with
* the given \a url.
*
* \warning You should call \c checkForUpdates() before using this function
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getLatestVersion (const QString& url) const
{
return getUpdater (url)->latestVersion();
}
/**
* Returns the module version of the \c Updater instance registered with the
* given \a url.
*
* \note If the module version is empty, then the \c Updater will use the
* application version as its module version.
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getModuleVersion (const QString& url) const
{
return getUpdater (url)->moduleVersion();
}
/**
* Returns the user-agent string used by the updater to communicate with
* the remote HTTP(S) server.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getUserAgentString (const QString& url) const
{
return getUpdater (url)->userAgentString();
}
/**
* Instructs the \c Updater instance with the registered \c url to download and
* interpret the update definitions file.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::checkForUpdates (const QString& url)
{
getUpdater (url)->checkForUpdates();
}
/**
* Changes the module \a name of the \c Updater instance registered at the
* given \a url.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
* \note The module name is used on the user prompts. If the module name is
* empty, then the prompts will show the name of the application.
*/
void QSimpleUpdater::setModuleName (const QString& url, const QString& name)
{
getUpdater (url)->setModuleName (name);
}
/**
* If \a notify is set to \c true, then the \c Updater instance registered with
* the given \a url will notify the user when an update is available.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setNotifyOnUpdate (const QString& url,
const bool notify)
{
getUpdater (url)->setNotifyOnUpdate (notify);
}
/**
* If \a notify is set to \c true, then the \c Updater instance registered with
* the given \a url will notify the user when it has finished interpreting the
* update definitions file.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setNotifyOnFinish (const QString& url,
const bool notify)
{
getUpdater (url)->setNotifyOnFinish (notify);
}
/**
* Changes the platform key of the \c Updater isntance registered at the given
* \a url.
*
* If the platform key is empty, then the system will use the following keys:
* - On iOS: \c ios
* - On Mac OSX: \c osx
* - On Android: \c android
* - On GNU/Linux: \c linux
* - On Microsoft Windows: \c windows
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setPlatformKey (const QString& url,
const QString& platform)
{
getUpdater (url)->setPlatformKey (platform);
}
/**
* Changes the module \version of the \c Updater instance registered at the
* given \a url.
*
* \note The module version is used to compare it with the remove version.
* If the module name is empty, then the \c Updater instance will use the
* application version.
*/
void QSimpleUpdater::setModuleVersion (const QString& url,
const QString& version)
{
getUpdater (url)->setModuleVersion (version);
}
/**
* If the \a enabled parameter is set to \c true, the \c Updater instance
* registered with the given \a url will open the integrated downloader
* if the user agrees to install the update (if any).
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setDownloaderEnabled (const QString& url,
const bool enabled)
{
getUpdater (url)->setDownloaderEnabled (enabled);
}
/**
* Changes the user-agent string used by the updater to communicate
* with the remote server
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setUserAgentString (const QString& url,
const QString& agent)
{
getUpdater (url)->setUserAgentString (agent);
}
/**
* If the \a customAppcast parameter is set to \c true, then the \c Updater
* will not try to read the network reply from the server, instead, it will
* emit the \c appcastDownloaded() signal, which allows the application to
* read and interpret the appcast file by itself.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setUseCustomAppcast (const QString& url,
const bool customAppcast)
{
getUpdater (url)->setUseCustomAppcast (customAppcast);
}
/**
* If the \a custom parameter is set to \c true, the \c Updater instance
* registered with the given \a url will not try to open the downloaded file.
*
* If you want to implement your own way to handle the downloaded file, just
* bind to the \c downloadFinished() signal and disable the integrated
* downloader with the \c setUseCustomInstallProcedures() function.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setUseCustomInstallProcedures (const QString& url,
const bool custom)
{
getUpdater (url)->setUseCustomInstallProcedures (custom);
}
void QSimpleUpdater::setNoNotifyDownload (const QString& url,
const bool custom)
{
getUpdater (url)->setNoNotifyDownload (custom);
}
void QSimpleUpdater::setCompareBySameString (const QString& url,
const bool custom)
{
getUpdater (url)->setCompareBySameString (custom);
}
void QSimpleUpdater::setMandatoryUpdate(const QString& url,
const bool mandatory_update)
{
getUpdater (url)->setMandatoryUpdate(mandatory_update);
}
/**
* Returns the \c Updater instance registered with the given \a url.
*
* If an \c Updater instance registered with teh given \a url does not exist,
* this function will create it and configure it automatically.
*/
Updater* QSimpleUpdater::getUpdater (const QString& url) const
{
if (!URLS.contains (url)) {
Updater* updater = new Updater;
updater->setUrl (url);
URLS.append (url);
UPDATERS.append (updater);
connect (updater, SIGNAL (checkingFinished (QString)),
this, SIGNAL (checkingFinished (QString)));
connect (updater, SIGNAL (downloadFinished (QString, QString)),
this, SIGNAL (downloadFinished (QString, QString)));
connect (updater, SIGNAL (appcastDownloaded (QString, QByteArray)),
this, SIGNAL (appcastDownloaded (QString, QByteArray)));
}
return UPDATERS.at (URLS.indexOf (url));
}
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#include "Updater.h"
#include "QSimpleUpdater.h"
static QList<QString> URLS;
static QList<Updater*> UPDATERS;
QSimpleUpdater::~QSimpleUpdater()
{
URLS.clear();
foreach (Updater* updater, UPDATERS)
updater->deleteLater();
UPDATERS.clear();
}
/**
* Returns the only instance of the class
*/
QSimpleUpdater* QSimpleUpdater::getInstance()
{
static QSimpleUpdater updater;
return &updater;
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* uses a custom appcast format and/or allows the application to read and
* interpret the downloaded appcast file
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::usesCustomAppcast (const QString& url) const
{
return getUpdater (url)->customAppcast();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* shall notify the user when an update is available.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::getNotifyOnUpdate (const QString& url) const
{
return getUpdater (url)->notifyOnUpdate();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* shall notify the user when it finishes checking for updates.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::getNotifyOnFinish (const QString& url) const
{
return getUpdater (url)->notifyOnFinish();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* has an update available.
*
* \warning You should call \c checkForUpdates() before using this function
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::getUpdateAvailable (const QString& url) const
{
return getUpdater (url)->updateAvailable();
}
bool QSimpleUpdater::getUpdateSameVersionAvailable (const QString& url) const
{
return getUpdater (url)->updateSameVersionAvailable();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* has the integrated downloader enabled.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::getDownloaderEnabled (const QString& url) const
{
return getUpdater (url)->downloaderEnabled();
}
/**
* Returns \c true if the \c Updater instance registered with the given \a url
* shall try to open the downloaded file.
*
* If you want to implement your own way to handle the downloaded file, just
* bind to the \c downloadFinished() signal and disable the integrated
* downloader with the \c setUseCustomInstallProcedures() function.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
bool QSimpleUpdater::usesCustomInstallProcedures (const QString& url) const
{
return getUpdater (url)->useCustomInstallProcedures();
}
/**
* Returns the URL to open in a web browser of the \c Updater instance
* registered with the given \a url.
*
* \note If the module name is empty, then the \c Updater will use the
* application name as its module name.
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getOpenUrl (const QString& url) const
{
return getUpdater (url)->openUrl();
}
/**
* Returns the changelog of the \c Updater instance registered with the given
* \a url.
*
* \warning You should call \c checkForUpdates() before using this function
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getChangelog (const QString& url) const
{
return getUpdater (url)->changelog();
}
/**
* Returns the module name of the \c Updater instance registered with the given
* \a url.
*
* \note If the module name is empty, then the \c Updater will use the
* application name as its module name.
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getModuleName (const QString& url) const
{
return getUpdater (url)->moduleName();
}
/**
* Returns the download URL of the \c Updater instance registered with the given
* \a url.
*
* \warning You should call \c checkForUpdates() before using this function
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getDownloadUrl (const QString& url) const
{
return getUpdater (url)->downloadUrl();
}
/**
* Returns the platform key of the \c Updater registered with the given \a url.
* If you do not define a platform key, the system will assign the following
* platform key:
* - On iOS: \c ios
* - On Mac OSX: \c osx
* - On Android: \c android
* - On GNU/Linux: \c linux
* - On Microsoft Windows: \c windows
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getPlatformKey (const QString& url) const
{
return getUpdater (url)->platformKey();
}
/**
* Returns the remote module version of the \c Updater instance registered with
* the given \a url.
*
* \warning You should call \c checkForUpdates() before using this function
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getLatestVersion (const QString& url) const
{
return getUpdater (url)->latestVersion();
}
/**
* Returns the module version of the \c Updater instance registered with the
* given \a url.
*
* \note If the module version is empty, then the \c Updater will use the
* application version as its module version.
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getModuleVersion (const QString& url) const
{
return getUpdater (url)->moduleVersion();
}
/**
* Returns the user-agent string used by the updater to communicate with
* the remote HTTP(S) server.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
QString QSimpleUpdater::getUserAgentString (const QString& url) const
{
return getUpdater (url)->userAgentString();
}
/**
* Instructs the \c Updater instance with the registered \c url to download and
* interpret the update definitions file.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::checkForUpdates (const QString& url)
{
getUpdater (url)->checkForUpdates();
}
/**
* Changes the module \a name of the \c Updater instance registered at the
* given \a url.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
* \note The module name is used on the user prompts. If the module name is
* empty, then the prompts will show the name of the application.
*/
void QSimpleUpdater::setModuleName (const QString& url, const QString& name)
{
getUpdater (url)->setModuleName (name);
}
/**
* If \a notify is set to \c true, then the \c Updater instance registered with
* the given \a url will notify the user when an update is available.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setNotifyOnUpdate (const QString& url,
const bool notify)
{
getUpdater (url)->setNotifyOnUpdate (notify);
}
/**
* If \a notify is set to \c true, then the \c Updater instance registered with
* the given \a url will notify the user when it has finished interpreting the
* update definitions file.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setNotifyOnFinish (const QString& url,
const bool notify)
{
getUpdater (url)->setNotifyOnFinish (notify);
}
/**
* Changes the platform key of the \c Updater isntance registered at the given
* \a url.
*
* If the platform key is empty, then the system will use the following keys:
* - On iOS: \c ios
* - On Mac OSX: \c osx
* - On Android: \c android
* - On GNU/Linux: \c linux
* - On Microsoft Windows: \c windows
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setPlatformKey (const QString& url,
const QString& platform)
{
getUpdater (url)->setPlatformKey (platform);
}
/**
* Changes the module \version of the \c Updater instance registered at the
* given \a url.
*
* \note The module version is used to compare it with the remove version.
* If the module name is empty, then the \c Updater instance will use the
* application version.
*/
void QSimpleUpdater::setModuleVersion (const QString& url,
const QString& version)
{
getUpdater (url)->setModuleVersion (version);
}
/**
* If the \a enabled parameter is set to \c true, the \c Updater instance
* registered with the given \a url will open the integrated downloader
* if the user agrees to install the update (if any).
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setDownloaderEnabled (const QString& url,
const bool enabled)
{
getUpdater (url)->setDownloaderEnabled (enabled);
}
/**
* Changes the user-agent string used by the updater to communicate
* with the remote server
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setUserAgentString (const QString& url,
const QString& agent)
{
getUpdater (url)->setUserAgentString (agent);
}
/**
* If the \a customAppcast parameter is set to \c true, then the \c Updater
* will not try to read the network reply from the server, instead, it will
* emit the \c appcastDownloaded() signal, which allows the application to
* read and interpret the appcast file by itself.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setUseCustomAppcast (const QString& url,
const bool customAppcast)
{
getUpdater (url)->setUseCustomAppcast (customAppcast);
}
/**
* If the \a custom parameter is set to \c true, the \c Updater instance
* registered with the given \a url will not try to open the downloaded file.
*
* If you want to implement your own way to handle the downloaded file, just
* bind to the \c downloadFinished() signal and disable the integrated
* downloader with the \c setUseCustomInstallProcedures() function.
*
* \note If an \c Updater instance registered with the given \a url is not
* found, that \c Updater instance will be initialized automatically
*/
void QSimpleUpdater::setUseCustomInstallProcedures (const QString& url,
const bool custom)
{
getUpdater (url)->setUseCustomInstallProcedures (custom);
}
void QSimpleUpdater::setNoNotifyDownload (const QString& url,
const bool custom)
{
getUpdater (url)->setNoNotifyDownload (custom);
}
void QSimpleUpdater::setCompareBySameString (const QString& url,
const bool custom)
{
getUpdater (url)->setCompareBySameString (custom);
}
void QSimpleUpdater::setMandatoryUpdate(const QString& url,
const bool mandatory_update)
{
getUpdater (url)->setMandatoryUpdate(mandatory_update);
}
/**
* Returns the \c Updater instance registered with the given \a url.
*
* If an \c Updater instance registered with teh given \a url does not exist,
* this function will create it and configure it automatically.
*/
Updater* QSimpleUpdater::getUpdater (const QString& url) const
{
if (!URLS.contains (url)) {
Updater* updater = new Updater;
updater->setUrl (url);
URLS.append (url);
UPDATERS.append (updater);
connect (updater, SIGNAL (checkingFinished (QString)),
this, SIGNAL (checkingFinished (QString)));
connect (updater, SIGNAL (downloadFinished (QString, QString)),
this, SIGNAL (downloadFinished (QString, QString)));
connect (updater, SIGNAL (appcastDownloaded (QString, QByteArray)),
this, SIGNAL (appcastDownloaded (QString, QByteArray)));
}
return UPDATERS.at (URLS.indexOf (url));
}

View File

@ -1,498 +1,498 @@
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#include <QJsonValue>
#include <QJsonObject>
#include <QMessageBox>
#include <QApplication>
#include <QJsonDocument>
#include <QDesktopServices>
#include "Updater.h"
#include "Downloader.h"
#include "cfg.h"
#include "qsettings.h"
Updater::Updater() {
m_url = "";
m_openUrl = "";
m_changelog = "";
m_downloadUrl = "";
m_latestVersion = "";
m_customAppcast = false;
m_notifyOnUpdate = true;
m_notifyOnFinish = false;
m_updateAvailable = true;
m_sameVersion = false;
m_downloaderEnabled = true;
m_noTipDownload = false;
m_bSameStringCompare = false;
m_moduleName = qApp->applicationName();
m_moduleVersion = qApp->applicationVersion();
m_mandatoryUpdate = false;
m_downloader = new Downloader();
m_manager = new QNetworkAccessManager();
QNetworkReply *pReply = m_manager->get(QNetworkRequest(QUrl(UpdVerUrl)));
QReplyTimeout *pTimeout = new QReplyTimeout(pReply, 10000);
// 超时进一步处理
connect(pTimeout, &QReplyTimeout::timeout, [=]() {
qDebug() << "Timeout";
});
#if defined Q_OS_WIN
m_platform = "windows";
#elif defined Q_OS_MAC
m_platform = "osx";
#elif defined Q_OS_LINUX
m_platform = "linux";
#elif defined Q_OS_ANDROID
m_platform = "android";
#elif defined Q_OS_IOS
m_platform = "ios";
#endif
setUserAgentString (QString ("%1/%2 (Qt; QSimpleUpdater)").arg(qApp->applicationName(), qApp->applicationVersion()));
connect (m_downloader, SIGNAL(downloadFinished(QString, QString)), this, SIGNAL (downloadFinished(QString, QString)));
connect (m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onReply(QNetworkReply*)));
}
Updater::~Updater()
{
delete m_downloader;
}
/**
* Returns the URL of the update definitions file
*/
QString Updater::url() const
{
return m_url;
}
/**
* Returns the URL that the update definitions file wants us to open in
* a web browser.
*
* \warning You should call \c checkForUpdates() before using this functio
*/
QString Updater::openUrl() const
{
return m_openUrl;
}
/**
* Returns the changelog defined by the update definitions file.
* \warning You should call \c checkForUpdates() before using this function
*/
QString Updater::changelog() const
{
return m_changelog;
}
/**
* Returns the name of the module (if defined)
*/
QString Updater::moduleName() const
{
return m_moduleName;
}
/**
* Returns the platform key (be it system-set or user-set).
* If you do not define a platform key, the system will assign the following
* platform key:
* - On iOS: \c ios
* - On Mac OSX: \c osx
* - On Android: \c android
* - On GNU/Linux: \c linux
* - On Microsoft Windows: \c windows
*/
QString Updater::platformKey() const
{
return m_platform;
}
/**
* Returns the download URL defined by the update definitions file.
* \warning You should call \c checkForUpdates() before using this function
*/
QString Updater::downloadUrl() const
{
return m_downloadUrl;
}
/**
* Returns the latest version defined by the update definitions file.
* \warning You should call \c checkForUpdates() before using this function
*/
QString Updater::latestVersion() const
{
return m_latestVersion;
}
/**
* Returns the user-agent header used by the client when communicating
* with the server through HTTP
*/
QString Updater::userAgentString() const
{
return m_userAgentString;
}
/**
* Returns the "local" version of the installed module
*/
QString Updater::moduleVersion() const
{
return m_moduleVersion;
}
/**
* Returns \c true if the updater should NOT interpret the downloaded appcast.
* This is useful if you need to store more variables (or information) in the
* JSON file or use another appcast format (e.g. XML)
*/
bool Updater::customAppcast() const
{
return m_customAppcast;
}
/**
* Returns \c true if the updater should notify the user when an update is
* available.
*/
bool Updater::notifyOnUpdate() const
{
return m_notifyOnUpdate;
}
/**
* Returns \c true if the updater should notify the user when it finishes
* checking for updates.
*
* \note If set to \c true, the \c Updater will notify the user even when there
* are no updates available (by congratulating him/her about being smart)
*/
bool Updater::notifyOnFinish() const
{
return m_notifyOnFinish;
}
/**
* Returns \c true if there the current update is mandatory.
* \warning You should call \c checkForUpdates() before using this function
*/
bool Updater::mandatoryUpdate() const
{
return m_mandatoryUpdate;
}
/**
* Returns \c true if there is an update available.
* \warning You should call \c checkForUpdates() before using this function
*/
bool Updater::updateAvailable() const {
return m_updateAvailable;
}
bool Updater::updateSameVersionAvailable() const {
return m_sameVersion;
}
/**
* Returns \c true if the integrated downloader is enabled.
* \note If set to \c true, the \c Updater will open the downloader dialog if
* the user agrees to download the update.
*/
bool Updater::downloaderEnabled() const
{
return m_downloaderEnabled;
}
/**
* Returns \c true if the updater shall not intervene when the download has
* finished (you can use the \c QSimpleUpdater signals to know when the
* download is completed).
*/
bool Updater::useCustomInstallProcedures() const
{
return m_downloader->useCustomInstallProcedures();
}
/**
* Downloads and interpets the update definitions file referenced by the
* \c url() function.
*/
void Updater::checkForUpdates(){
QNetworkRequest request (url());
if(!userAgentString().isEmpty()) request.setRawHeader("User-Agent", userAgentString().toUtf8());
m_manager->get(request);
}
/**
* Changes the \c url in which the \c Updater can find the update definitions
* file.
*/
void Updater::setUrl (const QString& url)
{
m_url = url;
}
/**
* Changes the module \a name.
* \note The module name is used on the user prompts. If the module name is
* empty, then the prompts will show the name of the application.
*/
void Updater::setModuleName (const QString& name)
{
m_moduleName = name;
}
/**
* If \a notify is set to \c true, then the \c Updater will notify the user
* when an update is available.
*/
void Updater::setNotifyOnUpdate (const bool notify)
{
m_notifyOnUpdate = notify;
}
/**
* If \a notify is set to \c true, then the \c Updater will notify the user
* when it has finished interpreting the update definitions file.
*/
void Updater::setNotifyOnFinish (const bool notify)
{
m_notifyOnFinish = notify;
}
void Updater::setNoNotifyDownload(const bool notify)
{
m_noTipDownload = notify;
}
void Updater::setCompareBySameString(const bool notify)
{
m_bSameStringCompare = notify;
}
/**
* Changes the user agent string used to identify the client application
* from the server in a HTTP session.
*
* By default, the user agent will co
*/
void Updater::setUserAgentString (const QString& agent)
{
m_userAgentString = agent;
m_downloader->setUserAgentString (agent);
}
/**
* Changes the module \a version
* \note The module version is used to compare the local and remote versions.
* If the \a version parameter is empty, then the \c Updater will use the
* application version (referenced by \c qApp)
*/
void Updater::setModuleVersion (const QString& version)
{
m_moduleVersion = version;
}
/**
* If the \a enabled parameter is set to \c true, the \c Updater will open the
* integrated downloader if the user agrees to install the update (if any)
*/
void Updater::setDownloaderEnabled (const bool enabled)
{
m_downloaderEnabled = enabled;
}
/**
* Changes the platform key.
* If the platform key is empty, then the system will use the following keys:
* - On iOS: \c ios
* - On Mac OSX: \c osx
* - On Android: \c android
* - On GNU/Linux: \c linux
* - On Microsoft Windows: \c windows
*/
void Updater::setPlatformKey (const QString& platformKey)
{
m_platform = platformKey;
}
/**
* If the \a customAppcast parameter is set to \c true, then the \c Updater
* will not try to read the network reply from the server, instead, it will
* emit the \c appcastDownloaded() signal, which allows the application to
* read and interpret the appcast file by itself
*/
void Updater::setUseCustomAppcast (const bool customAppcast)
{
m_customAppcast = customAppcast;
}
/**
* If the \a custom parameter is set to \c true, the \c Updater will not try
* to open the downloaded file. Use the signals fired by the \c QSimpleUpdater
* to install the update from the downloaded file by yourself.
*/
void Updater::setUseCustomInstallProcedures (const bool custom)
{
m_downloader->setUseCustomInstallProcedures (custom);
}
/**
* If the \a mandatory_update is set to \c true, the \c Updater has to download and install the
* update. If the user cancels or exits, the application will close
*/
void Updater::setMandatoryUpdate(const bool mandatory_update)
{
m_mandatoryUpdate = mandatory_update;
}
/**
* Called when the download of the update definitions file is finished.
*/
void Updater::onReply(QNetworkReply* reply) {
/* Check if we need to redirect */
QUrl redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!redirect.isEmpty()) {
setUrl (redirect.toString());
checkForUpdates();
return;
}
reply->ignoreSslErrors();
/* There was a network error */
int err = reply->error();
if (err != QNetworkReply::NoError) {
qDebug()<<"Updater::onReply QNetworkReply::Error="<< err <<reply->url();
setUpdateAvailable (false);
emit checkingFinished (url());
return;
}
/* The application wants to interpret the appcast by itself */
if (customAppcast()) {
emit appcastDownloaded (url(), reply->readAll());
emit checkingFinished (url());
return;
}
/* Try to create a JSON document from downloaded data */
QJsonDocument document = QJsonDocument::fromJson (reply->readAll());
/* JSON is invalid */
if(document.isNull()) {
qDebug()<<"Updater::onReply document.isNull()";
setUpdateAvailable (false);
emit checkingFinished (url());
return;
}
/* Get the platform information */
QJsonObject updates = document.object().value ("updates").toObject();
QJsonObject platform = updates.value(platformKey()).toObject();
/* Get update information */
m_openUrl = platform.value("open-url").toString();
m_changelog = platform.value("changelog_zhCN").toString();
m_downloadUrl = platform.value("download-url").toString();
m_latestVersion = platform.value("latest-version").toString();
if(platform.contains("mandatory-update")) m_mandatoryUpdate = platform.value ("mandatory-update").toBool();
/* Compare latest and current version */
if(m_bSameStringCompare) {
m_sameVersion = false;
if(latestVersion()==moduleVersion()) m_sameVersion=true;
setUpdateAvailable(!m_sameVersion);
} else {
if(latestVersion()==moduleVersion()){
setUpdateAvailable(false);
m_sameVersion = true;
} else {
setUpdateAvailable(compare(latestVersion(), moduleVersion()));
m_sameVersion = false;
}
}
emit checkingFinished(url());
}
/**
* Prompts the user based on the value of the \a available parameter and the
* settings of this instance of the \c Updater class.
*/
void Updater::setUpdateAvailable(const bool available) {
m_updateAvailable = available;
QMessageBox box;
box.setTextFormat (Qt::RichText);
box.setIcon (QMessageBox::Information);
if(updateAvailable() && (notifyOnUpdate() || notifyOnFinish())) {
QString text = tr("Would you like to download the update now?");
if(m_mandatoryUpdate) text = tr ("Would you like to download the update now? This is a mandatory update, exiting now will close the application");
if(m_noTipDownload) {
m_downloader->setUrlId (url());
m_downloader->setFileName (downloadUrl().split ("/").last());
m_downloader->setMandatoryUpdate(m_mandatoryUpdate);
m_downloader->startDownload (QUrl (downloadUrl()));
m_downloader->m_strVersion=latestVersion();
} else {
if (!openUrl().isEmpty()) QDesktopServices::openUrl (QUrl (openUrl()));
else if (downloaderEnabled()) {
m_downloader->setUrlId (url());
m_downloader->setFileName (downloadUrl().split ("/").last());
m_downloader->setMandatoryUpdate(m_mandatoryUpdate);
m_downloader->startDownload (QUrl (downloadUrl()));
m_downloader->m_strVersion=latestVersion();
}
else QDesktopServices::openUrl (QUrl (downloadUrl()));
}
}
else if (notifyOnFinish()) {
box.setStandardButtons (QMessageBox::Close);
box.setInformativeText (tr ("No updates are available for the moment"));
box.setText ("<h3>"
+ tr ("Congratulations! You are running the "
"latest version of %1").arg (moduleName())
+ "</h3>");
box.exec();
}
}
/**
* Compares the two version strings (\a x and \a y).
* - If \a x is greater than \y, this function returns \c true.
* - If \a y is greater than \x, this function returns \c false.
* - If both versions are the same, this function returns \c false.
*/
bool Updater::compare(const QString& x, const QString& y) {
QStringList versionsX = x.split(".");
QStringList versionsY = y.split(".");
int count = qMin(versionsX.count(), versionsY.count());
for (int i = 0; i < count; ++i) {
int a = QString(versionsX.at (i)).toInt();
int b = QString(versionsY.at (i)).toInt();
if(a >= b) return true;
else if(b > a) return false;
}
return versionsY.count() < versionsX.count();
}
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#include <QJsonValue>
#include <QJsonObject>
#include <QMessageBox>
#include <QApplication>
#include <QJsonDocument>
#include <QDesktopServices>
#include "Updater.h"
#include "Downloader.h"
#include "cfg.h"
#include "qsettings.h"
Updater::Updater() {
m_url = "";
m_openUrl = "";
m_changelog = "";
m_downloadUrl = "";
m_latestVersion = "";
m_customAppcast = false;
m_notifyOnUpdate = true;
m_notifyOnFinish = false;
m_updateAvailable = true;
m_sameVersion = false;
m_downloaderEnabled = true;
m_noTipDownload = false;
m_bSameStringCompare = false;
m_moduleName = qApp->applicationName();
m_moduleVersion = qApp->applicationVersion();
m_mandatoryUpdate = false;
m_downloader = new Downloader();
m_manager = new QNetworkAccessManager();
QNetworkReply *pReply = m_manager->get(QNetworkRequest(QUrl(UpdVerUrl)));
QReplyTimeout *pTimeout = new QReplyTimeout(pReply, 10000);
// 超时进一步处理
connect(pTimeout, &QReplyTimeout::timeout, [=]() {
qDebug() << "Timeout";
});
#if defined Q_OS_WIN
m_platform = "windows";
#elif defined Q_OS_MAC
m_platform = "osx";
#elif defined Q_OS_LINUX
m_platform = "linux";
#elif defined Q_OS_ANDROID
m_platform = "android";
#elif defined Q_OS_IOS
m_platform = "ios";
#endif
setUserAgentString (QString ("%1/%2 (Qt; QSimpleUpdater)").arg(qApp->applicationName(), qApp->applicationVersion()));
connect (m_downloader, SIGNAL(downloadFinished(QString, QString)), this, SIGNAL (downloadFinished(QString, QString)));
connect (m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onReply(QNetworkReply*)));
}
Updater::~Updater()
{
delete m_downloader;
}
/**
* Returns the URL of the update definitions file
*/
QString Updater::url() const
{
return m_url;
}
/**
* Returns the URL that the update definitions file wants us to open in
* a web browser.
*
* \warning You should call \c checkForUpdates() before using this functio
*/
QString Updater::openUrl() const
{
return m_openUrl;
}
/**
* Returns the changelog defined by the update definitions file.
* \warning You should call \c checkForUpdates() before using this function
*/
QString Updater::changelog() const
{
return m_changelog;
}
/**
* Returns the name of the module (if defined)
*/
QString Updater::moduleName() const
{
return m_moduleName;
}
/**
* Returns the platform key (be it system-set or user-set).
* If you do not define a platform key, the system will assign the following
* platform key:
* - On iOS: \c ios
* - On Mac OSX: \c osx
* - On Android: \c android
* - On GNU/Linux: \c linux
* - On Microsoft Windows: \c windows
*/
QString Updater::platformKey() const
{
return m_platform;
}
/**
* Returns the download URL defined by the update definitions file.
* \warning You should call \c checkForUpdates() before using this function
*/
QString Updater::downloadUrl() const
{
return m_downloadUrl;
}
/**
* Returns the latest version defined by the update definitions file.
* \warning You should call \c checkForUpdates() before using this function
*/
QString Updater::latestVersion() const
{
return m_latestVersion;
}
/**
* Returns the user-agent header used by the client when communicating
* with the server through HTTP
*/
QString Updater::userAgentString() const
{
return m_userAgentString;
}
/**
* Returns the "local" version of the installed module
*/
QString Updater::moduleVersion() const
{
return m_moduleVersion;
}
/**
* Returns \c true if the updater should NOT interpret the downloaded appcast.
* This is useful if you need to store more variables (or information) in the
* JSON file or use another appcast format (e.g. XML)
*/
bool Updater::customAppcast() const
{
return m_customAppcast;
}
/**
* Returns \c true if the updater should notify the user when an update is
* available.
*/
bool Updater::notifyOnUpdate() const
{
return m_notifyOnUpdate;
}
/**
* Returns \c true if the updater should notify the user when it finishes
* checking for updates.
*
* \note If set to \c true, the \c Updater will notify the user even when there
* are no updates available (by congratulating him/her about being smart)
*/
bool Updater::notifyOnFinish() const
{
return m_notifyOnFinish;
}
/**
* Returns \c true if there the current update is mandatory.
* \warning You should call \c checkForUpdates() before using this function
*/
bool Updater::mandatoryUpdate() const
{
return m_mandatoryUpdate;
}
/**
* Returns \c true if there is an update available.
* \warning You should call \c checkForUpdates() before using this function
*/
bool Updater::updateAvailable() const {
return m_updateAvailable;
}
bool Updater::updateSameVersionAvailable() const {
return m_sameVersion;
}
/**
* Returns \c true if the integrated downloader is enabled.
* \note If set to \c true, the \c Updater will open the downloader dialog if
* the user agrees to download the update.
*/
bool Updater::downloaderEnabled() const
{
return m_downloaderEnabled;
}
/**
* Returns \c true if the updater shall not intervene when the download has
* finished (you can use the \c QSimpleUpdater signals to know when the
* download is completed).
*/
bool Updater::useCustomInstallProcedures() const
{
return m_downloader->useCustomInstallProcedures();
}
/**
* Downloads and interpets the update definitions file referenced by the
* \c url() function.
*/
void Updater::checkForUpdates(){
QNetworkRequest request (url());
if(!userAgentString().isEmpty()) request.setRawHeader("User-Agent", userAgentString().toUtf8());
m_manager->get(request);
}
/**
* Changes the \c url in which the \c Updater can find the update definitions
* file.
*/
void Updater::setUrl (const QString& url)
{
m_url = url;
}
/**
* Changes the module \a name.
* \note The module name is used on the user prompts. If the module name is
* empty, then the prompts will show the name of the application.
*/
void Updater::setModuleName (const QString& name)
{
m_moduleName = name;
}
/**
* If \a notify is set to \c true, then the \c Updater will notify the user
* when an update is available.
*/
void Updater::setNotifyOnUpdate (const bool notify)
{
m_notifyOnUpdate = notify;
}
/**
* If \a notify is set to \c true, then the \c Updater will notify the user
* when it has finished interpreting the update definitions file.
*/
void Updater::setNotifyOnFinish (const bool notify)
{
m_notifyOnFinish = notify;
}
void Updater::setNoNotifyDownload(const bool notify)
{
m_noTipDownload = notify;
}
void Updater::setCompareBySameString(const bool notify)
{
m_bSameStringCompare = notify;
}
/**
* Changes the user agent string used to identify the client application
* from the server in a HTTP session.
*
* By default, the user agent will co
*/
void Updater::setUserAgentString (const QString& agent)
{
m_userAgentString = agent;
m_downloader->setUserAgentString (agent);
}
/**
* Changes the module \a version
* \note The module version is used to compare the local and remote versions.
* If the \a version parameter is empty, then the \c Updater will use the
* application version (referenced by \c qApp)
*/
void Updater::setModuleVersion (const QString& version)
{
m_moduleVersion = version;
}
/**
* If the \a enabled parameter is set to \c true, the \c Updater will open the
* integrated downloader if the user agrees to install the update (if any)
*/
void Updater::setDownloaderEnabled (const bool enabled)
{
m_downloaderEnabled = enabled;
}
/**
* Changes the platform key.
* If the platform key is empty, then the system will use the following keys:
* - On iOS: \c ios
* - On Mac OSX: \c osx
* - On Android: \c android
* - On GNU/Linux: \c linux
* - On Microsoft Windows: \c windows
*/
void Updater::setPlatformKey (const QString& platformKey)
{
m_platform = platformKey;
}
/**
* If the \a customAppcast parameter is set to \c true, then the \c Updater
* will not try to read the network reply from the server, instead, it will
* emit the \c appcastDownloaded() signal, which allows the application to
* read and interpret the appcast file by itself
*/
void Updater::setUseCustomAppcast (const bool customAppcast)
{
m_customAppcast = customAppcast;
}
/**
* If the \a custom parameter is set to \c true, the \c Updater will not try
* to open the downloaded file. Use the signals fired by the \c QSimpleUpdater
* to install the update from the downloaded file by yourself.
*/
void Updater::setUseCustomInstallProcedures (const bool custom)
{
m_downloader->setUseCustomInstallProcedures (custom);
}
/**
* If the \a mandatory_update is set to \c true, the \c Updater has to download and install the
* update. If the user cancels or exits, the application will close
*/
void Updater::setMandatoryUpdate(const bool mandatory_update)
{
m_mandatoryUpdate = mandatory_update;
}
/**
* Called when the download of the update definitions file is finished.
*/
void Updater::onReply(QNetworkReply* reply) {
/* Check if we need to redirect */
QUrl redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!redirect.isEmpty()) {
setUrl (redirect.toString());
checkForUpdates();
return;
}
reply->ignoreSslErrors();
/* There was a network error */
int err = reply->error();
if (err != QNetworkReply::NoError) {
qDebug()<<"Updater::onReply QNetworkReply::Error="<< err <<reply->url();
setUpdateAvailable (false);
emit checkingFinished (url());
return;
}
/* The application wants to interpret the appcast by itself */
if (customAppcast()) {
emit appcastDownloaded (url(), reply->readAll());
emit checkingFinished (url());
return;
}
/* Try to create a JSON document from downloaded data */
QJsonDocument document = QJsonDocument::fromJson (reply->readAll());
/* JSON is invalid */
if(document.isNull()) {
qDebug()<<"Updater::onReply document.isNull()";
setUpdateAvailable (false);
emit checkingFinished (url());
return;
}
/* Get the platform information */
QJsonObject updates = document.object().value ("updates").toObject();
QJsonObject platform = updates.value(platformKey()).toObject();
/* Get update information */
m_openUrl = platform.value("open-url").toString();
m_changelog = platform.value("changelog_zhCN").toString();
m_downloadUrl = platform.value("download-url").toString();
m_latestVersion = platform.value("latest-version").toString();
if(platform.contains("mandatory-update")) m_mandatoryUpdate = platform.value ("mandatory-update").toBool();
/* Compare latest and current version */
if(m_bSameStringCompare) {
m_sameVersion = false;
if(latestVersion()==moduleVersion()) m_sameVersion=true;
setUpdateAvailable(!m_sameVersion);
} else {
if(latestVersion()==moduleVersion()){
setUpdateAvailable(false);
m_sameVersion = true;
} else {
setUpdateAvailable(compare(latestVersion(), moduleVersion()));
m_sameVersion = false;
}
}
emit checkingFinished(url());
}
/**
* Prompts the user based on the value of the \a available parameter and the
* settings of this instance of the \c Updater class.
*/
void Updater::setUpdateAvailable(const bool available) {
m_updateAvailable = available;
QMessageBox box;
box.setTextFormat (Qt::RichText);
box.setIcon (QMessageBox::Information);
if(updateAvailable() && (notifyOnUpdate() || notifyOnFinish())) {
QString text = tr("Would you like to download the update now?");
if(m_mandatoryUpdate) text = tr ("Would you like to download the update now? This is a mandatory update, exiting now will close the application");
if(m_noTipDownload) {
m_downloader->setUrlId (url());
m_downloader->setFileName (downloadUrl().split ("/").last());
m_downloader->setMandatoryUpdate(m_mandatoryUpdate);
m_downloader->startDownload (QUrl (downloadUrl()));
m_downloader->m_strVersion=latestVersion();
} else {
if (!openUrl().isEmpty()) QDesktopServices::openUrl (QUrl (openUrl()));
else if (downloaderEnabled()) {
m_downloader->setUrlId (url());
m_downloader->setFileName (downloadUrl().split ("/").last());
m_downloader->setMandatoryUpdate(m_mandatoryUpdate);
m_downloader->startDownload (QUrl (downloadUrl()));
m_downloader->m_strVersion=latestVersion();
}
else QDesktopServices::openUrl (QUrl (downloadUrl()));
}
}
else if (notifyOnFinish()) {
box.setStandardButtons (QMessageBox::Close);
box.setInformativeText (tr ("No updates are available for the moment"));
box.setText ("<h3>"
+ tr ("Congratulations! You are running the "
"latest version of %1").arg (moduleName())
+ "</h3>");
box.exec();
}
}
/**
* Compares the two version strings (\a x and \a y).
* - If \a x is greater than \y, this function returns \c true.
* - If \a y is greater than \x, this function returns \c false.
* - If both versions are the same, this function returns \c false.
*/
bool Updater::compare(const QString& x, const QString& y) {
QStringList versionsX = x.split(".");
QStringList versionsY = y.split(".");
int count = qMin(versionsX.count(), versionsY.count());
for (int i = 0; i < count; ++i) {
int a = QString(versionsX.at (i)).toInt();
int b = QString(versionsY.at (i)).toInt();
if(a >= b) return true;
else if(b > a) return false;
}
return versionsY.count() < versionsX.count();
}

View File

@ -1,156 +1,156 @@
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#ifndef _QSIMPLEUPDATER_UPDATER_H
#define _QSIMPLEUPDATER_UPDATER_H
#include <QUrl>
#include <QObject>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QSimpleUpdater.h>
class Downloader;
/**
* \brief Downloads and interprests the update definition file
*/
class QSU_DECL Updater : public QObject
{
Q_OBJECT
signals:
void checkingFinished (const QString& url);
void downloadFinished (const QString& url, const QString& filepath);
void appcastDownloaded (const QString& url, const QByteArray& data);
public:
Updater();
~Updater();
QString url() const;
QString openUrl() const;
QString changelog() const;
QString moduleName() const;
QString downloadUrl() const;
QString platformKey() const;
QString moduleVersion() const;
QString latestVersion() const;
QString userAgentString() const;
bool mandatoryUpdate() const;
bool customAppcast() const;
bool notifyOnUpdate() const;
bool notifyOnFinish() const;
bool updateAvailable() const;
bool updateSameVersionAvailable() const;
bool downloaderEnabled() const;
bool useCustomInstallProcedures() const;
public slots:
void checkForUpdates();
void setUrl (const QString& url);
void setModuleName (const QString& name);
void setNotifyOnUpdate (const bool notify);
void setNotifyOnFinish (const bool notify);
void setNoNotifyDownload(const bool notify);
void setCompareBySameString(const bool notify);
void setUserAgentString (const QString& agent);
void setModuleVersion (const QString& version);
void setDownloaderEnabled (const bool enabled);
void setPlatformKey (const QString& platformKey);
void setUseCustomAppcast (const bool customAppcast);
void setUseCustomInstallProcedures (const bool custom);
void setMandatoryUpdate (const bool mandatory_update);
private slots:
void onReply (QNetworkReply* reply);
void setUpdateAvailable (const bool available);
private:
bool compare (const QString& x, const QString& y);
private:
QString m_url;
QString m_userAgentString;
bool m_customAppcast;
bool m_notifyOnUpdate;
bool m_notifyOnFinish;
bool m_updateAvailable;
bool m_sameVersion;
bool m_downloaderEnabled;
bool m_mandatoryUpdate;
bool m_noTipDownload;
bool m_bSameStringCompare;
QString m_openUrl;
QString m_platform;
QString m_changelog;
QString m_moduleName;
QString m_downloadUrl;
QString m_moduleVersion;
QString m_latestVersion;
Downloader* m_downloader;
QNetworkAccessManager* m_manager;
};
#include <QObject>
#include <QTimer>
#include <QNetworkReply>
class QReplyTimeout : public QObject {
Q_OBJECT
public:
QReplyTimeout(QNetworkReply *reply, const int timeout) : QObject(reply) {
Q_ASSERT(reply);
if (reply && reply->isRunning()) { // 启动单次定时器
QTimer::singleShot(timeout, this, SLOT(onTimeout()));
}
}
signals:
void timeout(); // 超时信号 - 供进一步处理
private slots:
void onTimeout() { // 处理超时
QNetworkReply *reply = static_cast<QNetworkReply*>(parent());
if (reply->isRunning()) {
reply->abort();
reply->deleteLater();
emit timeout();
}
}
};
#endif
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This file is part of the QSimpleUpdater library, which is released under
* the DBAD license, you can read a copy of it below:
*
* DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING,
* DISTRIBUTION AND MODIFICATION:
*
* Do whatever you like with the original work, just don't be a dick.
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the
* name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's
* REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content.
* That would make you a PROPER dick.
*
* If you become rich through modifications, related works/services, or
* supporting the original work, share the love.
* Only a dick would make loads off this work and not buy the original works
* creator(s) a pint.
*
* Code is provided with no warranty. Using somebody else's code and bitching
* when it goes wrong makes you a DONKEY dick.
* Fix the problem yourself. A non-dick would submit the fix back.
*/
#ifndef _QSIMPLEUPDATER_UPDATER_H
#define _QSIMPLEUPDATER_UPDATER_H
#include <QUrl>
#include <QObject>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QSimpleUpdater.h>
class Downloader;
/**
* \brief Downloads and interprests the update definition file
*/
class QSU_DECL Updater : public QObject
{
Q_OBJECT
signals:
void checkingFinished (const QString& url);
void downloadFinished (const QString& url, const QString& filepath);
void appcastDownloaded (const QString& url, const QByteArray& data);
public:
Updater();
~Updater();
QString url() const;
QString openUrl() const;
QString changelog() const;
QString moduleName() const;
QString downloadUrl() const;
QString platformKey() const;
QString moduleVersion() const;
QString latestVersion() const;
QString userAgentString() const;
bool mandatoryUpdate() const;
bool customAppcast() const;
bool notifyOnUpdate() const;
bool notifyOnFinish() const;
bool updateAvailable() const;
bool updateSameVersionAvailable() const;
bool downloaderEnabled() const;
bool useCustomInstallProcedures() const;
public slots:
void checkForUpdates();
void setUrl (const QString& url);
void setModuleName (const QString& name);
void setNotifyOnUpdate (const bool notify);
void setNotifyOnFinish (const bool notify);
void setNoNotifyDownload(const bool notify);
void setCompareBySameString(const bool notify);
void setUserAgentString (const QString& agent);
void setModuleVersion (const QString& version);
void setDownloaderEnabled (const bool enabled);
void setPlatformKey (const QString& platformKey);
void setUseCustomAppcast (const bool customAppcast);
void setUseCustomInstallProcedures (const bool custom);
void setMandatoryUpdate (const bool mandatory_update);
private slots:
void onReply (QNetworkReply* reply);
void setUpdateAvailable (const bool available);
private:
bool compare (const QString& x, const QString& y);
private:
QString m_url;
QString m_userAgentString;
bool m_customAppcast;
bool m_notifyOnUpdate;
bool m_notifyOnFinish;
bool m_updateAvailable;
bool m_sameVersion;
bool m_downloaderEnabled;
bool m_mandatoryUpdate;
bool m_noTipDownload;
bool m_bSameStringCompare;
QString m_openUrl;
QString m_platform;
QString m_changelog;
QString m_moduleName;
QString m_downloadUrl;
QString m_moduleVersion;
QString m_latestVersion;
Downloader* m_downloader;
QNetworkAccessManager* m_manager;
};
#include <QObject>
#include <QTimer>
#include <QNetworkReply>
class QReplyTimeout : public QObject {
Q_OBJECT
public:
QReplyTimeout(QNetworkReply *reply, const int timeout) : QObject(reply) {
Q_ASSERT(reply);
if (reply && reply->isRunning()) { // 启动单次定时器
QTimer::singleShot(timeout, this, SLOT(onTimeout()));
}
}
signals:
void timeout(); // 超时信号 - 供进一步处理
private slots:
void onTimeout() { // 处理超时
QNetworkReply *reply = static_cast<QNetworkReply*>(parent());
if (reply->isRunning()) {
reply->abort();
reply->deleteLater();
emit timeout();
}
}
};
#endif

View File

@ -1,34 +1,34 @@
/*
* Copyright (c) 2015-2016 Alex Spataru <alex_spataru@outlook.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef TEST_DOWNLOADER_H
#define TEST_DOWNLOADER_H
#include <QtTest>
#include <Downloader.h>
class Test_Downloader : public QObject
{
Q_OBJECT
};
#endif
/*
* Copyright (c) 2015-2016 Alex Spataru <alex_spataru@outlook.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef TEST_DOWNLOADER_H
#define TEST_DOWNLOADER_H
#include <QtTest>
#include <Downloader.h>
class Test_Downloader : public QObject
{
Q_OBJECT
};
#endif

View File

@ -1,34 +1,34 @@
/*
* Copyright (c) 2015-2016 Alex Spataru <alex_spataru@outlook.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef TEST_QSIMPLEUPDATER_H
#define TEST_QSIMPLEUPDATER_H
#include <QtTest>
#include <QSimpleUpdater.h>
class Test_QSimpleUpdater : public QObject
{
Q_OBJECT
};
#endif
/*
* Copyright (c) 2015-2016 Alex Spataru <alex_spataru@outlook.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef TEST_QSIMPLEUPDATER_H
#define TEST_QSIMPLEUPDATER_H
#include <QtTest>
#include <QSimpleUpdater.h>
class Test_QSimpleUpdater : public QObject
{
Q_OBJECT
};
#endif

View File

@ -1,34 +1,34 @@
/*
* Copyright (c) 2015-2016 Alex Spataru <alex_spataru@outlook.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef TEST_UPDATER_H
#define TEST_UPDATER_H
#include <QtTest>
#include <Updater.h>
class Test_Updater : public QObject
{
Q_OBJECT
};
#endif
/*
* Copyright (c) 2015-2016 Alex Spataru <alex_spataru@outlook.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef TEST_UPDATER_H
#define TEST_UPDATER_H
#include <QtTest>
#include <Updater.h>
class Test_Updater : public QObject
{
Q_OBJECT
};
#endif

View File

@ -1,41 +1,41 @@
/*
* Copyright (c) 2015-2016 Alex Spataru <alex_spataru@outlook.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "Test_Updater.h"
#include "Test_Downloader.h"
#include "Test_QSimpleUpdater.h"
int main (int argc, char* argv[])
{
QApplication app (argc, argv);
app.setApplicationName ("QSimpleUpdater Tests");
app.setOrganizationName ("The QSimpleUpdater Library");
QTest::qExec (new Test_Updater, argc, argv);
QTest::qExec (new Test_Downloader, argc, argv);
QTest::qExec (new Test_QSimpleUpdater, argc, argv);
QTimer::singleShot (1000, Qt::PreciseTimer, qApp, SLOT (quit()));
return app.exec();
}
/*
* Copyright (c) 2015-2016 Alex Spataru <alex_spataru@outlook.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "Test_Updater.h"
#include "Test_Downloader.h"
#include "Test_QSimpleUpdater.h"
int main (int argc, char* argv[])
{
QApplication app (argc, argv);
app.setApplicationName ("QSimpleUpdater Tests");
app.setOrganizationName ("The QSimpleUpdater Library");
QTest::qExec (new Test_Updater, argc, argv);
QTest::qExec (new Test_Downloader, argc, argv);
QTest::qExec (new Test_QSimpleUpdater, argc, argv);
QTimer::singleShot (1000, Qt::PreciseTimer, qApp, SLOT (quit()));
return app.exec();
}

View File

@ -1,137 +1,137 @@
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This work is free. You can redistribute it and/or modify it under the
* terms of the Do What The Fuck You Want To Public License, Version 2,
* as published by Sam Hocevar. See the COPYING file for more details.
*/
#include "Window.h"
#include "ui_Window.h"
#include <QDebug>
#include <QSimpleUpdater.h>
//==============================================================================
// Define the URL of the Update Definitions file
//==============================================================================
static const QString DEFS_URL = "https://raw.githubusercontent.com/"
"alex-spataru/QSimpleUpdater/master/tutorial/"
"definitions/updates.json";
//==============================================================================
// Window::Window
//==============================================================================
Window::Window (QWidget* parent) : QMainWindow (parent)
{
m_ui = new Ui::Window;
m_ui->setupUi (this);
setWindowTitle (qApp->applicationName());
/* QSimpleUpdater is single-instance */
m_updater = QSimpleUpdater::getInstance();
/* Check for updates when the "Check For Updates" button is clicked */
connect (m_updater, SIGNAL (checkingFinished (QString)),
this, SLOT (updateChangelog (QString)));
connect (m_updater, SIGNAL (appcastDownloaded (QString, QByteArray)),
this, SLOT (displayAppcast (QString, QByteArray)));
/* React to button clicks */
connect (m_ui->resetButton, SIGNAL (clicked()),
this, SLOT (resetFields()));
connect (m_ui->closeButton, SIGNAL (clicked()),
this, SLOT (close()));
connect (m_ui->checkButton, SIGNAL (clicked()),
this, SLOT (checkForUpdates()));
/* Resize the dialog to fit */
setMinimumSize (minimumSizeHint());
resize (minimumSizeHint());
/* Reset the UI state */
resetFields();
}
//==============================================================================
// Window::~Window
//==============================================================================
Window::~Window()
{
delete m_ui;
}
//==============================================================================
// Window::checkForUpdates
//==============================================================================
void Window::resetFields()
{
m_ui->installedVersion->setText ("0.1");
m_ui->customAppcast->setChecked (false);
m_ui->enableDownloader->setChecked (true);
m_ui->showAllNotifcations->setChecked (false);
m_ui->showUpdateNotifications->setChecked (true);
m_ui->mandatoryUpdate->setChecked (false);
}
//==============================================================================
// Window::checkForUpdates
//==============================================================================
void Window::checkForUpdates()
{
/* Get settings from the UI */
QString version = m_ui->installedVersion->text();
bool customAppcast = m_ui->customAppcast->isChecked();
bool downloaderEnabled = m_ui->enableDownloader->isChecked();
bool notifyOnFinish = m_ui->showAllNotifcations->isChecked();
bool notifyOnUpdate = m_ui->showUpdateNotifications->isChecked();
bool mandatoryUpdate = m_ui->mandatoryUpdate->isChecked();
/* Apply the settings */
m_updater->setModuleVersion (DEFS_URL, version);
m_updater->setNotifyOnFinish (DEFS_URL, notifyOnFinish);
m_updater->setNotifyOnUpdate (DEFS_URL, notifyOnUpdate);
m_updater->setUseCustomAppcast (DEFS_URL, customAppcast);
m_updater->setDownloaderEnabled (DEFS_URL, downloaderEnabled);
m_updater->setMandatoryUpdate (DEFS_URL, mandatoryUpdate);
/* Check for updates */
m_updater->checkForUpdates (DEFS_URL);
}
//==============================================================================
// Window::updateChangelog
//==============================================================================
void Window::updateChangelog (const QString& url)
{
if (url == DEFS_URL)
m_ui->changelogText->setText (m_updater->getChangelog (url));
}
//==============================================================================
// Window::displayAppcast
//==============================================================================
void Window::displayAppcast (const QString& url, const QByteArray& reply)
{
if (url == DEFS_URL) {
QString text = "This is the downloaded appcast: <p><pre>" +
QString::fromUtf8 (reply) +
"</pre></p><p> If you need to store more information on the "
"appcast (or use another format), just use the "
"<b>QSimpleUpdater::setCustomAppcast()</b> function. "
"It allows your application to interpret the appcast "
"using your code and not QSU's code.</p>";
m_ui->changelogText->setText (text);
}
}
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This work is free. You can redistribute it and/or modify it under the
* terms of the Do What The Fuck You Want To Public License, Version 2,
* as published by Sam Hocevar. See the COPYING file for more details.
*/
#include "Window.h"
#include "ui_Window.h"
#include <QDebug>
#include <QSimpleUpdater.h>
//==============================================================================
// Define the URL of the Update Definitions file
//==============================================================================
static const QString DEFS_URL = "https://raw.githubusercontent.com/"
"alex-spataru/QSimpleUpdater/master/tutorial/"
"definitions/updates.json";
//==============================================================================
// Window::Window
//==============================================================================
Window::Window (QWidget* parent) : QMainWindow (parent)
{
m_ui = new Ui::Window;
m_ui->setupUi (this);
setWindowTitle (qApp->applicationName());
/* QSimpleUpdater is single-instance */
m_updater = QSimpleUpdater::getInstance();
/* Check for updates when the "Check For Updates" button is clicked */
connect (m_updater, SIGNAL (checkingFinished (QString)),
this, SLOT (updateChangelog (QString)));
connect (m_updater, SIGNAL (appcastDownloaded (QString, QByteArray)),
this, SLOT (displayAppcast (QString, QByteArray)));
/* React to button clicks */
connect (m_ui->resetButton, SIGNAL (clicked()),
this, SLOT (resetFields()));
connect (m_ui->closeButton, SIGNAL (clicked()),
this, SLOT (close()));
connect (m_ui->checkButton, SIGNAL (clicked()),
this, SLOT (checkForUpdates()));
/* Resize the dialog to fit */
setMinimumSize (minimumSizeHint());
resize (minimumSizeHint());
/* Reset the UI state */
resetFields();
}
//==============================================================================
// Window::~Window
//==============================================================================
Window::~Window()
{
delete m_ui;
}
//==============================================================================
// Window::checkForUpdates
//==============================================================================
void Window::resetFields()
{
m_ui->installedVersion->setText ("0.1");
m_ui->customAppcast->setChecked (false);
m_ui->enableDownloader->setChecked (true);
m_ui->showAllNotifcations->setChecked (false);
m_ui->showUpdateNotifications->setChecked (true);
m_ui->mandatoryUpdate->setChecked (false);
}
//==============================================================================
// Window::checkForUpdates
//==============================================================================
void Window::checkForUpdates()
{
/* Get settings from the UI */
QString version = m_ui->installedVersion->text();
bool customAppcast = m_ui->customAppcast->isChecked();
bool downloaderEnabled = m_ui->enableDownloader->isChecked();
bool notifyOnFinish = m_ui->showAllNotifcations->isChecked();
bool notifyOnUpdate = m_ui->showUpdateNotifications->isChecked();
bool mandatoryUpdate = m_ui->mandatoryUpdate->isChecked();
/* Apply the settings */
m_updater->setModuleVersion (DEFS_URL, version);
m_updater->setNotifyOnFinish (DEFS_URL, notifyOnFinish);
m_updater->setNotifyOnUpdate (DEFS_URL, notifyOnUpdate);
m_updater->setUseCustomAppcast (DEFS_URL, customAppcast);
m_updater->setDownloaderEnabled (DEFS_URL, downloaderEnabled);
m_updater->setMandatoryUpdate (DEFS_URL, mandatoryUpdate);
/* Check for updates */
m_updater->checkForUpdates (DEFS_URL);
}
//==============================================================================
// Window::updateChangelog
//==============================================================================
void Window::updateChangelog (const QString& url)
{
if (url == DEFS_URL)
m_ui->changelogText->setText (m_updater->getChangelog (url));
}
//==============================================================================
// Window::displayAppcast
//==============================================================================
void Window::displayAppcast (const QString& url, const QByteArray& reply)
{
if (url == DEFS_URL) {
QString text = "This is the downloaded appcast: <p><pre>" +
QString::fromUtf8 (reply) +
"</pre></p><p> If you need to store more information on the "
"appcast (or use another format), just use the "
"<b>QSimpleUpdater::setCustomAppcast()</b> function. "
"It allows your application to interpret the appcast "
"using your code and not QSU's code.</p>";
m_ui->changelogText->setText (text);
}
}

View File

@ -1,40 +1,40 @@
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This work is free. You can redistribute it and/or modify it under the
* terms of the Do What The Fuck You Want To Public License, Version 2,
* as published by Sam Hocevar. See the COPYING file for more details.
*/
#ifndef _WINDOW_H
#define _WINDOW_H
#include <QMainWindow>
#include <QApplication>
namespace Ui {
class Window;
}
class QSimpleUpdater;
class Window : public QMainWindow
{
Q_OBJECT
public:
explicit Window (QWidget* parent = 0);
~Window();
public slots:
void resetFields();
void checkForUpdates();
void updateChangelog (const QString& url);
void displayAppcast (const QString& url, const QByteArray& reply);
private:
Ui::Window* m_ui;
QSimpleUpdater* m_updater;
};
#endif
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This work is free. You can redistribute it and/or modify it under the
* terms of the Do What The Fuck You Want To Public License, Version 2,
* as published by Sam Hocevar. See the COPYING file for more details.
*/
#ifndef _WINDOW_H
#define _WINDOW_H
#include <QMainWindow>
#include <QApplication>
namespace Ui {
class Window;
}
class QSimpleUpdater;
class Window : public QMainWindow
{
Q_OBJECT
public:
explicit Window (QWidget* parent = 0);
~Window();
public slots:
void resetFields();
void checkForUpdates();
void updateChangelog (const QString& url);
void displayAppcast (const QString& url, const QByteArray& reply);
private:
Ui::Window* m_ui;
QSimpleUpdater* m_updater;
};
#endif

View File

@ -1,21 +1,21 @@
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This work is free. You can redistribute it and/or modify it under the
* terms of the Do What The Fuck You Want To Public License, Version 2,
* as published by Sam Hocevar. See the COPYING file for more details.
*/
#include "Window.h"
int main (int argc, char** argv)
{
QApplication app (argc, argv);
app.setApplicationVersion ("1.0");
app.setApplicationName ("Bob's Badass App");
Window window;
window.show();
return app.exec();
}
/*
* Copyright (c) 2014-2016 Alex Spataru <alex_spataru@outlook.com>
*
* This work is free. You can redistribute it and/or modify it under the
* terms of the Do What The Fuck You Want To Public License, Version 2,
* as published by Sam Hocevar. See the COPYING file for more details.
*/
#include "Window.h"
int main (int argc, char** argv)
{
QApplication app (argc, argv);
app.setApplicationVersion ("1.0");
app.setApplicationName ("Bob's Badass App");
Window window;
window.show();
return app.exec();
}

View File

@ -1,43 +1,43 @@
#include "aboutdlg.h"
#include "globaldefine.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
AboutDlg::AboutDlg(QWidget *parent) : QDialog(parent) {
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
setWindowTitle(tr("About"));
auto hBox = new QHBoxLayout(this);
hBox->setContentsMargins(24,24,24,24);
hBox->setSpacing(24);
auto label_4 = new QLabel();
label_4->setPixmap(QPixmap(":/res/Logo.png"));
hBox->addWidget(label_4);
auto vBox = new QVBoxLayout();
auto label = new QLabel("LedOK Express");
QFont font;
font.setPointSize(24);
label->setFont(font);
label->setTextFormat(Qt::AutoText);
label->setAlignment(Qt::AlignCenter);
vBox->addWidget(label);
auto label_2 = new QLabel(APP_VERSION);
QFont font1;
font1.setPointSize(14);
label_2->setFont(font1);
label_2->setAlignment(Qt::AlignCenter);
vBox->addWidget(label_2);
auto label_3 = new QLabel("<a href=\"https://www.ledok.cn/\">www.ledok.cn");
QFont font2;
font2.setPointSize(15);
label_3->setFont(font2);
label_3->setAlignment(Qt::AlignCenter);
label_3->setOpenExternalLinks(true);
vBox->addWidget(label_3);
hBox->addLayout(vBox);
}
#include "aboutdlg.h"
#include "globaldefine.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
AboutDlg::AboutDlg(QWidget *parent) : QDialog(parent) {
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
setWindowTitle(tr("About"));
auto hBox = new QHBoxLayout(this);
hBox->setContentsMargins(24,24,24,24);
hBox->setSpacing(24);
auto label_4 = new QLabel();
label_4->setPixmap(QPixmap(":/res/Logo.png"));
hBox->addWidget(label_4);
auto vBox = new QVBoxLayout();
auto label = new QLabel("LedOK Express");
QFont font;
font.setPointSize(24);
label->setFont(font);
label->setTextFormat(Qt::AutoText);
label->setAlignment(Qt::AlignCenter);
vBox->addWidget(label);
auto label_2 = new QLabel(APP_VERSION);
QFont font1;
font1.setPointSize(14);
label_2->setFont(font1);
label_2->setAlignment(Qt::AlignCenter);
vBox->addWidget(label_2);
auto label_3 = new QLabel("<a href=\"https://www.ledok.cn/\">www.ledok.cn");
QFont font2;
font2.setPointSize(15);
label_3->setFont(font2);
label_3->setAlignment(Qt::AlignCenter);
label_3->setOpenExternalLinks(true);
vBox->addWidget(label_3);
hBox->addLayout(vBox);
}

View File

@ -1,12 +1,12 @@
#ifndef ABOUTDLG_H
#define ABOUTDLG_H
#include <basedlg.h>
class AboutDlg : public QDialog {
Q_OBJECT
public:
explicit AboutDlg(QWidget *parent = nullptr);
};
#endif // ABOUTDLG_H
#ifndef ABOUTDLG_H
#define ABOUTDLG_H
#include <basedlg.h>
class AboutDlg : public QDialog {
Q_OBJECT
public:
explicit AboutDlg(QWidget *parent = nullptr);
};
#endif // ABOUTDLG_H

View File

@ -1,84 +1,84 @@
#include "changepasswordform.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QMessageBox>
#include <QSettings>
#include "cfg.h"
#include "QTextCodec"
ChangePasswordForm::ChangePasswordForm(QWidget *parent) : BaseDlg(parent) {
resize(240, 160);
auto vBox = new QVBoxLayout(this);
auto hBox = new QHBoxLayout();
auto label = new QLabel(tr("Old password"));
hBox->addWidget(label);
fdOld = new QLineEdit();
fdOld->setEchoMode(QLineEdit::Password);
fdOld->setMaxLength(16);
hBox->addWidget(fdOld);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
auto label_2 = new QLabel(tr("New password"));
hBox->addWidget(label_2);
fdNew = new QLineEdit();
fdNew->setEchoMode(QLineEdit::Password);
fdNew->setMaxLength(8);
hBox->addWidget(fdNew);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
auto label_3 = new QLabel(tr("Repeat again"));
hBox->addWidget(label_3);
fdAgn = new QLineEdit();
fdAgn->setEchoMode(QLineEdit::Password);
fdAgn->setMaxLength(8);
hBox->addWidget(fdAgn);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
auto pushButton_2 = new QPushButton(tr("OK"));
pushButton_2->setProperty("ssType", "progManageTool");
hBox->addWidget(pushButton_2);
connect(pushButton_2, &QPushButton::clicked, this, [this]() {
QString pwdOld = fdOld->text();
if(pwdOld.isEmpty()) {
QMessageBox::warning(this, tr("Tip"), tr("Please input old password"));
fdOld->setFocus();
return;
}
QSettings settings;
QString pwdRaw = settings.value("advUiPs").toString();
QString pwd = pwdRaw.isEmpty() ? "888" : QTextCodec::codecForName("GBK")->toUnicode(QByteArray::fromBase64(pwdRaw.toLocal8Bit()));
if(pwd != pwdOld) {
QMessageBox::critical(this, tr("Tip"), tr("Old password is wrong"));
fdOld->setFocus();
return;
}
QString pwdNew = fdNew->text();
if(pwdNew.length() < 6) {
QMessageBox::warning(this, tr("Tip"), tr("Please enter a password with more than 6 characters"));
fdNew->setFocus();
return;
}
QString pwdAgn = fdAgn->text();
if(pwdAgn != pwdNew) {
QMessageBox::warning(this, tr("Tip"), tr("The new password is not consistent in two times"));
fdAgn->setFocus();
return;
}
settings.setValue("advUiPs", QString::fromLatin1(pwdNew.toLocal8Bit().toBase64()));
QMessageBox::information(this, tr("Tip"), tr("Password changed successfully"));
accept();
});
auto pushButton = new QPushButton(tr("Cancel"));
pushButton->setProperty("ssType", "progManageTool");
hBox->addWidget(pushButton);
connect(pushButton, &QPushButton::clicked, this, &ChangePasswordForm::reject);
vBox->addLayout(hBox);
}
#include "changepasswordform.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QMessageBox>
#include <QSettings>
#include "cfg.h"
#include "QTextCodec"
ChangePasswordForm::ChangePasswordForm(QWidget *parent) : BaseDlg(parent) {
resize(240, 160);
auto vBox = new QVBoxLayout(this);
auto hBox = new QHBoxLayout();
auto label = new QLabel(tr("Old password"));
hBox->addWidget(label);
fdOld = new QLineEdit();
fdOld->setEchoMode(QLineEdit::Password);
fdOld->setMaxLength(16);
hBox->addWidget(fdOld);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
auto label_2 = new QLabel(tr("New password"));
hBox->addWidget(label_2);
fdNew = new QLineEdit();
fdNew->setEchoMode(QLineEdit::Password);
fdNew->setMaxLength(8);
hBox->addWidget(fdNew);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
auto label_3 = new QLabel(tr("Repeat again"));
hBox->addWidget(label_3);
fdAgn = new QLineEdit();
fdAgn->setEchoMode(QLineEdit::Password);
fdAgn->setMaxLength(8);
hBox->addWidget(fdAgn);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
auto pushButton_2 = new QPushButton(tr("OK"));
pushButton_2->setProperty("ssType", "progManageTool");
hBox->addWidget(pushButton_2);
connect(pushButton_2, &QPushButton::clicked, this, [this]() {
QString pwdOld = fdOld->text();
if(pwdOld.isEmpty()) {
QMessageBox::warning(this, tr("Tip"), tr("Please input old password"));
fdOld->setFocus();
return;
}
QSettings settings;
QString pwdRaw = settings.value("advUiPs").toString();
QString pwd = pwdRaw.isEmpty() ? "888" : QTextCodec::codecForName("GBK")->toUnicode(QByteArray::fromBase64(pwdRaw.toLocal8Bit()));
if(pwd != pwdOld) {
QMessageBox::critical(this, tr("Tip"), tr("Old password is wrong"));
fdOld->setFocus();
return;
}
QString pwdNew = fdNew->text();
if(pwdNew.length() < 6) {
QMessageBox::warning(this, tr("Tip"), tr("Please enter a password with more than 6 characters"));
fdNew->setFocus();
return;
}
QString pwdAgn = fdAgn->text();
if(pwdAgn != pwdNew) {
QMessageBox::warning(this, tr("Tip"), tr("The new password is not consistent in two times"));
fdAgn->setFocus();
return;
}
settings.setValue("advUiPs", QString::fromLatin1(pwdNew.toLocal8Bit().toBase64()));
QMessageBox::information(this, tr("Tip"), tr("Password changed successfully"));
accept();
});
auto pushButton = new QPushButton(tr("Cancel"));
pushButton->setProperty("ssType", "progManageTool");
hBox->addWidget(pushButton);
connect(pushButton, &QPushButton::clicked, this, &ChangePasswordForm::reject);
vBox->addLayout(hBox);
}

View File

@ -1,16 +1,16 @@
#ifndef CHANGEPASSWORDFORM_H
#define CHANGEPASSWORDFORM_H
#include "basedlg.h"
#include <QLineEdit>
class ChangePasswordForm : public BaseDlg {
Q_OBJECT
public:
explicit ChangePasswordForm(QWidget *parent = nullptr);
QLineEdit *fdOld, *fdNew, *fdAgn;
};
#endif // CHANGEPASSWORDFORM_H
#ifndef CHANGEPASSWORDFORM_H
#define CHANGEPASSWORDFORM_H
#include "basedlg.h"
#include <QLineEdit>
class ChangePasswordForm : public BaseDlg {
Q_OBJECT
public:
explicit ChangePasswordForm(QWidget *parent = nullptr);
QLineEdit *fdOld, *fdNew, *fdAgn;
};
#endif // CHANGEPASSWORDFORM_H

View File

@ -1,137 +1,137 @@
#include "customprogressindicator.h"
#include <QPainter>
#include <QPainterPath>
CustomProgressIndicator::CustomProgressIndicator(QWidget* parent)
: QWidget(parent),
angle_(0),
timerId_(-1),
delay_(20),
displayedWhenStopped_(false),
color_(Qt::green) {
setAttribute(Qt::WA_DeleteOnClose);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setFocusPolicy(Qt::NoFocus);
setWindowFlags(Qt::FramelessWindowHint);//无窗体
setAttribute(Qt::WA_TranslucentBackground);//背景透明
}
bool CustomProgressIndicator::isAnimated () const {
return (timerId_ != -1);
}
void CustomProgressIndicator::setDisplayedWhenStopped(bool state) {
displayedWhenStopped_ = state;
update();
}
bool CustomProgressIndicator::isDisplayedWhenStopped() const {
return displayedWhenStopped_;
}
void CustomProgressIndicator::setDisplayModel(int iFlag)
{
m_iLoopBackFlag=iFlag;
}
void CustomProgressIndicator::startAnimation() {
angle_ = 0;
if (timerId_ == -1) {
timerId_ = startTimer(delay_);
}
}
void CustomProgressIndicator::setDisplayStringInfo(QString strTip,QString strTiping) {
m_strTip=strTip;
m_strTiping=strTiping;
update();
}
void CustomProgressIndicator::stopAnimation() {
if (timerId_ != -1) {
killTimer(timerId_);
}
timerId_ = -1;
update();
}
void CustomProgressIndicator::setAnimationDelay(int delay) {
if (timerId_ != -1){
killTimer(timerId_);
}
delay_ = delay;
if (timerId_ != -1){
timerId_ = startTimer(delay_);
}
}
void CustomProgressIndicator::setColor(const QColor & color) {
color_ = color;
update();
}
QSize CustomProgressIndicator::sizeHint() const {
return QSize(80,80);
}
void CustomProgressIndicator::timerEvent(QTimerEvent *) {
angle_ = (angle_+30)%360;
update();
}
void CustomProgressIndicator::paintEvent(QPaintEvent *) {
QPainter p(this);
drawJuHua(&p);
}
void CustomProgressIndicator::drawJuHua(QPainter *painter)
{
painter->setRenderHint(QPainter::Antialiasing);
if (displayedWhenStopped_ && !isAnimated()) //如果displayedWhenStopped_==flash并且动画已经停止则不绘制
{
painter->setPen(color_);
painter->drawPixmap(rect(),currentPix_);
painter->drawText(rect(), Qt::AlignCenter, m_strTip);
return;
}
int width = qMin(this->width(), this->height());
int outerRadius = (width-1) >> 1;
int innerRadius = int(((width-1) >> 1)*0.38);
int capsuleHeight = outerRadius - innerRadius;
int capsuleWidth = (width > 32 ) ? (int)(capsuleHeight *0.23) : (int)(capsuleHeight *0.35);
int capsuleRadius = capsuleWidth >> 1;
if(m_iLoopBackFlag==1)
{
painter->setPen(color_);
painter->drawText(rect(), Qt::AlignCenter, m_strTiping);
}
else {
/* 撰写进度 */
if (progress_ > 0 && progress_ < 100) {
painter->setPen(color_);
painter->drawText(rect(), Qt::AlignCenter, QString("%1%").arg(progress_));
}
else if (progress_ == 100) {
stopAnimation();
}
}
for (int i=0; i<12; ++i) {
QColor color = color_;
color.setAlphaF(1.0f - (i/12.0f));
painter->setPen(Qt::NoPen);
painter->setBrush(color);
painter->save();
painter->translate(rect().center());
painter->rotate(angle_ - i*30.0f);
painter->drawRoundedRect(((-capsuleWidth) >> 1), -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius);
painter->restore();
}
}
#include "customprogressindicator.h"
#include <QPainter>
#include <QPainterPath>
CustomProgressIndicator::CustomProgressIndicator(QWidget* parent)
: QWidget(parent),
angle_(0),
timerId_(-1),
delay_(20),
displayedWhenStopped_(false),
color_(Qt::green) {
setAttribute(Qt::WA_DeleteOnClose);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setFocusPolicy(Qt::NoFocus);
setWindowFlags(Qt::FramelessWindowHint);//无窗体
setAttribute(Qt::WA_TranslucentBackground);//背景透明
}
bool CustomProgressIndicator::isAnimated () const {
return (timerId_ != -1);
}
void CustomProgressIndicator::setDisplayedWhenStopped(bool state) {
displayedWhenStopped_ = state;
update();
}
bool CustomProgressIndicator::isDisplayedWhenStopped() const {
return displayedWhenStopped_;
}
void CustomProgressIndicator::setDisplayModel(int iFlag)
{
m_iLoopBackFlag=iFlag;
}
void CustomProgressIndicator::startAnimation() {
angle_ = 0;
if (timerId_ == -1) {
timerId_ = startTimer(delay_);
}
}
void CustomProgressIndicator::setDisplayStringInfo(QString strTip,QString strTiping) {
m_strTip=strTip;
m_strTiping=strTiping;
update();
}
void CustomProgressIndicator::stopAnimation() {
if (timerId_ != -1) {
killTimer(timerId_);
}
timerId_ = -1;
update();
}
void CustomProgressIndicator::setAnimationDelay(int delay) {
if (timerId_ != -1){
killTimer(timerId_);
}
delay_ = delay;
if (timerId_ != -1){
timerId_ = startTimer(delay_);
}
}
void CustomProgressIndicator::setColor(const QColor & color) {
color_ = color;
update();
}
QSize CustomProgressIndicator::sizeHint() const {
return QSize(80,80);
}
void CustomProgressIndicator::timerEvent(QTimerEvent *) {
angle_ = (angle_+30)%360;
update();
}
void CustomProgressIndicator::paintEvent(QPaintEvent *) {
QPainter p(this);
drawJuHua(&p);
}
void CustomProgressIndicator::drawJuHua(QPainter *painter)
{
painter->setRenderHint(QPainter::Antialiasing);
if (displayedWhenStopped_ && !isAnimated()) //如果displayedWhenStopped_==flash并且动画已经停止则不绘制
{
painter->setPen(color_);
painter->drawPixmap(rect(),currentPix_);
painter->drawText(rect(), Qt::AlignCenter, m_strTip);
return;
}
int width = qMin(this->width(), this->height());
int outerRadius = (width-1) >> 1;
int innerRadius = int(((width-1) >> 1)*0.38);
int capsuleHeight = outerRadius - innerRadius;
int capsuleWidth = (width > 32 ) ? (int)(capsuleHeight *0.23) : (int)(capsuleHeight *0.35);
int capsuleRadius = capsuleWidth >> 1;
if(m_iLoopBackFlag==1)
{
painter->setPen(color_);
painter->drawText(rect(), Qt::AlignCenter, m_strTiping);
}
else {
/* 撰写进度 */
if (progress_ > 0 && progress_ < 100) {
painter->setPen(color_);
painter->drawText(rect(), Qt::AlignCenter, QString("%1%").arg(progress_));
}
else if (progress_ == 100) {
stopAnimation();
}
}
for (int i=0; i<12; ++i) {
QColor color = color_;
color.setAlphaF(1.0f - (i/12.0f));
painter->setPen(Qt::NoPen);
painter->setBrush(color);
painter->save();
painter->translate(rect().center());
painter->rotate(angle_ - i*30.0f);
painter->drawRoundedRect(((-capsuleWidth) >> 1), -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius);
painter->restore();
}
}

View File

@ -1,116 +1,116 @@
#ifndef CUSTOMPROGRESSINDICATOR_H
#define CUSTOMPROGRESSINDICATOR_H
#include <QWidget>
#include <QColor>
#include <QTimer>
/*
*
*
* 727057301@qq.com
* 201721016:26:48
* QT版本5.0.2
* CSDNhttp://blog.csdn.net/csnd_ayo
* **************************************
*
* 使QT.pro中加入 C++11
*
*
pIndicator = new CustomProgressIndicator(this);
pIndicator->setColor(Qt::red);
pIndicator->startAnimation();
*/
class CustomProgressIndicator : public QWidget
{
Q_OBJECT
Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay)
Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped)
Q_PROPERTY(QColor color READ color WRITE setColor)
public:
CustomProgressIndicator(QWidget* parent = nullptr);
int animationDelay() const { return delay_; }
/* 动画是否正在进行中 */
bool isAnimated () const;
/* 动画完毕后,是否隐藏菊花转 */
bool isDisplayedWhenStopped() const;
/* 当前菊花转的颜色 */
const QColor & color() const { return color_; }
/* 虚函数:当前大小 */
virtual QSize sizeHint() const;
void setBackground(const QString& _icon) {
currentPix_ = QPixmap(_icon);
}
signals:
void Finished(void);
public slots:
/* 开始动画 */
void startAnimation();
/* 停止动画 */
void stopAnimation();
/* 设置停止菊花,显示圆圈加对号*/
void setDisplayStringInfo(QString strTip,QString strTiping);
void setDisplayModel(int iFlag);//iFlag 0:表示进度统计1表示strTiping提示结束后显示strTip
/* 设置菊花转的转速 */
void setAnimationDelay(int delay);
/* 动画完毕后,是否隐藏菊花转 */
void setDisplayedWhenStopped(bool state);
/* 设置菊花转颜色 */
void setColor(const QColor & color);
/*
*
* _progress 0 < _progress < 100
*/
void onProgress(QString msg, int _progress, bool done)
{
Q_UNUSED(msg)
progress_ = _progress;
if(done)
{
progress_=100;
}
}
protected:
/* 系统基类函数 */
virtual void timerEvent(QTimerEvent * event);
virtual void paintEvent(QPaintEvent * event);
void drawJuHua(QPainter *painter);
private:
/* 角度 */
unsigned int angle_;
/* 定时器ID */
int timerId_;
/* 转速 */
int delay_;
/* 是否隐藏 */
bool displayedWhenStopped_;
/* 菊花转颜色 */
QColor color_;
/* 进度 */
int progress_;
/* 背景图 */
QPixmap currentPix_;
/*显示圆圈中的字符串内容*/
QString m_strTip = "";
QString m_strTiping = "";
int m_iLoopBackFlag = 0;
};
#endif // CUSTOMPROGRESSINDICATOR_H
#ifndef CUSTOMPROGRESSINDICATOR_H
#define CUSTOMPROGRESSINDICATOR_H
#include <QWidget>
#include <QColor>
#include <QTimer>
/*
*
*
* 727057301@qq.com
* 201721016:26:48
* QT版本5.0.2
* CSDNhttp://blog.csdn.net/csnd_ayo
* **************************************
*
* 使QT.pro中加入 C++11
*
*
pIndicator = new CustomProgressIndicator(this);
pIndicator->setColor(Qt::red);
pIndicator->startAnimation();
*/
class CustomProgressIndicator : public QWidget
{
Q_OBJECT
Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay)
Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped)
Q_PROPERTY(QColor color READ color WRITE setColor)
public:
CustomProgressIndicator(QWidget* parent = nullptr);
int animationDelay() const { return delay_; }
/* 动画是否正在进行中 */
bool isAnimated () const;
/* 动画完毕后,是否隐藏菊花转 */
bool isDisplayedWhenStopped() const;
/* 当前菊花转的颜色 */
const QColor & color() const { return color_; }
/* 虚函数:当前大小 */
virtual QSize sizeHint() const;
void setBackground(const QString& _icon) {
currentPix_ = QPixmap(_icon);
}
signals:
void Finished(void);
public slots:
/* 开始动画 */
void startAnimation();
/* 停止动画 */
void stopAnimation();
/* 设置停止菊花,显示圆圈加对号*/
void setDisplayStringInfo(QString strTip,QString strTiping);
void setDisplayModel(int iFlag);//iFlag 0:表示进度统计1表示strTiping提示结束后显示strTip
/* 设置菊花转的转速 */
void setAnimationDelay(int delay);
/* 动画完毕后,是否隐藏菊花转 */
void setDisplayedWhenStopped(bool state);
/* 设置菊花转颜色 */
void setColor(const QColor & color);
/*
*
* _progress 0 < _progress < 100
*/
void onProgress(QString msg, int _progress, bool done)
{
Q_UNUSED(msg)
progress_ = _progress;
if(done)
{
progress_=100;
}
}
protected:
/* 系统基类函数 */
virtual void timerEvent(QTimerEvent * event);
virtual void paintEvent(QPaintEvent * event);
void drawJuHua(QPainter *painter);
private:
/* 角度 */
unsigned int angle_;
/* 定时器ID */
int timerId_;
/* 转速 */
int delay_;
/* 是否隐藏 */
bool displayedWhenStopped_;
/* 菊花转颜色 */
QColor color_;
/* 进度 */
int progress_;
/* 背景图 */
QPixmap currentPix_;
/*显示圆圈中的字符串内容*/
QString m_strTip = "";
QString m_strTiping = "";
int m_iLoopBackFlag = 0;
};
#endif // CUSTOMPROGRESSINDICATOR_H

View File

@ -1,62 +1,62 @@
#include "extendedgroupbox.h"
ExtendedGroupBox::ExtendedGroupBox(QWidget *parent /*= nullptr*/, State state /*= STATE_NORMAL*/)
: QGroupBox(parent)
{
setCheckable(true);
state_ = state;
if (state_ == STATE_NORMAL)
{
//隐藏垂直边框
setFlat(true);
}
connect(this, SIGNAL(clicked(bool)), this, SLOT(onChecked(bool)));
}
ExtendedGroupBox::ExtendedGroupBox(const QString &title, QWidget *parent /*= nullptr*/, State state /*= STATE_NORMAL*/)
: QGroupBox(title, parent)
{
setCheckable(true);
state_ = state;
if (state_ == STATE_NORMAL)
{
//隐藏垂直边框
setFlat(true);
}
// this->toggled();
connect(this, SIGNAL(toggled(bool)), this, SLOT(onChecked(bool)));
}
void ExtendedGroupBox::onChecked(bool checked)
{
if (checked)
{
//显示垂直边框
QList<QWidget *> widgets = findChildren<QWidget *>();
for (auto iter = widgets.begin(); iter != widgets.end(); ++iter)
{
(*iter)->setVisible(true);
}
state_ = STATE_EXPAND;
}
else
{
//隐藏垂直边框
QList<QWidget *> widgets = findChildren<QWidget *>();
for (auto iter = widgets.begin(); iter != widgets.end(); ++iter)
(*iter)->setVisible(false);
// QList<QLayout *> layouts = findChildren<QLayout *>();
// for (auto iter1 = layouts.begin(); iter1 != layouts.end(); ++iter1)
// (*iter1)->setVisible(false);
// QLayout aa;
// a->
state_ = STATE_NORMAL;
}
}
ExtendedGroupBox::State ExtendedGroupBox::getState() const
{
return state_;
}
#include "extendedgroupbox.h"
ExtendedGroupBox::ExtendedGroupBox(QWidget *parent /*= nullptr*/, State state /*= STATE_NORMAL*/)
: QGroupBox(parent)
{
setCheckable(true);
state_ = state;
if (state_ == STATE_NORMAL)
{
//隐藏垂直边框
setFlat(true);
}
connect(this, SIGNAL(clicked(bool)), this, SLOT(onChecked(bool)));
}
ExtendedGroupBox::ExtendedGroupBox(const QString &title, QWidget *parent /*= nullptr*/, State state /*= STATE_NORMAL*/)
: QGroupBox(title, parent)
{
setCheckable(true);
state_ = state;
if (state_ == STATE_NORMAL)
{
//隐藏垂直边框
setFlat(true);
}
// this->toggled();
connect(this, SIGNAL(toggled(bool)), this, SLOT(onChecked(bool)));
}
void ExtendedGroupBox::onChecked(bool checked)
{
if (checked)
{
//显示垂直边框
QList<QWidget *> widgets = findChildren<QWidget *>();
for (auto iter = widgets.begin(); iter != widgets.end(); ++iter)
{
(*iter)->setVisible(true);
}
state_ = STATE_EXPAND;
}
else
{
//隐藏垂直边框
QList<QWidget *> widgets = findChildren<QWidget *>();
for (auto iter = widgets.begin(); iter != widgets.end(); ++iter)
(*iter)->setVisible(false);
// QList<QLayout *> layouts = findChildren<QLayout *>();
// for (auto iter1 = layouts.begin(); iter1 != layouts.end(); ++iter1)
// (*iter1)->setVisible(false);
// QLayout aa;
// a->
state_ = STATE_NORMAL;
}
}
ExtendedGroupBox::State ExtendedGroupBox::getState() const
{
return state_;
}

View File

@ -1,32 +1,32 @@
#ifndef EXTENDEDGROUPBOX_H
#define EXTENDEDGROUPBOX_H
#include <QGroupBox>
#include <QVector>
class ExtendedGroupBox : public QGroupBox
{
Q_OBJECT
public:
enum State
{
STATE_NORMAL,
STATE_EXPAND
};
public:
ExtendedGroupBox(QWidget *parent = nullptr, State state = STATE_NORMAL);
ExtendedGroupBox(const QString &title, QWidget *parent = nullptr, State state = STATE_NORMAL);
private Q_SLOTS:
void onChecked(bool checked);
public:
void addWidget(QWidget *widget);
State getState() const;
private:
State state_;
};
#endif // EXTENDEDGROUPBOX_H
#ifndef EXTENDEDGROUPBOX_H
#define EXTENDEDGROUPBOX_H
#include <QGroupBox>
#include <QVector>
class ExtendedGroupBox : public QGroupBox
{
Q_OBJECT
public:
enum State
{
STATE_NORMAL,
STATE_EXPAND
};
public:
ExtendedGroupBox(QWidget *parent = nullptr, State state = STATE_NORMAL);
ExtendedGroupBox(const QString &title, QWidget *parent = nullptr, State state = STATE_NORMAL);
private Q_SLOTS:
void onChecked(bool checked);
public:
void addWidget(QWidget *widget);
State getState() const;
private:
State state_;
};
#endif // EXTENDEDGROUPBOX_H

View File

@ -6,6 +6,10 @@ extern "C"{
#include <libswscale/swscale.h>
}
static void imgCleanupHandler(void *info) {
delete [] (uchar*)info;
}
QString videoInfo(QByteArray url, QImage &img, int64_t *dur, AVCodecID *codec_id) {
AVFormatContext *fmt_ctx = avformat_alloc_context();
QString err;
@ -44,9 +48,12 @@ QString videoInfo(QByteArray url, QImage &img, int64_t *dur, AVCodecID *codec_id
avcodec_free_context(&vcCtx);
goto free;
}
auto sws_ctx = sws_getContext(vcCtx->width, vcCtx->height, vcCtx->pix_fmt, vcCtx->width, vcCtx->height, AV_PIX_FMT_RGB32, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);
auto sws_ctx = sws_getContext(vcCtx->width, vcCtx->height, vcCtx->pix_fmt, vcCtx->width, vcCtx->height, AV_PIX_FMT_RGB32, SWS_FAST_BILINEAR, 0, 0, 0);
auto packet = av_packet_alloc();
auto frm = av_frame_alloc();
int dstStride[4]{(vcCtx->width*4+63)/64*64};
dstStride[3] = dstStride[0] * vcCtx->height;
uint8_t *dst[4]{0};
while(1) {
if(av_read_frame(fmt_ctx, packet) < 0) break;
if(packet->stream_index != vi_idx) continue;
@ -54,10 +61,9 @@ QString videoInfo(QByteArray url, QImage &img, int64_t *dur, AVCodecID *codec_id
if(res < 0) break;
while((res = avcodec_receive_frame(vcCtx, frm)) != AVERROR(EAGAIN)) {
if(res < 0) goto free2;
img = QImage(vcCtx->width, vcCtx->height, QImage::Format_ARGB32);
uint8_t *dst[4]{img.bits()};
int dstStride[4]{img.bytesPerLine()};
dst[0] = new uchar[dstStride[3]];
sws_scale(sws_ctx, frm->data, frm->linesize, 0, vcCtx->height, dst, dstStride);
img = QImage(dst[0], vcCtx->width, vcCtx->height, dstStride[0], QImage::Format_ARGB32, imgCleanupHandler, dst[0]);
goto free2;
}
}
@ -71,188 +77,6 @@ QString videoInfo(QByteArray url, QImage &img, int64_t *dur, AVCodecID *codec_id
avformat_close_input(&fmt_ctx);
return err;
}
QString videoTrans(int sw, int sh, int dw, int dh, int cnt, QPointF pos, QByteArray file) {
AVFormatContext *in_fmt = avformat_alloc_context(), *out_fmt = 0;
AVCodecContext *de_ctx = 0, *en_ctx = 0;
QString err;
char buf[AV_ERROR_MAX_STRING_SIZE];
int ret;
{
if((ret = avformat_open_input(&in_fmt, file.constData(), nullptr, nullptr)) < 0) {
err = QString("Couldn't open input stream. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free;
}
if((ret = avformat_find_stream_info(in_fmt, nullptr)) < 0) {
err = QString("Couldn't find stream information. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free;
}
auto outfile = file+"-square.mp4";
if((ret = avformat_alloc_output_context2(&out_fmt, 0, "mp4", outfile.constData())) < 0) {
err = QString("avformat_alloc_output_context2 fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free;
}
int vi_idx = -1;
for(uint ss=0; ss<in_fmt->nb_streams; ss++) {
AVStream *stream = in_fmt->streams[ss];
AVStream *out_stream = avformat_new_stream(out_fmt, 0);
if((ret = avcodec_parameters_copy(out_stream->codecpar, stream->codecpar)) < 0) {
err = QString("avcodec_parameters_copy fail. ") + av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free;
}
out_stream->time_base = stream->time_base;
out_stream->start_time = stream->start_time;
out_stream->duration = stream->duration;
out_stream->avg_frame_rate = stream->avg_frame_rate;
out_stream->sample_aspect_ratio = {1,1};
if(vi_idx == -1 && stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) vi_idx = ss;
}
if(vi_idx == -1) {
err = "Didn't find a Video Stream";
goto free;
}
auto codecpar = in_fmt->streams[vi_idx]->codecpar;
qDebug()<<"codec_id"<<codecpar->codec_id<<avcodec_get_name(codecpar->codec_id);
auto decoder = avcodec_find_decoder(codecpar->codec_id);
if(decoder==0) {
err = "Could not found Video Decoder";
goto free;
}
de_ctx = avcodec_alloc_context3(decoder);
avcodec_parameters_to_context(de_ctx, codecpar);
if(avcodec_open2(de_ctx, decoder, 0) < 0) {
err = "Could not open Video decode Ctx";
goto free;
}
auto out_codecpar = out_fmt->streams[vi_idx]->codecpar;
out_codecpar->codec_id = AV_CODEC_ID_H264;
out_codecpar->format = AV_PIX_FMT_YUV420P;
out_codecpar->width = dw;
out_codecpar->height = dh;
out_codecpar->sample_aspect_ratio = {1,1};
out_fmt->streams[vi_idx]->sample_aspect_ratio = {1,1};
auto encoder = avcodec_find_encoder(out_codecpar->codec_id);
if(encoder==0) {
fprintf(stderr, "Codec not found\n");
goto free;
}
en_ctx = avcodec_alloc_context3(encoder);
avcodec_parameters_to_context(en_ctx, out_codecpar);
en_ctx->bit_rate = dw*dh*6;
en_ctx->gop_size = de_ctx->gop_size;
en_ctx->max_b_frames = 3;
en_ctx->framerate = de_ctx->framerate;
en_ctx->time_base = out_fmt->streams[vi_idx]->time_base;
if((ret = avcodec_open2(en_ctx, encoder, 0)) < 0) {
err = QString("Open video encode ctx failed. ") + av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free;
}
if(out_fmt->flags & AVFMT_NOFILE) qDebug()<<"AVFMT_NOFILE";
else if((ret = avio_open(&out_fmt->pb, outfile.constData(), AVIO_FLAG_WRITE)) < 0) {
err = QString("avio_open fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free;
}
if((ret = avformat_write_header(out_fmt, 0)) < 0) {
err = QString("avformat_write_header fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free;
}
auto sws_ctx = sws_getContext(de_ctx->width, de_ctx->height, de_ctx->pix_fmt, sw, sh, AV_PIX_FMT_0RGB, SWS_FAST_BILINEAR, 0, 0, 0);
auto out_sws_ctx = sws_getContext(dw, dh, AV_PIX_FMT_0RGB, dw, dh, AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, 0, 0, 0);
auto packet = av_packet_alloc();
auto frm = av_frame_alloc();
auto out_frm = av_frame_alloc();
QImage img(sw, sh, QImage::Format_RGB32);
uint8_t *img_data[4]{img.bits(), 0, 0, 0};
int img_linesize[4]{img.bytesPerLine(), 0, 0, 0};
QImage out_img(dw, dh, QImage::Format_RGB32);
uint8_t *out_img_data[4]{out_img.bits(), 0, 0, 0};
int out_img_linesize[4]{out_img.bytesPerLine(), 0, 0, 0};
QPainter painter(&out_img);
while(1) {
if((ret = av_read_frame(in_fmt, packet)) < 0) {
if(ret!=AVERROR_EOF) {
err = QString("Read packet fail: ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
break;
}
ret = avcodec_send_packet(de_ctx, 0);
} else {
if(packet->stream_index != vi_idx) {
av_interleaved_write_frame(out_fmt, packet);
continue;
}
ret = avcodec_send_packet(de_ctx, packet);
}
if(ret < 0) {
err = QString("avcodec_send_packet fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
break;
}
while((ret = avcodec_receive_frame(de_ctx, frm)) != AVERROR(EAGAIN)) {
if(ret < 0) {
if(ret!=AVERROR_EOF) {
err = QString("Receive frame fail: ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free2;
}
ret = avcodec_send_frame(en_ctx, 0);
} else {
sws_scale(sws_ctx, frm->data, frm->linesize, 0, de_ctx->height, img_data, img_linesize);
painter.drawImage(pos, img);
auto apos = pos;
for(int i=1; i<cnt; i++) {
apos.rx() -= dw;
apos.ry() += dh/cnt;
painter.drawImage(apos, img);
}
av_frame_unref(out_frm);
av_frame_copy_props(out_frm, frm);
out_frm->format = AV_PIX_FMT_YUV420P;
out_frm->width = dw;
out_frm->height = dh;
out_frm->sample_aspect_ratio = {1,1};
if((ret = av_frame_get_buffer(out_frm, 0)) < 0) {
err = QString("av_frame_get_buffer fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free2;
}
sws_scale(out_sws_ctx, out_img_data, out_img_linesize, 0, dh, out_frm->data, out_frm->linesize);
ret = avcodec_send_frame(en_ctx, out_frm);
}
if(ret < 0) {
err = QString("avcodec_send_frame fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
goto free2;
}
while((ret = avcodec_receive_packet(en_ctx, packet)) != AVERROR(EAGAIN)) {
if(ret < 0) {
if(ret!=AVERROR_EOF) err = QString("Receive frame fail: ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret);
else {
av_interleaved_write_frame(out_fmt, 0);
av_write_trailer(out_fmt);
}
goto free2;
} else {
av_interleaved_write_frame(out_fmt, packet);
}
}
}
}
free2:
av_frame_free(&frm);
av_frame_free(&out_frm);
av_packet_free(&packet);
sws_freeContext(sws_ctx);
sws_freeContext(out_sws_ctx);
}
free:
avcodec_free_context(&de_ctx);
avcodec_free_context(&en_ctx);
avformat_close_input(&in_fmt);
avio_closep(&out_fmt->pb);
if(out_fmt) avformat_free_context(out_fmt);
return err;
}
QString audioInfo(QByteArray url, int64_t *dur) {
AVFormatContext *fmt_ctx = avformat_alloc_context();
QString err;

View File

@ -7,7 +7,6 @@ extern "C"{
}
QString videoInfo(QByteArray url, QImage &, int64_t *dur, AVCodecID *);
QString videoTrans(int sw, int sh, int dw, int dh, int cnt, QPointF pos, QByteArray file);
QString audioInfo(QByteArray url, int64_t *dur);
#endif // FFUTIL_H

View File

@ -13,9 +13,12 @@ LoColorSelector::LoColorSelector(const QString &text, const QColor &color, QWidg
}
void LoColorSelector::init() {
connect(this, &QPushButton::clicked, this, [this]{
QColorDialog colorDlg(this->color, this);
QColorDialog colorDlg(this);
colorDlg.setOption(QColorDialog::ShowAlphaChannel);
colorDlg.setOption(QColorDialog::DontUseNativeDialog);
auto color = this->color;
color.setAlpha(255);
colorDlg.setCurrentColor(color);
auto btn = new QPushButton(tr("Transparent"));
connect(btn, &QPushButton::clicked, &colorDlg, [&colorDlg] {
@ -25,10 +28,8 @@ void LoColorSelector::init() {
static_cast<QBoxLayout *>(colorDlg.layout()->itemAt(0)->layout()->itemAt(0)->layout())->insertWidget(2, btn);
if(colorDlg.exec() != QColorDialog::Accepted) return;
QColor color = colorDlg.selectedColor();
if(color == this->color) return;
color = colorDlg.selectedColor();
if(! color.isValid()) return;
if(color.alpha()==0 && this->color.alpha()==0) color.setAlpha(255);
setColor(color);
emit sColorChanged(color);
});

View File

@ -7,13 +7,13 @@ LoDateSelector::LoDateSelector(QWidget *parent) : QPushButton(parent) {
setStyleSheet(R"rrr(
LoDateSelector {
background-color: transparent;
image: url(:/res/ProgramManager/EditProgram/DateSelect_enable.png);
image: url(:/res/program/DateSelect_enable.png);
padding: 0;
max-width: 32px;
max-height: 32px;
}
LoDateSelector:!enabled{
image: url(:/res/ProgramManager/EditProgram/DateSelect_e.png);
image: url(:/res/program/DateSelect_e.png);
}
LoDateSelector:pressed {
margin-top: 1px;

View File

@ -1,78 +1,78 @@
#include "loemptydialog.h"
#include <QVBoxLayout>
LoEmptyDialog::LoEmptyDialog(QWidget *parent) : BaseDlg(parent) {
setAttribute(Qt::WA_DeleteOnClose);
auto pal = palette();
pal.setBrush(QPalette::Window, QColor(0xdd, 0xdd, 0xdd, 0xdd));
setPalette(pal);
auto vBox = new QVBoxLayout(this);
vBox->addStretch();
mIndicator = new CustomProgressIndicator(this);
mIndicator->setDisplayModel(1);
mIndicator->setColor(QColor(0x0088dd));
mIndicator->setDisplayedWhenStopped(true);//动画停止后任就显示,直到关闭窗口
mIndicator->startAnimation();
vBox->addWidget(mIndicator, 0, Qt::AlignCenter);
vBox->addStretch();
label = new QLabel();
label->setAlignment(Qt::AlignCenter);
label->setStyleSheet("font-size: 24px; font-weight: bold; color: #08d;");
vBox->addWidget(label);
vBox->addStretch();
}
void LoEmptyDialog::SetTipTextContent(QString strTip) {
label->setText(strTip);
}
void LoEmptyDialog::SetFailedTipString(QString strTip) {
mTimeroutTip = strTip;
}
bool LoEmptyDialog::getLockStatus() {
return iLockFlag;
}
void LoEmptyDialog::lock(QString strTip, QString finishTip, QString timeroutTip) {
iLockFlag = true;
label->setText(strTip);
mFinishTip = finishTip;
mTimeroutTip = timeroutTip;
}
void LoEmptyDialog::unlock() {
if(iClosedFlag==1) return;
label->setText(mFinishTip);
if(mIndicator != nullptr) {
mIndicator->setBackground(":/res/success.png");
mIndicator->stopAnimation();
CloseWndByDelaySec(600);
}
iClosedFlag=1;
iLockFlag = false;
}
void LoEmptyDialog::TimerOutUnlock() {
if(iClosedFlag==1) return;
label->setText(mTimeroutTip);
if(mIndicator != nullptr) {
mIndicator->setBackground(":/res/tip.png");
mIndicator->stopAnimation();
CloseWndByDelaySec(600);
}
iClosedFlag = 1;
}
void LoEmptyDialog::CloseWndByDelaySec(int iCloseWndDelaySec) {
auto timer = new QTimer(this);
timer->setSingleShot(true);
connect(timer, &QTimer::timeout, this, [this, timer] {
timer->stop();
close();
emit sigClose();
});
timer->start(iCloseWndDelaySec);
}
#include "loemptydialog.h"
#include <QVBoxLayout>
LoEmptyDialog::LoEmptyDialog(QWidget *parent) : BaseDlg(parent) {
setAttribute(Qt::WA_DeleteOnClose);
auto pal = palette();
pal.setBrush(QPalette::Window, QColor(0xdd, 0xdd, 0xdd, 0xdd));
setPalette(pal);
auto vBox = new QVBoxLayout(this);
vBox->addStretch();
mIndicator = new CustomProgressIndicator(this);
mIndicator->setDisplayModel(1);
mIndicator->setColor(QColor(0x0088dd));
mIndicator->setDisplayedWhenStopped(true);//动画停止后任就显示,直到关闭窗口
mIndicator->startAnimation();
vBox->addWidget(mIndicator, 0, Qt::AlignCenter);
vBox->addStretch();
label = new QLabel();
label->setAlignment(Qt::AlignCenter);
label->setStyleSheet("font-size: 24px; font-weight: bold; color: #08d;");
vBox->addWidget(label);
vBox->addStretch();
}
void LoEmptyDialog::SetTipTextContent(QString strTip) {
label->setText(strTip);
}
void LoEmptyDialog::SetFailedTipString(QString strTip) {
mTimeroutTip = strTip;
}
bool LoEmptyDialog::getLockStatus() {
return iLockFlag;
}
void LoEmptyDialog::lock(QString strTip, QString finishTip, QString timeroutTip) {
iLockFlag = true;
label->setText(strTip);
mFinishTip = finishTip;
mTimeroutTip = timeroutTip;
}
void LoEmptyDialog::unlock() {
if(iClosedFlag==1) return;
label->setText(mFinishTip);
if(mIndicator != nullptr) {
mIndicator->setBackground(":/res/success.png");
mIndicator->stopAnimation();
CloseWndByDelaySec(600);
}
iClosedFlag=1;
iLockFlag = false;
}
void LoEmptyDialog::TimerOutUnlock() {
if(iClosedFlag==1) return;
label->setText(mTimeroutTip);
if(mIndicator != nullptr) {
mIndicator->setBackground(":/res/tip.png");
mIndicator->stopAnimation();
CloseWndByDelaySec(600);
}
iClosedFlag = 1;
}
void LoEmptyDialog::CloseWndByDelaySec(int iCloseWndDelaySec) {
auto timer = new QTimer(this);
timer->setSingleShot(true);
connect(timer, &QTimer::timeout, this, [this, timer] {
timer->stop();
close();
emit sigClose();
});
timer->start(iCloseWndDelaySec);
}

View File

@ -1,37 +1,37 @@
#ifndef LOEMPTYDIALOG_H
#define LOEMPTYDIALOG_H
#include <basedlg.h>
#include <base/customprogressindicator.h>
#include <QLabel>
class LoEmptyDialog : public BaseDlg {
Q_OBJECT
public:
explicit LoEmptyDialog(QWidget *parent = nullptr);
int exec() override {
emit startUp();
return BaseDlg::exec();
}
CustomProgressIndicator *mIndicator{0};
signals:
void startUp();
void sigClose();
public slots:
void lock(QString strTip,QString strUnLockTip,QString strTimerOutUnLockTip);
void unlock();
void TimerOutUnlock();
bool getLockStatus();
void SetFailedTipString(QString strTip);
void SetTipTextContent(QString strTip);
private:
QLabel *label;
int iClosedFlag=0;
bool iLockFlag = false;
QString mFinishTip;
QString mTimeroutTip;
LoEmptyDialog *m_pSelf=nullptr;
void CloseWndByDelaySec(int iCloseWndDelaySec);
};
#endif // LOEMPTYDIALOG_H
#ifndef LOEMPTYDIALOG_H
#define LOEMPTYDIALOG_H
#include <basedlg.h>
#include <base/customprogressindicator.h>
#include <QLabel>
class LoEmptyDialog : public BaseDlg {
Q_OBJECT
public:
explicit LoEmptyDialog(QWidget *parent = nullptr);
int exec() override {
emit startUp();
return BaseDlg::exec();
}
CustomProgressIndicator *mIndicator{0};
signals:
void startUp();
void sigClose();
public slots:
void lock(QString strTip,QString strUnLockTip,QString strTimerOutUnLockTip);
void unlock();
void TimerOutUnlock();
bool getLockStatus();
void SetFailedTipString(QString strTip);
void SetTipTextContent(QString strTip);
private:
QLabel *label;
int iClosedFlag=0;
bool iLockFlag = false;
QString mFinishTip;
QString mTimeroutTip;
LoEmptyDialog *m_pSelf=nullptr;
void CloseWndByDelaySec(int iCloseWndDelaySec);
};
#endif // LOEMPTYDIALOG_H

View File

@ -19,13 +19,7 @@ void CheckableHeader::paintSection(QPainter *painter, const QRect &rect, int log
LoQTreeWidget::LoQTreeWidget(QWidget *parent) : QTreeWidget(parent), m_checkState(CheckNone) {
fdIsSelAll = new QCheckBox();
fdIsSelAll->setStyleSheet(R"rrr(
QCheckBox::indicator {
width: 24px;
height: 24px;
margin-left: 10px;
}
)rrr");
fdIsSelAll->setStyleSheet("QCheckBox{margin-left: 5px;}");
m_header = new CheckableHeader(Qt::Horizontal, fdIsSelAll);
setHeader(m_header);
setProperty("ssType", "topList");

View File

@ -1,41 +1,41 @@
#include "pixbmpshowdialog.h"
#include "ui_pixbmpshowdialog.h"
#include <QPainter>
PixbmpShowDialog::PixbmpShowDialog(QWidget *parent) :
BaseDlg(parent),
ui(new Ui::PixbmpShowDialog)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
}
PixbmpShowDialog::~PixbmpShowDialog()
{
delete ui;
}
void PixbmpShowDialog::ResizeByPixmap(int w,int h)
{
m_iWidth=w;
m_iHeight=h;
int iWidth=w;
int iHeight=h;
if(iWidth<rect().width()&&iHeight<rect().height())
this->resize(iWidth,iHeight);
else {
if(iWidth>iHeight)
this->resize(rect().height()*iWidth/iHeight,rect().height());
else
this->resize(rect().width(),rect().width()*iHeight/iWidth);
}
}
void PixbmpShowDialog::paintEvent(QPaintEvent * event)
{
Q_UNUSED(event);
QPainter painter(this);
//painter.eraseRect(rect());
// painter.scale(m_PixMap.width(), m_PixMap.height());
QRectF sourceRt(0,0,m_iWidth,m_iHeight);
painter.drawPixmap(rect(), m_PixMap,sourceRt);
}
#include "pixbmpshowdialog.h"
#include "ui_pixbmpshowdialog.h"
#include <QPainter>
PixbmpShowDialog::PixbmpShowDialog(QWidget *parent) :
BaseDlg(parent),
ui(new Ui::PixbmpShowDialog)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
}
PixbmpShowDialog::~PixbmpShowDialog()
{
delete ui;
}
void PixbmpShowDialog::ResizeByPixmap(int w,int h)
{
m_iWidth=w;
m_iHeight=h;
int iWidth=w;
int iHeight=h;
if(iWidth<rect().width()&&iHeight<rect().height())
this->resize(iWidth,iHeight);
else {
if(iWidth>iHeight)
this->resize(rect().height()*iWidth/iHeight,rect().height());
else
this->resize(rect().width(),rect().width()*iHeight/iWidth);
}
}
void PixbmpShowDialog::paintEvent(QPaintEvent * event)
{
Q_UNUSED(event);
QPainter painter(this);
//painter.eraseRect(rect());
// painter.scale(m_PixMap.width(), m_PixMap.height());
QRectF sourceRt(0,0,m_iWidth,m_iHeight);
painter.drawPixmap(rect(), m_PixMap,sourceRt);
}

View File

@ -1,30 +1,30 @@
#ifndef PIXBMPSHOWDIALOG_H
#define PIXBMPSHOWDIALOG_H
#include <basedlg.h>
namespace Ui {
class PixbmpShowDialog;
}
class PixbmpShowDialog : public BaseDlg
{
Q_OBJECT
public:
explicit PixbmpShowDialog(QWidget *parent = nullptr);
~PixbmpShowDialog();
QPixmap m_PixMap;
void ResizeByPixmap(int w,int h);
int m_iWidth;
int m_iHeight;
public:
virtual void paintEvent(QPaintEvent *);
private:
Ui::PixbmpShowDialog *ui;
};
#endif // PIXBMPSHOWDIALOG_H
#ifndef PIXBMPSHOWDIALOG_H
#define PIXBMPSHOWDIALOG_H
#include <basedlg.h>
namespace Ui {
class PixbmpShowDialog;
}
class PixbmpShowDialog : public BaseDlg
{
Q_OBJECT
public:
explicit PixbmpShowDialog(QWidget *parent = nullptr);
~PixbmpShowDialog();
QPixmap m_PixMap;
void ResizeByPixmap(int w,int h);
int m_iWidth;
int m_iHeight;
public:
virtual void paintEvent(QPaintEvent *);
private:
Ui::PixbmpShowDialog *ui;
};
#endif // PIXBMPSHOWDIALOG_H

View File

@ -1,88 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PixbmpShowDialog</class>
<widget class="QDialog" name="PixbmpShowDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="minimumSize">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>PixbmpShowDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>199</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PixbmpShowDialog</class>
<widget class="QDialog" name="PixbmpShowDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="minimumSize">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>PixbmpShowDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>199</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,335 +1,335 @@
#include <QAxObject>
#include <QFile>
#include <QStringList>
#include <QDebug>
#include "qexcel.h"
#include "QMessageBox"
#include <objbase.h>
QExcel::QExcel(QString xlsFilePath, QObject *parent)
{
excel = nullptr;
workBooks = nullptr;
workBook = nullptr;
sheets = nullptr;
sheet = nullptr;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
excel = new QAxObject("Excel.Application");
excel->setProperty("Visible", false);
workBooks = excel->querySubObject("Workbooks");
if(workBooks!=nullptr)
{
QFile file(xlsFilePath);
if (file.exists())
{
workBooks->dynamicCall("Open(const QString&)", xlsFilePath);
workBook = excel->querySubObject("ActiveWorkBook");
sheets = workBook->querySubObject("WorkSheets");
}
m_bSupportExcel=true;
}
else {
QMessageBox::information(nullptr, "Title", tr("no support QExcel"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
m_bSupportExcel=false;
}
}
QExcel::~QExcel()
{
if(excel!=nullptr)
close();
}
void QExcel::close()
{
excel->dynamicCall("Quit()");
delete sheet;
delete sheets;
delete workBook;
delete workBooks;
delete excel;
excel = nullptr;
workBooks = nullptr;
workBook = nullptr;
sheets = nullptr;
sheet = nullptr;
}
QAxObject *QExcel::getWorkBooks()
{
return workBooks;
}
QAxObject *QExcel::getWorkBook()
{
return workBook;
}
QAxObject *QExcel::getWorkSheets()
{
return sheets;
}
QAxObject *QExcel::getWorkSheet()
{
return sheet;
}
void QExcel::selectSheet(const QString& sheetName)
{
sheet = sheets->querySubObject("Item(const QString&)", sheetName);
}
void QExcel::deleteSheet(const QString& sheetName)
{
QAxObject * a = sheets->querySubObject("Item(const QString&)", sheetName);
a->dynamicCall("delete");
}
void QExcel::deleteSheet(int sheetIndex)
{
QAxObject * a = sheets->querySubObject("Item(int)", sheetIndex);
a->dynamicCall("delete");
}
void QExcel::selectSheet(int sheetIndex)
{
sheet = sheets->querySubObject("Item(int)", sheetIndex);
}
void QExcel::setCellString(int row, int column, const QString& value)
{
QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column);
range->dynamicCall("SetValue(const QString&)", value);
}
void QExcel::setCellFontBold(int row, int column, bool isBold)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Bold", isBold);
}
void QExcel::setCellFontSize(int row, int column, int size)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Size", size);
}
void QExcel::mergeCells(const QString& cell)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("VerticalAlignment", -4108);//xlCenter
range->setProperty("WrapText", true);
range->setProperty("MergeCells", true);
}
void QExcel::mergeCells(int topLeftRow, int topLeftColumn, int bottomRightRow, int bottomRightColumn)
{
QString cell;
cell.append(QChar(topLeftColumn - 1 + 'A'));
cell.append(QString::number(topLeftRow));
cell.append(":");
cell.append(QChar(bottomRightColumn - 1 + 'A'));
cell.append(QString::number(bottomRightRow));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("VerticalAlignment", -4108);//xlCenter
range->setProperty("WrapText", true);
range->setProperty("MergeCells", true);
}
QVariant QExcel::getCellValue(int row, int column)
{
QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column);
return range->property("Value");
}
void QExcel::save()
{
workBook->dynamicCall("Save()");
}
int QExcel::getSheetsCount()
{
return sheets->property("Count").toInt();
}
QString QExcel::getSheetName()
{
return sheet->property("Name").toString();
}
QString QExcel::getSheetName(int sheetIndex)
{
QAxObject * a = sheets->querySubObject("Item(int)", sheetIndex);
return a->property("Name").toString();
}
void QExcel::getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn)
{
QAxObject *usedRange = sheet->querySubObject("UsedRange");
*topLeftRow = usedRange->property("Row").toInt();
*topLeftColumn = usedRange->property("Column").toInt();
QAxObject *rows = usedRange->querySubObject("Rows");
*bottomRightRow = *topLeftRow + rows->property("Count").toInt() - 1;
QAxObject *columns = usedRange->querySubObject("Columns");
*bottomRightColumn = *topLeftColumn + columns->property("Count").toInt() - 1;
}
void QExcel::setColumnWidth(int column, int width)
{
QString columnName;
columnName.append(QChar(column - 1 + 'A'));
columnName.append(":");
columnName.append(QChar(column - 1 + 'A'));
QAxObject * col = sheet->querySubObject("Columns(const QString&)", columnName);
col->setProperty("ColumnWidth", width);
}
void QExcel::setCellTextCenter(int row, int column)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("HorizontalAlignment", -4108);//xlCenter
}
void QExcel::setCellTextWrap(int row, int column, bool isWrap)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("WrapText", isWrap);
}
void QExcel::setAutoFitRow(int row)
{
QString rowsName;
rowsName.append(QString::number(row));
rowsName.append(":");
rowsName.append(QString::number(row));
QAxObject * rows = sheet->querySubObject("Rows(const QString &)", rowsName);
rows->dynamicCall("AutoFit()");
}
void QExcel::insertSheet(QString sheetName)
{
sheets->querySubObject("Add()");
QAxObject * a = sheets->querySubObject("Item(int)", 1);
a->setProperty("Name", sheetName);
}
void QExcel::mergeSerialSameCellsInAColumn(int column, int topRow)
{
int a,b,c,rowsCount;
getUsedRange(&a, &b, &rowsCount, &c);
int aMergeStart = topRow, aMergeEnd = topRow + 1;
QString value;
while(aMergeEnd <= rowsCount)
{
value = getCellValue(aMergeStart, column).toString();
while(value == getCellValue(aMergeEnd, column).toString())
{
clearCell(aMergeEnd, column);
aMergeEnd++;
}
aMergeEnd--;
mergeCells(aMergeStart, column, aMergeEnd, column);
aMergeStart = aMergeEnd + 1;
aMergeEnd = aMergeStart + 1;
}
}
void QExcel::clearCell(int row, int column)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->dynamicCall("ClearContents()");
}
void QExcel::clearCell(const QString& cell)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->dynamicCall("ClearContents()");
}
int QExcel::getUsedRowsCount()
{
QAxObject *usedRange = sheet->querySubObject("UsedRange");
int topRow = usedRange->property("Row").toInt();
QAxObject *rows = usedRange->querySubObject("Rows");
int bottomRow = topRow + rows->property("Count").toInt() - 1;
return bottomRow;
}
void QExcel::setCellString(const QString& cell, const QString& value)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->dynamicCall("SetValue(const QString&)", value);
}
void QExcel::setCellFontSize(const QString &cell, int size)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Size", size);
}
void QExcel::setCellTextCenter(const QString &cell)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("HorizontalAlignment", -4108);//xlCenter
}
void QExcel::setCellFontBold(const QString &cell, bool isBold)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Bold", isBold);
}
void QExcel::setCellTextWrap(const QString &cell, bool isWrap)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("WrapText", isWrap);
}
void QExcel::setRowHeight(int row, int height)
{
QString rowsName;
rowsName.append(QString::number(row));
rowsName.append(":");
rowsName.append(QString::number(row));
QAxObject * r = sheet->querySubObject("Rows(const QString &)", rowsName);
r->setProperty("RowHeight", height);
}
#include <QAxObject>
#include <QFile>
#include <QStringList>
#include <QDebug>
#include "qexcel.h"
#include "QMessageBox"
#include <objbase.h>
QExcel::QExcel(QString xlsFilePath, QObject *parent)
{
excel = nullptr;
workBooks = nullptr;
workBook = nullptr;
sheets = nullptr;
sheet = nullptr;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
excel = new QAxObject("Excel.Application");
excel->setProperty("Visible", false);
workBooks = excel->querySubObject("Workbooks");
if(workBooks!=nullptr)
{
QFile file(xlsFilePath);
if (file.exists())
{
workBooks->dynamicCall("Open(const QString&)", xlsFilePath);
workBook = excel->querySubObject("ActiveWorkBook");
sheets = workBook->querySubObject("WorkSheets");
}
m_bSupportExcel=true;
}
else {
QMessageBox::information(nullptr, "Title", tr("no support QExcel"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
m_bSupportExcel=false;
}
}
QExcel::~QExcel()
{
if(excel!=nullptr)
close();
}
void QExcel::close()
{
excel->dynamicCall("Quit()");
delete sheet;
delete sheets;
delete workBook;
delete workBooks;
delete excel;
excel = nullptr;
workBooks = nullptr;
workBook = nullptr;
sheets = nullptr;
sheet = nullptr;
}
QAxObject *QExcel::getWorkBooks()
{
return workBooks;
}
QAxObject *QExcel::getWorkBook()
{
return workBook;
}
QAxObject *QExcel::getWorkSheets()
{
return sheets;
}
QAxObject *QExcel::getWorkSheet()
{
return sheet;
}
void QExcel::selectSheet(const QString& sheetName)
{
sheet = sheets->querySubObject("Item(const QString&)", sheetName);
}
void QExcel::deleteSheet(const QString& sheetName)
{
QAxObject * a = sheets->querySubObject("Item(const QString&)", sheetName);
a->dynamicCall("delete");
}
void QExcel::deleteSheet(int sheetIndex)
{
QAxObject * a = sheets->querySubObject("Item(int)", sheetIndex);
a->dynamicCall("delete");
}
void QExcel::selectSheet(int sheetIndex)
{
sheet = sheets->querySubObject("Item(int)", sheetIndex);
}
void QExcel::setCellString(int row, int column, const QString& value)
{
QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column);
range->dynamicCall("SetValue(const QString&)", value);
}
void QExcel::setCellFontBold(int row, int column, bool isBold)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Bold", isBold);
}
void QExcel::setCellFontSize(int row, int column, int size)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Size", size);
}
void QExcel::mergeCells(const QString& cell)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("VerticalAlignment", -4108);//xlCenter
range->setProperty("WrapText", true);
range->setProperty("MergeCells", true);
}
void QExcel::mergeCells(int topLeftRow, int topLeftColumn, int bottomRightRow, int bottomRightColumn)
{
QString cell;
cell.append(QChar(topLeftColumn - 1 + 'A'));
cell.append(QString::number(topLeftRow));
cell.append(":");
cell.append(QChar(bottomRightColumn - 1 + 'A'));
cell.append(QString::number(bottomRightRow));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("VerticalAlignment", -4108);//xlCenter
range->setProperty("WrapText", true);
range->setProperty("MergeCells", true);
}
QVariant QExcel::getCellValue(int row, int column)
{
QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column);
return range->property("Value");
}
void QExcel::save()
{
workBook->dynamicCall("Save()");
}
int QExcel::getSheetsCount()
{
return sheets->property("Count").toInt();
}
QString QExcel::getSheetName()
{
return sheet->property("Name").toString();
}
QString QExcel::getSheetName(int sheetIndex)
{
QAxObject * a = sheets->querySubObject("Item(int)", sheetIndex);
return a->property("Name").toString();
}
void QExcel::getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn)
{
QAxObject *usedRange = sheet->querySubObject("UsedRange");
*topLeftRow = usedRange->property("Row").toInt();
*topLeftColumn = usedRange->property("Column").toInt();
QAxObject *rows = usedRange->querySubObject("Rows");
*bottomRightRow = *topLeftRow + rows->property("Count").toInt() - 1;
QAxObject *columns = usedRange->querySubObject("Columns");
*bottomRightColumn = *topLeftColumn + columns->property("Count").toInt() - 1;
}
void QExcel::setColumnWidth(int column, int width)
{
QString columnName;
columnName.append(QChar(column - 1 + 'A'));
columnName.append(":");
columnName.append(QChar(column - 1 + 'A'));
QAxObject * col = sheet->querySubObject("Columns(const QString&)", columnName);
col->setProperty("ColumnWidth", width);
}
void QExcel::setCellTextCenter(int row, int column)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("HorizontalAlignment", -4108);//xlCenter
}
void QExcel::setCellTextWrap(int row, int column, bool isWrap)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("WrapText", isWrap);
}
void QExcel::setAutoFitRow(int row)
{
QString rowsName;
rowsName.append(QString::number(row));
rowsName.append(":");
rowsName.append(QString::number(row));
QAxObject * rows = sheet->querySubObject("Rows(const QString &)", rowsName);
rows->dynamicCall("AutoFit()");
}
void QExcel::insertSheet(QString sheetName)
{
sheets->querySubObject("Add()");
QAxObject * a = sheets->querySubObject("Item(int)", 1);
a->setProperty("Name", sheetName);
}
void QExcel::mergeSerialSameCellsInAColumn(int column, int topRow)
{
int a,b,c,rowsCount;
getUsedRange(&a, &b, &rowsCount, &c);
int aMergeStart = topRow, aMergeEnd = topRow + 1;
QString value;
while(aMergeEnd <= rowsCount)
{
value = getCellValue(aMergeStart, column).toString();
while(value == getCellValue(aMergeEnd, column).toString())
{
clearCell(aMergeEnd, column);
aMergeEnd++;
}
aMergeEnd--;
mergeCells(aMergeStart, column, aMergeEnd, column);
aMergeStart = aMergeEnd + 1;
aMergeEnd = aMergeStart + 1;
}
}
void QExcel::clearCell(int row, int column)
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->dynamicCall("ClearContents()");
}
void QExcel::clearCell(const QString& cell)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->dynamicCall("ClearContents()");
}
int QExcel::getUsedRowsCount()
{
QAxObject *usedRange = sheet->querySubObject("UsedRange");
int topRow = usedRange->property("Row").toInt();
QAxObject *rows = usedRange->querySubObject("Rows");
int bottomRow = topRow + rows->property("Count").toInt() - 1;
return bottomRow;
}
void QExcel::setCellString(const QString& cell, const QString& value)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->dynamicCall("SetValue(const QString&)", value);
}
void QExcel::setCellFontSize(const QString &cell, int size)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Size", size);
}
void QExcel::setCellTextCenter(const QString &cell)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("HorizontalAlignment", -4108);//xlCenter
}
void QExcel::setCellFontBold(const QString &cell, bool isBold)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Bold", isBold);
}
void QExcel::setCellTextWrap(const QString &cell, bool isWrap)
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("WrapText", isWrap);
}
void QExcel::setRowHeight(int row, int height)
{
QString rowsName;
rowsName.append(QString::number(row));
rowsName.append(":");
rowsName.append(QString::number(row));
QAxObject * r = sheet->querySubObject("Rows(const QString &)", rowsName);
r->setProperty("RowHeight", height);
}

View File

@ -1,82 +1,82 @@
#ifndef QEXCEL_H
#define QEXCEL_H
#include <QString>
#include <QVariant>
class QAxObject;
class QExcel : public QObject
{
public:
QExcel(QString xlsFilePath, QObject *parent = 0);
~QExcel();
public:
QAxObject * getWorkBooks();
QAxObject * getWorkBook();
QAxObject * getWorkSheets();
QAxObject * getWorkSheet();
int m_bSupportExcel=false;
public:
/**************************************************************************/
/* 工作表 */
/**************************************************************************/
void selectSheet(const QString& sheetName);
//sheetIndex 起始于 1
void selectSheet(int sheetIndex);
void deleteSheet(const QString& sheetName);
void deleteSheet(int sheetIndex);
void insertSheet(QString sheetName);
int getSheetsCount();
//在 selectSheet() 之后才可调用
QString getSheetName();
QString getSheetName(int sheetIndex);
/**************************************************************************/
/* 单元格 */
/**************************************************************************/
void setCellString(int row, int column, const QString& value);
//cell 例如 "A7"
void setCellString(const QString& cell, const QString& value);
//range 例如 "A5:C7"
void mergeCells(const QString& range);
void mergeCells(int topLeftRow, int topLeftColumn, int bottomRightRow, int bottomRightColumn);
QVariant getCellValue(int row, int column);
void clearCell(int row, int column);
void clearCell(const QString& cell);
/**************************************************************************/
/* 布局格式 */
/**************************************************************************/
void getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn);
void setColumnWidth(int column, int width);
void setRowHeight(int row, int height);
void setCellTextCenter(int row, int column);
void setCellTextCenter(const QString& cell);
void setCellTextWrap(int row, int column, bool isWrap);
void setCellTextWrap(const QString& cell, bool isWrap);
void setAutoFitRow(int row);
void mergeSerialSameCellsInAColumn(int column, int topRow);
int getUsedRowsCount();
void setCellFontBold(int row, int column, bool isBold);
void setCellFontBold(const QString& cell, bool isBold);
void setCellFontSize(int row, int column, int size);
void setCellFontSize(const QString& cell, int size);
/**************************************************************************/
/* 文件 */
/**************************************************************************/
void save();
void close();
private:
QAxObject * excel;
QAxObject * workBooks;
QAxObject * workBook;
QAxObject * sheets;
QAxObject * sheet;
};
#endif
#ifndef QEXCEL_H
#define QEXCEL_H
#include <QString>
#include <QVariant>
class QAxObject;
class QExcel : public QObject
{
public:
QExcel(QString xlsFilePath, QObject *parent = 0);
~QExcel();
public:
QAxObject * getWorkBooks();
QAxObject * getWorkBook();
QAxObject * getWorkSheets();
QAxObject * getWorkSheet();
int m_bSupportExcel=false;
public:
/**************************************************************************/
/* 工作表 */
/**************************************************************************/
void selectSheet(const QString& sheetName);
//sheetIndex 起始于 1
void selectSheet(int sheetIndex);
void deleteSheet(const QString& sheetName);
void deleteSheet(int sheetIndex);
void insertSheet(QString sheetName);
int getSheetsCount();
//在 selectSheet() 之后才可调用
QString getSheetName();
QString getSheetName(int sheetIndex);
/**************************************************************************/
/* 单元格 */
/**************************************************************************/
void setCellString(int row, int column, const QString& value);
//cell 例如 "A7"
void setCellString(const QString& cell, const QString& value);
//range 例如 "A5:C7"
void mergeCells(const QString& range);
void mergeCells(int topLeftRow, int topLeftColumn, int bottomRightRow, int bottomRightColumn);
QVariant getCellValue(int row, int column);
void clearCell(int row, int column);
void clearCell(const QString& cell);
/**************************************************************************/
/* 布局格式 */
/**************************************************************************/
void getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn);
void setColumnWidth(int column, int width);
void setRowHeight(int row, int height);
void setCellTextCenter(int row, int column);
void setCellTextCenter(const QString& cell);
void setCellTextWrap(int row, int column, bool isWrap);
void setCellTextWrap(const QString& cell, bool isWrap);
void setAutoFitRow(int row);
void mergeSerialSameCellsInAColumn(int column, int topRow);
int getUsedRowsCount();
void setCellFontBold(int row, int column, bool isBold);
void setCellFontBold(const QString& cell, bool isBold);
void setCellFontSize(int row, int column, int size);
void setCellFontSize(const QString& cell, int size);
/**************************************************************************/
/* 文件 */
/**************************************************************************/
void save();
void close();
private:
QAxObject * excel;
QAxObject * workBooks;
QAxObject * workBook;
QAxObject * sheets;
QAxObject * sheet;
};
#endif

View File

@ -1,285 +1,285 @@
/*
* http://blog.csdn.net/u011417605,并在此基础上进行修改
* 1.
* 2.
* 3.
* 4.
* 5.255.IP值时IP格式
* 使QLineEdit嵌套四个小的QLineEdit使paintEvent画出来的使eventFilter来进行分发实现的
*
* QWidget替换原先的__super
*
*
* QLineEdit之间的空隙
*
* 192QLineEdit出
* text()使1921680127192.168.0.127
**/
#include "qiplineedit.h"
#include <QRegExpValidator>
#include <QPainter>
#include <QKeyEvent>
#include <QMessageBox>
#define SPACE 5
QIPLineEdit::QIPLineEdit(QWidget *parent) : QLineEdit(parent) {
QRegExp rx("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
pHBox = new QHBoxLayout(this);
pHBox->setSpacing(SPACE);
pHBox->setContentsMargins(0, 0, 0, 0);
for(int i = 0; i < 4; i++) {
m_lineEidt[i] = new QLineEdit(this);
m_lineEidt[i]->setFrame(false);
m_lineEidt[i]->setMaxLength(3);
m_lineEidt[i]->setAlignment(Qt::AlignCenter);
m_lineEidt[i]->installEventFilter(this);
m_lineEidt[i]->setValidator(new QRegExpValidator(rx, this));
m_lineEidt[i]->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
switch (i)
{
case 0:
m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(0, 0, 0);\n"
"border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n"
"border-right-color: rgbl(255, 255, 255,0);" "border-radius:0px"));
break;
case 1:
m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n"
"border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n" "border-left: 0px;\n"
"border-right-color: rgb(255, 255, 255);" "border-radius:0px"));
break;
case 2:
m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n"
"border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n" "border-left: 0px;\n"
"border-right-color: rgb(255, 255, 255);" "border-radius:0px"));
break;
case 3:
m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n"
"border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-left: 0px;\n"
"border-right-color: rgb(0, 0, 0);" "border-radius:0px"));
break;
default:
break;
}
pHBox->addWidget(m_lineEidt[i]);
}
this->setReadOnly(true);
m_Color=Qt::white;
connect(m_lineEidt[0],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit1TextChanged(const QString &)));
connect(m_lineEidt[1],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit2TextChanged(const QString &)));
connect(m_lineEidt[2],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit3TextChanged(const QString &)));
connect(m_lineEidt[3],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit4TextChanged(const QString &)));
}
QIPLineEdit::~QIPLineEdit() {
m_lineEidt[0]->deleteLater();
m_lineEidt[1]->deleteLater();
m_lineEidt[2]->deleteLater();
m_lineEidt[3]->deleteLater();
pHBox->deleteLater();
}
void QIPLineEdit::MySetColor(QColor cr)
{
m_Color=cr;
}
void QIPLineEdit::OnLineEdit1TextChanged(const QString & strtemp)
{
if(strtemp.right(1)=="."||strtemp.right(1)=="")
{
m_lineEidt[0]->setText(strtemp.left(strtemp.length()-1));
m_lineEidt[0 + 1]->setFocus();
m_lineEidt[0 + 1]->setCursorPosition(0);
}
}
void QIPLineEdit::OnLineEdit2TextChanged(const QString & strtemp)
{
if(strtemp.right(1)=="."||strtemp.right(1)=="")
{
m_lineEidt[1]->setText(strtemp.left(strtemp.length()-1));
m_lineEidt[1 + 1]->setFocus();
m_lineEidt[1 + 1]->setCursorPosition(0);
}
}
void QIPLineEdit::OnLineEdit3TextChanged(const QString & strtemp)
{
if(strtemp.right(1)=="."||strtemp.right(1)=="")
{
m_lineEidt[2]->setText(strtemp.left(strtemp.length()-1));
m_lineEidt[2 + 1]->setFocus();
m_lineEidt[2 + 1]->setCursorPosition(0);
}
}
void QIPLineEdit::OnLineEdit4TextChanged(const QString & strtemp)
{
if(strtemp.right(1)=="."||strtemp.right(1)=="")
{
m_lineEidt[3]->setText(strtemp.left(strtemp.length()-1));
}
}
void QIPLineEdit::paintEvent(QPaintEvent *event) {
QWidget::paintEvent(event);
QPainter painter(this);
QBrush brush;
int width = 0;
for(int i = 0; i < 3; i++) {
brush.setStyle(Qt::BrushStyle::SolidPattern);
//将两个lineEdit之间的空隙绘制成白色
brush.setColor(m_Color);
painter.setPen(m_Color);
painter.setBrush(brush);
painter.drawRect(m_lineEidt[i]->x() + m_lineEidt[i]->width(), m_lineEidt[i]->y(), SPACE, height());
//绘制空隙的边框
painter.setPen(Qt::black);
painter.drawLine(0, 0, this->width(), 0);
painter.drawLine(0, this->height() - 1, this->width(), this->height() - 1);
//绘制小黑点
brush.setColor(Qt::black);
painter.setPen(QPen());
painter.setBrush(brush);
width += m_lineEidt[i]->width() + (i == 0 ? 2 : SPACE);//布局的间隔
painter.drawEllipse(width, height() / 2 + 4, 1, 1);
}
}
int QIPLineEdit::getIndex(QLineEdit *pEdit){
int index = -1;
for(int i = 0; i < 4; i++) if(pEdit == m_lineEidt[i]) index = i;
return index;
}
bool QIPLineEdit::eventFilter(QObject *obj, QEvent *ev) {
if(children().contains(obj) && QEvent::KeyPress == ev->type()) {
QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(ev);
QLineEdit *pEdit = qobject_cast<QLineEdit *>(obj);
switch (keyEvent->key()) {
case Qt::Key_0:
case Qt::Key_1:
case Qt::Key_2:
case Qt::Key_3:
case Qt::Key_4:
case Qt::Key_5:
case Qt::Key_6:
case Qt::Key_7:
case Qt::Key_8:
case Qt::Key_9:
{
QString strText = pEdit->text();
if (pEdit->selectedText().length())
{
pEdit->text().replace(pEdit->selectedText(), QChar(keyEvent->key()));
}
else if (strText.length() == 2 || (strText.length() < 2 && strText.toInt() * 10 > 255))
{
int index = getIndex(pEdit);
if (index != -1 && index != 3)
{
m_lineEidt[index + 1]->setFocus();
m_lineEidt[index + 1]->selectAll();
}
}
else if (strText.length() == 2 && strText.toInt() * 10 < 255)
{
if (Qt::Key_0 == keyEvent->key() && strText.toInt())
{
pEdit->setText(strText.insert(pEdit->cursorPosition(), QChar(Qt::Key_0)));
}
}
return QWidget::eventFilter(obj, ev);
}
break;
case Qt::Key_Backspace:
{
QString strText = pEdit->text();
if (!strText.length() || (strText.length() && !pEdit->cursorPosition()))
{
int index = getIndex(pEdit);
if (index != -1 && index != 0)
{
m_lineEidt[index - 1]->setFocus();
int length = m_lineEidt[index - 1]->text().length();
m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
}
}
return QWidget::eventFilter(obj, ev);
}
break;
case Qt::Key_Left:
{
if (!pEdit->cursorPosition())
{
int index = getIndex(pEdit);
if (index != -1 && index != 0)
{
m_lineEidt[index - 1]->setFocus();
int length = m_lineEidt[index - 1]->text().length();
m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
}
}
return QWidget::eventFilter(obj, ev);
}
break;
case Qt::Key_Right:
{
if (pEdit->cursorPosition() == pEdit->text().length())
{
int index = getIndex(pEdit);
if (index != -1 && index != 3)
{
m_lineEidt[index + 1]->setFocus();
m_lineEidt[index + 1]->setCursorPosition(0);
}
}
return QWidget::eventFilter(obj, ev);
}
break;
default:
break;
}
}
return false;
}
void QIPLineEdit::setText(const QString &strIP)
{
if (!isTextValid(strIP))
{
QMessageBox::warning(this, "Attention", "Your IP Address is Invalid!["+strIP+"]", QMessageBox::StandardButton::Ok);
return;
}
else
{
int i = 0;
QStringList ipList = strIP.split(".");
foreach (QString ip, ipList)
{
m_lineEidt[i]->setText(ip);
i++;
}
}
}
bool QIPLineEdit::isTextValid(const QString &strIP) {
QRegExp rx2("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b");
return rx2.exactMatch(strIP);
}
QString QIPLineEdit::text() const
{
QString strIP;
for (int i = 0; i < 4; i++)
{
strIP.append(m_lineEidt[i]->text());
if (i < 3)
{
strIP.append(".");
}
}
return strIP;
}
void QIPLineEdit::MyClear()
{
m_lineEidt[0]->clear();
m_lineEidt[1]->clear();
m_lineEidt[2]->clear();
m_lineEidt[3]->clear();
}
/*
* http://blog.csdn.net/u011417605,并在此基础上进行修改
* 1.
* 2.
* 3.
* 4.
* 5.255.IP值时IP格式
* 使QLineEdit嵌套四个小的QLineEdit使paintEvent画出来的使eventFilter来进行分发实现的
*
* QWidget替换原先的__super
*
*
* QLineEdit之间的空隙
*
* 192QLineEdit出
* text()使1921680127192.168.0.127
**/
#include "qiplineedit.h"
#include <QRegExpValidator>
#include <QPainter>
#include <QKeyEvent>
#include <QMessageBox>
#define SPACE 5
QIPLineEdit::QIPLineEdit(QWidget *parent) : QLineEdit(parent) {
QRegExp rx("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
pHBox = new QHBoxLayout(this);
pHBox->setSpacing(SPACE);
pHBox->setContentsMargins(0, 0, 0, 0);
for(int i = 0; i < 4; i++) {
m_lineEidt[i] = new QLineEdit(this);
m_lineEidt[i]->setFrame(false);
m_lineEidt[i]->setMaxLength(3);
m_lineEidt[i]->setAlignment(Qt::AlignCenter);
m_lineEidt[i]->installEventFilter(this);
m_lineEidt[i]->setValidator(new QRegExpValidator(rx, this));
m_lineEidt[i]->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
switch (i)
{
case 0:
m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(0, 0, 0);\n"
"border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n"
"border-right-color: rgbl(255, 255, 255,0);" "border-radius:0px"));
break;
case 1:
m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n"
"border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n" "border-left: 0px;\n"
"border-right-color: rgb(255, 255, 255);" "border-radius:0px"));
break;
case 2:
m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n"
"border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n" "border-left: 0px;\n"
"border-right-color: rgb(255, 255, 255);" "border-radius:0px"));
break;
case 3:
m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n"
"border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-left: 0px;\n"
"border-right-color: rgb(0, 0, 0);" "border-radius:0px"));
break;
default:
break;
}
pHBox->addWidget(m_lineEidt[i]);
}
this->setReadOnly(true);
m_Color=Qt::white;
connect(m_lineEidt[0],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit1TextChanged(const QString &)));
connect(m_lineEidt[1],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit2TextChanged(const QString &)));
connect(m_lineEidt[2],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit3TextChanged(const QString &)));
connect(m_lineEidt[3],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit4TextChanged(const QString &)));
}
QIPLineEdit::~QIPLineEdit() {
m_lineEidt[0]->deleteLater();
m_lineEidt[1]->deleteLater();
m_lineEidt[2]->deleteLater();
m_lineEidt[3]->deleteLater();
pHBox->deleteLater();
}
void QIPLineEdit::MySetColor(QColor cr)
{
m_Color=cr;
}
void QIPLineEdit::OnLineEdit1TextChanged(const QString & strtemp)
{
if(strtemp.right(1)=="."||strtemp.right(1)=="")
{
m_lineEidt[0]->setText(strtemp.left(strtemp.length()-1));
m_lineEidt[0 + 1]->setFocus();
m_lineEidt[0 + 1]->setCursorPosition(0);
}
}
void QIPLineEdit::OnLineEdit2TextChanged(const QString & strtemp)
{
if(strtemp.right(1)=="."||strtemp.right(1)=="")
{
m_lineEidt[1]->setText(strtemp.left(strtemp.length()-1));
m_lineEidt[1 + 1]->setFocus();
m_lineEidt[1 + 1]->setCursorPosition(0);
}
}
void QIPLineEdit::OnLineEdit3TextChanged(const QString & strtemp)
{
if(strtemp.right(1)=="."||strtemp.right(1)=="")
{
m_lineEidt[2]->setText(strtemp.left(strtemp.length()-1));
m_lineEidt[2 + 1]->setFocus();
m_lineEidt[2 + 1]->setCursorPosition(0);
}
}
void QIPLineEdit::OnLineEdit4TextChanged(const QString & strtemp)
{
if(strtemp.right(1)=="."||strtemp.right(1)=="")
{
m_lineEidt[3]->setText(strtemp.left(strtemp.length()-1));
}
}
void QIPLineEdit::paintEvent(QPaintEvent *event) {
QWidget::paintEvent(event);
QPainter painter(this);
QBrush brush;
int width = 0;
for(int i = 0; i < 3; i++) {
brush.setStyle(Qt::BrushStyle::SolidPattern);
//将两个lineEdit之间的空隙绘制成白色
brush.setColor(m_Color);
painter.setPen(m_Color);
painter.setBrush(brush);
painter.drawRect(m_lineEidt[i]->x() + m_lineEidt[i]->width(), m_lineEidt[i]->y(), SPACE, height());
//绘制空隙的边框
painter.setPen(Qt::black);
painter.drawLine(0, 0, this->width(), 0);
painter.drawLine(0, this->height() - 1, this->width(), this->height() - 1);
//绘制小黑点
brush.setColor(Qt::black);
painter.setPen(QPen());
painter.setBrush(brush);
width += m_lineEidt[i]->width() + (i == 0 ? 2 : SPACE);//布局的间隔
painter.drawEllipse(width, height() / 2 + 4, 1, 1);
}
}
int QIPLineEdit::getIndex(QLineEdit *pEdit){
int index = -1;
for(int i = 0; i < 4; i++) if(pEdit == m_lineEidt[i]) index = i;
return index;
}
bool QIPLineEdit::eventFilter(QObject *obj, QEvent *ev) {
if(children().contains(obj) && QEvent::KeyPress == ev->type()) {
QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(ev);
QLineEdit *pEdit = qobject_cast<QLineEdit *>(obj);
switch (keyEvent->key()) {
case Qt::Key_0:
case Qt::Key_1:
case Qt::Key_2:
case Qt::Key_3:
case Qt::Key_4:
case Qt::Key_5:
case Qt::Key_6:
case Qt::Key_7:
case Qt::Key_8:
case Qt::Key_9:
{
QString strText = pEdit->text();
if (pEdit->selectedText().length())
{
pEdit->text().replace(pEdit->selectedText(), QChar(keyEvent->key()));
}
else if (strText.length() == 2 || (strText.length() < 2 && strText.toInt() * 10 > 255))
{
int index = getIndex(pEdit);
if (index != -1 && index != 3)
{
m_lineEidt[index + 1]->setFocus();
m_lineEidt[index + 1]->selectAll();
}
}
else if (strText.length() == 2 && strText.toInt() * 10 < 255)
{
if (Qt::Key_0 == keyEvent->key() && strText.toInt())
{
pEdit->setText(strText.insert(pEdit->cursorPosition(), QChar(Qt::Key_0)));
}
}
return QWidget::eventFilter(obj, ev);
}
break;
case Qt::Key_Backspace:
{
QString strText = pEdit->text();
if (!strText.length() || (strText.length() && !pEdit->cursorPosition()))
{
int index = getIndex(pEdit);
if (index != -1 && index != 0)
{
m_lineEidt[index - 1]->setFocus();
int length = m_lineEidt[index - 1]->text().length();
m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
}
}
return QWidget::eventFilter(obj, ev);
}
break;
case Qt::Key_Left:
{
if (!pEdit->cursorPosition())
{
int index = getIndex(pEdit);
if (index != -1 && index != 0)
{
m_lineEidt[index - 1]->setFocus();
int length = m_lineEidt[index - 1]->text().length();
m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
}
}
return QWidget::eventFilter(obj, ev);
}
break;
case Qt::Key_Right:
{
if (pEdit->cursorPosition() == pEdit->text().length())
{
int index = getIndex(pEdit);
if (index != -1 && index != 3)
{
m_lineEidt[index + 1]->setFocus();
m_lineEidt[index + 1]->setCursorPosition(0);
}
}
return QWidget::eventFilter(obj, ev);
}
break;
default:
break;
}
}
return false;
}
void QIPLineEdit::setText(const QString &strIP)
{
if (!isTextValid(strIP))
{
QMessageBox::warning(this, "Attention", "Your IP Address is Invalid!["+strIP+"]", QMessageBox::StandardButton::Ok);
return;
}
else
{
int i = 0;
QStringList ipList = strIP.split(".");
foreach (QString ip, ipList)
{
m_lineEidt[i]->setText(ip);
i++;
}
}
}
bool QIPLineEdit::isTextValid(const QString &strIP) {
QRegExp rx2("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b");
return rx2.exactMatch(strIP);
}
QString QIPLineEdit::text() const
{
QString strIP;
for (int i = 0; i < 4; i++)
{
strIP.append(m_lineEidt[i]->text());
if (i < 3)
{
strIP.append(".");
}
}
return strIP;
}
void QIPLineEdit::MyClear()
{
m_lineEidt[0]->clear();
m_lineEidt[1]->clear();
m_lineEidt[2]->clear();
m_lineEidt[3]->clear();
}

View File

@ -1,37 +1,37 @@
#ifndef QIPLINEEDIT_H
#define QIPLINEEDIT_H
#include <QLineEdit>
#include <QEvent>
#include <QHBoxLayout>
class QIPLineEdit : public QLineEdit {
Q_OBJECT
public:
QIPLineEdit(QWidget *parent = nullptr);
~QIPLineEdit();
void setText(const QString &strIP);
QString text() const;
void MyClear();
void MySetColor(QColor cr);
protected:
void paintEvent(QPaintEvent *event);
bool eventFilter(QObject *obj, QEvent *ev);
int getIndex(QLineEdit *pEdit);
bool isTextValid(const QString &strIP);
protected slots:
void OnLineEdit1TextChanged(const QString & strtemp);
void OnLineEdit2TextChanged(const QString & strtemp);
void OnLineEdit3TextChanged(const QString & strtemp);
void OnLineEdit4TextChanged(const QString & strtemp);
private:
QLineEdit *m_lineEidt[4];
QHBoxLayout *pHBox;
QColor m_Color;
};
#endif // QIPLINEEDIT_H
#ifndef QIPLINEEDIT_H
#define QIPLINEEDIT_H
#include <QLineEdit>
#include <QEvent>
#include <QHBoxLayout>
class QIPLineEdit : public QLineEdit {
Q_OBJECT
public:
QIPLineEdit(QWidget *parent = nullptr);
~QIPLineEdit();
void setText(const QString &strIP);
QString text() const;
void MyClear();
void MySetColor(QColor cr);
protected:
void paintEvent(QPaintEvent *event);
bool eventFilter(QObject *obj, QEvent *ev);
int getIndex(QLineEdit *pEdit);
bool isTextValid(const QString &strIP);
protected slots:
void OnLineEdit1TextChanged(const QString & strtemp);
void OnLineEdit2TextChanged(const QString & strtemp);
void OnLineEdit3TextChanged(const QString & strtemp);
void OnLineEdit4TextChanged(const QString & strtemp);
private:
QLineEdit *m_lineEidt[4];
QHBoxLayout *pHBox;
QColor m_Color;
};
#endif // QIPLINEEDIT_H

View File

@ -1,169 +1,169 @@
#include "readexcel.h"
#include <QDebug>
#include <iostream>
ReadExcel::ReadExcel()
:m_row(0), m_col(0), m_filename("")
{
m_excel = new QAxObject("Excel.Application");
}
ReadExcel::~ReadExcel()
{
if (!m_mapdata.empty()) {
m_mapdata.clear();
}
delete m_excel;
}
//
bool ReadExcel::openExcel(const QString &filename)
{
if (filename.isEmpty()) {
m_row = 0;
m_col = 0;
return false;
}
QFile file(filename);
if (!file.exists()){
m_row = 0;
m_col = 0;
return false;
};
if (!m_mapdata.empty()) {
m_mapdata.clear();
}
m_filename = filename;
try {
getALLfromExcel();
} catch (...) {
return false;
}
return true;
}
void ReadExcel::getALLfromDirNormalExcel(QString strFileName)
{
openExcelForWrite(strFileName);
}
bool ReadExcel::openExcelForWrite(const QString &filename)
{
if (filename.isEmpty()) {
m_row = 0;
m_col = 0;
return false;
}
QFile file(filename);
if (!file.exists()){
m_row = 0;
m_col = 0;
return false;
};
if (!m_mapdata.empty()) {
m_mapdata.clear();
}
m_filename = filename;
try {
WriteALLfromExcel();
} catch (...) {
return false;
}
return true;
}
void ReadExcel::getInfo(int &row, int &col) const
{
row = m_row;
col = m_col;
}
std::string ReadExcel::getCellData(const int &row, const int &col)
{
if (row >= 1 && row <= m_row && col >= 1 && col <= m_col) {
p.m_row = row;
p.m_col = col;
return m_mapdata[p];
} else {
return nullptr;
}
}
int ReadExcel::WriteCellData(const int &row, const int &col,std::string strValue )
{
p.m_row = row;
p.m_col = col;
m_mapdata[p]=strValue;
return 0;
}
void ReadExcel::getALLfromExcel()
{
m_excel->setProperty("Visible", 0);
QAxObject* workbooks = m_excel->querySubObject("WorkBooks");
workbooks->dynamicCall("Open (const QString&)", m_filename);
QAxObject* workbook = m_excel->querySubObject("ActiveWorkBook");
QAxObject* worksheets = workbook->querySubObject("WorkSheets");
Q_UNUSED(worksheets)
QAxObject* worksheet = workbook->querySubObject("Worksheets(int)", 1); //worksheet number
QAxObject* usedrange = worksheet->querySubObject("UsedRange");
QAxObject* rows = usedrange->querySubObject("Rows");
QAxObject* columns = usedrange->querySubObject("Columns");
int intRowStart = usedrange->property("Row").toInt();
int intColStart = usedrange->property("Column").toInt();
int intCols = columns->property("Count").toInt();
int intRows = rows->property("Count").toInt();
m_row = intRows;
m_col = intCols;
QAxObject * cell;
for (int i = intRowStart; i < intRowStart + intRows; i++)
{
for (int j = intColStart; j < intColStart + intCols; j++)
{
Position pos(i, j);
cell = m_excel->querySubObject("Cells(Int, Int)", i, j );
QVariant cellValue = cell->dynamicCall("value");
m_mapdata.insert(std::pair<Position, std::string>(pos, cellValue.toString().toStdString()));
}
}
m_excel->setProperty("DisplayAlerts", 0);
workbook->dynamicCall("Save(void)");
workbook->dynamicCall("Close (Boolean)", false);
m_excel->setProperty("DisplayAlerts",1);
}
void ReadExcel::WriteALLfromExcel()
{
m_excel->setProperty("Visible", 0);
QAxObject* workbooks = m_excel->querySubObject("WorkBooks");
workbooks->dynamicCall("Open (const QString&)", m_filename);
QAxObject* workbook = m_excel->querySubObject("ActiveWorkBook");
QAxObject* worksheets = workbook->querySubObject("WorkSheets");
Q_UNUSED(worksheets)
QAxObject* worksheet = workbook->querySubObject("Worksheets(int)", 1); //worksheet number
QAxObject* usedrange = worksheet->querySubObject("UsedRange");
QAxObject* rows = usedrange->querySubObject("Rows");
QAxObject* columns = usedrange->querySubObject("Columns");
int intRowStart = usedrange->property("Row").toInt();
int intColStart = usedrange->property("Column").toInt();
int intCols = columns->property("Count").toInt();
int intRows = rows->property("Count").toInt();
m_row = intRows;
m_col = intCols;
QAxObject * cell;
for (int i = intRowStart; i < intRowStart + intRows; i++)
{
for (int j = intColStart; j < intColStart + intCols; j++)
{
Position pos(i, j);
cell = m_excel->querySubObject("Cells(Int, Int)", i, j );
QVariant cellValue = cell->dynamicCall("value");
m_mapdata.insert(std::pair<Position, std::string>(pos, cellValue.toString().toStdString()));
}
}
m_excel->setProperty("DisplayAlerts", 0);
workbook->dynamicCall("Save(void)");
workbook->dynamicCall("Close (Boolean)", false);
m_excel->setProperty("DisplayAlerts",1);
}
#include "readexcel.h"
#include <QDebug>
#include <iostream>
ReadExcel::ReadExcel()
:m_row(0), m_col(0), m_filename("")
{
m_excel = new QAxObject("Excel.Application");
}
ReadExcel::~ReadExcel()
{
if (!m_mapdata.empty()) {
m_mapdata.clear();
}
delete m_excel;
}
//
bool ReadExcel::openExcel(const QString &filename)
{
if (filename.isEmpty()) {
m_row = 0;
m_col = 0;
return false;
}
QFile file(filename);
if (!file.exists()){
m_row = 0;
m_col = 0;
return false;
};
if (!m_mapdata.empty()) {
m_mapdata.clear();
}
m_filename = filename;
try {
getALLfromExcel();
} catch (...) {
return false;
}
return true;
}
void ReadExcel::getALLfromDirNormalExcel(QString strFileName)
{
openExcelForWrite(strFileName);
}
bool ReadExcel::openExcelForWrite(const QString &filename)
{
if (filename.isEmpty()) {
m_row = 0;
m_col = 0;
return false;
}
QFile file(filename);
if (!file.exists()){
m_row = 0;
m_col = 0;
return false;
};
if (!m_mapdata.empty()) {
m_mapdata.clear();
}
m_filename = filename;
try {
WriteALLfromExcel();
} catch (...) {
return false;
}
return true;
}
void ReadExcel::getInfo(int &row, int &col) const
{
row = m_row;
col = m_col;
}
std::string ReadExcel::getCellData(const int &row, const int &col)
{
if (row >= 1 && row <= m_row && col >= 1 && col <= m_col) {
p.m_row = row;
p.m_col = col;
return m_mapdata[p];
} else {
return nullptr;
}
}
int ReadExcel::WriteCellData(const int &row, const int &col,std::string strValue )
{
p.m_row = row;
p.m_col = col;
m_mapdata[p]=strValue;
return 0;
}
void ReadExcel::getALLfromExcel()
{
m_excel->setProperty("Visible", 0);
QAxObject* workbooks = m_excel->querySubObject("WorkBooks");
workbooks->dynamicCall("Open (const QString&)", m_filename);
QAxObject* workbook = m_excel->querySubObject("ActiveWorkBook");
QAxObject* worksheets = workbook->querySubObject("WorkSheets");
Q_UNUSED(worksheets)
QAxObject* worksheet = workbook->querySubObject("Worksheets(int)", 1); //worksheet number
QAxObject* usedrange = worksheet->querySubObject("UsedRange");
QAxObject* rows = usedrange->querySubObject("Rows");
QAxObject* columns = usedrange->querySubObject("Columns");
int intRowStart = usedrange->property("Row").toInt();
int intColStart = usedrange->property("Column").toInt();
int intCols = columns->property("Count").toInt();
int intRows = rows->property("Count").toInt();
m_row = intRows;
m_col = intCols;
QAxObject * cell;
for (int i = intRowStart; i < intRowStart + intRows; i++)
{
for (int j = intColStart; j < intColStart + intCols; j++)
{
Position pos(i, j);
cell = m_excel->querySubObject("Cells(Int, Int)", i, j );
QVariant cellValue = cell->dynamicCall("value");
m_mapdata.insert(std::pair<Position, std::string>(pos, cellValue.toString().toStdString()));
}
}
m_excel->setProperty("DisplayAlerts", 0);
workbook->dynamicCall("Save(void)");
workbook->dynamicCall("Close (Boolean)", false);
m_excel->setProperty("DisplayAlerts",1);
}
void ReadExcel::WriteALLfromExcel()
{
m_excel->setProperty("Visible", 0);
QAxObject* workbooks = m_excel->querySubObject("WorkBooks");
workbooks->dynamicCall("Open (const QString&)", m_filename);
QAxObject* workbook = m_excel->querySubObject("ActiveWorkBook");
QAxObject* worksheets = workbook->querySubObject("WorkSheets");
Q_UNUSED(worksheets)
QAxObject* worksheet = workbook->querySubObject("Worksheets(int)", 1); //worksheet number
QAxObject* usedrange = worksheet->querySubObject("UsedRange");
QAxObject* rows = usedrange->querySubObject("Rows");
QAxObject* columns = usedrange->querySubObject("Columns");
int intRowStart = usedrange->property("Row").toInt();
int intColStart = usedrange->property("Column").toInt();
int intCols = columns->property("Count").toInt();
int intRows = rows->property("Count").toInt();
m_row = intRows;
m_col = intCols;
QAxObject * cell;
for (int i = intRowStart; i < intRowStart + intRows; i++)
{
for (int j = intColStart; j < intColStart + intCols; j++)
{
Position pos(i, j);
cell = m_excel->querySubObject("Cells(Int, Int)", i, j );
QVariant cellValue = cell->dynamicCall("value");
m_mapdata.insert(std::pair<Position, std::string>(pos, cellValue.toString().toStdString()));
}
}
m_excel->setProperty("DisplayAlerts", 0);
workbook->dynamicCall("Save(void)");
workbook->dynamicCall("Close (Boolean)", false);
m_excel->setProperty("DisplayAlerts",1);
}

View File

@ -1,78 +1,78 @@
#ifndef READEXCEL_H
#define READEXCEL_H
#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <QAxObject>
#include <QString>
#include <QFile>
class Position
{
public:
Position() {
m_row = 0;
m_col = 0;
}
Position(int row, int col) {
m_row = row;
m_col = col;
}
public:
int m_row;
int m_col;
public:
bool operator<(const Position & ct) const // 两个const是必需的。
{
if (m_row < ct.m_row) {
return true;
} else if (m_row == ct.m_row) {
if ( m_col < ct.m_col ) {
return true;
}
}
return false;
}
};
class ReadExcel
{
public:
ReadExcel();
~ReadExcel();
public:
//打开excel文件
bool openExcel(const QString& filename);
void getALLfromDirNormalExcel(QString strFileName);
bool openExcelForWrite(const QString &filename);
//获取 指定单元格的数据
std::string getCellData(const int& row, const int& col);
int WriteCellData(const int& row, const int& col,std::string strValue );
//获取 行数,列数
void getInfo(int& row, int& col) const;
private:
void getALLfromExcel();
void WriteALLfromExcel();
private:
int m_row; //行
int m_col; //列
QString m_filename;
QAxObject* m_excel;
int m_rowWrite; //行
int m_colWrite; //列
QAxObject* m_excelWrite;
std::map<Position, std::string> m_mapdata;
std::map<Position, std::string> m_mapdataWrite;
Position p;
};
#endif // READEXCEL_H
#ifndef READEXCEL_H
#define READEXCEL_H
#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <QAxObject>
#include <QString>
#include <QFile>
class Position
{
public:
Position() {
m_row = 0;
m_col = 0;
}
Position(int row, int col) {
m_row = row;
m_col = col;
}
public:
int m_row;
int m_col;
public:
bool operator<(const Position & ct) const // 两个const是必需的。
{
if (m_row < ct.m_row) {
return true;
} else if (m_row == ct.m_row) {
if ( m_col < ct.m_col ) {
return true;
}
}
return false;
}
};
class ReadExcel
{
public:
ReadExcel();
~ReadExcel();
public:
//打开excel文件
bool openExcel(const QString& filename);
void getALLfromDirNormalExcel(QString strFileName);
bool openExcelForWrite(const QString &filename);
//获取 指定单元格的数据
std::string getCellData(const int& row, const int& col);
int WriteCellData(const int& row, const int& col,std::string strValue );
//获取 行数,列数
void getInfo(int& row, int& col) const;
private:
void getALLfromExcel();
void WriteALLfromExcel();
private:
int m_row; //行
int m_col; //列
QString m_filename;
QAxObject* m_excel;
int m_rowWrite; //行
int m_colWrite; //列
QAxObject* m_excelWrite;
std::map<Position, std::string> m_mapdata;
std::map<Position, std::string> m_mapdataWrite;
Position p;
};
#endif // READEXCEL_H

View File

@ -1,58 +1,58 @@
#include "softconfigdialog.h"
#include "cfg.h"
#include "globaldefine.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QSettings>
SoftConfigDialog::SoftConfigDialog(QWidget *parent) : BaseDlg(parent) {
resize(400, 300);
setWindowTitle(tr("Software Configuration"));
auto vbox = new QVBoxLayout(this);
auto pushButton = new QPushButton("X");
pushButton->setMinimumSize(30, 24);
connect(pushButton, &QPushButton::clicked, this, &QWidget::close);
vbox->addWidget(pushButton, 0, Qt::AlignRight);
press_fd = new QCheckBox(tr("Video compress to")+" 720p");
press_fd->setChecked(gVideoCompress);
vbox->addWidget(press_fd);
trans_fd = new QCheckBox(tr("Video transcoding to")+" h264");
trans_fd->setChecked(gVideoTranscoding);
vbox->addWidget(trans_fd);
auto hbox = new QHBoxLayout();
hbox->setContentsMargins(-1, 0, -1, -1);
anti_fd = new QCheckBox(tr("Text antialiasing"));
anti_fd->setChecked(gTextAntialiasing);
hbox->addWidget(anti_fd, 0, Qt::AlignTop);
auto anti_tip = new QLabel(tr("TextAntilaTip"));
anti_tip->setStyleSheet("color:#FF0000;");
anti_tip->setWordWrap(true);
hbox->addWidget(anti_tip);
vbox->addLayout(hbox);
vbox->addWidget(guangying_fd = new QCheckBox(tr("GuangYinPin")));
guangying_fd->setChecked(gShowLoraScreen);
vbox->addWidget(fdWidthSplit = new QCheckBox(tr("Width Split")));
fdWidthSplit->setChecked(gWidthSplit);
auto ok_btn = new QPushButton(tr("OK"));
vbox->addWidget(ok_btn, 0, Qt::AlignCenter);
connect(ok_btn, &QPushButton::clicked, this, [this]() {
QSettings settings;
settings.setValue("VideoCompress", gVideoCompress = press_fd->isChecked());
settings.setValue("VideoTranscoding", gVideoTranscoding = trans_fd->isChecked());
settings.setValue("TextAntialiasing", gTextAntialiasing = anti_fd->isChecked());
settings.setValue("GuangYingPin",gShowLoraScreen = guangying_fd->isChecked());
settings.setValue("WidthSplit", gWidthSplit = fdWidthSplit->isChecked());
accept();
});
}
#include "softconfigdialog.h"
#include "cfg.h"
#include "globaldefine.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QSettings>
SoftConfigDialog::SoftConfigDialog(QWidget *parent) : BaseDlg(parent) {
resize(400, 300);
setWindowTitle(tr("Software Config"));
auto vbox = new QVBoxLayout(this);
auto pushButton = new QPushButton("X");
pushButton->setMinimumSize(30, 24);
connect(pushButton, &QPushButton::clicked, this, &QWidget::close);
vbox->addWidget(pushButton, 0, Qt::AlignRight);
press_fd = new QCheckBox(tr("Video compress to")+" 720p");
press_fd->setChecked(gVideoCompress);
vbox->addWidget(press_fd);
trans_fd = new QCheckBox(tr("Video transcoding to")+" h264");
trans_fd->setChecked(gVideoTranscoding);
vbox->addWidget(trans_fd);
auto hbox = new QHBoxLayout();
hbox->setContentsMargins(-1, 0, -1, -1);
anti_fd = new QCheckBox(tr("Text antialiasing"));
anti_fd->setChecked(gTextAntialiasing);
hbox->addWidget(anti_fd, 0, Qt::AlignTop);
auto anti_tip = new QLabel(tr("TextAntilaTip"));
anti_tip->setStyleSheet("color:#FF0000;");
anti_tip->setWordWrap(true);
hbox->addWidget(anti_tip);
vbox->addLayout(hbox);
vbox->addWidget(guangying_fd = new QCheckBox(tr("GuangYinPin")));
guangying_fd->setChecked(gShowLoraScreen);
vbox->addWidget(fdWidthSplit = new QCheckBox(tr("Width Split")));
fdWidthSplit->setChecked(gWidthSplit);
auto ok_btn = new QPushButton(tr("OK"));
vbox->addWidget(ok_btn, 0, Qt::AlignCenter);
connect(ok_btn, &QPushButton::clicked, this, [this]() {
QSettings settings;
settings.setValue("VideoCompress", gVideoCompress = press_fd->isChecked());
settings.setValue("VideoTranscoding", gVideoTranscoding = trans_fd->isChecked());
settings.setValue("TextAntialiasing", gTextAntialiasing = anti_fd->isChecked());
settings.setValue("GuangYingPin",gShowLoraScreen = guangying_fd->isChecked());
settings.setValue("WidthSplit", gWidthSplit = fdWidthSplit->isChecked());
accept();
});
}

View File

@ -1,15 +1,15 @@
#ifndef SOFTCONFIGDIALOG_H
#define SOFTCONFIGDIALOG_H
#include "basedlg.h"
#include <QCheckBox>
class SoftConfigDialog : public BaseDlg {
Q_OBJECT
public:
explicit SoftConfigDialog(QWidget *parent = nullptr);
QCheckBox *press_fd, *trans_fd, *anti_fd, *guangying_fd, *fdWidthSplit;
};
#endif // SOFTCONFIGDIALOG_H
#ifndef SOFTCONFIGDIALOG_H
#define SOFTCONFIGDIALOG_H
#include "basedlg.h"
#include <QCheckBox>
class SoftConfigDialog : public BaseDlg {
Q_OBJECT
public:
explicit SoftConfigDialog(QWidget *parent = nullptr);
QCheckBox *press_fd, *trans_fd, *anti_fd, *guangying_fd, *fdWidthSplit;
};
#endif // SOFTCONFIGDIALOG_H

View File

@ -1,484 +1,484 @@
#include "switchcontrol.h"
#include "qpainter.h"
#include <QPainterPath>
#include "qevent.h"
#include "qtimer.h"
#include "qdebug.h"
SwitchControl::SwitchControl(QWidget *parent): QWidget(parent)
{
checked = false;
buttonStyle = ButtonStyle_Rect;
bgColorOff = QColor(225, 225, 225);
bgColorOn = QColor(250, 250, 250);
sliderColorOff = QColor(100, 100, 100);
sliderColorOn = QColor(100, 184, 255);
textColorOff = QColor(255, 255, 255);
textColorOn = QColor(10, 10, 10);
textOff = "";
textOn = "";
imageOff = ":/image/btncheckoff1.png";
imageOn = ":/image/btncheckon1.png";
space = 2;
rectRadius = 5;
step = width() / 50;
startX = 0;
endX = 0;
timer = new QTimer(this);
timer->setInterval(5);
connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
setFont(QFont("Microsoft Yahei", 10));
}
SwitchControl::~SwitchControl()
{
}
void SwitchControl::mousePressEvent(QMouseEvent *)
{
checked = !checked;
//每次移动的步长为宽度的 50分之一
step = width() / 50;
//状态切换改变后自动计算终点坐标
if (checked) {
if (buttonStyle == ButtonStyle_Rect) {
endX = width() - width() / 2;
} else if (buttonStyle == ButtonStyle_CircleIn) {
endX = width() - height();
} else if (buttonStyle == ButtonStyle_CircleOut) {
endX = width() - height() + space;
}
} else {
endX = 0;
}
timer->start();
emit checkedChanged(checked);
}
void SwitchControl::resizeEvent(QResizeEvent *)
{
//每次移动的步长为宽度的 50分之一
step = width() / 50;
//尺寸大小改变后自动设置起点坐标为终点
if (checked) {
if (buttonStyle == ButtonStyle_Rect) {
startX = width() - width() / 2;
} else if (buttonStyle == ButtonStyle_CircleIn) {
startX = width() - height();
} else if (buttonStyle == ButtonStyle_CircleOut) {
startX = width() - height() + space;
}
} else {
startX = 0;
}
update();
}
void SwitchControl::paintEvent(QPaintEvent *)
{
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
if (buttonStyle == ButtonStyle_Image) {
//绘制图片
drawImage(&painter);
} else {
//绘制背景
drawBg(&painter);
//绘制滑块
drawSlider(&painter);
//绘制文字
drawText(&painter);
}
}
void SwitchControl::drawBg(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
if (!checked) {
painter->setBrush(bgColorOff);
} else {
painter->setBrush(bgColorOn);
}
if (buttonStyle == ButtonStyle_Rect) {
painter->drawRoundedRect(rect(), rectRadius, rectRadius);
} else if (buttonStyle == ButtonStyle_CircleIn) {
QRect rect(0, 0, width(), height());
//半径为高度的一半
int radius = rect.height() / 2;
//圆的宽度为高度
int circleWidth = rect.height();
QPainterPath path;
path.moveTo(radius, rect.left());
path.arcTo(QRectF(rect.left(), rect.top(), circleWidth, circleWidth), 90, 180);
path.lineTo(rect.width() - radius, rect.height());
path.arcTo(QRectF(rect.width() - rect.height(), rect.top(), circleWidth, circleWidth), 270, 180);
path.lineTo(radius, rect.top());
painter->drawPath(path);
} else if (buttonStyle == ButtonStyle_CircleOut) {
QRect rect(space, space, width() - space * 2, height() - space * 2);
painter->drawRoundedRect(rect, rectRadius, rectRadius);
}
painter->restore();
}
void SwitchControl::drawSlider(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
if (!checked) {
painter->setBrush(sliderColorOff);
} else {
painter->setBrush(sliderColorOn);
}
if (buttonStyle == ButtonStyle_Rect) {
int sliderWidth = width() / 2 - space * 2;
int sliderHeight = height() - space * 2;
QRect sliderRect(startX + space, space, sliderWidth , sliderHeight);
painter->drawRoundedRect(sliderRect, rectRadius, rectRadius);
} else if (buttonStyle == ButtonStyle_CircleIn) {
QRect rect(0, 0, width(), height());
int sliderWidth = rect.height() - space * 2;
QRect sliderRect(startX + space, space, sliderWidth, sliderWidth);
painter->drawEllipse(sliderRect);
} else if (buttonStyle == ButtonStyle_CircleOut) {
QRect rect(0, 0, width() - space, height() - space);
int sliderWidth = rect.height();
QRect sliderRect(startX, space / 2, sliderWidth, sliderWidth);
painter->drawEllipse(sliderRect);
}
painter->restore();
}
void SwitchControl::drawText(QPainter *painter)
{
painter->save();
if (!checked) {
painter->setPen(textColorOff);
painter->drawText(width() / 2, 0, width() / 2 - space, height(), Qt::AlignCenter, textOff);
} else {
painter->setPen(textColorOn);
painter->drawText(0, 0, width() / 2 + space * 2, height(), Qt::AlignCenter, textOn);
}
painter->restore();
}
void SwitchControl::drawImage(QPainter *painter)
{
painter->save();
QPixmap pix;
if (!checked) {
pix = QPixmap(imageOff);
} else {
pix = QPixmap(imageOn);
}
//自动等比例平滑缩放居中显示
int targetWidth = pix.width();
int targetHeight = pix.height();
pix = pix.scaled(targetWidth, targetHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
int pixX = rect().center().x() - targetWidth / 2;
int pixY = rect().center().y() - targetHeight / 2;
QPoint point(pixX, pixY);
painter->drawPixmap(point, pix);
painter->restore();
}
void SwitchControl::updateValue()
{
if (checked) {
if (startX < endX) {
startX = startX + step;
} else {
startX = endX;
timer->stop();
}
} else {
if (startX > endX) {
startX = startX - step;
} else {
startX = endX;
timer->stop();
}
}
update();
}
void SwitchControl::setChecked(bool checked)
{
if (this->checked != checked) {
this->checked = checked;
emit checkedChanged(checked);
update();
}
}
void SwitchControl::setCheckedStatus(bool checked)
{
if (this->checked != checked) {
this->checked = checked;
}
update();
step = width() / 50;
//状态切换改变后自动计算终点坐标
if (checked) {
if (buttonStyle == ButtonStyle_Rect) {
endX = width() - width() / 2;
} else if (buttonStyle == ButtonStyle_CircleIn) {
endX = width() - height();
} else if (buttonStyle == ButtonStyle_CircleOut) {
endX = width() - height() + space;
}
} else {
endX = 0;
}
timer->start();
}
void SwitchControl::setButtonStyle(SwitchControl::ButtonStyle buttonStyle)
{
this->buttonStyle = buttonStyle;
update();
}
void SwitchControl::setBgColor(QColor bgColorOff, QColor bgColorOn)
{
this->bgColorOff = bgColorOff;
this->bgColorOn = bgColorOn;
update();
}
void SwitchControl::setSliderColor(QColor sliderColorOff, QColor sliderColorOn)
{
this->sliderColorOff = sliderColorOff;
this->sliderColorOn = sliderColorOn;
update();
}
void SwitchControl::setTextColor(QColor textColorOff, QColor textColorOn)
{
this->textColorOff = textColorOff;
this->textColorOn = textColorOn;
update();
}
void SwitchControl::setText(QString textOff, QString textOn)
{
this->textOff = textOff;
this->textOn = textOn;
update();
}
void SwitchControl::setImage(QString imageOff, QString imageOn)
{
this->imageOff = imageOff;
this->imageOn = imageOn;
update();
}
void SwitchControl::setSpace(int space)
{
this->space = space;
update();
}
void SwitchControl::setRectRadius(int rectRadius)
{
this->rectRadius = rectRadius;
update();
}
/*#include <QPainter>
#include <QMouseEvent>
SwitchControl::SwitchControl(QWidget *parent)
: QWidget(parent)
{
m_nHeight=16;
m_bChecked=false;
m_radius=8.0;
m_nMargin=5;
m_checkedColor=QColor(0, 150, 136);
m_thumbColor=Qt::white;
m_disabledColor=QColor(190, 190, 190);
m_background=Qt::black;
setAttribute(Qt::WA_DeleteOnClose);
// 鼠标滑过光标形状 - 手型
setCursor(Qt::PointingHandCursor);
// 连接信号槽
connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}
// 绘制开关
void SwitchControl::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
QColor background;
QColor thumbColor;
qreal dOpacity;
if (isEnabled()) { // 可用状态
if (m_bChecked) { // 打开状态
background = m_checkedColor;
thumbColor = m_checkedColor;
dOpacity = 0.600;
} else { //关闭状态
background = m_background;
thumbColor = m_thumbColor;
dOpacity = 0.800;
}
} else { // 不可用状态
background = m_background;
dOpacity = 0.260;
thumbColor = m_disabledColor;
}
// 绘制大椭圆
painter.setBrush(background);
painter.setOpacity(dOpacity);
path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin-(m_nHeight / 2), height() - 2 * m_nMargin), m_radius, m_radius);
painter.drawPath(path.simplified());
// 绘制小椭圆
painter.setBrush(thumbColor);
painter.setOpacity(1.0);
painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height()));
}
// 鼠标按下事件
void SwitchControl::mousePressEvent(QMouseEvent *event)
{
if (isEnabled()) {
if (event->buttons() & Qt::LeftButton) {
event->accept();
} else {
event->ignore();
}
}
}
// 鼠标释放事件 - 切换开关状态、发射toggled()信号
void SwitchControl::mouseReleaseEvent(QMouseEvent *event)
{
if (isEnabled()) {
if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) {
event->accept();
m_bChecked = !m_bChecked;
emit toggled(m_bChecked);
m_timer.start(10);
} else {
event->ignore();
}
}
}
// 大小改变事件
void SwitchControl::resizeEvent(QResizeEvent *event)
{
m_nX = m_nHeight / 2;
m_nY = m_nHeight / 2;
QWidget::resizeEvent(event);
}
// 默认大小
QSize SwitchControl::sizeHint() const
{
return minimumSizeHint();
}
// 最小大小
QSize SwitchControl::minimumSizeHint() const
{
return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin);
}
// 切换状态 - 滑动
void SwitchControl::onTimeout()
{
if (m_bChecked) {
m_nX += 1;
if (m_nX >= width() - m_nHeight*2)
m_timer.stop();
} else {
m_nX -= 1;
if (m_nX <= m_nHeight / 2)
m_timer.stop();
}
update();
}
// 返回开关状态 - 打开true 关闭false
bool SwitchControl::isToggled() const
{
return m_bChecked;
}
// 设置开关状态
void SwitchControl::setToggle(bool checked)
{
m_bChecked = checked;
m_timer.start(10);
}
// 设置背景颜色
void SwitchControl::setBackgroundColor(QColor color)
{
m_background = color;
}
// 设置拇指颜色
void SwitchControl::setthumbColor(QColor color)
{
//拇指颜色
m_thumbColor = color;
}
// 设置选中颜色
void SwitchControl::setCheckedColor(QColor color)
{
m_checkedColor = color;
}
// 设置不可用颜色
void SwitchControl::setDisbaledColor(QColor color)
{
m_disabledColor = color;
}
*/
#include "switchcontrol.h"
#include "qpainter.h"
#include <QPainterPath>
#include "qevent.h"
#include "qtimer.h"
#include "qdebug.h"
SwitchControl::SwitchControl(QWidget *parent): QWidget(parent)
{
checked = false;
buttonStyle = ButtonStyle_Rect;
bgColorOff = QColor(225, 225, 225);
bgColorOn = QColor(250, 250, 250);
sliderColorOff = QColor(100, 100, 100);
sliderColorOn = QColor(100, 184, 255);
textColorOff = QColor(255, 255, 255);
textColorOn = QColor(10, 10, 10);
textOff = "";
textOn = "";
imageOff = ":/image/btncheckoff1.png";
imageOn = ":/image/btncheckon1.png";
space = 2;
rectRadius = 5;
step = width() / 50;
startX = 0;
endX = 0;
timer = new QTimer(this);
timer->setInterval(5);
connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
setFont(QFont("Microsoft Yahei", 10));
}
SwitchControl::~SwitchControl()
{
}
void SwitchControl::mousePressEvent(QMouseEvent *)
{
checked = !checked;
//每次移动的步长为宽度的 50分之一
step = width() / 50;
//状态切换改变后自动计算终点坐标
if (checked) {
if (buttonStyle == ButtonStyle_Rect) {
endX = width() - width() / 2;
} else if (buttonStyle == ButtonStyle_CircleIn) {
endX = width() - height();
} else if (buttonStyle == ButtonStyle_CircleOut) {
endX = width() - height() + space;
}
} else {
endX = 0;
}
timer->start();
emit checkedChanged(checked);
}
void SwitchControl::resizeEvent(QResizeEvent *)
{
//每次移动的步长为宽度的 50分之一
step = width() / 50;
//尺寸大小改变后自动设置起点坐标为终点
if (checked) {
if (buttonStyle == ButtonStyle_Rect) {
startX = width() - width() / 2;
} else if (buttonStyle == ButtonStyle_CircleIn) {
startX = width() - height();
} else if (buttonStyle == ButtonStyle_CircleOut) {
startX = width() - height() + space;
}
} else {
startX = 0;
}
update();
}
void SwitchControl::paintEvent(QPaintEvent *)
{
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
if (buttonStyle == ButtonStyle_Image) {
//绘制图片
drawImage(&painter);
} else {
//绘制背景
drawBg(&painter);
//绘制滑块
drawSlider(&painter);
//绘制文字
drawText(&painter);
}
}
void SwitchControl::drawBg(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
if (!checked) {
painter->setBrush(bgColorOff);
} else {
painter->setBrush(bgColorOn);
}
if (buttonStyle == ButtonStyle_Rect) {
painter->drawRoundedRect(rect(), rectRadius, rectRadius);
} else if (buttonStyle == ButtonStyle_CircleIn) {
QRect rect(0, 0, width(), height());
//半径为高度的一半
int radius = rect.height() / 2;
//圆的宽度为高度
int circleWidth = rect.height();
QPainterPath path;
path.moveTo(radius, rect.left());
path.arcTo(QRectF(rect.left(), rect.top(), circleWidth, circleWidth), 90, 180);
path.lineTo(rect.width() - radius, rect.height());
path.arcTo(QRectF(rect.width() - rect.height(), rect.top(), circleWidth, circleWidth), 270, 180);
path.lineTo(radius, rect.top());
painter->drawPath(path);
} else if (buttonStyle == ButtonStyle_CircleOut) {
QRect rect(space, space, width() - space * 2, height() - space * 2);
painter->drawRoundedRect(rect, rectRadius, rectRadius);
}
painter->restore();
}
void SwitchControl::drawSlider(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
if (!checked) {
painter->setBrush(sliderColorOff);
} else {
painter->setBrush(sliderColorOn);
}
if (buttonStyle == ButtonStyle_Rect) {
int sliderWidth = width() / 2 - space * 2;
int sliderHeight = height() - space * 2;
QRect sliderRect(startX + space, space, sliderWidth , sliderHeight);
painter->drawRoundedRect(sliderRect, rectRadius, rectRadius);
} else if (buttonStyle == ButtonStyle_CircleIn) {
QRect rect(0, 0, width(), height());
int sliderWidth = rect.height() - space * 2;
QRect sliderRect(startX + space, space, sliderWidth, sliderWidth);
painter->drawEllipse(sliderRect);
} else if (buttonStyle == ButtonStyle_CircleOut) {
QRect rect(0, 0, width() - space, height() - space);
int sliderWidth = rect.height();
QRect sliderRect(startX, space / 2, sliderWidth, sliderWidth);
painter->drawEllipse(sliderRect);
}
painter->restore();
}
void SwitchControl::drawText(QPainter *painter)
{
painter->save();
if (!checked) {
painter->setPen(textColorOff);
painter->drawText(width() / 2, 0, width() / 2 - space, height(), Qt::AlignCenter, textOff);
} else {
painter->setPen(textColorOn);
painter->drawText(0, 0, width() / 2 + space * 2, height(), Qt::AlignCenter, textOn);
}
painter->restore();
}
void SwitchControl::drawImage(QPainter *painter)
{
painter->save();
QPixmap pix;
if (!checked) {
pix = QPixmap(imageOff);
} else {
pix = QPixmap(imageOn);
}
//自动等比例平滑缩放居中显示
int targetWidth = pix.width();
int targetHeight = pix.height();
pix = pix.scaled(targetWidth, targetHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
int pixX = rect().center().x() - targetWidth / 2;
int pixY = rect().center().y() - targetHeight / 2;
QPoint point(pixX, pixY);
painter->drawPixmap(point, pix);
painter->restore();
}
void SwitchControl::updateValue()
{
if (checked) {
if (startX < endX) {
startX = startX + step;
} else {
startX = endX;
timer->stop();
}
} else {
if (startX > endX) {
startX = startX - step;
} else {
startX = endX;
timer->stop();
}
}
update();
}
void SwitchControl::setChecked(bool checked)
{
if (this->checked != checked) {
this->checked = checked;
emit checkedChanged(checked);
update();
}
}
void SwitchControl::setCheckedStatus(bool checked)
{
if (this->checked != checked) {
this->checked = checked;
}
update();
step = width() / 50;
//状态切换改变后自动计算终点坐标
if (checked) {
if (buttonStyle == ButtonStyle_Rect) {
endX = width() - width() / 2;
} else if (buttonStyle == ButtonStyle_CircleIn) {
endX = width() - height();
} else if (buttonStyle == ButtonStyle_CircleOut) {
endX = width() - height() + space;
}
} else {
endX = 0;
}
timer->start();
}
void SwitchControl::setButtonStyle(SwitchControl::ButtonStyle buttonStyle)
{
this->buttonStyle = buttonStyle;
update();
}
void SwitchControl::setBgColor(QColor bgColorOff, QColor bgColorOn)
{
this->bgColorOff = bgColorOff;
this->bgColorOn = bgColorOn;
update();
}
void SwitchControl::setSliderColor(QColor sliderColorOff, QColor sliderColorOn)
{
this->sliderColorOff = sliderColorOff;
this->sliderColorOn = sliderColorOn;
update();
}
void SwitchControl::setTextColor(QColor textColorOff, QColor textColorOn)
{
this->textColorOff = textColorOff;
this->textColorOn = textColorOn;
update();
}
void SwitchControl::setText(QString textOff, QString textOn)
{
this->textOff = textOff;
this->textOn = textOn;
update();
}
void SwitchControl::setImage(QString imageOff, QString imageOn)
{
this->imageOff = imageOff;
this->imageOn = imageOn;
update();
}
void SwitchControl::setSpace(int space)
{
this->space = space;
update();
}
void SwitchControl::setRectRadius(int rectRadius)
{
this->rectRadius = rectRadius;
update();
}
/*#include <QPainter>
#include <QMouseEvent>
SwitchControl::SwitchControl(QWidget *parent)
: QWidget(parent)
{
m_nHeight=16;
m_bChecked=false;
m_radius=8.0;
m_nMargin=5;
m_checkedColor=QColor(0, 150, 136);
m_thumbColor=Qt::white;
m_disabledColor=QColor(190, 190, 190);
m_background=Qt::black;
setAttribute(Qt::WA_DeleteOnClose);
// 鼠标滑过光标形状 - 手型
setCursor(Qt::PointingHandCursor);
// 连接信号槽
connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}
// 绘制开关
void SwitchControl::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
QColor background;
QColor thumbColor;
qreal dOpacity;
if (isEnabled()) { // 可用状态
if (m_bChecked) { // 打开状态
background = m_checkedColor;
thumbColor = m_checkedColor;
dOpacity = 0.600;
} else { //关闭状态
background = m_background;
thumbColor = m_thumbColor;
dOpacity = 0.800;
}
} else { // 不可用状态
background = m_background;
dOpacity = 0.260;
thumbColor = m_disabledColor;
}
// 绘制大椭圆
painter.setBrush(background);
painter.setOpacity(dOpacity);
path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin-(m_nHeight / 2), height() - 2 * m_nMargin), m_radius, m_radius);
painter.drawPath(path.simplified());
// 绘制小椭圆
painter.setBrush(thumbColor);
painter.setOpacity(1.0);
painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height()));
}
// 鼠标按下事件
void SwitchControl::mousePressEvent(QMouseEvent *event)
{
if (isEnabled()) {
if (event->buttons() & Qt::LeftButton) {
event->accept();
} else {
event->ignore();
}
}
}
// 鼠标释放事件 - 切换开关状态、发射toggled()信号
void SwitchControl::mouseReleaseEvent(QMouseEvent *event)
{
if (isEnabled()) {
if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) {
event->accept();
m_bChecked = !m_bChecked;
emit toggled(m_bChecked);
m_timer.start(10);
} else {
event->ignore();
}
}
}
// 大小改变事件
void SwitchControl::resizeEvent(QResizeEvent *event)
{
m_nX = m_nHeight / 2;
m_nY = m_nHeight / 2;
QWidget::resizeEvent(event);
}
// 默认大小
QSize SwitchControl::sizeHint() const
{
return minimumSizeHint();
}
// 最小大小
QSize SwitchControl::minimumSizeHint() const
{
return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin);
}
// 切换状态 - 滑动
void SwitchControl::onTimeout()
{
if (m_bChecked) {
m_nX += 1;
if (m_nX >= width() - m_nHeight*2)
m_timer.stop();
} else {
m_nX -= 1;
if (m_nX <= m_nHeight / 2)
m_timer.stop();
}
update();
}
// 返回开关状态 - 打开true 关闭false
bool SwitchControl::isToggled() const
{
return m_bChecked;
}
// 设置开关状态
void SwitchControl::setToggle(bool checked)
{
m_bChecked = checked;
m_timer.start(10);
}
// 设置背景颜色
void SwitchControl::setBackgroundColor(QColor color)
{
m_background = color;
}
// 设置拇指颜色
void SwitchControl::setthumbColor(QColor color)
{
//拇指颜色
m_thumbColor = color;
}
// 设置选中颜色
void SwitchControl::setCheckedColor(QColor color)
{
m_checkedColor = color;
}
// 设置不可用颜色
void SwitchControl::setDisbaledColor(QColor color)
{
m_disabledColor = color;
}
*/

View File

@ -1,230 +1,230 @@
#ifndef SWITCHCONTROL_H
#define SWITCHCONTROL_H
/**
* :feiyangqingyun(QQ:517216493) 2016-11-6
* 1: ///
* 2:
* 3:
* 4:
* 5:
* 6:
*/
#include <QWidget>
class QTimer;
class SwitchControl: public QWidget
{
Q_OBJECT
public:
enum ButtonStyle {
ButtonStyle_Rect = 0, //圆角矩形
ButtonStyle_CircleIn = 1, //内圆形
ButtonStyle_CircleOut = 2,//外圆形
ButtonStyle_Image = 3 //图片
};
SwitchControl(QWidget *parent = 0);
~SwitchControl();
protected:
void mousePressEvent(QMouseEvent *);
void resizeEvent(QResizeEvent *);
void paintEvent(QPaintEvent *);
void drawBg(QPainter *painter);
void drawSlider(QPainter *painter);
void drawText(QPainter *painter);
void drawImage(QPainter *painter);
private:
bool checked; //是否选中
ButtonStyle buttonStyle; //开关按钮样式
QColor bgColorOff; //关闭时背景颜色
QColor bgColorOn; //打开时背景颜色
QColor sliderColorOff; //关闭时滑块颜色
QColor sliderColorOn; //打开时滑块颜色
QColor textColorOff; //关闭时文本颜色
QColor textColorOn; //打开时文本颜色
QString textOff; //关闭时显示的文字
QString textOn; //打开时显示的文字
QString imageOff; //关闭时显示的图片
QString imageOn; //打开时显示的图片
int space; //滑块离背景间隔
int rectRadius; //圆角角度
int step; //每次移动的步长
int startX; //滑块开始X轴坐标
int endX; //滑块结束X轴坐标
QTimer *timer; //定时器绘制
private slots:
void updateValue();
public:
bool getChecked()const
{
return checked;
}
ButtonStyle getButtonStyle()const
{
return buttonStyle;
}
QColor getBgColorOff()const
{
return bgColorOff;
}
QColor getBgColorOn()const
{
return bgColorOn;
}
QColor getSliderColorOff()const
{
return sliderColorOff;
}
QColor getSliderColorOn()const
{
return sliderColorOn;
}
QColor getTextColorOff()const
{
return textColorOff;
}
QColor getTextColorOn()const
{
return textColorOn;
}
QString getTextOff()const
{
return textOff;
}
QString getTextOn()const
{
return textOn;
}
QString getImageOff()const
{
return imageOff;
}
QString getImageOn()const
{
return imageOn;
}
int getSpace()const
{
return space;
}
int getRectRadius()const
{
return rectRadius;
}
public slots:
//设置是否选中
void setChecked(bool checked);
void setCheckedStatus(bool checked);
//设置风格样式
void setButtonStyle(ButtonStyle buttonStyle);
//设置背景颜色
void setBgColor(QColor bgColorOff, QColor bgColorOn);
//设置滑块颜色
void setSliderColor(QColor sliderColorOff, QColor sliderColorOn);
//设置文本颜色
void setTextColor(QColor textColorOff, QColor textColorOn);
//设置文本
void setText(QString textOff, QString textOn);
//设置背景图片
void setImage(QString imageOff, QString imageOn);
//设置间隔
void setSpace(int space);
//设置圆角角度
void setRectRadius(int rectRadius);
signals:
void checkedChanged(bool checked);
};
/*
#include <QWidget>
#include <QTimer>
class SwitchControl : public QWidget
{
Q_OBJECT
public:
explicit SwitchControl(QWidget *parent = nullptr);
// 返回开关状态 - 打开true 关闭false
bool isToggled() const;
// 设置开关状态
void setToggle(bool checked);
// 设置背景颜色
void setBackgroundColor(QColor color);
// 设置选中颜色
void setCheckedColor(QColor color);
// 设置不可用颜色
void setDisbaledColor(QColor color);
// 设置拇指颜色
void setthumbColor(QColor color);
protected:
// 绘制开关
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
// 鼠标按下事件
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
// 鼠标释放事件 - 切换开关状态、发射toggled()信号
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
// 大小改变事件
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
// 缺省大小
QSize sizeHint() const Q_DECL_OVERRIDE;
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
signals:
// 状态改变时,发射信号
void toggled(bool checked);
private slots:
// 状态切换时,用于产生滑动效果
void onTimeout();
private:
bool m_bChecked=false; //是否选中
QColor m_background; //背景颜色
QColor m_checkedColor; //选中颜色
QColor m_disabledColor; //不可用颜色
QColor m_thumbColor; //拇指颜色
qreal m_radius; //圆角
qreal m_nX; //x点坐标
qreal m_nY; //y点坐标
qint16 m_nHeight=20; //高度
qint16 m_nMargin=5; //外边距
QTimer m_timer; //定时器
};*/
#endif // SWITCHCONTROL_H
#ifndef SWITCHCONTROL_H
#define SWITCHCONTROL_H
/**
* :feiyangqingyun(QQ:517216493) 2016-11-6
* 1: ///
* 2:
* 3:
* 4:
* 5:
* 6:
*/
#include <QWidget>
class QTimer;
class SwitchControl: public QWidget
{
Q_OBJECT
public:
enum ButtonStyle {
ButtonStyle_Rect = 0, //圆角矩形
ButtonStyle_CircleIn = 1, //内圆形
ButtonStyle_CircleOut = 2,//外圆形
ButtonStyle_Image = 3 //图片
};
SwitchControl(QWidget *parent = 0);
~SwitchControl();
protected:
void mousePressEvent(QMouseEvent *);
void resizeEvent(QResizeEvent *);
void paintEvent(QPaintEvent *);
void drawBg(QPainter *painter);
void drawSlider(QPainter *painter);
void drawText(QPainter *painter);
void drawImage(QPainter *painter);
private:
bool checked; //是否选中
ButtonStyle buttonStyle; //开关按钮样式
QColor bgColorOff; //关闭时背景颜色
QColor bgColorOn; //打开时背景颜色
QColor sliderColorOff; //关闭时滑块颜色
QColor sliderColorOn; //打开时滑块颜色
QColor textColorOff; //关闭时文本颜色
QColor textColorOn; //打开时文本颜色
QString textOff; //关闭时显示的文字
QString textOn; //打开时显示的文字
QString imageOff; //关闭时显示的图片
QString imageOn; //打开时显示的图片
int space; //滑块离背景间隔
int rectRadius; //圆角角度
int step; //每次移动的步长
int startX; //滑块开始X轴坐标
int endX; //滑块结束X轴坐标
QTimer *timer; //定时器绘制
private slots:
void updateValue();
public:
bool getChecked()const
{
return checked;
}
ButtonStyle getButtonStyle()const
{
return buttonStyle;
}
QColor getBgColorOff()const
{
return bgColorOff;
}
QColor getBgColorOn()const
{
return bgColorOn;
}
QColor getSliderColorOff()const
{
return sliderColorOff;
}
QColor getSliderColorOn()const
{
return sliderColorOn;
}
QColor getTextColorOff()const
{
return textColorOff;
}
QColor getTextColorOn()const
{
return textColorOn;
}
QString getTextOff()const
{
return textOff;
}
QString getTextOn()const
{
return textOn;
}
QString getImageOff()const
{
return imageOff;
}
QString getImageOn()const
{
return imageOn;
}
int getSpace()const
{
return space;
}
int getRectRadius()const
{
return rectRadius;
}
public slots:
//设置是否选中
void setChecked(bool checked);
void setCheckedStatus(bool checked);
//设置风格样式
void setButtonStyle(ButtonStyle buttonStyle);
//设置背景颜色
void setBgColor(QColor bgColorOff, QColor bgColorOn);
//设置滑块颜色
void setSliderColor(QColor sliderColorOff, QColor sliderColorOn);
//设置文本颜色
void setTextColor(QColor textColorOff, QColor textColorOn);
//设置文本
void setText(QString textOff, QString textOn);
//设置背景图片
void setImage(QString imageOff, QString imageOn);
//设置间隔
void setSpace(int space);
//设置圆角角度
void setRectRadius(int rectRadius);
signals:
void checkedChanged(bool checked);
};
/*
#include <QWidget>
#include <QTimer>
class SwitchControl : public QWidget
{
Q_OBJECT
public:
explicit SwitchControl(QWidget *parent = nullptr);
// 返回开关状态 - 打开true 关闭false
bool isToggled() const;
// 设置开关状态
void setToggle(bool checked);
// 设置背景颜色
void setBackgroundColor(QColor color);
// 设置选中颜色
void setCheckedColor(QColor color);
// 设置不可用颜色
void setDisbaledColor(QColor color);
// 设置拇指颜色
void setthumbColor(QColor color);
protected:
// 绘制开关
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
// 鼠标按下事件
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
// 鼠标释放事件 - 切换开关状态、发射toggled()信号
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
// 大小改变事件
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
// 缺省大小
QSize sizeHint() const Q_DECL_OVERRIDE;
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
signals:
// 状态改变时,发射信号
void toggled(bool checked);
private slots:
// 状态切换时,用于产生滑动效果
void onTimeout();
private:
bool m_bChecked=false; //是否选中
QColor m_background; //背景颜色
QColor m_checkedColor; //选中颜色
QColor m_disabledColor; //不可用颜色
QColor m_thumbColor; //拇指颜色
qreal m_radius; //圆角
qreal m_nX; //x点坐标
qreal m_nY; //y点坐标
qint16 m_nHeight=20; //高度
qint16 m_nMargin=5; //外边距
QTimer m_timer; //定时器
};*/
#endif // SWITCHCONTROL_H

View File

@ -1,18 +0,0 @@
#include "table.h"
int Table::sizeHintForColumn(int column) const {
auto item = horizontalHeaderItem(column);
if(!item) return QTableWidget::sizeHintForColumn(column);
int width = item->data(0x99).toInt();
if(!width) return QTableWidget::sizeHintForColumn(column);
auto header = horizontalHeader();
if(header->sectionResizeMode(column)!=QHeaderView::ResizeToContents) return QTableWidget::sizeHintForColumn(column);
int colCnt = columnCount();
int remainWidth = header->width(), stretchWidth = width;
for(int cc=0; cc<colCnt; cc++) if(cc!=column && (item = horizontalHeaderItem(cc))) {
if(header->sectionResizeMode(cc)==QHeaderView::ResizeToContents) stretchWidth += item->data(0x99).toInt();
else remainWidth -= item->data(0x99).toInt();
}
if(remainWidth<=0) return QTableWidget::sizeHintForColumn(column);
return width * remainWidth / stretchWidth;
}

View File

@ -1,67 +0,0 @@
#ifndef TABLE_H
#define TABLE_H
#include <QTableWidget>
#include <QHeaderView>
struct ColAttr {
QString field;
QString text;
int width{0};
};
class Table : public QTableWidget {
Q_OBJECT
public:
explicit Table(QWidget *parent = nullptr) : QTableWidget{parent} {}
Table(std::initializer_list<ColAttr> colAttrs, QWidget *parent = nullptr) : QTableWidget{0, (int)colAttrs.size(), parent} {
int i = 0;
for(typename std::initializer_list<ColAttr>::const_iterator it = colAttrs.begin(); it != colAttrs.end(); ++it) {
auto item = horizontalHeaderItem(i);
if(!item) {
item = new QTableWidgetItem();
item->setData(0x99, it->width);
setHorizontalHeaderItem(i, item);
}
item->setText(it->text);
if(it->width>0) horizontalHeader()->resizeSection(i, it->width);
mFieldMap.insert(it->field, i++);
}
}
Table *setDefs() {
setSelectionBehavior(QTableWidget::SelectRows);
setEditTriggers(QAbstractItemView::NoEditTriggers);
setAlternatingRowColors(true);
horizontalHeader()->setBackgroundRole(QPalette::Window);
return this;
}
auto item(int row, QString column) {
auto col = mFieldMap[column];
return QTableWidget::item(row, col);
}
void setItem(int row, QString column, QTableWidgetItem *item) {
auto col = mFieldMap[column];
QTableWidget::setItem(row, col, item);
}
void setValue(int row, QString column, const QString &text) {
auto col = mFieldMap[column];
QTableWidget::setItem(row, col, new QTableWidgetItem(text));
}
auto cellWidget(int row, QString column) {
auto col = mFieldMap[column];
return QTableWidget::cellWidget(row, col);
}
void setCellWidget(int row, QString column, QWidget *widget) {
auto col = mFieldMap[column];
QTableWidget::setCellWidget(row, col, widget);
}
QMap<QString,int> mFieldMap;
protected:
int sizeHintForColumn(int column) const override;
};
#endif // TABLE_H

View File

@ -1,472 +1,472 @@
#include "taesclass.h"
Aes::~Aes()
{
}
Aes::Aes()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
//构造函数
Aes::Aes(int keysize,unsigned char* keyBytes)
{
SetNbNkNr(keysize); //设置密钥块数,轮数
memcpy(key,keyBytes,keysize); //字符串拷贝函数把keyBytes的keysize个字符复制到key中
KeyExpansion(); //密钥扩展,必须提前做的初始化
}
////////////////////////////////////////////////////////////////////////////////////////////////
void Aes::SetNbNkNr(int keySize)
{
Nb=4;
if(keySize==Bits128)
{
Nk=4; //4*4字节128位密钥10轮加密
Nr=10;
}
else if(keySize==Bits192)
{
Nk=6; //6*4字节192位密钥12轮加密
Nr=12;
}
else if(keySize==Bits256)
{
Nk=8; //8*4字节256位密钥14轮加密
Nr=14;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void Aes::KeyExpansion()
{
memset(w,0,16*15);
for(int row=0;row<Nk;row++) //拷贝seed 密钥
{
w[4*row+0] = key[4*row];
w[4*row+1] = key[4*row+1];
w[4*row+2] = key[4*row+2];
w[4*row+3] = key[4*row+3];
}
byte* temp = new byte[4];
for(int row=Nk;row<4*(Nr+1);row++)
{
temp[0]=w[4*row-4]; //当前列的前一列
temp[1]=w[4*row-3];
temp[2]=w[4*row-2];
temp[3]=w[4*row-1];
if(row%Nk==0) //逢nk时对当前列的前一列作特殊处理
{
temp=SubWord(RotWord(temp)); //先移位,再代换,最后和轮常量异或
temp[0] = (byte)( (int)temp[0] ^ (int) AesRcon[4*(row/Nk)+0] );
temp[1] = (byte)( (int)temp[1] ^ (int) AesRcon[4*(row/Nk)+1] );
temp[2] = (byte)( (int)temp[2] ^ (int) AesRcon[4*(row/Nk)+2] );
temp[3] = (byte)( (int)temp[3] ^ (int) AesRcon[4*(row/Nk)+3] );
}
else if ( Nk > 6 && (row % Nk == 4) ) //这个还没有搞清楚
{
temp = SubWord(temp);
}
// w[row] = w[row-Nk] xor temp
w[4*row+0] = (byte) ( (int) w[4*(row-Nk)+0] ^ (int)temp[0] );
w[4*row+1] = (byte) ( (int) w[4*(row-Nk)+1] ^ (int)temp[1] );
w[4*row+2] = (byte) ( (int) w[4*(row-Nk)+2] ^ (int)temp[2] );
w[4*row+3] = (byte) ( (int) w[4*(row-Nk)+3] ^ (int)temp[3] );
} // for loop
}
////////////////////////////////////////////////////////////////////////////////////////////////
//密钥移位函数
unsigned char* Aes::RotWord(unsigned char* word)
{
byte* temp = new byte[4];
temp[0] = word[1];
temp[1] = word[2];
temp[2] = word[3];
temp[3] = word[0];
return temp;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//密钥字代换函数
unsigned char* Aes::SubWord(unsigned char* word)
{
byte* temp = new byte[4];
for(int j=0;j<4;j++)
{
temp[j] = AesSbox[16*(word[j] >> 4)+(word[j] & 0x0f)]; //实际上也可以写成AesSbox[[j]];因为两者相等
}
return temp;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//Aes加密函数
void Aes::Cipher(unsigned char* input, unsigned char* output)
{
memset(&State[0][0],0,16);
for(int i=0;i<4*Nb;i++) //这里是先写列后写行的,即输入是一列一列的进来的
{
State[i%4][i/4]=input[i]; //换成先写行后写列也是可以的,只要在输出时也是这样就可以了
}
AddRoundKey(0); //轮密钥加
for (int round = 1; round <= (Nr - 1); round++) // main round loop
{
SubBytes(); //字节代换
ShiftRows(); //行移位
MixColumns(); //列混淆
AddRoundKey(round); //轮密钥加
} // main round loop
SubBytes(); //字节代换
ShiftRows(); //行移位
AddRoundKey(Nr); //轮密钥加
// output = state
for (int i = 0; i < (4 * Nb); i++)
{
output[i] = State[i % 4][ i / 4];
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//Aes解密函数
void Aes::InvCipher(unsigned char* input,unsigned char* output)
{
memset(&State[0][0],0,16);
for (int i = 0; i < (4 * Nb); i++)
{
State[i % 4][ i / 4] = input[i];
}
AddRoundKey(Nr);
for (int round = Nr-1; round >= 1; round--) // main round loop
{
InvShiftRows();
InvSubBytes();
AddRoundKey(round);
InvMixColumns();
} // end main round loop for InvCipher
InvShiftRows();
InvSubBytes();
AddRoundKey(0);
// output = state
for (int i = 0; i < (4 * Nb); i++)
{
output[i] = State[i % 4][ i / 4];
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//轮密钥加
void Aes::AddRoundKey(int round)
{
int i,j; //i行 j列 //因为密钥w是一列一列排列的即 k0 k4 k8 k12
for(j=0;j<4;j++) // k1 k5 k9 k13
{ // k2 k6 k10k14
for(i=0;i<4;i++) // k3 k7 k11k15
{ // 所以i行j列的下标是4*((round*4)+j)+i即16*round+4*j+i
State[i][j]=(unsigned char)((int)State[i][j]^(int)w[4*((round*4)+j)+i]);
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//字节代换函数
void Aes::SubBytes() //Page 103
{
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
State[i][j]=AesSbox[State[i][j]];
//因为 16*(State[i][j]>>4)+State[i][j]&0x0f=State[i][j]
}
}
}
void Aes::InvSubBytes()
{
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
State[i][j]=AesiSbox[State[i][j]]; //因为 16*(State[i][j]>>4)+State[i][j]&0x0f=State[i][j]
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void Aes::ShiftRows()
{
unsigned char temp[4*4]; //Page105
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
temp[4*i+j]=State[i][j];
}
}
for(i=1;i<4;i++)
{
for(j=0;j<4;j++)
{
if(i==1)State[i][j]=temp[4*i+(j+1)%4]; //第一行左移1位
else if(i==2)State[i][j]=temp[4*i+(j+2)%4]; //第二行左移2位
else if(i==3)State[i][j]=temp[4*i+(j+3)%4]; //第三行左移3位
}
}
}
void Aes::InvShiftRows()
{
unsigned char temp[4*4];
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
temp[4*i+j]=State[i][j];
}
}
for(i=1;i<4;i++)
{
for(j=0;j<4;j++)
{
//if(i==1)State[i][j]=temp[4*i+(j-1)%4]; 在此犯了一个错误 -1%4=-1 而不是3所以采用了下面再加一个4的做法
if(i==1)State[i][j]=temp[4*i+(j+3)%4]; //第一行右移1位 j-1+4=j+3
else if(i==2)State[i][j]=temp[4*i+(j+2)%4]; //第二行右移2位 j-2+4=j+2
else if(i==3)State[i][j]=temp[4*i+(j+1)%4]; //第三行右移3位 j-3+4=j+2
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void Aes::MixColumns()
{
unsigned char temp[4*4];
int i,j;
for(j=0;j<4;j++) //2 3 1 1 列混淆矩阵 Page107
{ //1 2 3 1
for(i=0;i<4;i++) //1 1 2 3
{ //3 1 1 2
temp[4*i+j]=State[i][j];
}
}
for(j=0;j<4;j++)
{
State[0][j] = (unsigned char) ( (int)gfmultby02(temp[0+j]) ^ (int)gfmultby03(temp[4*1+j]) ^
(int)gfmultby01(temp[4*2+j]) ^ (int)gfmultby01(temp[4*3+j]) );
State[1][j] = (unsigned char) ( (int)gfmultby01(temp[0+j]) ^ (int)gfmultby02(temp[4*1+j]) ^
(int)gfmultby03(temp[4*2+j]) ^ (int)gfmultby01(temp[4*3+j]) );
State[2][j] = (unsigned char) ( (int)gfmultby01(temp[0+j]) ^ (int)gfmultby01(temp[4*1+j]) ^
(int)gfmultby02(temp[4*2+j]) ^ (int)gfmultby03(temp[4*3+j]) );
State[3][j] = (unsigned char) ( (int)gfmultby03(temp[0+j]) ^ (int)gfmultby01(temp[4*1+j]) ^
(int)gfmultby01(temp[4*2+j]) ^ (int)gfmultby02(temp[4*3+j]) );
}
}
void Aes::InvMixColumns()
{
unsigned char temp[4*4];
int i,j;
for (i = 0; i < 4; i++) // copy State into temp[]
{
for (j = 0; j < 4; j++) //0e 0b 0d 09 逆变换矩阵 Page108
{ //09 0e 0b 0d
temp[4*i+j] = State[i][j]; //0d 09 0e 0b
} //0b 0d 09 0e
}
for (j = 0; j < 4; j++)
{
State[0][j] = (unsigned char) ( (int)gfmultby0e(temp[j]) ^ (int)gfmultby0b(temp[4+j]) ^
(int)gfmultby0d(temp[4*2+j]) ^ (int)gfmultby09(temp[4*3+j]) );
State[1][j] = (unsigned char) ( (int)gfmultby09(temp[j]) ^ (int)gfmultby0e(temp[4+j]) ^
(int)gfmultby0b(temp[4*2+j]) ^ (int)gfmultby0d(temp[4*3+j]) );
State[2][j] = (unsigned char) ( (int)gfmultby0d(temp[j]) ^ (int)gfmultby09(temp[4+j]) ^
(int)gfmultby0e(temp[4*2+j]) ^ (int)gfmultby0b(temp[4*3+j]) );
State[3][j] = (unsigned char) ( (int)gfmultby0b(temp[j]) ^ (int)gfmultby0d(temp[4+j]) ^
(int)gfmultby09(temp[4*2+j]) ^ (int)gfmultby0e(temp[4*3+j]) );
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char Aes::gfmultby01(unsigned char b)
{
return b;
}
unsigned char Aes::gfmultby02(unsigned char b)
{
if (b < 0x80)
return (unsigned char)(int)(b <<1);
else
return (unsigned char)( (int)(b << 1) ^ (int)(0x1b) );
}
unsigned char Aes::gfmultby03(unsigned char b)
{
return (unsigned char) ( (int)gfmultby02(b) ^ (int)b );
}
unsigned char Aes::gfmultby09(unsigned char b)
{
return (unsigned char)( (int)gfmultby02(gfmultby02(gfmultby02(b))) ^ (int)b );
}
unsigned char Aes::gfmultby0b(unsigned char b)
{
return (unsigned char)( (int)gfmultby02(gfmultby02(gfmultby02(b))) ^
(int)gfmultby02(b) ^ (int)b );
}
unsigned char Aes::gfmultby0d(unsigned char b)
{
return (unsigned char)( (int)gfmultby02(gfmultby02(gfmultby02(b))) ^
(int)gfmultby02(gfmultby02(b)) ^ (int)(b) );
}
unsigned char Aes::gfmultby0e(unsigned char b)
{
return (unsigned char)( (int)gfmultby02(gfmultby02(gfmultby02(b))) ^
(int)gfmultby02(gfmultby02(b)) ^(int)gfmultby02(b) );
}
TAesClass::TAesClass()
{
m_lpAes=NULL;
InitializePrivateKey(16,(unsigned char*)"\x79\x76\x68\x6B\x77\x66\x6E\x68\x72\x65\x73\x63\x6C\x6B\x70\x6E");
}
TAesClass::~TAesClass()
{
if (m_lpAes!=NULL)
{
delete m_lpAes;
}
}
//------------------------------------------------------------------------------------------------------------
// 编写人员wfnhddd
//
// 函数名称InitializeAes
//
// 函数描述初始化AES 密钥,密钥用于加密解密
//
// 调用参数:详细说明参考 MSDN 中的相关描述或相关的开发文档
//
// 返回数值:无
//
// 最近修改2009 年 08 月 07 日
//------------------------------------------------------------------------------------------------------------
VOID TAesClass::InitializePrivateKey(DWORD KeySize,UCHAR *KeyBytes)
{
if (m_lpAes)
{
delete m_lpAes;
m_lpAes=NULL;
}
m_lpAes=new Aes(KeySize,KeyBytes);
}
//------------------------------------------------------------------------------------------------------------
// 编写人员wfnhddd
//
// 函数名称OnAesEncrypt
//
// 函数描述用AES加密算法加密数据
//
// 调用参数:详细说明参考 MSDN 中的相关描述或相关的开发文档
//
// 返回数值:加密后的数据大小 ,错误返回值 0
//
// 最近修改2009 年 08 月 07 日
//------------------------------------------------------------------------------------------------------------
DWORD TAesClass::OnAesEncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer)
{
DWORD OutLength=0;
if (m_lpAes==NULL||OutBuffer==NULL)
{
return 0;
}
UCHAR *lpCurInBuff=(UCHAR *)InBuffer;
UCHAR *lpCurOutBuff=(UCHAR *)OutBuffer;
long blocknum=InLength/16;
long leftnum=InLength%16;
for(long i=0;i<blocknum;i++)
{
m_lpAes->Cipher(lpCurInBuff,lpCurOutBuff);
lpCurInBuff+=16;
lpCurOutBuff+=16;
OutLength+=16;
}
if(leftnum) //多余出leftnum 字节 则加密时 多出16-leftnum 个字节
{
UCHAR inbuff[16];
memset(inbuff,0,16);
memcpy(inbuff,lpCurInBuff,leftnum);
m_lpAes->Cipher(inbuff,lpCurOutBuff);
lpCurOutBuff+=16;
OutLength+=16;
}
//新增16个字节用以确定增加的字节数
UCHAR extrabuff[16];
memset(extrabuff,0,16);
*((LPDWORD)extrabuff)=16+(16-leftnum)%16; //多出16+(16-leftnum)%16个字节
m_lpAes->Cipher(extrabuff,lpCurOutBuff);
OutLength+=16;
return OutLength;
}
//------------------------------------------------------------------------------------------------------------
// 编写人员wfnhddd
//
// 函数名称OnAesUncrypt
//
// 函数描述用AES加密算法解密数据
//
// 调用参数:详细说明参考 MSDN 中的相关描述或相关的开发文档
//
// 返回数值:解密后的数据大小 ,错误返回值 0
//
// 最近修改2009 年 08 月 07 日
//------------------------------------------------------------------------------------------------------------
DWORD TAesClass::OnAesUncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer)
{
DWORD OutLength=0;
if (m_lpAes==NULL||OutBuffer==NULL)
{
return 0;
}
UCHAR *lpCurInBuff=(UCHAR *)InBuffer;
UCHAR *lpCurOutBuff=(UCHAR *)OutBuffer;
long blocknum=InLength/16;
long leftnum=InLength%16;
if(leftnum)
{
return 0;
}
for(long i=0;i<blocknum;i++)
{
m_lpAes->InvCipher(lpCurInBuff,lpCurOutBuff);
lpCurInBuff+=16;
lpCurOutBuff+=16;
OutLength+=16;
}
UCHAR *lpExtraInBuff=lpCurOutBuff-16;
DWORD dwExtraBytes=*((LPDWORD)lpExtraInBuff);
return (OutLength-dwExtraBytes);
}
#include "taesclass.h"
Aes::~Aes()
{
}
Aes::Aes()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
//构造函数
Aes::Aes(int keysize,unsigned char* keyBytes)
{
SetNbNkNr(keysize); //设置密钥块数,轮数
memcpy(key,keyBytes,keysize); //字符串拷贝函数把keyBytes的keysize个字符复制到key中
KeyExpansion(); //密钥扩展,必须提前做的初始化
}
////////////////////////////////////////////////////////////////////////////////////////////////
void Aes::SetNbNkNr(int keySize)
{
Nb=4;
if(keySize==Bits128)
{
Nk=4; //4*4字节128位密钥10轮加密
Nr=10;
}
else if(keySize==Bits192)
{
Nk=6; //6*4字节192位密钥12轮加密
Nr=12;
}
else if(keySize==Bits256)
{
Nk=8; //8*4字节256位密钥14轮加密
Nr=14;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void Aes::KeyExpansion()
{
memset(w,0,16*15);
for(int row=0;row<Nk;row++) //拷贝seed 密钥
{
w[4*row+0] = key[4*row];
w[4*row+1] = key[4*row+1];
w[4*row+2] = key[4*row+2];
w[4*row+3] = key[4*row+3];
}
byte* temp = new byte[4];
for(int row=Nk;row<4*(Nr+1);row++)
{
temp[0]=w[4*row-4]; //当前列的前一列
temp[1]=w[4*row-3];
temp[2]=w[4*row-2];
temp[3]=w[4*row-1];
if(row%Nk==0) //逢nk时对当前列的前一列作特殊处理
{
temp=SubWord(RotWord(temp)); //先移位,再代换,最后和轮常量异或
temp[0] = (byte)( (int)temp[0] ^ (int) AesRcon[4*(row/Nk)+0] );
temp[1] = (byte)( (int)temp[1] ^ (int) AesRcon[4*(row/Nk)+1] );
temp[2] = (byte)( (int)temp[2] ^ (int) AesRcon[4*(row/Nk)+2] );
temp[3] = (byte)( (int)temp[3] ^ (int) AesRcon[4*(row/Nk)+3] );
}
else if ( Nk > 6 && (row % Nk == 4) ) //这个还没有搞清楚
{
temp = SubWord(temp);
}
// w[row] = w[row-Nk] xor temp
w[4*row+0] = (byte) ( (int) w[4*(row-Nk)+0] ^ (int)temp[0] );
w[4*row+1] = (byte) ( (int) w[4*(row-Nk)+1] ^ (int)temp[1] );
w[4*row+2] = (byte) ( (int) w[4*(row-Nk)+2] ^ (int)temp[2] );
w[4*row+3] = (byte) ( (int) w[4*(row-Nk)+3] ^ (int)temp[3] );
} // for loop
}
////////////////////////////////////////////////////////////////////////////////////////////////
//密钥移位函数
unsigned char* Aes::RotWord(unsigned char* word)
{
byte* temp = new byte[4];
temp[0] = word[1];
temp[1] = word[2];
temp[2] = word[3];
temp[3] = word[0];
return temp;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//密钥字代换函数
unsigned char* Aes::SubWord(unsigned char* word)
{
byte* temp = new byte[4];
for(int j=0;j<4;j++)
{
temp[j] = AesSbox[16*(word[j] >> 4)+(word[j] & 0x0f)]; //实际上也可以写成AesSbox[[j]];因为两者相等
}
return temp;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//Aes加密函数
void Aes::Cipher(unsigned char* input, unsigned char* output)
{
memset(&State[0][0],0,16);
for(int i=0;i<4*Nb;i++) //这里是先写列后写行的,即输入是一列一列的进来的
{
State[i%4][i/4]=input[i]; //换成先写行后写列也是可以的,只要在输出时也是这样就可以了
}
AddRoundKey(0); //轮密钥加
for (int round = 1; round <= (Nr - 1); round++) // main round loop
{
SubBytes(); //字节代换
ShiftRows(); //行移位
MixColumns(); //列混淆
AddRoundKey(round); //轮密钥加
} // main round loop
SubBytes(); //字节代换
ShiftRows(); //行移位
AddRoundKey(Nr); //轮密钥加
// output = state
for (int i = 0; i < (4 * Nb); i++)
{
output[i] = State[i % 4][ i / 4];
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//Aes解密函数
void Aes::InvCipher(unsigned char* input,unsigned char* output)
{
memset(&State[0][0],0,16);
for (int i = 0; i < (4 * Nb); i++)
{
State[i % 4][ i / 4] = input[i];
}
AddRoundKey(Nr);
for (int round = Nr-1; round >= 1; round--) // main round loop
{
InvShiftRows();
InvSubBytes();
AddRoundKey(round);
InvMixColumns();
} // end main round loop for InvCipher
InvShiftRows();
InvSubBytes();
AddRoundKey(0);
// output = state
for (int i = 0; i < (4 * Nb); i++)
{
output[i] = State[i % 4][ i / 4];
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//轮密钥加
void Aes::AddRoundKey(int round)
{
int i,j; //i行 j列 //因为密钥w是一列一列排列的即 k0 k4 k8 k12
for(j=0;j<4;j++) // k1 k5 k9 k13
{ // k2 k6 k10k14
for(i=0;i<4;i++) // k3 k7 k11k15
{ // 所以i行j列的下标是4*((round*4)+j)+i即16*round+4*j+i
State[i][j]=(unsigned char)((int)State[i][j]^(int)w[4*((round*4)+j)+i]);
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//字节代换函数
void Aes::SubBytes() //Page 103
{
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
State[i][j]=AesSbox[State[i][j]];
//因为 16*(State[i][j]>>4)+State[i][j]&0x0f=State[i][j]
}
}
}
void Aes::InvSubBytes()
{
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
State[i][j]=AesiSbox[State[i][j]]; //因为 16*(State[i][j]>>4)+State[i][j]&0x0f=State[i][j]
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void Aes::ShiftRows()
{
unsigned char temp[4*4]; //Page105
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
temp[4*i+j]=State[i][j];
}
}
for(i=1;i<4;i++)
{
for(j=0;j<4;j++)
{
if(i==1)State[i][j]=temp[4*i+(j+1)%4]; //第一行左移1位
else if(i==2)State[i][j]=temp[4*i+(j+2)%4]; //第二行左移2位
else if(i==3)State[i][j]=temp[4*i+(j+3)%4]; //第三行左移3位
}
}
}
void Aes::InvShiftRows()
{
unsigned char temp[4*4];
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
temp[4*i+j]=State[i][j];
}
}
for(i=1;i<4;i++)
{
for(j=0;j<4;j++)
{
//if(i==1)State[i][j]=temp[4*i+(j-1)%4]; 在此犯了一个错误 -1%4=-1 而不是3所以采用了下面再加一个4的做法
if(i==1)State[i][j]=temp[4*i+(j+3)%4]; //第一行右移1位 j-1+4=j+3
else if(i==2)State[i][j]=temp[4*i+(j+2)%4]; //第二行右移2位 j-2+4=j+2
else if(i==3)State[i][j]=temp[4*i+(j+1)%4]; //第三行右移3位 j-3+4=j+2
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void Aes::MixColumns()
{
unsigned char temp[4*4];
int i,j;
for(j=0;j<4;j++) //2 3 1 1 列混淆矩阵 Page107
{ //1 2 3 1
for(i=0;i<4;i++) //1 1 2 3
{ //3 1 1 2
temp[4*i+j]=State[i][j];
}
}
for(j=0;j<4;j++)
{
State[0][j] = (unsigned char) ( (int)gfmultby02(temp[0+j]) ^ (int)gfmultby03(temp[4*1+j]) ^
(int)gfmultby01(temp[4*2+j]) ^ (int)gfmultby01(temp[4*3+j]) );
State[1][j] = (unsigned char) ( (int)gfmultby01(temp[0+j]) ^ (int)gfmultby02(temp[4*1+j]) ^
(int)gfmultby03(temp[4*2+j]) ^ (int)gfmultby01(temp[4*3+j]) );
State[2][j] = (unsigned char) ( (int)gfmultby01(temp[0+j]) ^ (int)gfmultby01(temp[4*1+j]) ^
(int)gfmultby02(temp[4*2+j]) ^ (int)gfmultby03(temp[4*3+j]) );
State[3][j] = (unsigned char) ( (int)gfmultby03(temp[0+j]) ^ (int)gfmultby01(temp[4*1+j]) ^
(int)gfmultby01(temp[4*2+j]) ^ (int)gfmultby02(temp[4*3+j]) );
}
}
void Aes::InvMixColumns()
{
unsigned char temp[4*4];
int i,j;
for (i = 0; i < 4; i++) // copy State into temp[]
{
for (j = 0; j < 4; j++) //0e 0b 0d 09 逆变换矩阵 Page108
{ //09 0e 0b 0d
temp[4*i+j] = State[i][j]; //0d 09 0e 0b
} //0b 0d 09 0e
}
for (j = 0; j < 4; j++)
{
State[0][j] = (unsigned char) ( (int)gfmultby0e(temp[j]) ^ (int)gfmultby0b(temp[4+j]) ^
(int)gfmultby0d(temp[4*2+j]) ^ (int)gfmultby09(temp[4*3+j]) );
State[1][j] = (unsigned char) ( (int)gfmultby09(temp[j]) ^ (int)gfmultby0e(temp[4+j]) ^
(int)gfmultby0b(temp[4*2+j]) ^ (int)gfmultby0d(temp[4*3+j]) );
State[2][j] = (unsigned char) ( (int)gfmultby0d(temp[j]) ^ (int)gfmultby09(temp[4+j]) ^
(int)gfmultby0e(temp[4*2+j]) ^ (int)gfmultby0b(temp[4*3+j]) );
State[3][j] = (unsigned char) ( (int)gfmultby0b(temp[j]) ^ (int)gfmultby0d(temp[4+j]) ^
(int)gfmultby09(temp[4*2+j]) ^ (int)gfmultby0e(temp[4*3+j]) );
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char Aes::gfmultby01(unsigned char b)
{
return b;
}
unsigned char Aes::gfmultby02(unsigned char b)
{
if (b < 0x80)
return (unsigned char)(int)(b <<1);
else
return (unsigned char)( (int)(b << 1) ^ (int)(0x1b) );
}
unsigned char Aes::gfmultby03(unsigned char b)
{
return (unsigned char) ( (int)gfmultby02(b) ^ (int)b );
}
unsigned char Aes::gfmultby09(unsigned char b)
{
return (unsigned char)( (int)gfmultby02(gfmultby02(gfmultby02(b))) ^ (int)b );
}
unsigned char Aes::gfmultby0b(unsigned char b)
{
return (unsigned char)( (int)gfmultby02(gfmultby02(gfmultby02(b))) ^
(int)gfmultby02(b) ^ (int)b );
}
unsigned char Aes::gfmultby0d(unsigned char b)
{
return (unsigned char)( (int)gfmultby02(gfmultby02(gfmultby02(b))) ^
(int)gfmultby02(gfmultby02(b)) ^ (int)(b) );
}
unsigned char Aes::gfmultby0e(unsigned char b)
{
return (unsigned char)( (int)gfmultby02(gfmultby02(gfmultby02(b))) ^
(int)gfmultby02(gfmultby02(b)) ^(int)gfmultby02(b) );
}
TAesClass::TAesClass()
{
m_lpAes=NULL;
InitializePrivateKey(16,(unsigned char*)"\x79\x76\x68\x6B\x77\x66\x6E\x68\x72\x65\x73\x63\x6C\x6B\x70\x6E");
}
TAesClass::~TAesClass()
{
if (m_lpAes!=NULL)
{
delete m_lpAes;
}
}
//------------------------------------------------------------------------------------------------------------
// 编写人员wfnhddd
//
// 函数名称InitializeAes
//
// 函数描述初始化AES 密钥,密钥用于加密解密
//
// 调用参数:详细说明参考 MSDN 中的相关描述或相关的开发文档
//
// 返回数值:无
//
// 最近修改2009 年 08 月 07 日
//------------------------------------------------------------------------------------------------------------
VOID TAesClass::InitializePrivateKey(DWORD KeySize,UCHAR *KeyBytes)
{
if (m_lpAes)
{
delete m_lpAes;
m_lpAes=NULL;
}
m_lpAes=new Aes(KeySize,KeyBytes);
}
//------------------------------------------------------------------------------------------------------------
// 编写人员wfnhddd
//
// 函数名称OnAesEncrypt
//
// 函数描述用AES加密算法加密数据
//
// 调用参数:详细说明参考 MSDN 中的相关描述或相关的开发文档
//
// 返回数值:加密后的数据大小 ,错误返回值 0
//
// 最近修改2009 年 08 月 07 日
//------------------------------------------------------------------------------------------------------------
DWORD TAesClass::OnAesEncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer)
{
DWORD OutLength=0;
if (m_lpAes==NULL||OutBuffer==NULL)
{
return 0;
}
UCHAR *lpCurInBuff=(UCHAR *)InBuffer;
UCHAR *lpCurOutBuff=(UCHAR *)OutBuffer;
long blocknum=InLength/16;
long leftnum=InLength%16;
for(long i=0;i<blocknum;i++)
{
m_lpAes->Cipher(lpCurInBuff,lpCurOutBuff);
lpCurInBuff+=16;
lpCurOutBuff+=16;
OutLength+=16;
}
if(leftnum) //多余出leftnum 字节 则加密时 多出16-leftnum 个字节
{
UCHAR inbuff[16];
memset(inbuff,0,16);
memcpy(inbuff,lpCurInBuff,leftnum);
m_lpAes->Cipher(inbuff,lpCurOutBuff);
lpCurOutBuff+=16;
OutLength+=16;
}
//新增16个字节用以确定增加的字节数
UCHAR extrabuff[16];
memset(extrabuff,0,16);
*((LPDWORD)extrabuff)=16+(16-leftnum)%16; //多出16+(16-leftnum)%16个字节
m_lpAes->Cipher(extrabuff,lpCurOutBuff);
OutLength+=16;
return OutLength;
}
//------------------------------------------------------------------------------------------------------------
// 编写人员wfnhddd
//
// 函数名称OnAesUncrypt
//
// 函数描述用AES加密算法解密数据
//
// 调用参数:详细说明参考 MSDN 中的相关描述或相关的开发文档
//
// 返回数值:解密后的数据大小 ,错误返回值 0
//
// 最近修改2009 年 08 月 07 日
//------------------------------------------------------------------------------------------------------------
DWORD TAesClass::OnAesUncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer)
{
DWORD OutLength=0;
if (m_lpAes==NULL||OutBuffer==NULL)
{
return 0;
}
UCHAR *lpCurInBuff=(UCHAR *)InBuffer;
UCHAR *lpCurOutBuff=(UCHAR *)OutBuffer;
long blocknum=InLength/16;
long leftnum=InLength%16;
if(leftnum)
{
return 0;
}
for(long i=0;i<blocknum;i++)
{
m_lpAes->InvCipher(lpCurInBuff,lpCurOutBuff);
lpCurInBuff+=16;
lpCurOutBuff+=16;
OutLength+=16;
}
UCHAR *lpExtraInBuff=lpCurOutBuff-16;
DWORD dwExtraBytes=*((LPDWORD)lpExtraInBuff);
return (OutLength-dwExtraBytes);
}

View File

@ -1,133 +1,133 @@
#ifndef TAESCLASS_H
#define TAESCLASS_H
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef unsigned long DWORD;
typedef unsigned char UCHAR,*PUCHAR;
typedef void *PVOID,*LPVOID;
typedef unsigned char byte;
typedef DWORD *PDWORD,*LPDWORD;
#ifndef VOID
#define VOID void
#endif
//#pragma once
//enum KeySize { Bits128, Bits192, Bits256 }; // key size, in bits, for construtor
#define Bits128 16
#define Bits192 24
#define Bits256 32
unsigned char AesSbox[16*16]=
{// populate the Sbox matrix
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/*0*/ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
/*1*/ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
/*2*/ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
/*3*/ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
/*4*/ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
/*5*/ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
/*6*/ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
/*7*/ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
/*8*/ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
/*9*/ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
/*a*/ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
/*b*/ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
/*c*/ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
/*d*/ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
/*e*/ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
/*f*/ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
unsigned char AesiSbox[16*16]=
{
// populate the iSbox matrix
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/*0*/ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
/*1*/ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
/*2*/ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
/*3*/ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
/*4*/ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
/*5*/ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
/*6*/ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
/*7*/ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
/*8*/ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
/*9*/ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
/*a*/ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
/*b*/ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
/*c*/ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
/*d*/ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
/*e*/ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
/*f*/ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
unsigned char AesRcon[11*4]=
{
0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00,
0x36, 0x00, 0x00, 0x00
};
class Aes // Advanced Encryption Standard
{
public:
~Aes();
Aes();
Aes(int keySize, unsigned char* keyBytes);
unsigned char State[4][4];
void Cipher(unsigned char* input, unsigned char* output); // encipher 16-bit input
void InvCipher(unsigned char* input, unsigned char* output); // decipher 16-bit input
private:
int Nb; // block size in 32-bit words. Always 4 for AES. (128 bits).
int Nk; // key size in 32-bit words. 4, 6, 8. (128, 192, 256 bits).
int Nr; // number of rounds. 10, 12, 14.
unsigned char key[32];
unsigned char w[16*15];
void SetNbNkNr(int keySize);
void AddRoundKey(int round); //轮密钥加
void SubBytes(); //S盒字节代换
void InvSubBytes(); //逆S盒字节代换
void ShiftRows(); //行移位
void InvShiftRows();
void MixColumns(); //列混淆
void InvMixColumns();
unsigned char gfmultby01(unsigned char b);
unsigned char gfmultby02(unsigned char b);
unsigned char gfmultby03(unsigned char b);
unsigned char gfmultby09(unsigned char b);
unsigned char gfmultby0b(unsigned char b);
unsigned char gfmultby0d(unsigned char b);
unsigned char gfmultby0e(unsigned char b);
void KeyExpansion(); //密钥扩展
unsigned char* SubWord(unsigned char* word); //密钥S盒字代换
unsigned char* RotWord(unsigned char* word); //密钥移位
};
class TAesClass
{
public:
TAesClass();
~TAesClass();
void InitializePrivateKey(DWORD KeySize,UCHAR *KeyBytes); //AES 密钥初始化
DWORD OnAesEncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer); //AES 加密数据
DWORD OnAesUncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer); //AES 解密数据
private:
Aes * m_lpAes;
};
#endif
#ifndef TAESCLASS_H
#define TAESCLASS_H
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef unsigned long DWORD;
typedef unsigned char UCHAR,*PUCHAR;
typedef void *PVOID,*LPVOID;
typedef unsigned char byte;
typedef DWORD *PDWORD,*LPDWORD;
#ifndef VOID
#define VOID void
#endif
//#pragma once
//enum KeySize { Bits128, Bits192, Bits256 }; // key size, in bits, for construtor
#define Bits128 16
#define Bits192 24
#define Bits256 32
unsigned char AesSbox[16*16]=
{// populate the Sbox matrix
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/*0*/ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
/*1*/ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
/*2*/ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
/*3*/ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
/*4*/ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
/*5*/ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
/*6*/ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
/*7*/ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
/*8*/ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
/*9*/ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
/*a*/ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
/*b*/ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
/*c*/ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
/*d*/ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
/*e*/ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
/*f*/ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
unsigned char AesiSbox[16*16]=
{
// populate the iSbox matrix
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/*0*/ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
/*1*/ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
/*2*/ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
/*3*/ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
/*4*/ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
/*5*/ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
/*6*/ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
/*7*/ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
/*8*/ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
/*9*/ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
/*a*/ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
/*b*/ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
/*c*/ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
/*d*/ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
/*e*/ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
/*f*/ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
unsigned char AesRcon[11*4]=
{
0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00,
0x36, 0x00, 0x00, 0x00
};
class Aes // Advanced Encryption Standard
{
public:
~Aes();
Aes();
Aes(int keySize, unsigned char* keyBytes);
unsigned char State[4][4];
void Cipher(unsigned char* input, unsigned char* output); // encipher 16-bit input
void InvCipher(unsigned char* input, unsigned char* output); // decipher 16-bit input
private:
int Nb; // block size in 32-bit words. Always 4 for AES. (128 bits).
int Nk; // key size in 32-bit words. 4, 6, 8. (128, 192, 256 bits).
int Nr; // number of rounds. 10, 12, 14.
unsigned char key[32];
unsigned char w[16*15];
void SetNbNkNr(int keySize);
void AddRoundKey(int round); //轮密钥加
void SubBytes(); //S盒字节代换
void InvSubBytes(); //逆S盒字节代换
void ShiftRows(); //行移位
void InvShiftRows();
void MixColumns(); //列混淆
void InvMixColumns();
unsigned char gfmultby01(unsigned char b);
unsigned char gfmultby02(unsigned char b);
unsigned char gfmultby03(unsigned char b);
unsigned char gfmultby09(unsigned char b);
unsigned char gfmultby0b(unsigned char b);
unsigned char gfmultby0d(unsigned char b);
unsigned char gfmultby0e(unsigned char b);
void KeyExpansion(); //密钥扩展
unsigned char* SubWord(unsigned char* word); //密钥S盒字代换
unsigned char* RotWord(unsigned char* word); //密钥移位
};
class TAesClass
{
public:
TAesClass();
~TAesClass();
void InitializePrivateKey(DWORD KeySize,UCHAR *KeyBytes); //AES 密钥初始化
DWORD OnAesEncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer); //AES 加密数据
DWORD OnAesUncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer); //AES 解密数据
private:
Aes * m_lpAes;
};
#endif

View File

@ -1,81 +1,81 @@
#include "updateledset3dialog.h"
#include "ui_updateledset3dialog.h"
#include <QSettings>
#include <cfg.h>
extern const QString DEFS_LEDSET_URL = "https://www.ledok.cn/download/definitions/ledset3updates.json";
UpdateLedset3Dialog::UpdateLedset3Dialog(QWidget *parent) :
BaseDlg(parent),
ui(new Ui::UpdateLedset3Dialog)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
ui->pushButton_2->setVisible(false);
QString strCurApkVersion="";
QSettings settings;
strCurApkVersion = settings.value(DEFS_LEDSET_URL).toString();
if(strCurApkVersion.isEmpty()) strCurApkVersion="0.0.0";
strCurApkVersion="0.0.0";
ui->label_2->setText(tr("CurVersion")+":"+strCurApkVersion);
ui->label_2->setVisible(false);
QSimpleUpdater *m_updater=QSimpleUpdater::getInstance();
connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(OnCheckForUpdates()));
connect(m_updater,SIGNAL(checkingFinished(QString)),this,SLOT(updateChangelog(QString)));
connect(m_updater,SIGNAL(downloadFinished(QString,QString)),this,SLOT(OnDownloadFinished(QString,QString)));
m_updater->getInstance()->setModuleVersion(DEFS_LEDSET_URL,strCurApkVersion);
m_updater->getInstance()->setNotifyOnUpdate(DEFS_LEDSET_URL,false);
m_updater->getInstance()->setNotifyOnFinish(DEFS_LEDSET_URL,false);
m_updater->getInstance()->setCompareBySameString(DEFS_LEDSET_URL,true);
m_updater->getInstance()->checkForUpdates(DEFS_LEDSET_URL);
ui->pushButton->setProperty("ssType", "progManageTool");
ui->pushButton_2->setProperty("ssType", "progManageTool");
}
UpdateLedset3Dialog::~UpdateLedset3Dialog()
{
delete ui;
}
void UpdateLedset3Dialog::OnDownloadFinished( QString url, QString filepath)
{
ui->label_2->setText(tr("CurVersion")+":"+m_updater->getInstance()->getLatestVersion(DEFS_LEDSET_URL));
ui->textEdit->setText(tr("Apk is download finished from internet,you can select LED Screen SYNC firmware now!"));
ui->pushButton_2->setVisible(false);
QSettings settings;
settings.setValue(url, m_strLastestVersion);
settings.setValue("ledset", filepath);
}
void UpdateLedset3Dialog::OnCheckForUpdates()
{
m_updater->getInstance()->setNotifyOnUpdate(DEFS_LEDSET_URL,true);
m_updater->getInstance()->setNotifyOnFinish(DEFS_LEDSET_URL,false);
// m_updater->getInstance()->setUseCustomInstallProcedures(DEFS_LEDSET_URL,true);
m_updater->getInstance()->setNoNotifyDownload(DEFS_LEDSET_URL,true);
m_updater->getInstance()->setCompareBySameString(DEFS_LEDSET_URL,true);
m_updater->getInstance()->setMandatoryUpdate(DEFS_LEDSET_URL,false);
m_updater->getInstance()->checkForUpdates(DEFS_LEDSET_URL);
}
void UpdateLedset3Dialog::updateChangelog(QString strTip)
{
Q_UNUSED(strTip)
if(m_updater->getInstance()->getUpdateAvailable(DEFS_LEDSET_URL))
{
QString strtip=tr("LatestVersion:");
m_strLastestVersion=m_updater->getInstance()->getLatestVersion(DEFS_LEDSET_URL);
strtip+= m_strLastestVersion +"\r\n";
strtip+= tr("Update log:")+"\r\n"+m_updater->getInstance()->getChangelog (DEFS_LEDSET_URL) ;
ui->textEdit->setText(strtip);
ui->pushButton_2->setVisible(true);
}
else {
ui->textEdit->setText(tr("The current version is already the latest version,,you can select LED Screen SYNC firmware now!"));
}
disconnect(m_updater,SIGNAL(checkingFinished(QString)),this,SLOT(updateChangelog(QString)));
}
#include "updateledset3dialog.h"
#include "ui_updateledset3dialog.h"
#include <QSettings>
#include <cfg.h>
extern const QString DEFS_LEDSET_URL = "https://www.ledok.cn/download/definitions/ledset3updates.json";
UpdateLedset3Dialog::UpdateLedset3Dialog(QWidget *parent) :
BaseDlg(parent),
ui(new Ui::UpdateLedset3Dialog)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
ui->pushButton_2->setVisible(false);
QString strCurApkVersion="";
QSettings settings;
strCurApkVersion = settings.value(DEFS_LEDSET_URL).toString();
if(strCurApkVersion.isEmpty()) strCurApkVersion="0.0.0";
strCurApkVersion="0.0.0";
ui->label_2->setText(tr("CurVersion")+":"+strCurApkVersion);
ui->label_2->setVisible(false);
QSimpleUpdater *m_updater=QSimpleUpdater::getInstance();
connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(OnCheckForUpdates()));
connect(m_updater,SIGNAL(checkingFinished(QString)),this,SLOT(updateChangelog(QString)));
connect(m_updater,SIGNAL(downloadFinished(QString,QString)),this,SLOT(OnDownloadFinished(QString,QString)));
m_updater->getInstance()->setModuleVersion(DEFS_LEDSET_URL,strCurApkVersion);
m_updater->getInstance()->setNotifyOnUpdate(DEFS_LEDSET_URL,false);
m_updater->getInstance()->setNotifyOnFinish(DEFS_LEDSET_URL,false);
m_updater->getInstance()->setCompareBySameString(DEFS_LEDSET_URL,true);
m_updater->getInstance()->checkForUpdates(DEFS_LEDSET_URL);
ui->pushButton->setProperty("ssType", "progManageTool");
ui->pushButton_2->setProperty("ssType", "progManageTool");
}
UpdateLedset3Dialog::~UpdateLedset3Dialog()
{
delete ui;
}
void UpdateLedset3Dialog::OnDownloadFinished( QString url, QString filepath)
{
ui->label_2->setText(tr("CurVersion")+":"+m_updater->getInstance()->getLatestVersion(DEFS_LEDSET_URL));
ui->textEdit->setText(tr("Apk is download finished from internet,you can select LED Screen SYNC firmware now!"));
ui->pushButton_2->setVisible(false);
QSettings settings;
settings.setValue(url, m_strLastestVersion);
settings.setValue("ledset", filepath);
}
void UpdateLedset3Dialog::OnCheckForUpdates()
{
m_updater->getInstance()->setNotifyOnUpdate(DEFS_LEDSET_URL,true);
m_updater->getInstance()->setNotifyOnFinish(DEFS_LEDSET_URL,false);
// m_updater->getInstance()->setUseCustomInstallProcedures(DEFS_LEDSET_URL,true);
m_updater->getInstance()->setNoNotifyDownload(DEFS_LEDSET_URL,true);
m_updater->getInstance()->setCompareBySameString(DEFS_LEDSET_URL,true);
m_updater->getInstance()->setMandatoryUpdate(DEFS_LEDSET_URL,false);
m_updater->getInstance()->checkForUpdates(DEFS_LEDSET_URL);
}
void UpdateLedset3Dialog::updateChangelog(QString strTip)
{
Q_UNUSED(strTip)
if(m_updater->getInstance()->getUpdateAvailable(DEFS_LEDSET_URL))
{
QString strtip=tr("LatestVersion:");
m_strLastestVersion=m_updater->getInstance()->getLatestVersion(DEFS_LEDSET_URL);
strtip+= m_strLastestVersion +"\r\n";
strtip+= tr("Update log:")+"\r\n"+m_updater->getInstance()->getChangelog (DEFS_LEDSET_URL) ;
ui->textEdit->setText(strtip);
ui->pushButton_2->setVisible(true);
}
else {
ui->textEdit->setText(tr("The current version is already the latest version,,you can select LED Screen SYNC firmware now!"));
}
disconnect(m_updater,SIGNAL(checkingFinished(QString)),this,SLOT(updateChangelog(QString)));
}

View File

@ -1,30 +1,30 @@
#ifndef UPDATELEDSET3DIALOG_H
#define UPDATELEDSET3DIALOG_H
#include <basedlg.h>
#include <QSimpleUpdater.h>
namespace Ui {
class UpdateLedset3Dialog;
}
class UpdateLedset3Dialog : public BaseDlg
{
Q_OBJECT
public:
explicit UpdateLedset3Dialog(QWidget *parent = nullptr);
~UpdateLedset3Dialog();
private:
Ui::UpdateLedset3Dialog *ui;
QSimpleUpdater *m_updater;
QString m_strLastestVersion="";
protected slots:
void OnCheckForUpdates() ;
void updateChangelog(QString);
void OnDownloadFinished( QString url, QString filepath);
};
#endif // UPDATELEDSET3DIALOG_H
#ifndef UPDATELEDSET3DIALOG_H
#define UPDATELEDSET3DIALOG_H
#include <basedlg.h>
#include <QSimpleUpdater.h>
namespace Ui {
class UpdateLedset3Dialog;
}
class UpdateLedset3Dialog : public BaseDlg
{
Q_OBJECT
public:
explicit UpdateLedset3Dialog(QWidget *parent = nullptr);
~UpdateLedset3Dialog();
private:
Ui::UpdateLedset3Dialog *ui;
QSimpleUpdater *m_updater;
QString m_strLastestVersion="";
protected slots:
void OnCheckForUpdates() ;
void updateChangelog(QString);
void OnDownloadFinished( QString url, QString filepath);
};
#endif // UPDATELEDSET3DIALOG_H

View File

@ -1,204 +1,204 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UpdateLedset3Dialog</class>
<widget class="QDialog" name="UpdateLedset3Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>381</width>
<height>272</height>
</rect>
</property>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>382</width>
<height>275</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>LedSet3.0 Update</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="maximumSize">
<size>
<width>30</width>
<height>24</height>
</size>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="styleSheet">
<string notr="true">border-top: 2px solid gray; </string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">image: url(:/res/ledset.png);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item alignment="Qt::AlignLeft">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>V1.0.0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QPushButton" name="pushButton_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Update</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>UpdateLedset3Dialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>355</x>
<y>22</y>
</hint>
<hint type="destinationlabel">
<x>190</x>
<y>135</y>
</hint>
</hints>
</connection>
</connections>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UpdateLedset3Dialog</class>
<widget class="QDialog" name="UpdateLedset3Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>381</width>
<height>272</height>
</rect>
</property>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>382</width>
<height>275</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>LedSet3.0 Update</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="maximumSize">
<size>
<width>30</width>
<height>24</height>
</size>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="styleSheet">
<string notr="true">border-top: 2px solid gray; </string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">image: url(:/res/ledset.png);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item alignment="Qt::AlignLeft">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>V1.0.0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QPushButton" name="pushButton_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Update</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>UpdateLedset3Dialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>355</x>
<y>22</y>
</hint>
<hint type="destinationlabel">
<x>190</x>
<y>135</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,38 +0,0 @@
#include "updaterdialog.h"
#include "cfg.h"
#include "ui_updaterdialog.h"
UpdaterDialog::UpdaterDialog(QWidget *parent) : BaseDlg(parent), ui(new Ui::UpdaterDialog) {
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
ui->pushButton_2->setVisible(false);
ui->label_2->setText(tr("CurVersion")+":"+APP_VERSION);
QSimpleUpdater *m_updater = QSimpleUpdater::getInstance();
connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(OnCheckForUpdates()));
connect(m_updater, SIGNAL(checkingFinished(QString)), this, SLOT(updateChangelog(QString)));
m_updater->setModuleVersion(UpdVerUrl, APP_VERSION);
m_updater->setNotifyOnUpdate(UpdVerUrl, false);
m_updater->setNotifyOnFinish(UpdVerUrl, false);
m_updater->checkForUpdates(UpdVerUrl);
}
UpdaterDialog::~UpdaterDialog(){
delete ui;
}
void UpdaterDialog::OnCheckForUpdates(){
QSimpleUpdater::getInstance()->setNotifyOnUpdate(UpdVerUrl, true);
QSimpleUpdater::getInstance()->setNotifyOnFinish(UpdVerUrl, false);
QSimpleUpdater::getInstance()->setMandatoryUpdate(UpdVerUrl, true);
QSimpleUpdater::getInstance()->checkForUpdates(UpdVerUrl);
}
void UpdaterDialog::updateChangelog(QString){
if(QSimpleUpdater::getInstance()->getUpdateAvailable(UpdVerUrl)){
QString strtip = tr("LatestVersion:") + QSimpleUpdater::getInstance()->getLatestVersion(UpdVerUrl) + "\r\n"
+ tr("Update log:") + "\r\n" + QSimpleUpdater::getInstance()->getChangelog(UpdVerUrl);
ui->textEdit->setText(strtip);
ui->pushButton_2->setVisible(true);
} else {
ui->textEdit->setText(tr("The current version is already the latest version") + "\r\n\r\n"
+ tr("Update log:") + "\r\n" + QSimpleUpdater::getInstance()->getChangelog(UpdVerUrl));
}
}

View File

@ -1,26 +0,0 @@
#ifndef UPDATERDIALOG_H
#define UPDATERDIALOG_H
#include <basedlg.h>
#include <QSimpleUpdater.h>
namespace Ui {
class UpdaterDialog;
}
class UpdaterDialog : public BaseDlg
{
Q_OBJECT
public:
explicit UpdaterDialog(QWidget *parent = nullptr);
~UpdaterDialog();
private:
Ui::UpdaterDialog *ui;
protected slots:
void OnCheckForUpdates() ;
void updateChangelog(QString);
};
#endif // UPDATERDIALOG_H

View File

@ -1,193 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UpdaterDialog</class>
<widget class="QDialog" name="UpdaterDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>400</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Software Update</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="maximumSize">
<size>
<width>30</width>
<height>24</height>
</size>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="styleSheet">
<string notr="true">border-top: 2px solid gray; </string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">image: url(:/res/Logo.png);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item alignment="Qt::AlignLeft">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>V1.0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QPushButton" name="pushButton_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Update</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>UpdaterDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>364</x>
<y>29</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>78</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,50 +1,61 @@
#include "waitingdlg.h"
#include <QBoxLayout>
#include <QTimerEvent>
WaitingDlg::WaitingDlg(QWidget *parent, QString text, QString sucText) : BaseDlg{parent}, sucText(sucText) {
setAttribute(Qt::WA_DeleteOnClose);
setModal(true);
auto pal = palette();
pal.setBrush(QPalette::Window, QColor(0xdddddd));
setPalette(pal);
auto vBox = new QVBoxLayout(this);
vBox->addStretch();
mIndicator = new CustomProgressIndicator(this);
mIndicator->setDisplayModel(1);
mIndicator->setColor(QColor(0x0088dd));
mIndicator->startAnimation();
vBox->addWidget(mIndicator, 0, Qt::AlignCenter);
vBox->addStretch();
fdText = new QLabel(text);
fdText->setAlignment(Qt::AlignCenter);
auto font = fdText->font();
font.setPixelSize(18);
font.setBold(true);
fdText->setFont(font);
pal = fdText->palette();
pal.setBrush(QPalette::WindowText, QColor(0x0088dd));
fdText->setPalette(pal);
vBox->addWidget(fdText);
vBox->addStretch();
}
void WaitingDlg::timerEvent(QTimerEvent *event) {
if(closeTimerId==event->timerId()) {
killTimer(closeTimerId);
closeTimerId = 0;
close();
} else BaseDlg::timerEvent(event);
}
void WaitingDlg::success() {
fdText->setText(sucText.isEmpty() ? tr("Success") : sucText);
mIndicator->setBackground(":/res/success.png");
mIndicator->stopAnimation();
closeTimerId = startTimer(800);
}
#include "waitingdlg.h"
#include <QBoxLayout>
#include <QTimerEvent>
#include <QPushButton>
WaitingDlg::WaitingDlg(QWidget *parent, QString text, QString sucText) : BaseDlg{parent}, sucText(sucText) {
setAttribute(Qt::WA_DeleteOnClose);
setModal(true);
auto pal = palette();
pal.setBrush(QPalette::Window, QColor(0xdddddd));
setPalette(pal);
auto vBox = new QVBoxLayout(this);
vBox->setContentsMargins(6, 3, 6, 6);
vBox->addStretch();
btnAbort = new QPushButton("X");
btnAbort->setStyleSheet(R"rrr(
QPushButton {border-radius: 4px; padding: 2px 6px; background: transparent;}
QPushButton:hover {background: rgba(0,0,0,0.2);}
QPushButton:pressed {background: rgba(0,0,0,0.3);}
)rrr");
connect(btnAbort, &QPushButton::clicked, this, &QDialog::reject);
vBox->addWidget(btnAbort, 0, Qt::AlignRight);
mIndicator = new CustomProgressIndicator(this);
mIndicator->setDisplayModel(1);
mIndicator->setColor(QColor(0x0088dd));
mIndicator->startAnimation();
vBox->addWidget(mIndicator, 0, Qt::AlignCenter);
vBox->addStretch();
fdText = new QLabel(text);
fdText->setAlignment(Qt::AlignCenter);
auto font = fdText->font();
font.setPixelSize(18);
font.setBold(true);
fdText->setFont(font);
pal = fdText->palette();
pal.setBrush(QPalette::WindowText, QColor(0x0088dd));
fdText->setPalette(pal);
vBox->addWidget(fdText);
vBox->addStretch();
}
void WaitingDlg::timerEvent(QTimerEvent *event) {
if(closeTimerId==event->timerId()) {
killTimer(closeTimerId);
closeTimerId = 0;
close();
} else BaseDlg::timerEvent(event);
}
void WaitingDlg::success() {
fdText->setText(sucText.isEmpty() ? tr("Success") : sucText);
mIndicator->setBackground(":/res/success.png");
mIndicator->stopAnimation();
closeTimerId = startTimer(800);
}

View File

@ -1,25 +1,25 @@
#ifndef WAITINGDLG_H
#define WAITINGDLG_H
#include "basedlg.h"
#include "base/customprogressindicator.h"
#include <QLabel>
class WaitingDlg : public BaseDlg {
Q_OBJECT
public:
explicit WaitingDlg(QWidget *parent = nullptr, QString text = 0, QString sucText = 0);
QLabel *fdText;
QString sucText;
CustomProgressIndicator *mIndicator;
public slots:
void success();
protected:
void timerEvent(QTimerEvent *) override;
private:
int closeTimerId{0};
};
#endif // WAITINGDLG_H
#ifndef WAITINGDLG_H
#define WAITINGDLG_H
#include "basedlg.h"
#include "base/customprogressindicator.h"
#include <QLabel>
class WaitingDlg : public BaseDlg {
Q_OBJECT
public:
explicit WaitingDlg(QWidget *parent = nullptr, QString text = 0, QString sucText = 0);
QPushButton *btnAbort;
QLabel *fdText;
QString sucText;
CustomProgressIndicator *mIndicator;
public slots:
void success();
protected:
void timerEvent(QTimerEvent *) override;
private:
int closeTimerId{0};
};
#endif // WAITINGDLG_H

View File

@ -1,116 +1,116 @@
/*
delegate.cpp
A delegate that allows the user to change integer values from the model
using a spin box widget.
*/
#include "x_checkboxdelegate.h"
#include <QCheckBox>
#include <QMouseEvent>
#include <QApplication>
X_CheckBoxDelegate::X_CheckBoxDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QWidget *X_CheckBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem & option ,
const QModelIndex & index ) const
{
// if(index.column()>=3&&index.column()<=9)
// {
// QCheckBox *editor = new QCheckBox(parent);
// // editor->setFrame(false);
// ///editor->setAlignment(Qt::AlignHCenter);
// // editor->setDisplayFormat("hh:mm");
// return editor;
// }
if(index.column()>=3&&index.column()<=9)
{
QCheckBox *editor=new QCheckBox(parent);
editor->installEventFilter(const_cast<X_CheckBoxDelegate*>(this));
return editor;
}
else
return QStyledItemDelegate::createEditor(parent,option,index);
return nullptr;
}
//void X_CheckBoxDelegate::setEditorData(QWidget *editor,
// const QModelIndex &index) const
//{
// if(index.column()>=3&&index.column()<=9)
// {
// bool data = index.model()->data(index, Qt::UserRole).toBool();
// QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
// checkBox->setChecked(data);
// }
// else
// QStyledItemDelegate::setEditorData(editor,index);
//}
//void X_CheckBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
// const QModelIndex &index) const
//{
// QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
// bool value = checkBox->isChecked();
// model->setData(index, value, Qt::UserRole);
//}
// 绘制复选框
void X_CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem viewOption(option);
initStyleOption(&viewOption, index);
if (option.state.testFlag(QStyle::State_HasFocus))
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
QStyledItemDelegate::paint(painter, viewOption, index);
if (index.column()>=3&&index.column()<=9)
{
bool data = index.model()->data(index, Qt::UserRole).toBool();
QStyleOptionButton checkBoxStyle;
checkBoxStyle.state = data ? QStyle::State_On : QStyle::State_Off;
checkBoxStyle.state |= QStyle::State_Enabled;
checkBoxStyle.iconSize = QSize(20, 20);
checkBoxStyle.rect = option.rect;
QCheckBox checkBox;
QApplication::style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter, &checkBox);
}
}
// 响应鼠标事件,更新数据
bool X_CheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
QRect decorationRect = option.rect;
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (event->type() == QEvent::MouseButtonPress && decorationRect.contains(mouseEvent->pos()))
{
if (index.column()>=3&&index.column()<=9)
{
bool data = model->data(index, Qt::UserRole).toBool();
model->setData(index, !data, Qt::UserRole);
}
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
void X_CheckBoxDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}
/*
delegate.cpp
A delegate that allows the user to change integer values from the model
using a spin box widget.
*/
#include "x_checkboxdelegate.h"
#include <QCheckBox>
#include <QMouseEvent>
#include <QApplication>
X_CheckBoxDelegate::X_CheckBoxDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QWidget *X_CheckBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem & option ,
const QModelIndex & index ) const
{
// if(index.column()>=3&&index.column()<=9)
// {
// QCheckBox *editor = new QCheckBox(parent);
// // editor->setFrame(false);
// ///editor->setAlignment(Qt::AlignHCenter);
// // editor->setDisplayFormat("hh:mm");
// return editor;
// }
if(index.column()>=3&&index.column()<=9)
{
QCheckBox *editor=new QCheckBox(parent);
editor->installEventFilter(const_cast<X_CheckBoxDelegate*>(this));
return editor;
}
else
return QStyledItemDelegate::createEditor(parent,option,index);
return nullptr;
}
//void X_CheckBoxDelegate::setEditorData(QWidget *editor,
// const QModelIndex &index) const
//{
// if(index.column()>=3&&index.column()<=9)
// {
// bool data = index.model()->data(index, Qt::UserRole).toBool();
// QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
// checkBox->setChecked(data);
// }
// else
// QStyledItemDelegate::setEditorData(editor,index);
//}
//void X_CheckBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
// const QModelIndex &index) const
//{
// QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
// bool value = checkBox->isChecked();
// model->setData(index, value, Qt::UserRole);
//}
// 绘制复选框
void X_CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem viewOption(option);
initStyleOption(&viewOption, index);
if (option.state.testFlag(QStyle::State_HasFocus))
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
QStyledItemDelegate::paint(painter, viewOption, index);
if (index.column()>=3&&index.column()<=9)
{
bool data = index.model()->data(index, Qt::UserRole).toBool();
QStyleOptionButton checkBoxStyle;
checkBoxStyle.state = data ? QStyle::State_On : QStyle::State_Off;
checkBoxStyle.state |= QStyle::State_Enabled;
checkBoxStyle.iconSize = QSize(20, 20);
checkBoxStyle.rect = option.rect;
QCheckBox checkBox;
QApplication::style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter, &checkBox);
}
}
// 响应鼠标事件,更新数据
bool X_CheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
QRect decorationRect = option.rect;
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (event->type() == QEvent::MouseButtonPress && decorationRect.contains(mouseEvent->pos()))
{
if (index.column()>=3&&index.column()<=9)
{
bool data = model->data(index, Qt::UserRole).toBool();
model->setData(index, !data, Qt::UserRole);
}
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
void X_CheckBoxDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}

View File

@ -1,73 +1,73 @@
#ifndef X_CHECKBOXDELEGATE_H
#define X_CHECKBOXDELEGATE_H
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QStyledItemDelegate>
//! [0]
class X_CheckBoxDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
X_CheckBoxDelegate(QObject *parent = nullptr);
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
// void setEditorData(QWidget *editor, const QModelIndex &index) const override;
// void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
};
//! [0]
#endif // X_CHECKBOXDELEGATE_H
#ifndef X_CHECKBOXDELEGATE_H
#define X_CHECKBOXDELEGATE_H
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QStyledItemDelegate>
//! [0]
class X_CheckBoxDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
X_CheckBoxDelegate(QObject *parent = nullptr);
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
// void setEditorData(QWidget *editor, const QModelIndex &index) const override;
// void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
};
//! [0]
#endif // X_CHECKBOXDELEGATE_H

View File

@ -1,35 +1,35 @@
#include "x_spinboxdelegate.h"
/*
A delegate that allows the user to change integer values from the model
using a spin box widget.
*/
#include <QSpinBox>
SpinBoxDelegate::SpinBoxDelegate(QObject *parent, int iFlag) : QStyledItemDelegate(parent) {
m_iFlag=iFlag;
}
QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const {
if(index.column()!=0) return 0;
QSpinBox *editor = new QSpinBox(parent);
editor->setFrame(false);
editor->setMinimum(0);
if(m_iFlag==0) editor->setMaximum(100);//亮度最大值
else if(m_iFlag==1) editor->setMaximum(15);//音量最大值
editor->setAlignment(Qt::AlignHCenter);
return editor;
}
void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const{
int value = index.model()->data(index, Qt::EditRole).toInt();
QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
spinBox->setValue(value);
}
void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const{
QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
spinBox->interpretText();
int value = spinBox->value();
model->setData(index, value, Qt::EditRole);
}
void SpinBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const {
editor->setGeometry(option.rect);
}
#include "x_spinboxdelegate.h"
/*
A delegate that allows the user to change integer values from the model
using a spin box widget.
*/
#include <QSpinBox>
SpinBoxDelegate::SpinBoxDelegate(QObject *parent, int iFlag) : QStyledItemDelegate(parent) {
m_iFlag=iFlag;
}
QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const {
if(index.column()!=0) return 0;
QSpinBox *editor = new QSpinBox(parent);
editor->setFrame(false);
editor->setMinimum(0);
if(m_iFlag==0) editor->setMaximum(100);//亮度最大值
else if(m_iFlag==1) editor->setMaximum(15);//音量最大值
editor->setAlignment(Qt::AlignHCenter);
return editor;
}
void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const{
int value = index.model()->data(index, Qt::EditRole).toInt();
QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
spinBox->setValue(value);
}
void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const{
QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
spinBox->interpretText();
int value = spinBox->value();
model->setData(index, value, Qt::EditRole);
}
void SpinBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const {
editor->setGeometry(option.rect);
}

View File

@ -1,67 +1,67 @@
#ifndef X_SPINBOXDELEGATE_H
#define X_SPINBOXDELEGATE_H
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QStyledItemDelegate>
#include <QSpinBox>
class SpinBoxDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
SpinBoxDelegate(QObject *parent = 0,int iFlag=0);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
public:
int m_iFlag=0;
};
#endif // X_SPINBOXDELEGATE_H
#ifndef X_SPINBOXDELEGATE_H
#define X_SPINBOXDELEGATE_H
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QStyledItemDelegate>
#include <QSpinBox>
class SpinBoxDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
SpinBoxDelegate(QObject *parent = 0,int iFlag=0);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
public:
int m_iFlag=0;
};
#endif // X_SPINBOXDELEGATE_H

View File

@ -1,62 +1,62 @@
#include "X_timeEditDelegate.h"
/*
delegate.cpp
A delegate that allows the user to change integer values from the model
using a spin box widget.
*/
#include "X_timeEditDelegate.h"
#include <QTimeEdit>
X_timeEditDelegate::X_timeEditDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QWidget *X_timeEditDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex & index ) const
{
if(index.column()==1||index.column()==2)
{
QTimeEdit *editor = new QTimeEdit(parent);
editor->setFrame(false);
editor->setAlignment(Qt::AlignHCenter);
editor->setDisplayFormat("hh:mm");
return editor;
}
return nullptr;
}
void X_timeEditDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QString value = index.model()->data(index, Qt::EditRole).toString();
QTimeEdit *spinBoxTimeEdit = static_cast<QTimeEdit*>(editor);
QTime qtime=QTime::fromString(value,"hh:mm");
spinBoxTimeEdit->setTime(qtime);
}
void X_timeEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QTimeEdit *spinBoxTimeEdit = static_cast<QTimeEdit*>(editor);
spinBoxTimeEdit->interpretText();
QString value = spinBoxTimeEdit->time().toString("hh:mm");
model->setData(index, value, Qt::EditRole);
}
void X_timeEditDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}
#include "X_timeEditDelegate.h"
/*
delegate.cpp
A delegate that allows the user to change integer values from the model
using a spin box widget.
*/
#include "X_timeEditDelegate.h"
#include <QTimeEdit>
X_timeEditDelegate::X_timeEditDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QWidget *X_timeEditDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex & index ) const
{
if(index.column()==1||index.column()==2)
{
QTimeEdit *editor = new QTimeEdit(parent);
editor->setFrame(false);
editor->setAlignment(Qt::AlignHCenter);
editor->setDisplayFormat("hh:mm");
return editor;
}
return nullptr;
}
void X_timeEditDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QString value = index.model()->data(index, Qt::EditRole).toString();
QTimeEdit *spinBoxTimeEdit = static_cast<QTimeEdit*>(editor);
QTime qtime=QTime::fromString(value,"hh:mm");
spinBoxTimeEdit->setTime(qtime);
}
void X_timeEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QTimeEdit *spinBoxTimeEdit = static_cast<QTimeEdit*>(editor);
spinBoxTimeEdit->interpretText();
QString value = spinBoxTimeEdit->time().toString("hh:mm");
model->setData(index, value, Qt::EditRole);
}
void X_timeEditDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}

View File

@ -1,75 +1,75 @@
#ifndef X_TIMEEDITDELEGATE_H
#define X_TIMEEDITDELEGATE_H
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QStyledItemDelegate>
//! [0]
class X_timeEditDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
X_timeEditDelegate(QObject *parent = 0);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
//! [0]
#endif // X_TIMEEDITDELEGATE_H
#ifndef X_TIMEEDITDELEGATE_H
#define X_TIMEEDITDELEGATE_H
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QStyledItemDelegate>
//! [0]
class X_timeEditDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
X_timeEditDelegate(QObject *parent = 0);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
//! [0]
#endif // X_TIMEEDITDELEGATE_H

View File

@ -1,60 +1,60 @@
#include "x_uimsgboxok.h"
#include "ui_x_uimsgboxok.h"
#include <QSettings>
#include <cfg.h>
X_UIMsgBoxOk::X_UIMsgBoxOk(QWidget *parent) :
BaseDlg(parent),
ui(new Ui::X_UIMsgBoxOk)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
m_bExitTypeFlag=0;
}
X_UIMsgBoxOk::~X_UIMsgBoxOk()
{
delete ui;
}
X_UIMsgBoxOk::X_UIMsgBoxOk(QString strTitle,QString text, QWidget *parent) :
BaseDlg(parent),
ui(new Ui::X_UIMsgBoxOk)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
ui->lInfoTip->adjustSize();
ui->label_3->setText(strTitle);
//让QLabel能够自动判断并换行显示
// ui->lInfoTip->setGeometry(QRect(328, 240, 329, 27*4)); //四倍行距
ui->lInfoTip->setWordWrap(true);
ui->lInfoTip->setAlignment(Qt::AlignTop);
ui->lInfoTip->setText(text);
ui->pushButton_3->setVisible(false);
m_bExitTypeFlag=0;
ui->pushButton->setProperty("ssType", "progManageTool");
ui->pushButton_2->setProperty("ssType", "progManageTool");
ui->pushButton_3->setProperty("ssType", "progManageTool");
}
X_UIMsgBoxOk::X_UIMsgBoxOk(QString strTitle,QString text, QWidget *parent,int iType) :
BaseDlg(parent),
ui(new Ui::X_UIMsgBoxOk)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
m_bExitTypeFlag=0;
ui->lInfoTip->adjustSize();
ui->label_3->setText(strTitle);
//让QLabel能够自动判断并换行显示
// ui->lInfoTip->setGeometry(QRect(328, 240, 329, 27*4)); //四倍行距
ui->lInfoTip->setWordWrap(true);
ui->lInfoTip->setAlignment(Qt::AlignTop);
ui->lInfoTip->setText(text);
ui->pushButton_3->setVisible(false);
if(iType==1) {
ui->lInfoTip->setStyleSheet("background:rgba(206,206,206,1)");
ui->frame->setStyleSheet("QFrame{background:rgba(206,206,206,1)}");
setStyleSheet("X_UIMsgBoxOk{background:rgba(206,206,206,1)}");
ui->pushButton->setProperty("ssType", "progManageTool");
ui->pushButton_2->setProperty("ssType", "progManageTool");
}
}
#include "x_uimsgboxok.h"
#include "ui_x_uimsgboxok.h"
#include <QSettings>
#include <cfg.h>
X_UIMsgBoxOk::X_UIMsgBoxOk(QWidget *parent) :
BaseDlg(parent),
ui(new Ui::X_UIMsgBoxOk)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
m_bExitTypeFlag=0;
}
X_UIMsgBoxOk::~X_UIMsgBoxOk()
{
delete ui;
}
X_UIMsgBoxOk::X_UIMsgBoxOk(QString strTitle,QString text, QWidget *parent) :
BaseDlg(parent),
ui(new Ui::X_UIMsgBoxOk)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
ui->lInfoTip->adjustSize();
ui->label_3->setText(strTitle);
//让QLabel能够自动判断并换行显示
// ui->lInfoTip->setGeometry(QRect(328, 240, 329, 27*4)); //四倍行距
ui->lInfoTip->setWordWrap(true);
ui->lInfoTip->setAlignment(Qt::AlignTop);
ui->lInfoTip->setText(text);
ui->pushButton_3->setVisible(false);
m_bExitTypeFlag=0;
ui->pushButton->setProperty("ssType", "progManageTool");
ui->pushButton_2->setProperty("ssType", "progManageTool");
ui->pushButton_3->setProperty("ssType", "progManageTool");
}
X_UIMsgBoxOk::X_UIMsgBoxOk(QString strTitle,QString text, QWidget *parent,int iType) :
BaseDlg(parent),
ui(new Ui::X_UIMsgBoxOk)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
m_bExitTypeFlag=0;
ui->lInfoTip->adjustSize();
ui->label_3->setText(strTitle);
//让QLabel能够自动判断并换行显示
// ui->lInfoTip->setGeometry(QRect(328, 240, 329, 27*4)); //四倍行距
ui->lInfoTip->setWordWrap(true);
ui->lInfoTip->setAlignment(Qt::AlignTop);
ui->lInfoTip->setText(text);
ui->pushButton_3->setVisible(false);
if(iType==1) {
ui->lInfoTip->setStyleSheet("background:rgba(206,206,206,1)");
ui->frame->setStyleSheet("QFrame{background:rgba(206,206,206,1)}");
setStyleSheet("X_UIMsgBoxOk{background:rgba(206,206,206,1)}");
ui->pushButton->setProperty("ssType", "progManageTool");
ui->pushButton_2->setProperty("ssType", "progManageTool");
}
}

View File

@ -1,24 +1,24 @@
#ifndef X_UIMSGBOXOK_H
#define X_UIMSGBOXOK_H
#include <basedlg.h>
namespace Ui {
class X_UIMsgBoxOk;
}
class X_UIMsgBoxOk : public BaseDlg
{
Q_OBJECT
public:
explicit X_UIMsgBoxOk(QWidget *parent = nullptr);
X_UIMsgBoxOk(QString strTitle, QString text, QWidget *parent = nullptr);
X_UIMsgBoxOk(QString strTitle, QString text, QWidget *parent = nullptr,int iType=0);
~X_UIMsgBoxOk();
int m_bExitTypeFlag=0;
private:
Ui::X_UIMsgBoxOk *ui;
};
#endif // X_UIMSGBOXOK_H
#ifndef X_UIMSGBOXOK_H
#define X_UIMSGBOXOK_H
#include <basedlg.h>
namespace Ui {
class X_UIMsgBoxOk;
}
class X_UIMsgBoxOk : public BaseDlg
{
Q_OBJECT
public:
explicit X_UIMsgBoxOk(QWidget *parent = nullptr);
X_UIMsgBoxOk(QString strTitle, QString text, QWidget *parent = nullptr);
X_UIMsgBoxOk(QString strTitle, QString text, QWidget *parent = nullptr,int iType=0);
~X_UIMsgBoxOk();
int m_bExitTypeFlag=0;
private:
Ui::X_UIMsgBoxOk *ui;
};
#endif // X_UIMSGBOXOK_H

View File

@ -1,243 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>X_UIMsgBoxOk</class>
<widget class="QDialog" name="X_UIMsgBoxOk">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>426</width>
<height>200</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QFrame" name="frame">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="maximumSize">
<size>
<width>31</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="styleSheet">
<string notr="true">border-top: 2px solid gray; </string>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">image: url(:/res/tip.png);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lInfoTip">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>X_UIMsgBoxOk</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>128</x>
<y>119</y>
</hint>
<hint type="destinationlabel">
<x>127</x>
<y>75</y>
</hint>
</hints>
</connection>
<connection>
<sender>pushButton_2</sender>
<signal>clicked()</signal>
<receiver>X_UIMsgBoxOk</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>220</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>127</x>
<y>75</y>
</hint>
</hints>
</connection>
</connections>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>X_UIMsgBoxOk</class>
<widget class="QDialog" name="X_UIMsgBoxOk">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>426</width>
<height>200</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QFrame" name="frame">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="maximumSize">
<size>
<width>31</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="styleSheet">
<string notr="true">border-top: 2px solid gray; </string>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">image: url(:/res/tip.png);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lInfoTip">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>X_UIMsgBoxOk</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>128</x>
<y>119</y>
</hint>
<hint type="destinationlabel">
<x>127</x>
<y>75</y>
</hint>
</hints>
</connection>
<connection>
<sender>pushButton_2</sender>
<signal>clicked()</signal>
<receiver>X_UIMsgBoxOk</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>220</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>127</x>
<y>75</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -48,7 +48,7 @@ bool BaseDlg::nativeEvent(const QByteArray &eventType, void *message, long *){
MSG *msg = (MSG*)message;
if(msg->message==WM_NCACTIVATE){
isActive = msg->wParam;
repaint();
update();
}
}
return false;

View File

@ -122,7 +122,7 @@ bool BaseWin::nativeEvent(const QByteArray &eventType, void *message, long *){
MSG *msg = (MSG*)message;
if(msg->message==WM_NCACTIVATE){
isActive = msg->wParam;
repaint();
update();
}
}
return false;

View File

@ -1,193 +1,193 @@
#include "hpptclient.h"
//HpptClient* HpptClient::gInstance = nullptr;
HpptClient::HpptClient(QObject *p): QObject(p) {
connect(&mNetAccessManager, &QNetworkAccessManager::finished, this, [this](QNetworkReply *reply) {
if(reply->property("data").isValid()) onHttpPostRspFinished(reply);
else onHttpGetRspFinished(reply);
});
}
void HpptClient::clearRp(QNetworkReply *rp) {
if(rp)
{
QString url = rp->request().url().toString();
QString postMD5 = rp->property("postMD5").toString();
QString postData = rp->property("data").toByteArray();
if(postMD5.isEmpty())
{
//清理对应缓存
mDownloadDataCache.remove(url);
//解除正在处理状态
mProcessingRq.remove(url);
}
else
{
//清理对应缓存
mDownloadDataCache.remove(postMD5);
//解除正在处理状态
mProcessingRq.remove(postMD5);
}
mRedirectMap.remove(url);
mRedirectMap.remove(postMD5);
//qDebug() << "delete cache, url:" << url << " postMOD5:" << postMD5;
rp->deleteLater();
}
}
void HpptClient::onHttpGetRspProgress(qint64 bytesReceived, qint64 bytesTotal)
{
Q_UNUSED(bytesReceived)
if(sender() == NULL)
{
return ;
}
QNetworkReply* rp = qobject_cast<QNetworkReply*>(sender());
if(rp == NULL)
{
return;
}
//qDebug() << "http get rsp progress:" << rp->url().toString() << bytesReceived << "/" << bytesTotal;
if(bytesTotal <= 0)
{
return;
}
QString url = rp->url().toString();
mDownloadDataCache[url].append(rp->readAll());
}
void HpptClient::onHttpGetRspFinished(QNetworkReply *reply) {
QByteArray rpData;
QString url = reply->url().toString();
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString strUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
switch(statusCode) {
case 200: {
rpData = mDownloadDataCache[reply->url().toString()];
QString redirectUrl = mRedirectMap[url];//重定向的url地址
if(redirectUrl.isEmpty()) emit httpGetRspReady(url, rpData);
else emit httpGetRspReady(redirectUrl, rpData);
}
break;
case 301:
case 302: {
if(!strUrl.isEmpty()) {
QString turl = mRedirectMap[url];
if(turl.isEmpty()) mRedirectMap[strUrl] = url;
else mRedirectMap[strUrl] = turl;
httpGet(strUrl);
}
}
break;
default: // error
{
qDebug() << url << "[get error:" << statusCode << "]";
QString redirectUrl = mRedirectMap[url];
if(redirectUrl.isEmpty()) emit httpGetRspReady(url, QByteArray());
else emit httpGetRspReady(redirectUrl, QByteArray());
}
break;
}
clearRp(reply);
}
void HpptClient::onHttpPostRspProgress(qint64, qint64 bytesTotal){
if(sender() == NULL) return;
QNetworkReply* rp = qobject_cast<QNetworkReply*>(sender());
if(rp == NULL) return;
if(bytesTotal <= 0) return;
mDownloadDataCache[rp->property("postMD5").toString()].append(rp->readAll());
}
void HpptClient::onHttpPostRspFinished(QNetworkReply *reply) {
QString url = reply->url().toString();
QString postMD5 = reply->property("postMD5").toString();
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
switch(statusCode) {
case 200: {
auto rpData = mDownloadDataCache[postMD5];
QString redirectMD5 = mRedirectMap[postMD5];
QString redirectUrl = mRedirectMap[url];
if(redirectMD5.isEmpty() || redirectUrl.isEmpty()) emit httpPostRspReady(url, postMD5, rpData);
else emit httpPostRspReady(redirectUrl, redirectMD5, rpData);
}
break;
case 301:
case 302: {
auto redireUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
if(!redireUrl.isEmpty()) {
QString turl = mRedirectMap[url];//direct by
if(turl.isEmpty()) mRedirectMap[redireUrl] = url;
else mRedirectMap[redireUrl] = turl;
QByteArray postData = reply->property("data").toByteArray();
QByteArray d = redireUrl.toUtf8() + postData;
QString md5 = QCryptographicHash::hash(d, QCryptographicHash::Md5);
QString tPostMD5 = mRedirectMap[md5];//direct by
if(tPostMD5.isEmpty()) mRedirectMap[md5] = postMD5;
else mRedirectMap[md5] = tPostMD5;
httpPost(redireUrl, postData);
}
}
break;
default:
QString redirectMD5 = mRedirectMap[postMD5];
QString redirectUrl = mRedirectMap[url];
if(redirectMD5.isEmpty() || redirectUrl.isEmpty())
{
emit httpPostRspReady(url, postMD5, QByteArray());
}
else
{
emit httpPostRspReady(redirectUrl, redirectMD5, QByteArray());
}
break;
}
clearRp(reply);
}
void HpptClient::httpGet(const QString &url) {
if(mProcessingRq.value(url, false)) return;//ignore when rq processing
auto values = mRedirectMap.values();
for(int i = 0; i < values.count(); i++) if(values[i] == url) return;//ignore when redirect processing
mProcessingRq.insert(url, true);
QNetworkRequest request{url};
QSslConfiguration config = request.sslConfiguration();
config.setPeerVerifyMode(QSslSocket::VerifyNone);
config.setProtocol(QSsl::TlsV1SslV3);
request.setSslConfiguration(config);
QNetworkReply* rp = mNetAccessManager.get(request);
connect(rp, &QNetworkReply::downloadProgress, this, &HpptClient::onHttpGetRspProgress);
}
QByteArray HpptClient::httpPost(const QString &url, const QByteArray &data) {
QByteArray md5 = QCryptographicHash::hash(url.toUtf8() + data, QCryptographicHash::Md5);
if(mProcessingRq.value(md5, false)) return md5;//ignore when rq processing
auto values = mRedirectMap.values();
for(int i=0; i < values.count(); i++) if(values[i] == md5) return md5; //ignore when redirect processing
mProcessingRq.insert(md5, true);
QNetworkRequest request{url};
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");//add by alahover 20200304
QNetworkReply* reply = mNetAccessManager.post(request, data);
reply->setProperty("postMD5", md5);
reply->setProperty("url", url);
reply->setProperty("data", data);
connect(reply, &QNetworkReply::downloadProgress, this, &HpptClient::onHttpPostRspProgress);
return md5;
}
#include "hpptclient.h"
//HpptClient* HpptClient::gInstance = nullptr;
HpptClient::HpptClient(QObject *p): QObject(p) {
connect(&mNetAccessManager, &QNetworkAccessManager::finished, this, [this](QNetworkReply *reply) {
if(reply->property("data").isValid()) onHttpPostRspFinished(reply);
else onHttpGetRspFinished(reply);
});
}
void HpptClient::clearRp(QNetworkReply *rp) {
if(rp)
{
QString url = rp->request().url().toString();
QString postMD5 = rp->property("postMD5").toString();
QString postData = rp->property("data").toByteArray();
if(postMD5.isEmpty())
{
//清理对应缓存
mDownloadDataCache.remove(url);
//解除正在处理状态
mProcessingRq.remove(url);
}
else
{
//清理对应缓存
mDownloadDataCache.remove(postMD5);
//解除正在处理状态
mProcessingRq.remove(postMD5);
}
mRedirectMap.remove(url);
mRedirectMap.remove(postMD5);
//qDebug() << "delete cache, url:" << url << " postMOD5:" << postMD5;
rp->deleteLater();
}
}
void HpptClient::onHttpGetRspProgress(qint64 bytesReceived, qint64 bytesTotal)
{
Q_UNUSED(bytesReceived)
if(sender() == NULL)
{
return ;
}
QNetworkReply* rp = qobject_cast<QNetworkReply*>(sender());
if(rp == NULL)
{
return;
}
//qDebug() << "http get rsp progress:" << rp->url().toString() << bytesReceived << "/" << bytesTotal;
if(bytesTotal <= 0)
{
return;
}
QString url = rp->url().toString();
mDownloadDataCache[url].append(rp->readAll());
}
void HpptClient::onHttpGetRspFinished(QNetworkReply *reply) {
QByteArray rpData;
QString url = reply->url().toString();
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString strUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
switch(statusCode) {
case 200: {
rpData = mDownloadDataCache[reply->url().toString()];
QString redirectUrl = mRedirectMap[url];//重定向的url地址
if(redirectUrl.isEmpty()) emit httpGetRspReady(url, rpData);
else emit httpGetRspReady(redirectUrl, rpData);
}
break;
case 301:
case 302: {
if(!strUrl.isEmpty()) {
QString turl = mRedirectMap[url];
if(turl.isEmpty()) mRedirectMap[strUrl] = url;
else mRedirectMap[strUrl] = turl;
httpGet(strUrl);
}
}
break;
default: // error
{
qDebug() << url << "[get error:" << statusCode << "]";
QString redirectUrl = mRedirectMap[url];
if(redirectUrl.isEmpty()) emit httpGetRspReady(url, QByteArray());
else emit httpGetRspReady(redirectUrl, QByteArray());
}
break;
}
clearRp(reply);
}
void HpptClient::onHttpPostRspProgress(qint64, qint64 bytesTotal){
if(sender() == NULL) return;
QNetworkReply* rp = qobject_cast<QNetworkReply*>(sender());
if(rp == NULL) return;
if(bytesTotal <= 0) return;
mDownloadDataCache[rp->property("postMD5").toString()].append(rp->readAll());
}
void HpptClient::onHttpPostRspFinished(QNetworkReply *reply) {
QString url = reply->url().toString();
QString postMD5 = reply->property("postMD5").toString();
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
switch(statusCode) {
case 200: {
auto rpData = mDownloadDataCache[postMD5];
QString redirectMD5 = mRedirectMap[postMD5];
QString redirectUrl = mRedirectMap[url];
if(redirectMD5.isEmpty() || redirectUrl.isEmpty()) emit httpPostRspReady(url, postMD5, rpData);
else emit httpPostRspReady(redirectUrl, redirectMD5, rpData);
}
break;
case 301:
case 302: {
auto redireUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
if(!redireUrl.isEmpty()) {
QString turl = mRedirectMap[url];//direct by
if(turl.isEmpty()) mRedirectMap[redireUrl] = url;
else mRedirectMap[redireUrl] = turl;
QByteArray postData = reply->property("data").toByteArray();
QByteArray d = redireUrl.toUtf8() + postData;
QString md5 = QCryptographicHash::hash(d, QCryptographicHash::Md5);
QString tPostMD5 = mRedirectMap[md5];//direct by
if(tPostMD5.isEmpty()) mRedirectMap[md5] = postMD5;
else mRedirectMap[md5] = tPostMD5;
httpPost(redireUrl, postData);
}
}
break;
default:
QString redirectMD5 = mRedirectMap[postMD5];
QString redirectUrl = mRedirectMap[url];
if(redirectMD5.isEmpty() || redirectUrl.isEmpty())
{
emit httpPostRspReady(url, postMD5, QByteArray());
}
else
{
emit httpPostRspReady(redirectUrl, redirectMD5, QByteArray());
}
break;
}
clearRp(reply);
}
void HpptClient::httpGet(const QString &url) {
if(mProcessingRq.value(url, false)) return;//ignore when rq processing
auto values = mRedirectMap.values();
for(int i = 0; i < values.count(); i++) if(values[i] == url) return;//ignore when redirect processing
mProcessingRq.insert(url, true);
QNetworkRequest request{url};
QSslConfiguration config = request.sslConfiguration();
config.setPeerVerifyMode(QSslSocket::VerifyNone);
config.setProtocol(QSsl::TlsV1SslV3);
request.setSslConfiguration(config);
QNetworkReply* rp = mNetAccessManager.get(request);
connect(rp, &QNetworkReply::downloadProgress, this, &HpptClient::onHttpGetRspProgress);
}
QByteArray HpptClient::httpPost(const QString &url, const QByteArray &data) {
QByteArray md5 = QCryptographicHash::hash(url.toUtf8() + data, QCryptographicHash::Md5);
if(mProcessingRq.value(md5, false)) return md5;//ignore when rq processing
auto values = mRedirectMap.values();
for(int i=0; i < values.count(); i++) if(values[i] == md5) return md5; //ignore when redirect processing
mProcessingRq.insert(md5, true);
QNetworkRequest request{url};
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");//add by alahover 20200304
QNetworkReply* reply = mNetAccessManager.post(request, data);
reply->setProperty("postMD5", md5);
reply->setProperty("url", url);
reply->setProperty("data", data);
connect(reply, &QNetworkReply::downloadProgress, this, &HpptClient::onHttpPostRspProgress);
return md5;
}

View File

@ -1,46 +1,46 @@
#ifndef HPPTCLIENT_H
#define HPPTCLIENT_H
#include <QObject>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
class HpptClient : public QObject {
Q_OBJECT
public:
HpptClient(QObject *p = nullptr);
void httpGet(const QString& url);
/// \return 返回url+data的md5
QByteArray httpPost(const QString& url, const QByteArray &data);
signals:
/// \brief httpGetRspReady http get 请求得到回复
/// \param url 请求的地址
/// \param data 回复的数据如果isEmpty则表示请求出错了
void httpGetRspReady(QString url, QByteArray data);
/// \brief httpPostRspReady http post 请求得到回复
/// \param url 请求的地址
/// \param postMD5 是post的时候url+数据的md5
/// \param data data是回复的数据如果isEmpty则表示请求出错了
void httpPostRspReady(QString url, QString postMD5, QByteArray data);
private slots:
void clearRp(QNetworkReply* rp);
void onHttpGetRspProgress(qint64 bytesReceived, qint64 bytesTotal); //* http get 回复进度
void onHttpGetRspFinished(QNetworkReply *reply); //* http get 处理完毕
void onHttpPostRspProgress(qint64 bytesReceived, qint64 bytesTotal); //* http post 回复进度
void onHttpPostRspFinished(QNetworkReply *reply); //* http get 处理完毕
private:
QNetworkAccessManager mNetAccessManager;
QString mCacheRoot; //* 缓存目录
QMap<QString, bool> mProcessingRq; //* 当前正在处理的请求url 和是否正在处理
QMap<QString, QByteArray> mDownloadDataCache; //* 数据缓存url -> data | postMD5 -> data
QMap<QString, QString> mRedirectMap; //* 重定向关系
};
#endif // HPPTCLIENT_H
#ifndef HPPTCLIENT_H
#define HPPTCLIENT_H
#include <QObject>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
class HpptClient : public QObject {
Q_OBJECT
public:
HpptClient(QObject *p = nullptr);
void httpGet(const QString& url);
/// \return 返回url+data的md5
QByteArray httpPost(const QString& url, const QByteArray &data);
signals:
/// \brief httpGetRspReady http get 请求得到回复
/// \param url 请求的地址
/// \param data 回复的数据如果isEmpty则表示请求出错了
void httpGetRspReady(QString url, QByteArray data);
/// \brief httpPostRspReady http post 请求得到回复
/// \param url 请求的地址
/// \param postMD5 是post的时候url+数据的md5
/// \param data data是回复的数据如果isEmpty则表示请求出错了
void httpPostRspReady(QString url, QString postMD5, QByteArray data);
private slots:
void clearRp(QNetworkReply* rp);
void onHttpGetRspProgress(qint64 bytesReceived, qint64 bytesTotal); //* http get 回复进度
void onHttpGetRspFinished(QNetworkReply *reply); //* http get 处理完毕
void onHttpPostRspProgress(qint64 bytesReceived, qint64 bytesTotal); //* http post 回复进度
void onHttpPostRspFinished(QNetworkReply *reply); //* http get 处理完毕
private:
QNetworkAccessManager mNetAccessManager;
QString mCacheRoot; //* 缓存目录
QMap<QString, bool> mProcessingRq; //* 当前正在处理的请求url 和是否正在处理
QMap<QString, QByteArray> mDownloadDataCache; //* 数据缓存url -> data | postMD5 -> data
QMap<QString, QString> mRedirectMap; //* 重定向关系
};
#endif // HPPTCLIENT_H

View File

@ -1,130 +1,130 @@
#include "taserialthread.h"
#include <QDebug>
TA_SerialThread::TA_SerialThread()
{
portCnt = 0;
portNewCnt=0;
m_arrSerial = new QSerialPort[10];
m_arrNewSerial=new QSerialPortInfo[10];
}
TA_SerialThread::~TA_SerialThread()
{
}
void TA_SerialThread::run()
{
}
void TA_SerialThread::SearchPort(void) {
portNewCnt=0;
//查找可用的串口
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
if(portNewCnt > 9) break;
m_arrNewSerial[portNewCnt]=info;
portNewCnt++;
}
for (int i=0;i<portNewCnt;i++) {
bool iHaveFlag=false;
for(int j=0;j<portCnt;j++)
{
if(m_arrSerial[j].portName()==m_arrNewSerial[i].portName())
{
iHaveFlag=true;
break;
}
}
if(!iHaveFlag) {
m_arrSerial[portCnt].setPort(m_arrNewSerial[i]);
portCnt++;
}
}
}
void TA_SerialThread::InitPortName(uint8_t portIndex,const QString &portName)
{
if(portIndex < portCnt)
m_arrSerial[portIndex].setPortName(portName);//const QString &name
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::InitPortBaudRate(uint8_t portIndex,qint32 baudRate)
{
if(portIndex < portCnt)
m_arrSerial[portIndex].setBaudRate(baudRate);//BaudRate baudRate
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::InitPortDataBits(uint8_t portIndex,QSerialPort::DataBits dataBits)
{
if(portIndex < portCnt)
m_arrSerial[portIndex].setDataBits(dataBits);//DataBits dataBits
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::InitPortParity(uint8_t portIndex,QSerialPort::Parity parity)
{
if(portIndex < portCnt)
m_arrSerial[portIndex].setParity(parity);//Parity parity
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::InitPortStopBits(uint8_t portIndex,QSerialPort::StopBits stopBits)
{
if(portIndex < portCnt)
{
m_arrSerial[portIndex].setStopBits(stopBits);//StopBits stopBits
m_arrSerial[portIndex].setFlowControl(QSerialPort::NoFlowControl);
}
else
qDebug()<<"OpenPort port index is out of range!";
}
bool TA_SerialThread::OpenPort(uint8_t portIndex)
{
bool result=false;
if(portIndex < portCnt)
result=m_arrSerial[portIndex].open(QIODevice::ReadWrite);
else
qDebug()<<"OpenPort port index is out of range!";
return result;
}
void TA_SerialThread::ClosePort(uint8_t portIndex)
{
if(portIndex < portCnt)
{
//关闭串口
m_arrSerial[portIndex].clear();
m_arrSerial[portIndex].close();
//m_arrSerial[portIndex].deleteLater();
}
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::SendDataBuf(uint8_t portIndex,const QByteArray &str)
{
if(portIndex < portCnt)
{
m_arrSerial[portIndex].write(str);
qDebug()<<str;
}
else
qDebug()<<"SendDataBuf port index is out of range!";
}
QByteArray TA_SerialThread::GetDataBuf(uint8_t portIndex) {
if(portIndex < portCnt) return m_arrSerial[portIndex].readAll();
else {
qDebug()<<"GetDataBuf port index is out of range!";
return nullptr;
}
}
#include "taserialthread.h"
#include <QDebug>
TA_SerialThread::TA_SerialThread()
{
portCnt = 0;
portNewCnt=0;
m_arrSerial = new QSerialPort[10];
m_arrNewSerial=new QSerialPortInfo[10];
}
TA_SerialThread::~TA_SerialThread()
{
}
void TA_SerialThread::run()
{
}
void TA_SerialThread::SearchPort(void) {
portNewCnt=0;
//查找可用的串口
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
if(portNewCnt > 9) break;
m_arrNewSerial[portNewCnt]=info;
portNewCnt++;
}
for (int i=0;i<portNewCnt;i++) {
bool iHaveFlag=false;
for(int j=0;j<portCnt;j++)
{
if(m_arrSerial[j].portName()==m_arrNewSerial[i].portName())
{
iHaveFlag=true;
break;
}
}
if(!iHaveFlag) {
m_arrSerial[portCnt].setPort(m_arrNewSerial[i]);
portCnt++;
}
}
}
void TA_SerialThread::InitPortName(uint8_t portIndex,const QString &portName)
{
if(portIndex < portCnt)
m_arrSerial[portIndex].setPortName(portName);//const QString &name
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::InitPortBaudRate(uint8_t portIndex,qint32 baudRate)
{
if(portIndex < portCnt)
m_arrSerial[portIndex].setBaudRate(baudRate);//BaudRate baudRate
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::InitPortDataBits(uint8_t portIndex,QSerialPort::DataBits dataBits)
{
if(portIndex < portCnt)
m_arrSerial[portIndex].setDataBits(dataBits);//DataBits dataBits
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::InitPortParity(uint8_t portIndex,QSerialPort::Parity parity)
{
if(portIndex < portCnt)
m_arrSerial[portIndex].setParity(parity);//Parity parity
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::InitPortStopBits(uint8_t portIndex,QSerialPort::StopBits stopBits)
{
if(portIndex < portCnt)
{
m_arrSerial[portIndex].setStopBits(stopBits);//StopBits stopBits
m_arrSerial[portIndex].setFlowControl(QSerialPort::NoFlowControl);
}
else
qDebug()<<"OpenPort port index is out of range!";
}
bool TA_SerialThread::OpenPort(uint8_t portIndex)
{
bool result=false;
if(portIndex < portCnt)
result=m_arrSerial[portIndex].open(QIODevice::ReadWrite);
else
qDebug()<<"OpenPort port index is out of range!";
return result;
}
void TA_SerialThread::ClosePort(uint8_t portIndex)
{
if(portIndex < portCnt)
{
//关闭串口
m_arrSerial[portIndex].clear();
m_arrSerial[portIndex].close();
//m_arrSerial[portIndex].deleteLater();
}
else
qDebug()<<"OpenPort port index is out of range!";
}
void TA_SerialThread::SendDataBuf(uint8_t portIndex,const QByteArray &str)
{
if(portIndex < portCnt)
{
m_arrSerial[portIndex].write(str);
qDebug()<<str;
}
else
qDebug()<<"SendDataBuf port index is out of range!";
}
QByteArray TA_SerialThread::GetDataBuf(uint8_t portIndex) {
if(portIndex < portCnt) return m_arrSerial[portIndex].readAll();
else {
qDebug()<<"GetDataBuf port index is out of range!";
return nullptr;
}
}

View File

@ -1,36 +1,36 @@
#ifndef TASERIALTHREAD_H
#define TASERIALTHREAD_H
#include <QThread>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QString>
class TA_SerialThread:public QThread
{
public:
TA_SerialThread();
~TA_SerialThread();
public:
uint8_t portCnt;
uint8_t portNewCnt;
QSerialPort *m_arrSerial;//ptr point to an array,maxium port num is 5
QSerialPortInfo *m_arrNewSerial;//ptr point to an array,maxium port num is 5
public:
void SearchPort(void);
void InitPortName(uint8_t portIndex,const QString &portName);
void InitPortBaudRate(uint8_t portIndex,qint32 baudRate);
void InitPortDataBits(uint8_t portIndex,QSerialPort::DataBits dataBits);
void InitPortParity(uint8_t portIndex,QSerialPort::Parity parity);
void InitPortStopBits(uint8_t portIndex,QSerialPort::StopBits stopBits);
bool OpenPort(uint8_t portIndex);
void ClosePort(uint8_t portIndex);
void SendDataBuf(uint8_t portIndex,const QByteArray &str);
QByteArray GetDataBuf(uint8_t portIndex);
private slots:
void run();
};
#endif // TASERIALTHREAD_H
#ifndef TASERIALTHREAD_H
#define TASERIALTHREAD_H
#include <QThread>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QString>
class TA_SerialThread:public QThread
{
public:
TA_SerialThread();
~TA_SerialThread();
public:
uint8_t portCnt;
uint8_t portNewCnt;
QSerialPort *m_arrSerial;//ptr point to an array,maxium port num is 5
QSerialPortInfo *m_arrNewSerial;//ptr point to an array,maxium port num is 5
public:
void SearchPort(void);
void InitPortName(uint8_t portIndex,const QString &portName);
void InitPortBaudRate(uint8_t portIndex,qint32 baudRate);
void InitPortDataBits(uint8_t portIndex,QSerialPort::DataBits dataBits);
void InitPortParity(uint8_t portIndex,QSerialPort::Parity parity);
void InitPortStopBits(uint8_t portIndex,QSerialPort::StopBits stopBits);
bool OpenPort(uint8_t portIndex);
void ClosePort(uint8_t portIndex);
void SendDataBuf(uint8_t portIndex,const QByteArray &str);
QByteArray GetDataBuf(uint8_t portIndex);
private slots:
void run();
};
#endif // TASERIALTHREAD_H

176
LedOK/css.css Normal file
View File

@ -0,0 +1,176 @@
QLineEdit,QComboBox,QAbstractSpinBox {
border: 1px solid #aaa;
border-radius: 3px;
padding: 2px;
}
QGroupBox {
border: 1px solid #aaa;
border-radius: 3px;
margin-top: 0.5em;
padding-top: 0.4em;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 0.5em;
}
QComboBox::drop-down,
QAbstractSpinBox::up-button,
QAbstractSpinBox::down-button {
border: 0;
}
QComboBox::down-arrow,
QAbstractSpinBox::down-arrow {
image: url(:/res/ArrowDropDown.png);
}
QComboBox::down-arrow:on,
QAbstractSpinBox::up-arrow {
image: url(:/res/ArrowDropUp.png);
}
QAbstractSpinBox::up-arrow:pressed {
top: -1px;
}
QAbstractSpinBox::down-arrow:pressed {
top: 1px;
}
QCheckBox::indicator, QTreeWidget::indicator {
border-image: url(:/res/CheckBoxUnchecked.png); width: 1em; height: 1em; margin-left: 0.25em;
}
QCheckBox::indicator:checked, QTreeWidget::indicator:checked {
border-image: url(:/res/CheckBoxChecked.png);
}
QCheckBox::indicator:disabled {
background-color: #666;
}
ExtendedGroupBox::indicator {
border-image: url(:/res/groupbox-unchecked.png);
}
ExtendedGroupBox::indicator:checked {
border-image: url(:/res/groupbox-checked.png);
}
QScrollArea {
border : 0;
}
QScrollBar:vertical {
width: 12px;
}
QScrollBar:horizontal {
height: 12px;
}
QMenu {
background-color: #eee;
border: 2px solid #ccc;
}
QMenu::item {
background-color: transparent;
}
QMenu::item:selected {
background-color: #8CD;
}
QListWidget {
selection-background-color: #8ce;
}
LoColorSelector {
border: 1px solid #aaa;
border-radius: 4px;
background-color: transparent;
padding: 3px 6px;
max-height: 30px;
}
QTreeWidget[ssType="topList"]::item {
border-right: 1px solid #ddd;
border-bottom: 1px solid #ddd;
height: 40px;
}
QTreeWidget[ssType="topList"] QHeaderView::section {
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
border-left: 0;
border-right: 0;
height: 36px;
}
QTreeWidget[ssType="topList"]::item:hover {
background-color: #ddd;
}
QPushButton[ssType="progManageTool"] {
border-radius: 4px;
background-color: #19c;
color: #000;
padding: 3px 6px;
}
QPushButton[ssType="progManageTool"]:hover {
background-color: #08b;
color: #fff;
}
QPushButton[ssType="progManageTool"]:pressed {
background-color: #07a;
}
QPushButton[ssType="progManageTool"]:disabled {
background-color: #bbb;
color: #777;
}
LoQTitleBar QPushButton {
border-radius: 4px;
icon-size: 20px;
width: 32px;
height: 28px;
}
LoQTitleBar QPushButton:press,
LoQTitleBar QPushButton:hover {
background-color: #C1C1C1;
}
LoQTitleBar QPushButton::menu-indicator {
image: none;
}
QToolButton[ss="MainTab"],
QToolButton[ss="CtrlTab"] {
border: none;
}
QToolButton[ss="MainTab"]:checked,
QToolButton[ss="MainTab"]:hover {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ddd, stop: 1.0 #8cd);
font-size: 15px;
color: #04d;
}
QToolButton[ss="CtrlTab"]:checked,
QToolButton[ss="CtrlTab"]:hover {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eee, stop: 1.0 #ade);
font-size: 15px;
color: #04d;
}
QPushButton#bnSelectFile {
border-radius: 4px;
background-color: #19c;
border: 1px solid #888;
padding: 3px 6px;
}
QPushButton#bnSelectFile:pressed {
background: transparent;
}
QPushButton[style="multiTool"] {
border-radius: 4px;
padding: 3px 6px;
}
QPushButton[style="multiTool"]:hover {
background-color: rgba(226,226,226,1);
}

View File

@ -1,77 +1,77 @@
#ifndef CONTROLPOWERSCHEDULE_H
#define CONTROLPOWERSCHEDULE_H
#include <QWidget>
#include <wDevicesManager/ledcard.h>
#include <communication/hpptclient.h>
#include <base/loemptydialog.h>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
namespace Ui {
class ControlPowerSchedule;
}
class ControlPowerSchedule : public QWidget
{
Q_OBJECT
public:
explicit ControlPowerSchedule(QWidget *parent = nullptr,QList<LedCard *> *m_pLedlist=nullptr);
~ControlPowerSchedule();
private:
Ui::ControlPowerSchedule *ui;
protected slots:
void refreshLable();
void OnClickAdd();
void OnClickImport();
void OnClickExport();
void OnClickDelete();
void OnClickClear();
void OnClickApply();
void OnClickReadback();
void OnClickClearSchedule();
//类似的控制操作信号和槽函数和变量定义
signals:
void sigSend(QJsonObject &,QString);
void sigHaveSchedule(bool);
protected slots:
void DeletePostingDlg();
void OnProHttpResponse(QString url, QString postMD5, QByteArray data);
void OnProHttpResponseAll(QString url, QString postMD5, QByteArray data);
void onSelectedDeviceList(QList<LedCard*> *);
void onReadbackAllThisPage();
void OnControlTypeSwitchIndexChanged(int index);
private:
QList<LedCard *> *m_pLedlist=nullptr;
LedCard *m_pLedCard = nullptr;
LedCard *m_oldLedlist = nullptr;
HpptClient *pHpptClient = nullptr;
HpptClient *pHpptClientAll = nullptr;
QString m_strUrl="";
LoEmptyDialog * m_PostingDlg=nullptr;
QTimer *m_pGetAskTimer=nullptr;
bool m_bSelected=false;
QStandardItemModel * m_pModel;
bool JieXiJsonTaskPower(QJsonObject oTaskPower);
QJsonObject GetJsonObjectPowerSchedule();
};
class ReadOnlyDelegate: public QStyledItemDelegate
{
Q_OBJECT
public:
ReadOnlyDelegate(QWidget *parent = nullptr):QStyledItemDelegate(parent)
{}
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override //final
{
Q_UNUSED(parent)
Q_UNUSED(option)
Q_UNUSED(index)
return nullptr;
}
};
#endif // CONTROLPOWERSCHEDULE_H
#ifndef CONTROLPOWERSCHEDULE_H
#define CONTROLPOWERSCHEDULE_H
#include <QWidget>
#include <device/ledcard.h>
#include <communication/hpptclient.h>
#include <base/loemptydialog.h>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
namespace Ui {
class ControlPowerSchedule;
}
class ControlPowerSchedule : public QWidget
{
Q_OBJECT
public:
explicit ControlPowerSchedule(QWidget *parent = nullptr,QList<LedCard *> *m_pLedlist=nullptr);
~ControlPowerSchedule();
void refreshLable();
private:
Ui::ControlPowerSchedule *ui;
protected slots:
void OnClickAdd();
void OnClickImport();
void OnClickExport();
void OnClickDelete();
void OnClickClear();
void OnClickApply();
void OnClickReadback();
void OnClickClearSchedule();
//类似的控制操作信号和槽函数和变量定义
signals:
void sigSend(QJsonObject &,QString);
void sigHaveSchedule(bool);
protected slots:
void DeletePostingDlg();
void OnProHttpResponse(QString url, QString postMD5, QByteArray data);
void OnProHttpResponseAll(QString url, QString postMD5, QByteArray data);
void onSelectedDeviceList(QList<LedCard*> *);
void onReadbackAllThisPage();
void OnControlTypeSwitchIndexChanged(int index);
private:
QList<LedCard *> *m_pLedlist=nullptr;
LedCard *m_pLedCard = nullptr;
LedCard *m_oldLedlist = nullptr;
HpptClient *pHpptClient = nullptr;
HpptClient *pHpptClientAll = nullptr;
QString m_strUrl="";
LoEmptyDialog * m_PostingDlg=nullptr;
QTimer *m_pGetAskTimer=nullptr;
bool m_bSelected=false;
QStandardItemModel * m_pModel;
bool JieXiJsonTaskPower(QJsonObject oTaskPower);
QJsonObject GetJsonObjectPowerSchedule();
};
class ReadOnlyDelegate: public QStyledItemDelegate
{
Q_OBJECT
public:
ReadOnlyDelegate(QWidget *parent = nullptr):QStyledItemDelegate(parent)
{}
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override //final
{
Q_UNUSED(parent)
Q_UNUSED(option)
Q_UNUSED(index)
return nullptr;
}
};
#endif // CONTROLPOWERSCHEDULE_H

View File

@ -1,255 +1,255 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ControlPowerSchedule</class>
<widget class="QWidget" name="ControlPowerSchedule">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>422</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Edit area</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="pushButtonAdd">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonDelete">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonClear">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonImport">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Import</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonExport">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="labelPowerScheduleTip">
<property name="text">
<string>It is power off state outside the schedule time period</string>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="tableView">
<property name="styleSheet">
<string notr="true">background-color: #FFFFFF;</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Send command</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonApply">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonClearSchedule">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Clear Schedule</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonReadback">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Readback</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ControlPowerSchedule</class>
<widget class="QWidget" name="ControlPowerSchedule">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>422</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Edit area</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="pushButtonAdd">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonDelete">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonClear">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonImport">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Import</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonExport">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="labelPowerScheduleTip">
<property name="text">
<string>It is power off state outside the schedule time period</string>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="tableView">
<property name="styleSheet">
<string notr="true">background-color: #FFFFFF;</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Send command</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonApply">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonClearSchedule">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Clear Schedule</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonReadback">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Readback</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,155 @@
#include "controlpowerwidget.h"
#include "gutil/qgui.h"
#include "globaldefine.h"
#include "base/waitingdlg.h"
#include "tools.h"
#include <QMessageBox>
ControlPowerWidget::ControlPowerWidget(QWidget *parent, QList<LedCard *> *list) : QWidget(parent) {
auto vBox = new VBox(this);
lbScreenCfg = new QLabel;
lbScreenCfg->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbScreenCfg);
auto hBox = new HBox(vBox);
hBox->addStretch();
fdManual = new QRadioButton;
hBox->addWidget(fdManual);
hBox->addSpacing(40);
fdSchedule = new QRadioButton;
hBox->addWidget(fdSchedule);
hBox->addStretch();
auto stack = new QStackedLayout(vBox);
{
auto vBox = new VBox(stack);
vBox->addSpacing(20);
auto hBox = new HBox(vBox);
hBox->addStretch();
lbScreen = new QLabel;
hBox->addWidget(lbScreen);
fdScreen = new SwitchControl;
fdScreen->setMinimumSize(QSize(80, 33));
fdScreen->setSliderColor(QColor(0, 0, 0), QColor(0, 160, 230));
fdScreen->setBgColor(QColor(200,200,200), QColor(0x00cc00));
fdScreen->setTextColor(QColor(100,100,100), QColor(0, 160, 230));
connect(fdScreen, &SwitchControl::checkedChanged, this, [this](bool checked) {
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "SetScreenOn");
json.insert("_type", "SetScreenOn");
json.insert("on", checked);
if(gSelCards->count() == 1) {
auto waitingDlg = new WaitingDlg(this, (checked ? tr("SetScreenOn") : tr("SetScreenOff"))+" ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [reply, waitingDlg] {
Def_CtrlSetReqAfter
});
} else {
if(checked) foreach(auto card, *gSelCards) {
Def_CtrlSetMulti(tr("SetScreenOn"))
}
else foreach(auto card, *gSelCards) {
Def_CtrlSetMulti(tr("SetScreenOff"))
}
}
});
hBox->addWidget(fdScreen);
hBox->addStretch();
btnScreenGet = new QPushButton;
btnScreenGet->setMinimumSize(QSize(60, 30));
btnScreenGet->setProperty("ssType", "progManageTool");
connect(btnScreenGet, &QPushButton::clicked, this, [this] {
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "IsScreenOn");
json.insert("_type", "IsScreenOn");
if(gSelCards->count() == 1) {
auto waitingDlg = new WaitingDlg(this, tr("IsScreenOn")+" ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg] {
Def_CtrlSingleGetReply
waitingDlg->success();
fdScreen->setCheckedStatus(json["on"].toBool());
});
} else {
foreach(auto card, *gSelCards) {
auto reply = Tools::netManager().post(reqForJson("http://"+card->m_strCardIp+":2016/settings"), QJsonDocument{json}.toJson(QJsonDocument::Compact));
auto cardId = card->m_strCardId;
connect(reply, &QNetworkReply::finished, this, [reply, cardId] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(err.isEmpty()) err = json["on"].toBool() ? tr("On") : tr("Off");
gFdResInfo->append(cardId+" "+tr("IsScreenOn")+" "+err);
});
}
}
});
vBox->addWidget(btnScreenGet, 0, Qt::AlignCenter);
vBox->addStretch();
}
m_pSchedule = new ControlPowerSchedule(this, list);
connect(m_pSchedule, &ControlPowerSchedule::sigHaveSchedule, this, [=](bool b) {
if(b) fdSchedule->setChecked(true);
else fdManual->setChecked(true);
});
stack->addWidget(m_pSchedule);
connect(fdSchedule, &QRadioButton::toggled, stack, &QStackedLayout::setCurrentIndex);
fdManual->setChecked(true);
connect(gDevicePanel, &DevicePanel::sigSelectedDeviceList, this, [this] {
if(isVisible()) init();
});
transUi();
}
void ControlPowerWidget::showEvent(QShowEvent *event) {
QWidget::showEvent(event);
init();
}
void ControlPowerWidget::init() {
bool isSingle = gSelCards->count()==1;
if(! isSingle) return;
auto card = gSelCards->at(0);
QJsonObject json;
json.insert("_id", "IsScreenOn");
json.insert("_type", "IsScreenOn");
auto reply = Tools::netManager().post(reqForJson("http://"+card->m_strCardIp+":2016/settings"), QJsonDocument{json}.toJson(QJsonDocument::Compact));
connect(reply, &QNetworkReply::finished, this, [this, reply] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
fdScreen->setCheckedStatus(json["on"].toBool());
});
}
void ControlPowerWidget::changeEvent(QEvent *event) {
QWidget::changeEvent(event);
if(event->type() == QEvent::LanguageChange) transUi();
}
void ControlPowerWidget::transUi() {
lbScreenCfg->setText(tr("Power Configuration"));
fdManual->setText(tr("Manual"));
fdSchedule->setText(tr("Schedule"));
lbScreen->setText(tr("Power"));
fdScreen->setText(tr("Off"), tr("On"));
btnScreenGet->setText(tr("Readback"));
m_pSchedule->refreshLable();
}

View File

@ -0,0 +1,29 @@
#ifndef CONTROLPOWERWIDGET_H
#define CONTROLPOWERWIDGET_H
#include <device/controlpowerschedule.h>
#include <QRadioButton>
#include <base/switchcontrol.h>
class ControlPowerWidget : public QWidget {
Q_OBJECT
public:
explicit ControlPowerWidget(QWidget *parent = nullptr,QList<LedCard *> *m_pLedlist=nullptr);
protected:
void showEvent(QShowEvent *event) override;
void init();
void changeEvent(QEvent *) override;
void transUi();
private:
ControlPowerSchedule *m_pSchedule=nullptr;
QLabel *lbScreenCfg;
QRadioButton *fdManual;
QRadioButton *fdSchedule;
QLabel *lbScreen;
SwitchControl *fdScreen;
QPushButton *btnScreenGet;
};
#endif // CONTROLPOWERWIDGET_H

View File

@ -1,67 +1,67 @@
#ifndef CONTROLTESTWIDGET_H
#define CONTROLTESTWIDGET_H
#include <QWidget>
#include <wDevicesManager/ledcard.h>
#include <communication/hpptclient.h>
#include <base/loemptydialog.h>
namespace Ui {
class ControlTestWidget;
}
class ControlTestWidget : public QWidget
{
Q_OBJECT
public:
explicit ControlTestWidget(QWidget *parent = nullptr,QList<LedCard *> *m_pLedlist=nullptr);
~ControlTestWidget();
private:
Ui::ControlTestWidget *ui;
protected slots:
void OnStartTestLine();
void OnStartTestGray();
void OnStartTestColor();
void OnStopTest();
void OnpushButton1();
void OnpushButton2();
void OnpushButton3();
void OnpushButton4();
void OnpushButton5();
void OnpushButton6();
void OnpushButton7();
void OnpushButton8();
void OnpushButton9();
void OnpushButton0();
void OnpushButtonClear();
void OnpushButtonReset();
void OnpushButtonAnycast();
void refreshLable();
//类似的控制操作信号和槽函数和变量定义
signals:
void sigTcpSend(int);
void sigSend(QJsonObject &,QString);
protected slots:
void DeletePostingDlg();
void OnProHttpResponse(QString url, QString postMD5, QByteArray data);
void OnProHttpResponseAll(QString url, QString postMD5, QByteArray data);
void onSelectedDeviceList(QList<LedCard*> *);
void onReadbackAllThisPage();
void OnControlTypeSwitchIndexChanged(int index);
private:
QList<LedCard *> *m_pLedlist=nullptr;
LedCard *m_pLedCard = nullptr;
LedCard *m_oldLedlist = nullptr;
HpptClient *pHpptClient = nullptr;
HpptClient *pHpptClientAll = nullptr;
QString m_strUrl="";
LoEmptyDialog * m_PostingDlg=nullptr;
QTimer *m_pGetAskTimer=nullptr;
bool m_bSelected=false;
void SendAnycastCmd(QString strIp,int iProgramIndex);
};
#endif // CONTROLTESTWIDGET_H
#ifndef CONTROLTESTWIDGET_H
#define CONTROLTESTWIDGET_H
#include <QWidget>
#include <device/ledcard.h>
#include <communication/hpptclient.h>
#include <base/loemptydialog.h>
namespace Ui {
class ControlTestWidget;
}
class ControlTestWidget : public QWidget
{
Q_OBJECT
public:
explicit ControlTestWidget(QWidget *parent = nullptr,QList<LedCard *> *m_pLedlist=nullptr);
~ControlTestWidget();
private:
Ui::ControlTestWidget *ui;
protected slots:
void OnStartTestLine();
void OnStartTestGray();
void OnStartTestColor();
void OnStopTest();
void OnpushButton1();
void OnpushButton2();
void OnpushButton3();
void OnpushButton4();
void OnpushButton5();
void OnpushButton6();
void OnpushButton7();
void OnpushButton8();
void OnpushButton9();
void OnpushButton0();
void OnpushButtonClear();
void OnpushButtonReset();
void OnpushButtonAnycast();
void refreshLable();
//类似的控制操作信号和槽函数和变量定义
signals:
void sigTcpSend(int);
void sigSend(QJsonObject &,QString);
protected slots:
void DeletePostingDlg();
void OnProHttpResponse(QString url, QString postMD5, QByteArray data);
void OnProHttpResponseAll(QString url, QString postMD5, QByteArray data);
void onSelectedDeviceList(QList<LedCard*> *);
void onReadbackAllThisPage();
void OnControlTypeSwitchIndexChanged(int index);
private:
QList<LedCard *> *m_pLedlist=nullptr;
LedCard *m_pLedCard = nullptr;
LedCard *m_oldLedlist = nullptr;
HpptClient *pHpptClient = nullptr;
HpptClient *pHpptClientAll = nullptr;
QString m_strUrl="";
LoEmptyDialog * m_PostingDlg=nullptr;
QTimer *m_pGetAskTimer=nullptr;
bool m_bSelected=false;
void SendAnycastCmd(QString strIp,int iProgramIndex);
};
#endif // CONTROLTESTWIDGET_H

View File

@ -1,60 +1,60 @@
#ifndef CONTROLVOLUMESCHEDULE_H
#define CONTROLVOLUMESCHEDULE_H
#include <QWidget>
#include <wDevicesManager/ledcard.h>
#include <communication/hpptclient.h>
#include <base/loemptydialog.h>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
namespace Ui {
class ControlVolumeSchedule;
}
class ControlVolumeSchedule : public QWidget
{
Q_OBJECT
public:
explicit ControlVolumeSchedule(QWidget *parent = nullptr,QList<LedCard *> *m_pLedlist=nullptr);
~ControlVolumeSchedule();
protected slots:
void refreshLable();
void OnClickAdd();
void OnClickImport();
void OnClickExport();
void OnClickDelete();
void OnClickClear();
void OnClickApply();
void OnClickReadback();
private:
Ui::ControlVolumeSchedule *ui;
//类似的控制操作信号和槽函数和变量定义
signals:
void sigSend(QJsonObject &,QString);
void sigHaveSchedule(bool);
protected slots:
void DeletePostingDlg();
void OnProHttpResponse(QString url, QString postMD5, QByteArray data);
void OnProHttpResponseAll(QString url, QString postMD5, QByteArray data);
void onSelectedDeviceList(QList<LedCard*> *);
void onReadbackAllThisPage();
void OnControlTypeSwitchIndexChanged(int index);
private:
QList<LedCard *> *m_pLedlist=nullptr;
LedCard *m_pLedCard = nullptr;
LedCard *m_oldLedlist = nullptr;
HpptClient *pHpptClient = nullptr;
HpptClient *pHpptClientAll = nullptr;
QString m_strUrl="";
LoEmptyDialog * m_PostingDlg=nullptr;
QTimer *m_pGetAskTimer=nullptr;
bool m_bSelected=false;
QStandardItemModel * m_pModel;
bool JieXiJsonTaskVolume(QJsonObject oTaskVolume);
QJsonObject GetJsonObjectVolumeSchedule();
};
#endif // CONTROLVOLUMESCHEDULE_H
#ifndef CONTROLVOLUMESCHEDULE_H
#define CONTROLVOLUMESCHEDULE_H
#include <QWidget>
#include <device/ledcard.h>
#include <communication/hpptclient.h>
#include <base/loemptydialog.h>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
namespace Ui {
class ControlVolumeSchedule;
}
class ControlVolumeSchedule : public QWidget
{
Q_OBJECT
public:
explicit ControlVolumeSchedule(QWidget *parent = nullptr,QList<LedCard *> *m_pLedlist=nullptr);
~ControlVolumeSchedule();
void refreshLable();
protected slots:
void OnClickAdd();
void OnClickImport();
void OnClickExport();
void OnClickDelete();
void OnClickClear();
void OnClickApply();
void OnClickReadback();
private:
Ui::ControlVolumeSchedule *ui;
//类似的控制操作信号和槽函数和变量定义
signals:
void sigSend(QJsonObject &,QString);
void sigHaveSchedule(bool);
protected slots:
void DeletePostingDlg();
void OnProHttpResponse(QString url, QString postMD5, QByteArray data);
void OnProHttpResponseAll(QString url, QString postMD5, QByteArray data);
void onSelectedDeviceList(QList<LedCard*> *);
void onReadbackAllThisPage();
void OnControlTypeSwitchIndexChanged(int index);
private:
QList<LedCard *> *m_pLedlist=nullptr;
LedCard *m_pLedCard = nullptr;
LedCard *m_oldLedlist = nullptr;
HpptClient *pHpptClient = nullptr;
HpptClient *pHpptClientAll = nullptr;
QString m_strUrl="";
LoEmptyDialog * m_PostingDlg=nullptr;
QTimer *m_pGetAskTimer=nullptr;
bool m_bSelected=false;
QStandardItemModel * m_pModel;
bool JieXiJsonTaskVolume(QJsonObject oTaskVolume);
QJsonObject GetJsonObjectVolumeSchedule();
};
#endif // CONTROLVOLUMESCHEDULE_H

View File

@ -1,251 +1,251 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ControlVolumeSchedule</class>
<widget class="QWidget" name="ControlVolumeSchedule">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>708</width>
<height>447</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="labelVolumeScheduleTip">
<property name="text">
<string>Defalut volume tip</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="pushButtonAdd">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonDelete">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonClear">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="labelDefalutVolume">
<property name="text">
<string>Default Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: #FFFFFF;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>(0-15)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonImport">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Import</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonExport">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTableView" name="tableView">
<property name="styleSheet">
<string notr="true">background-color: #FFFFFF;</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonApply">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonReadback">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Readback</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ControlVolumeSchedule</class>
<widget class="QWidget" name="ControlVolumeSchedule">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>708</width>
<height>447</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="labelVolumeScheduleTip">
<property name="text">
<string>Defalut volume tip</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="pushButtonAdd">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonDelete">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonClear">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="labelDefalutVolume">
<property name="text">
<string>Default Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: #FFFFFF;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>(0-15)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonImport">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Import</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonExport">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTableView" name="tableView">
<property name="styleSheet">
<string notr="true">background-color: #FFFFFF;</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonApply">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonReadback">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Readback</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,154 @@
#include "controlvolumewidget.h"
#include "gutil/qgui.h"
#include "globaldefine.h"
#include "base/waitingdlg.h"
#include "tools.h"
#include <QMessageBox>
ControlVolumeWidget::ControlVolumeWidget(QWidget *parent,QList<LedCard *> *list) : QWidget(parent) {
auto vBox = new VBox(this);
lbVolumeControl = new QLabel;
lbVolumeControl->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbVolumeControl);
auto hBox = new HBox(vBox);
hBox->addStretch();
fdManual = new QRadioButton;
hBox->addWidget(fdManual);
hBox->addSpacing(40);
fdSchedule = new QRadioButton;
hBox->addWidget(fdSchedule);
hBox->addStretch();
auto stack = new QStackedLayout(vBox);
{
auto vBox = new VBox(stack);
vBox->addSpacing(20);
auto hBox = new HBox(vBox);
hBox->addStretch();
lbVolume = new QLabel;
hBox->addWidget(lbVolume);
fdVolume = new QSlider(Qt::Horizontal);
fdVolume->setTickPosition(QSlider::TicksAbove);
fdVolume->setRange(0, 15);
connect(fdVolume, &QSlider::sliderReleased, this, [=] {
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "SetVolume");
json.insert("_type", "SetVolume");
json.insert("volume", fdVolume->value());
if(gSelCards->count() == 1) {
auto waitingDlg = new WaitingDlg(this, tr("SetVolume")+" ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [reply, waitingDlg] {
Def_CtrlSetReqAfter
});
} else {
foreach(auto card, *gSelCards) {
Def_CtrlSetMulti(tr("SetVolume"))
}
}
});
hBox->addWidget(fdVolume);
auto lbCurVol = new QLabel;
lbCurVol->setMinimumWidth(30);
connect(fdVolume, &QSlider::valueChanged, lbCurVol, (void(QLabel::*)(int))&QLabel::setNum);
hBox->addWidget(lbCurVol);
hBox->addStretch();
fdVolumeGet = new QPushButton;
fdVolumeGet->setMinimumSize(QSize(60, 30));
fdVolumeGet->setProperty("ssType", "progManageTool");
connect(fdVolumeGet, &QPushButton::clicked, this, [=] {
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "GetVolume");
json.insert("_type", "GetVolume");
if(gSelCards->count() == 1) {
auto waitingDlg = new WaitingDlg(this, tr("GetVolume")+" ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg] {
Def_CtrlSingleGetReply
waitingDlg->success();
fdVolume->setValue(json["volume"].toInt());
});
} else {
foreach(auto card, *gSelCards) {
auto reply = Tools::netManager().post(reqForJson("http://"+card->m_strCardIp+":2016/settings"), QJsonDocument{json}.toJson(QJsonDocument::Compact));
auto cardId = card->m_strCardId;
connect(reply, &QNetworkReply::finished, this, [reply, cardId] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(err.isEmpty()) err = QString::number(json["volume"].toInt());
gFdResInfo->append(cardId+" "+tr("GetVolume")+" "+err);
});
}
}
});
vBox->addWidget(fdVolumeGet, 0, Qt::AlignCenter);
vBox->addStretch();
}
m_pSchedule = new ControlVolumeSchedule(this, list);
connect(m_pSchedule, &ControlVolumeSchedule::sigHaveSchedule, this, [=](bool b) {
if(b) fdSchedule->setChecked(true);
else fdManual->setChecked(true);
});
stack->addWidget(m_pSchedule);
connect(fdSchedule, &QRadioButton::toggled, stack, &QStackedLayout::setCurrentIndex);
fdManual->setChecked(true);
connect(gDevicePanel, &DevicePanel::sigSelectedDeviceList, this, [this] {
if(isVisible()) init();
});
transUi();
}
void ControlVolumeWidget::showEvent(QShowEvent *event) {
QWidget::showEvent(event);
init();
}
void ControlVolumeWidget::init() {
bool isSingle = gSelCards->count()==1;
if(! isSingle) return;
auto card = gSelCards->at(0);
QJsonObject json;
json.insert("_id", "GetVolume");
json.insert("_type", "GetVolume");
auto reply = Tools::netManager().post(reqForJson("http://"+card->m_strCardIp+":2016/settings"), QJsonDocument{json}.toJson(QJsonDocument::Compact));
connect(reply, &QNetworkReply::finished, this, [this, reply] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
fdVolume->setValue(json["volume"].toInt());
});
}
void ControlVolumeWidget::changeEvent(QEvent *event) {
QWidget::changeEvent(event);
if(event->type() == QEvent::LanguageChange) transUi();
}
void ControlVolumeWidget::transUi() {
lbVolumeControl->setText(tr("Volume Control"));
fdManual->setText(tr("Manual"));
fdSchedule->setText(tr("Schedule"));
lbVolume->setText(tr("Volume"));
fdVolumeGet->setText(tr("Readback"));
m_pSchedule->refreshLable();
}

View File

@ -0,0 +1,31 @@
#ifndef CONTROLVOLUMEWIDGET_H
#define CONTROLVOLUMEWIDGET_H
#include <QWidget>
#include <device/controlvolumeschedule.h>
#include "QStackedWidget"
#include <QRadioButton>
class ControlVolumeWidget : public QWidget {
Q_OBJECT
public:
explicit ControlVolumeWidget(QWidget *parent = nullptr,QList<LedCard *> *m_pLedlist=nullptr);
protected:
void showEvent(QShowEvent *event) override;
void init();
void changeEvent(QEvent *) override;
void transUi();
private:
ControlVolumeSchedule *m_pSchedule;
QLabel *lbVolumeControl;
QRadioButton *fdManual;
QRadioButton *fdSchedule;
QLabel *lbVolume;
QSlider *fdVolume;
QPushButton *fdVolumeGet;
};
#endif // CONTROLVOLUMEWIDGET_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,119 @@
#ifndef CTRLADVANCEDPANEL_H
#define CTRLADVANCEDPANEL_H
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QTextEdit>
#include <QJsonObject>
#include <QGroupBox>
#include <QRadioButton>
#include <QCheckBox>
#include <QFile>
#include <QThread>
class CtrlAdvancedPanel : public QWidget {
Q_OBJECT
public:
explicit CtrlAdvancedPanel(QWidget *parent = nullptr);
protected:
void showEvent(QShowEvent *event) override;
void init();
void changeEvent(QEvent *) override;
void transUi();
void keyReleaseEvent(QKeyEvent *) override;
void mouseReleaseEvent(QMouseEvent *) override;
private:
bool isPassed{false};
QLabel *lbTitle;
QLabel *lbScreenWidth;
QLineEdit *fdScreenWidth;
QLabel *lbScreenHeight;
QLineEdit *fdScreenHeight;
QPushButton *btnScreenSet;
QLabel *lbAlias;
QLineEdit *fdAlias;
QPushButton *btnAliasSet;
QLabel *labelWebServer;
QComboBox *fdWebServerAddr;
QLabel *lbCompanyId;
QLineEdit *fdCompanyId;
QPushButton *btnWebServerSet;
QLabel *label;
QComboBox *fdRealtimeServer;
QPushButton *btnRealtimeServerSet;
QPushButton *btnRealtimeClear;
QPushButton *btnWareUpdate;
QLabel *lbWareTip;
QPushButton *btnApkCheck;
QComboBox *fdPkg;
QPushButton *fdUninstall;
QPushButton *btnIsRunning;
QPushButton *btnRestart;
QPushButton *btnClearProg;
QPushButton *btnGetLog;
QPushButton *btnSetBack, *btnPlayerBackSet, *btnPlayerBackClear;
QLabel *lbTimingReboot;
QPushButton *btnTimingRebootSet, *btnTimingRebootGet;
QGroupBox *grpM80, *grpY50;
QComboBox *fdM80Resolu, *fdDisMode;
QPushButton *btnM80Set, *btnY50Set;
QPushButton *btnM80Refresh;
QPushButton *btnM80Restore;
QLabel *lbDisMode;
QPushButton *btnDisModeSet, *btnDisModeGet;
QLabel *lbScreenPos, *lbScreenOff;
QPushButton *btnScreenOffSet, *btnScreenOffGet;
QGroupBox *grpHighForBusy;
QRadioButton *fdHighForBusy;
QRadioButton *fdTopLevelLH;
QPushButton *btnHighForBusySet;
QPushButton *btnGetTopLevel;
QPushButton *btnLedSet3;
QPushButton *btnLedSet4;
QPushButton *btnBindTaxiIc;
QGroupBox *grpMinMaxBrightness;
QLabel *lbMinBright;
QLineEdit *fdMinBright;
QPushButton *btnMinBrightGet;
QPushButton *btnMinBrightSet;
QLabel *label_3;
QLineEdit *fdMaxBright;
QPushButton *btnMaxBrightGet;
QPushButton *btnMaxBrightSet;
QGroupBox *grpBoxHiddenSettings;
QPushButton *btnSysUpd, *btnMcuUpd, *btnMcuGet;
QLabel *lbRotate, *lbBaudCfg, *lbBaudModel, *lbUart, *lbBaud;
QPushButton *btnBaudSet, *btnBaudGet;
QCheckBox *fdIsOpenADB;
QLabel *lbCustomJson;
QTextEdit *fdCustomJson;
QPushButton *btnSendCustomJson;
QLabel *lbTraficProtocol, *lbCardMode, *lbTraficPort;
QComboBox *fdServerType;
QPushButton *btnTraficProtSet, *btnTraficProtGet, *btnTraficSet, *btnTraficGet;
};
class PlayerBackSendThread : public QThread {
Q_OBJECT
public:
PlayerBackSendThread(const QString &file, const QString &ip);
QString file, ip;
QString err;
protected:
void run();
signals:
void emErr(QString);
};
#endif // CTRLADVANCEDPANEL_H

View File

@ -1,15 +1,12 @@
#ifndef CTRLBRIGHTPANEL_H
#define CTRLBRIGHTPANEL_H
#include "ledcard.h"
#include "base/table.h"
#include <QButtonGroup>
#include "gutil/qgui.h"
#include <QLabel>
#include <QPushButton>
#include <QRadioButton>
#include <QCheckBox>
#include <QSlider>
#include <QStackedLayout>
#include <QStyledItemDelegate>
class CtrlBrightPanel : public QWidget {
Q_OBJECT
@ -22,12 +19,13 @@ protected:
void transUi();
private:
bool restoreScheduleJson(QJsonObject, int = 100);
QJsonObject getScheduleJson(int = 100);
bool restoreScheduleJson(QJsonDocument &, int);
void getScheduleJson(QJsonObject &, int);
QLabel *lbBrightCfg;
QRadioButton *radioAuto;
QRadioButton *radioManual;
QRadioButton *radioSchedule;
QCheckBox *fdAdaptToOld;
char mSensi{-1};
char mTask{-1};

View File

@ -0,0 +1,424 @@
#include "ctrlhdmipanel.h"
#include "gutil/qgui.h"
#include "tools.h"
#include "globaldefine.h"
#include "base/waitingdlg.h"
#include <QMessageBox>
#include <QButtonGroup>
#include <QTimeEdit>
#include <QJsonArray>
CtrlHdmiPanel::CtrlHdmiPanel(QWidget *parent) : QWidget(parent) {
auto vBox = new QVBoxLayout(this);
lbHdmiCfg = new QLabel;
lbHdmiCfg->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbHdmiCfg);
auto line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
vBox->addWidget(line);
auto hBox = new QHBoxLayout();
hBox->addStretch();
fdManual = new QRadioButton;
hBox->addWidget(fdManual);
hBox->addSpacing(40);
fdSchedule = new QRadioButton;
hBox->addWidget(fdSchedule);
hBox->addStretch();
vBox->addLayout(hBox);
auto stacked = new QStackedLayout;
vBox->addLayout(stacked);
{
auto vBox = new VBox(stacked);
vBox->addSpacing(20);
auto hBox = new HBox(vBox);
hBox->addStretch();
fdAsync = new QRadioButton;
hBox->addWidget(fdAsync);
hBox->addSpacing(20);
fdHdmi = new QRadioButton("HDMI");
hBox->addWidget(fdHdmi);
hBox->addSpacing(20);
fdHdmi2 = new QRadioButton("HDMI 2");
hBox->addWidget(fdHdmi2);
hBox->addStretch();
auto btnGroup = new QButtonGroup(this);
btnGroup->addButton(fdAsync, 0);
btnGroup->addButton(fdHdmi, 1);
btnGroup->addButton(fdHdmi2, 2);
connect(btnGroup, &QButtonGroup::idToggled, this, [this](int id, bool checked) {
if(! checked) return;
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "SyncSwitch");
json.insert("_type", "SyncSwitch");
json.insert("switchOn", (bool)id);
if(id) json.insert("number", id);
if(gSelCards->count() == 1) {
auto waitingDlg = new WaitingDlg(this, checked ? tr("SyncSwitch") : tr("AnSyncSwitch"));
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [reply, waitingDlg] {
Def_CtrlSetReqAfter
});
} else {
foreach(auto card, *gSelCards) {
if(checked){
Def_CtrlSetMulti(tr("SyncSwitch"))
} else {
Def_CtrlSetMulti(tr("AnSyncSwitch"))
}
}
}
});
vBox->addSpacing(20);
hBox = new HBox(vBox);
hBox->addStretch();
btnGetSync = new QPushButton;
btnGetSync->setMinimumSize(60, 30);
btnGetSync->setProperty("ssType", "progManageTool");
connect(btnGetSync, &QPushButton::clicked, this, [this] {
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "IsSync");
json.insert("_type", "IsSync");
if(gSelCards->count() == 1) {
auto waitingDlg = new WaitingDlg(this, tr("IsSync"));
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg] {
Def_CtrlSingleGetReply
waitingDlg->success();
auto switchOn = json["switchOn"];
if(switchOn.isUndefined()) switchOn = json["result"];
if(! switchOn.toBool()) fdAsync->setChecked(true);
else if(json["number"].toInt()==2) fdHdmi2->setChecked(true);
else fdHdmi->setChecked(true);
});
} else {
foreach(auto card, *gSelCards) {
auto reply = Tools::netManager().post(reqForJson("http://"+card->m_strCardIp+":2016/settings"), QJsonDocument{json}.toJson(QJsonDocument::Compact));
auto cardId = card->m_strCardId;
connect(reply, &QNetworkReply::finished, this, [reply, cardId] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(err.isEmpty()) {
auto switchOn = json["switchOn"];
if(switchOn.isUndefined()) switchOn = json["result"];
if(! switchOn.toBool()) err = tr("Async");
else {
err = "HDMI";
auto number = json["number"].toInt();
if(number) err += " "+QString::number(number);
}
}
gFdResInfo->append(cardId+" "+err);
});
}
}
});
hBox->addWidget(btnGetSync);
hBox->addStretch();
vBox->addStretch();
}
{
auto vBox = new VBox(stacked);
auto hBox = new HBox(vBox);
hBox->setSpacing(10);
tableSche = new Table({
{"start", "", 100},
{"end", "", 100},
{"0", "", 60},
{"1", "", 60},
{"2", "", 60},
{"3", "", 60},
{"4", "", 60},
{"5", "", 60},
{"6", "", 60}
});
tableSche->setDefs();
tableSche->setStyleSheet("Table {selection-background-color: #8ce;}");
btnScheAdd = new QPushButton;
btnScheAdd->setMinimumSize(QSize(60, 30));
btnScheAdd->setProperty("ssType", "progManageTool");
connect(btnScheAdd, &QPushButton::clicked, this, [this] {
int row = tableSche->appendRow();
auto timeEdit = new QTimeEdit(QTime(0, 0));
timeEdit->setDisplayFormat("HH:mm");
timeEdit->setAlignment(Qt::AlignCenter);
tableSche->setCellWidget(row, "start", timeEdit);
timeEdit = new QTimeEdit(QTime(1, 0));
timeEdit->setDisplayFormat("HH:mm");
timeEdit->setAlignment(Qt::AlignCenter);
tableSche->setCellWidget(row, "end", timeEdit);
for(int i=0; i<7; i++) {
auto fd = new QCheckBox;
fd->setChecked(true);
tableSche->setCellWidget(row, QString::number(i), fd);
}
});
hBox->addWidget(btnScheAdd);
btnScheDel = new QPushButton;
btnScheDel->setMinimumSize(QSize(60, 30));
btnScheDel->setProperty("ssType", "progManageTool");
connect(btnScheDel, &QPushButton::clicked, this, [this] {
auto selected = tableSche->selectedRanges();
if(! selected.isEmpty()) tableSche->model()->removeRows(selected[0].topRow(), selected[0].rowCount());
});
hBox->addWidget(btnScheDel);
btnScheClear = new QPushButton;
btnScheClear->setMinimumSize(QSize(60, 30));
btnScheClear->setProperty("ssType", "progManageTool");
connect(btnScheClear, &QPushButton::clicked, tableSche, &Table::clearRows);
hBox->addWidget(btnScheClear);
hBox->addStretch();
btnScheImport = new QPushButton;
btnScheImport->setMinimumSize(QSize(0, 30));
btnScheImport->setProperty("ssType", "progManageTool");
connect(btnScheImport, &QPushButton::clicked, this, [this] {
auto dir = QSettings().value("CtrlScheduleDir").toString();
if(dir.isEmpty()) dir = "/";
QString scheFile = QFileDialog::getOpenFileName(this, tr("Import File"), dir, tr("Sync Schedule")+" (*.syncs)");
if(scheFile.isEmpty()) return;
QFile scheQFile(scheFile);
if(! scheQFile.open(QIODevice::ReadOnly)) return;
auto data = scheQFile.readAll();
scheQFile.close();
restoreScheduleJson(QJsonDocument::fromJson(data).object());
});
hBox->addWidget(btnScheImport);
btnScheExport = new QPushButton;
btnScheExport->setMinimumSize(QSize(0, 30));
btnScheExport->setProperty("ssType", "progManageTool");
connect(btnScheExport, &QPushButton::clicked, this, [this] {
QSettings settings;
auto dir = settings.value("CtrlScheduleDir").toString();
if(dir.isEmpty()) dir = "/";
QString scheFile = QFileDialog::getSaveFileName(this, tr("Save File"), dir, tr("Sync Schedule")+" (*.syncs)");
if(scheFile.isEmpty()) return;
settings.setValue("CtrlScheduleDir", QFileInfo(scheFile).absolutePath());
QFile scheQFile(scheFile);
if(! scheQFile.open(QIODevice::WriteOnly)) return;
scheQFile.write(QJsonDocument(getScheduleJson()).toJson());
scheQFile.close();
});
hBox->addWidget(btnScheExport);
labelSyncScheduleTip = new QLabel;
labelSyncScheduleTip->setWordWrap(true);
vBox->addWidget(labelSyncScheduleTip);
vBox->addWidget(tableSche);
hBox = new HBox(vBox);
hBox->addStretch();
btnScheSet = new QPushButton;
btnScheSet->setProperty("ssType", "progManageTool");
btnScheSet->setMinimumSize(QSize(60, 30));
connect(btnScheSet, &QPushButton::clicked, this, [this] {
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "SetTimingHdmiInTask");
json.insert("_type", "SetTimingHdmiInTask");
if(gSelCards->count() == 1) {
json.insert("HdmiInTask", getScheduleJson());
auto waitingDlg = new WaitingDlg(this, tr("SetTimingHdmiInTask"));
Def_CtrlReqPre;
connect(reply, &QNetworkReply::finished, this, [reply, waitingDlg] {
Def_CtrlSetReqAfter
});
} else {
foreach(auto card, *gSelCards) {
json.insert("HdmiInTask", getScheduleJson());
Def_CtrlSetMulti(tr("SetTimingHdmiInTask"))
}
}
});
hBox->addWidget(btnScheSet);
hBox->addStretch();
btnScheGet = new QPushButton;
btnScheGet->setMinimumSize(QSize(0, 30));
btnScheGet->setProperty("ssType", "progManageTool");
connect(btnScheGet, &QPushButton::clicked, this, [this] {
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "GetTimingHdmiInTask");
json.insert("_type", "GetTimingHdmiInTask");
if(gSelCards->count() == 1) {
auto waitingDlg = new WaitingDlg(this, tr("GetTimingHdmiInTask"));
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg] {
Def_CtrlSingleGetReply
waitingDlg->success();
restoreScheduleJson(json["creenTask"].toObject());
});
}
});
hBox->addWidget(btnScheGet);
hBox->addStretch();
}
auto m_buttonGroup = new QButtonGroup;
m_buttonGroup->addButton(fdManual, 0);
m_buttonGroup->addButton(fdSchedule, 1);
connect(m_buttonGroup,SIGNAL(buttonClicked(int)),stacked,SLOT(setCurrentIndex(int)));
fdManual->setChecked(true);
stacked->setCurrentIndex(0);
connect(gDevicePanel, &DevicePanel::sigSelectedDeviceList, this, [this] {
if(isVisible()) init();
});
transUi();
}
void CtrlHdmiPanel::showEvent(QShowEvent *event) {
QWidget::showEvent(event);
init();
}
void CtrlHdmiPanel::init() {
bool isSingle = gSelCards->count()==1;
btnScheGet->setEnabled(isSingle);
if(! isSingle) {
fdHdmi2->setVisible(true);
return;
}
auto card = gSelCards->at(0);
fdHdmi2->setVisible(card->m_strCardId.startsWith("m8s", Qt::CaseInsensitive));
QJsonObject json;
json.insert("_id", "IsSync");
json.insert("_type", "IsSync");
auto reply = Tools::netManager().post(reqForJson("http://"+card->m_strCardIp+":2016/settings"), QJsonDocument{json}.toJson(QJsonDocument::Compact));
connect(reply, &QNetworkReply::finished, this, [this, reply] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
auto switchOn = json["switchOn"];
if(switchOn.isUndefined()) switchOn = json["result"];
if(! switchOn.toBool()) fdAsync->setChecked(true);
else if(json["number"].toInt()==2) fdHdmi2->setChecked(true);
else fdHdmi->setChecked(true);
});
}
void CtrlHdmiPanel::changeEvent(QEvent *event) {
QWidget::changeEvent(event);
if(event->type() == QEvent::LanguageChange) transUi();
}
void CtrlHdmiPanel::transUi() {
lbHdmiCfg->setText(tr("HDMI Configuration"));
fdManual->setText(tr("Manual"));
fdSchedule->setText(tr("Schedule"));
fdAsync->setText(tr("Async"));
btnGetSync->setText(tr("Readback"));
tableSche->setHeaderText("start", tr("Start Time"));
tableSche->setHeaderText("end", tr("End Time"));
tableSche->setHeaderText("0", tr("SUN"));
tableSche->setHeaderText("1", tr("MON"));
tableSche->setHeaderText("2", tr("TUE"));
tableSche->setHeaderText("3", tr("WED"));
tableSche->setHeaderText("4", tr("THU"));
tableSche->setHeaderText("5", tr("FRI"));
tableSche->setHeaderText("6", tr("SAT"));
btnScheAdd->setText(tr("Add"));
btnScheSet->setText(tr("Apply"));
btnScheClear->setText(tr("Clear"));
btnScheDel->setText(tr("Delete"));
btnScheImport->setText(tr("Import"));
btnScheExport->setText(tr("Export"));
labelSyncScheduleTip->setText(tr("By default, the asynchronous content is played, and the synchronous signal content is played in the fixed time period"));
btnScheSet->setText(tr("Apply"));
btnScheGet->setText(tr("Readback"));
}
void CtrlHdmiPanel::restoreScheduleJson(QJsonObject oTaskSync) {
tableSche->setRowCount(0);
auto oSchedules = oTaskSync["schedules"].toArray();
foreach(auto oSchedule, oSchedules) {
int row = tableSche->rowCount();
tableSche->insertRow(row);
auto timeEdit = new QTimeEdit(QTime::fromString(oSchedule["startTime"].toString()+":00"));
timeEdit->setDisplayFormat("HH:mm");
timeEdit->setAlignment(Qt::AlignCenter);
tableSche->setCellWidget(row, "start", timeEdit);
timeEdit = new QTimeEdit(QTime::fromString(oSchedule["endTime"].toString()+":00"));
timeEdit->setDisplayFormat("HH:mm");
timeEdit->setAlignment(Qt::AlignCenter);
tableSche->setCellWidget(row, "end", timeEdit);
if(oSchedule["filterType"].toString()=="None") for(int i=0; i<7; i++) {
auto fd = new QCheckBox;
fd->setChecked(true);
tableSche->setCellWidget(row, QString::number(i), fd);
} else if(oSchedule["filterType"].toString()=="Week") {
auto weekFilter = oSchedule["weekFilter"].toArray();
for(int i=0; i<7; i++) {
auto fd = new QCheckBox;
if(weekFilter.contains(i)) fd->setChecked(true);
tableSche->setCellWidget(row, QString::number(i), fd);
}
}
}
}
QJsonObject CtrlHdmiPanel::getScheduleJson() {
QJsonArray schedules;
for(int i=0; i<tableSche->rowCount(); i++) {
QJsonObject schedule;
schedule["timeType"] = "Range";
schedule["startTime"] = static_cast<QTimeEdit*>(tableSche->cellWidget(i, "start"))->text();
schedule["endTime"] = static_cast<QTimeEdit*>(tableSche->cellWidget(i, "end"))->text();
schedule["dateType"] = "All";
schedule["monthFilter"] = QJsonArray();
QJsonArray weekFilter;
for(int d=0; d<7; d++) if(static_cast<QCheckBox*>(tableSche->cellWidget(i, QString::number(d)))->isChecked()) weekFilter.append(d);
if(weekFilter.size()>=7) {
schedule["filterType"] = "None";
weekFilter = QJsonArray();
} else schedule["filterType"] = "Week";
schedule["weekFilter"] = weekFilter;
schedules.append(schedule);
}
return QJsonObject{
{"createBy", "alahover"},
{"name", "TimingScreen"},
{"schedules", schedules}
};
}

View File

@ -0,0 +1,38 @@
#ifndef CTRLHDMIPANEL_H
#define CTRLHDMIPANEL_H
#include "base/switchcontrol.h"
#include "gutil/qgui.h"
#include <QLabel>
#include <QRadioButton>
#include <QPushButton>
class CtrlHdmiPanel : public QWidget {
Q_OBJECT
public:
explicit CtrlHdmiPanel(QWidget *parent = nullptr);
void restoreScheduleJson(QJsonObject oTaskSync);
QJsonObject getScheduleJson();
protected:
void showEvent(QShowEvent *event) override;
void init();
void changeEvent(QEvent *) override;
void transUi();
private:
QLabel *lbHdmiCfg;
QRadioButton *fdManual, *fdSchedule, *fdAsync, *fdHdmi, *fdHdmi2;
QPushButton *btnGetSync;
Table *tableSche;
QPushButton *btnScheAdd;
QPushButton *btnScheDel;
QPushButton *btnScheClear;
QPushButton *btnScheImport;
QPushButton *btnScheExport;
QLabel *labelSyncScheduleTip;
QPushButton *btnScheSet;
QPushButton *btnScheGet;
};
#endif // CTRLHDMIPANEL_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
#ifndef CTRLNETWORKPANEL_H
#define CTRLNETWORKPANEL_H
#include <device/ledcard.h>
#include <communication/hpptclient.h>
#include <base/loemptydialog.h>
#include "base/qiplineedit.h"
#include "base/switchcontrol.h"
#include <QButtonGroup>
#include <QJsonObject>
#include <QRadioButton>
#include <QGroupBox>
#include <QCheckBox>
struct ApnInfo {
QString apn;
QString carrier;
QString mcc;
QString mmsc;
QString mmsport;
QString mmsproxy;
QString mnc;
QString password;
QString port;
QString proxy;
QString server;
QString type;
QString user;
};
class CtrlNetworkPanel : public QWidget {
Q_OBJECT
public:
explicit CtrlNetworkPanel(QWidget *parent = nullptr);
void getCurrentAPN(QString &);
protected:
void showEvent(QShowEvent *event) override;
void init();
void changeEvent(QEvent *) override;
void transUi();
private:
QLabel *lbLanCfg;
QRadioButton *fdDhcp, *fdSpecifyIp;
QGroupBox *gBoxSpecifyIp;
QLabel *labelIpAddress;
QIPLineEdit *fdIP;
QLabel *labelMaskAddress;
QIPLineEdit *fdGateWay;
QLabel *labelGateway;
QIPLineEdit *fdMask;
QLabel *labelDnsAddress;
QIPLineEdit *fdDns;
QPushButton *btnLanSet;
QPushButton *btnLanGet;
QLabel *label_5;
QLabel *lbWifiName;
QLabel *lbWifiPassword;
QRadioButton *fdIsWifi, *fdIsHotspot;
QComboBox *fdWifiName;
QLineEdit *fdWifiPassword;
QPushButton *btnScan;
QPushButton *btnWiFiSet;
QPushButton *btnWiFiGet;
QLabel *lbHotspotName;
QLabel *lbHotspotPassword;
QLineEdit *fdHotspotName;
QLineEdit *fdHotspotPassword;
QFrame *line_3;
QLabel *lbCellularConfig;
QCheckBox *fdEnableCellular;
QPushButton *btnSIMStatusGet;
QGroupBox *groupApn;
QLabel *lbCheckStatusTip;
QLabel *label_2;
QComboBox *fdMcc;
QLabel *label_3;
QComboBox *fdCarrierName;
QPushButton *btnAPNCusSet, *btnAPNCusGet;
QLabel *label_10;
SwitchControl *fdFightModel;
QPushButton *btnFlightModelGet;
QLabel *lbCus_Name, *lbCus_User, *lbCus_pwd, *lbCus_mmsPort, *lbCus_mmsProxy, *lbCus_port, *lbCus_proxy, *lbCus_server, *lbCus_type;
QLineEdit *fdCus_apn, *fdCus_Name, *fdCus_User, *fdCus_pwd, *fdCus_type, *fdCus_server, *fdCus_port, *fdCus_proxy, *fdCus_mmsc, *fdCus_mmsPort, *fdCus_mmsProxy;
};
#endif // CTRLNETWORKPANEL_H

View File

@ -0,0 +1,253 @@
#include "ctrlpwdpanel.h"
#include "gutil/qgui.h"
#include "base/waitingdlg.h"
#include "QFileDialog"
#include <QMessageBox>
#include <QJsonObject>
#include <globaldefine.h>
#include "tools.h"
CtrlPwdPanel::CtrlPwdPanel(QWidget *parent) : QWidget(parent) {
auto vBox = new VBox(this);
lbPwdConfig = new QLabel;
lbPwdConfig->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbPwdConfig);
vBox->addSpacing(20);
auto grid = new Grid(vBox);
grid->setColumnStretch(0, 1);
grid->setColumnStretch(3, 1);
lbOldPwd = new QLabel;
grid->addWidget(lbOldPwd, 0, 1);
lbNewPwd = new QLabel;
grid->addWidget(lbNewPwd, 1, 1);
lbPwdAgain = new QLabel;
grid->addWidget(lbPwdAgain, 2, 1);
fdOldPwd = new QLineEdit;
fdOldPwd->setFixedSize(160, 30);
fdOldPwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
grid->addWidget(fdOldPwd, 0, 2);
fdNewPwd = new QLineEdit;
fdNewPwd->setFixedSize(160, 30);
fdNewPwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
grid->addWidget(fdNewPwd, 1, 2);
fdPwdAgain = new QLineEdit;
fdPwdAgain->setFixedSize(160, 30);
fdPwdAgain->setEchoMode(QLineEdit::PasswordEchoOnEdit);
grid->addWidget(fdPwdAgain, 2, 2);
vBox->addSpacing(20);
auto hBox = new HBox(vBox);
hBox->addStretch();
btnPwdSet = new QPushButton;
btnPwdSet->setMinimumSize(60, 30);
btnPwdSet->setProperty("ssType", "progManageTool");
connect(btnPwdSet, &QPushButton::clicked, this, [this] {
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
if(fdOldPwd->isVisible() && fdOldPwd->text().isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("InputOriginalPasswordTip"));
return;
}
if(fdNewPwd->text().isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("InputNewPasswordTip"));
return;
}
if(fdPwdAgain->text().isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("InputRepeatPasswordTip"));
return;
}
if(fdNewPwd->text() != fdPwdAgain->text()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("InputRepeatPasswordNotSameTip"));
return;
}
auto res = QMessageBox::information(gMainWin, tr("Tip Info"), tr("After setting the password, please remember the password and record it. If you forget the password, the device will be unable to operate. Are you sure you want to continue with this operation?"), QMessageBox::Ok, QMessageBox::Cancel);
if(res != QMessageBox::Ok) return;
QJsonObject json;
json.insert("_id", "SetControllerPassword");
json.insert("_type", "SetControllerPassword");
json.insert("pwd", fdOldPwd->text());
json.insert("newPwd", fdNewPwd->text());
if(gSelCards->count() == 1) {
auto waitingDlg = new WaitingDlg(this, tr("SetControllerPassword")+" ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, card, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
waitingDlg->close();
QMessageBox::critical(gMainWin, tr("Error"), err);
return;
}
if(json["result"].toInt()) {
waitingDlg->close();
QMessageBox::critical(gMainWin, tr("Tip"), tr("OriginalPasswordErrorTip"));
return;
}
waitingDlg->success();
lbOldPwd->show();
fdOldPwd->show();
btnPwdClear->show();
btnPwdSet->setText(tr("Modify password"));
card->bPassword = true;
fdNewPwd->clear();
fdPwdAgain->clear();
fdOldPwd->clear();
});
} else {
foreach(auto card, *gSelCards) {
auto reply = Tools::netManager().post(reqForJson("http://"+card->m_strCardIp+":2016/settings"), QJsonDocument{json}.toJson(QJsonDocument::Compact));
connect(reply, &QNetworkReply::finished, card, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(err.isEmpty()) {
if(json["result"].toInt()) err = tr("OriginalPasswordErrorTip");
else {
err = tr("Success");
lbOldPwd->show();
fdOldPwd->show();
btnPwdClear->show();
btnPwdSet->setText(tr("Modify password"));
card->bPassword = true;
}
}
gFdResInfo->append(card->m_strCardId+" "+tr("SetControllerPassword")+" "+err);
});
}
}
});
hBox->addWidget(btnPwdSet);
btnPwdClear = new QPushButton;
btnPwdClear->setMinimumSize(60, 30);
btnPwdClear->setProperty("ssType", "progManageTool");
connect(btnPwdClear, &QPushButton::clicked, this, [this] {
if(gSelCards->isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("NoSelectedController"));
return;
}
if(fdOldPwd->isVisible() && fdOldPwd->text().isEmpty()) {
QMessageBox::information(gMainWin, tr("Tip"), tr("InputOriginalPasswordTip"));
return;
}
QJsonObject json;
json.insert("_id", "SetControllerPassword");
json.insert("_type", "SetControllerPassword");
json.insert("pwd", fdOldPwd->text());
json.insert("newPwd","");
if(gSelCards->count() == 1) {
auto waitingDlg = new WaitingDlg(this, tr("SetControllerPassword")+" ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, card, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
waitingDlg->close();
QMessageBox::critical(gMainWin, tr("Error"), err);
return;
}
if(json["result"].toInt()) {
waitingDlg->close();
QMessageBox::critical(gMainWin, tr("Tip"), tr("OriginalPasswordErrorTip"));
return;
}
waitingDlg->success();
lbOldPwd->hide();
fdOldPwd->hide();
btnPwdClear->hide();
btnPwdSet->setText(tr("Set encryption"));
card->bPassword = false;
fdNewPwd->clear();
fdPwdAgain->clear();
fdOldPwd->clear();
});
} else {
foreach(auto card, *gSelCards) {
auto reply = Tools::netManager().post(reqForJson("http://"+card->m_strCardIp+":2016/settings"), QJsonDocument{json}.toJson(QJsonDocument::Compact));
connect(reply, &QNetworkReply::finished, card, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(err.isEmpty()) {
if(json["result"].toInt()) err = tr("OriginalPasswordErrorTip");
else {
err = tr("Success");
lbOldPwd->hide();
fdOldPwd->hide();
btnPwdClear->hide();
btnPwdSet->setText(tr("Set encryption"));
card->bPassword = false;
}
}
gFdResInfo->append(card->m_strCardId+" "+tr("SetControllerPassword")+" "+err);
});
}
}
});
hBox->addWidget(btnPwdClear);
hBox->addStretch();
vBox->addStretch();
connect(gDevicePanel, &DevicePanel::sigSelectedDeviceList, this, [this] {
if(isVisible()) init();
});
transUi();
}
void CtrlPwdPanel::showEvent(QShowEvent *event) {
QWidget::showEvent(event);
init();
}
void CtrlPwdPanel::init() {
bool isSingle = gSelCards->count()==1;
if(! isSingle) return;
auto card = gSelCards->at(0);
QJsonObject json;
json.insert("_id", "HasControllerPassword");
json.insert("_type", "HasControllerPassword");
auto reply = Tools::netManager().post(reqForJson("http://"+card->m_strCardIp+":2016/settings"), QJsonDocument{json}.toJson(QJsonDocument::Compact));
connect(reply, &QNetworkReply::finished, card, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
if(json["result"].toBool()) {
lbOldPwd->show();
fdOldPwd->show();
btnPwdClear->show();
btnPwdSet->setText(tr("Modify password"));
card->bPassword = true;
} else {
lbOldPwd->hide();
fdOldPwd->hide();
btnPwdClear->hide();
btnPwdSet->setText(tr("Set encryption"));
card->bPassword = false;
}
});
}
void CtrlPwdPanel::changeEvent(QEvent *event) {
QWidget::changeEvent(event);
if(event->type() == QEvent::LanguageChange) transUi();
}
void CtrlPwdPanel::transUi() {
lbPwdConfig->setText(tr("Set Password"));
lbOldPwd->setText(tr("Original password"));
lbNewPwd->setText(tr("New password"));
lbPwdAgain->setText(tr("Enter again"));
fdOldPwd->setPlaceholderText(tr("original password"));
fdNewPwd->setPlaceholderText(tr("New password"));
fdPwdAgain->setPlaceholderText(tr("Repeat new password"));
btnPwdSet->setText(tr("Set encryption"));
btnPwdClear->setText(tr("Cancel encryption"));
}

View File

@ -0,0 +1,30 @@
#ifndef CTRLPWDPANEL_H
#define CTRLPWDPANEL_H
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
class CtrlPwdPanel : public QWidget {
Q_OBJECT
public:
explicit CtrlPwdPanel(QWidget *parent = nullptr);
protected:
void showEvent(QShowEvent *event) override;
void init();
void changeEvent(QEvent *) override;
void transUi();
private:
QLabel *lbPwdConfig;
QLabel *lbOldPwd;
QLabel *lbNewPwd;
QLabel *lbPwdAgain;
QLineEdit *fdOldPwd;
QLineEdit *fdNewPwd;
QLineEdit *fdPwdAgain;
QPushButton *btnPwdSet;
QPushButton *btnPwdClear;
};
#endif // CTRLPWDPANEL_H

View File

@ -59,12 +59,12 @@ private:
QCheckBox *checkBoxVolume;
QCheckBox *checkBoxScreenSwitch;
QHBoxLayout *horizontalLayout_7;
QPushButton *pushButtonSetSync;
QPushButton *btnSyncSet;
QPushButton *fdSyncGet;
QGroupBox *groupBox_4;
QHBoxLayout *horizontalLayout_11;
QRadioButton *radioButton_4;
QRadioButton *radioButton_5;
QRadioButton *fdMaster;
QRadioButton *fdSlave;
QHBoxLayout *horizontalLayout_12;
QPushButton *btnLoraMasterSet;
QPushButton *btnLoraMasterGet;

Some files were not shown because too many files have changed in this diff Show More