彻底改版2.0
BIN
tool/0snap/base64helper.jpg
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
tool/0snap/comtool.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
tool/0snap/countcode.jpg
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
tool/0snap/emailtool.jpg
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
tool/0snap/keydemo.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
tool/0snap/keytool.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
tool/0snap/livedemo.jpg
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
tool/0snap/livetool.jpg
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
tool/0snap/moneytool.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
tool/0snap/netserver.jpg
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
tool/0snap/netserver2.jpg
Normal file
|
After Width: | Height: | Size: 293 KiB |
BIN
tool/0snap/nettool.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
tool/0snap/pngtool.jpg
Normal file
|
After Width: | Height: | Size: 109 KiB |
9
tool/3rd_qextserialport/3rd_qextserialport.pri
Normal file
@@ -0,0 +1,9 @@
|
||||
HEADERS += \
|
||||
$$PWD/qextserialport.h \
|
||||
$$PWD/qextserialport_global.h \
|
||||
$$PWD/qextserialport_p.h
|
||||
|
||||
SOURCES += $$PWD/qextserialport.cpp
|
||||
|
||||
win32:SOURCES += $$PWD/qextserialport_win.cpp
|
||||
unix:SOURCES += $$PWD/qextserialport_unix.cpp
|
||||
1095
tool/3rd_qextserialport/qextserialport.cpp
Normal file
234
tool/3rd_qextserialport/qextserialport.h
Normal file
@@ -0,0 +1,234 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** 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 _QEXTSERIALPORT_H_
|
||||
#define _QEXTSERIALPORT_H_
|
||||
|
||||
#include <QtCore/QIODevice>
|
||||
#include "qextserialport_global.h"
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <termios.h>
|
||||
#endif
|
||||
/*line status constants*/
|
||||
// ### QESP2.0 move to enum
|
||||
#define LS_CTS 0x01
|
||||
#define LS_DSR 0x02
|
||||
#define LS_DCD 0x04
|
||||
#define LS_RI 0x08
|
||||
#define LS_RTS 0x10
|
||||
#define LS_DTR 0x20
|
||||
#define LS_ST 0x40
|
||||
#define LS_SR 0x80
|
||||
|
||||
/*error constants*/
|
||||
// ### QESP2.0 move to enum
|
||||
#define E_NO_ERROR 0
|
||||
#define E_INVALID_FD 1
|
||||
#define E_NO_MEMORY 2
|
||||
#define E_CAUGHT_NON_BLOCKED_SIGNAL 3
|
||||
#define E_PORT_TIMEOUT 4
|
||||
#define E_INVALID_DEVICE 5
|
||||
#define E_BREAK_CONDITION 6
|
||||
#define E_FRAMING_ERROR 7
|
||||
#define E_IO_ERROR 8
|
||||
#define E_BUFFER_OVERRUN 9
|
||||
#define E_RECEIVE_OVERFLOW 10
|
||||
#define E_RECEIVE_PARITY_ERROR 11
|
||||
#define E_TRANSMIT_OVERFLOW 12
|
||||
#define E_READ_FAILED 13
|
||||
#define E_WRITE_FAILED 14
|
||||
#define E_FILE_NOT_FOUND 15
|
||||
#define E_PERMISSION_DENIED 16
|
||||
#define E_AGAIN 17
|
||||
|
||||
enum BaudRateType {
|
||||
#if defined(Q_OS_UNIX) || defined(qdoc)
|
||||
BAUD50 = 50, //POSIX ONLY
|
||||
BAUD75 = 75, //POSIX ONLY
|
||||
BAUD134 = 134, //POSIX ONLY
|
||||
BAUD150 = 150, //POSIX ONLY
|
||||
BAUD200 = 200, //POSIX ONLY
|
||||
BAUD1800 = 1800, //POSIX ONLY
|
||||
# if defined(B76800) || defined(qdoc)
|
||||
BAUD76800 = 76800, //POSIX ONLY
|
||||
# endif
|
||||
# if (defined(B230400) && defined(B4000000)) || defined(qdoc)
|
||||
BAUD230400 = 230400, //POSIX ONLY
|
||||
BAUD460800 = 460800, //POSIX ONLY
|
||||
BAUD500000 = 500000, //POSIX ONLY
|
||||
BAUD576000 = 576000, //POSIX ONLY
|
||||
BAUD921600 = 921600, //POSIX ONLY
|
||||
BAUD1000000 = 1000000, //POSIX ONLY
|
||||
BAUD1152000 = 1152000, //POSIX ONLY
|
||||
BAUD1500000 = 1500000, //POSIX ONLY
|
||||
BAUD2000000 = 2000000, //POSIX ONLY
|
||||
BAUD2500000 = 2500000, //POSIX ONLY
|
||||
BAUD3000000 = 3000000, //POSIX ONLY
|
||||
BAUD3500000 = 3500000, //POSIX ONLY
|
||||
BAUD4000000 = 4000000, //POSIX ONLY
|
||||
# endif
|
||||
#endif //Q_OS_UNIX
|
||||
#if defined(Q_OS_WIN) || defined(qdoc)
|
||||
BAUD14400 = 14400, //WINDOWS ONLY
|
||||
BAUD56000 = 56000, //WINDOWS ONLY
|
||||
BAUD128000 = 128000, //WINDOWS ONLY
|
||||
BAUD256000 = 256000, //WINDOWS ONLY
|
||||
#endif //Q_OS_WIN
|
||||
BAUD110 = 110,
|
||||
BAUD300 = 300,
|
||||
BAUD600 = 600,
|
||||
BAUD1200 = 1200,
|
||||
BAUD2400 = 2400,
|
||||
BAUD4800 = 4800,
|
||||
BAUD9600 = 9600,
|
||||
BAUD19200 = 19200,
|
||||
BAUD38400 = 38400,
|
||||
BAUD57600 = 57600,
|
||||
BAUD115200 = 115200
|
||||
};
|
||||
|
||||
enum DataBitsType {
|
||||
DATA_5 = 5,
|
||||
DATA_6 = 6,
|
||||
DATA_7 = 7,
|
||||
DATA_8 = 8
|
||||
};
|
||||
|
||||
enum ParityType {
|
||||
PAR_NONE,
|
||||
PAR_ODD,
|
||||
PAR_EVEN,
|
||||
#if defined(Q_OS_WIN) || defined(qdoc)
|
||||
PAR_MARK, //WINDOWS ONLY
|
||||
#endif
|
||||
PAR_SPACE
|
||||
};
|
||||
|
||||
enum StopBitsType {
|
||||
STOP_1,
|
||||
#if defined(Q_OS_WIN) || defined(qdoc)
|
||||
STOP_1_5, //WINDOWS ONLY
|
||||
#endif
|
||||
STOP_2
|
||||
};
|
||||
|
||||
enum FlowType {
|
||||
FLOW_OFF,
|
||||
FLOW_HARDWARE,
|
||||
FLOW_XONXOFF
|
||||
};
|
||||
|
||||
/**
|
||||
* structure to contain port settings
|
||||
*/
|
||||
struct PortSettings {
|
||||
BaudRateType BaudRate;
|
||||
DataBitsType DataBits;
|
||||
ParityType Parity;
|
||||
StopBitsType StopBits;
|
||||
FlowType FlowControl;
|
||||
long Timeout_Millisec;
|
||||
};
|
||||
|
||||
class QextSerialPortPrivate;
|
||||
class QEXTSERIALPORT_EXPORT QextSerialPort: public QIODevice
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(QextSerialPort)
|
||||
Q_ENUMS(QueryMode)
|
||||
Q_PROPERTY(QString portName READ portName WRITE setPortName)
|
||||
Q_PROPERTY(QueryMode queryMode READ queryMode WRITE setQueryMode)
|
||||
public:
|
||||
enum QueryMode {
|
||||
Polling,
|
||||
EventDriven
|
||||
};
|
||||
|
||||
explicit QextSerialPort(QueryMode mode = EventDriven, QObject *parent = 0);
|
||||
explicit QextSerialPort(const QString &name, QueryMode mode = EventDriven, QObject *parent = 0);
|
||||
explicit QextSerialPort(const PortSettings &s, QueryMode mode = EventDriven, QObject *parent = 0);
|
||||
QextSerialPort(const QString &name, const PortSettings &s, QueryMode mode = EventDriven, QObject *parent = 0);
|
||||
|
||||
~QextSerialPort();
|
||||
|
||||
QString portName() const;
|
||||
QueryMode queryMode() const;
|
||||
BaudRateType baudRate() const;
|
||||
DataBitsType dataBits() const;
|
||||
ParityType parity() const;
|
||||
StopBitsType stopBits() const;
|
||||
FlowType flowControl() const;
|
||||
|
||||
bool open(OpenMode mode);
|
||||
bool isSequential() const;
|
||||
void close();
|
||||
void flush();
|
||||
qint64 bytesAvailable() const;
|
||||
bool canReadLine() const;
|
||||
QByteArray readAll();
|
||||
|
||||
ulong lastError() const;
|
||||
|
||||
ulong lineStatus();
|
||||
QString errorString();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setPortName(const QString &name);
|
||||
void setQueryMode(QueryMode mode);
|
||||
void setBaudRate(BaudRateType);
|
||||
void setDataBits(DataBitsType);
|
||||
void setParity(ParityType);
|
||||
void setStopBits(StopBitsType);
|
||||
void setFlowControl(FlowType);
|
||||
void setTimeout(long);
|
||||
|
||||
void setDtr(bool set = true);
|
||||
void setRts(bool set = true);
|
||||
|
||||
Q_SIGNALS:
|
||||
void dsrChanged(bool status);
|
||||
|
||||
protected:
|
||||
qint64 readData(char *data, qint64 maxSize);
|
||||
qint64 writeData(const char *data, qint64 maxSize);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QextSerialPort)
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_onWinEvent(HANDLE))
|
||||
#endif
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_canRead())
|
||||
|
||||
QextSerialPortPrivate *const d_ptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
72
tool/3rd_qextserialport/qextserialport_global.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** 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 QEXTSERIALPORT_GLOBAL_H
|
||||
#define QEXTSERIALPORT_GLOBAL_H
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#ifdef QEXTSERIALPORT_BUILD_SHARED
|
||||
# define QEXTSERIALPORT_EXPORT Q_DECL_EXPORT
|
||||
#elif defined(QEXTSERIALPORT_USING_SHARED)
|
||||
# define QEXTSERIALPORT_EXPORT Q_DECL_IMPORT
|
||||
#else
|
||||
# define QEXTSERIALPORT_EXPORT
|
||||
#endif
|
||||
|
||||
// ### for compatible with old version. should be removed in QESP 2.0
|
||||
#ifdef _TTY_NOWARN_
|
||||
# define QESP_NO_WARN
|
||||
#endif
|
||||
#ifdef _TTY_NOWARN_PORT_
|
||||
# define QESP_NO_PORTABILITY_WARN
|
||||
#endif
|
||||
|
||||
/*if all warning messages are turned off, flag portability warnings to be turned off as well*/
|
||||
#ifdef QESP_NO_WARN
|
||||
# define QESP_NO_PORTABILITY_WARN
|
||||
#endif
|
||||
|
||||
/*macros for warning and debug messages*/
|
||||
#ifdef QESP_NO_PORTABILITY_WARN
|
||||
# define QESP_PORTABILITY_WARNING while (false)qWarning
|
||||
#else
|
||||
# define QESP_PORTABILITY_WARNING qWarning
|
||||
#endif /*QESP_NOWARN_PORT*/
|
||||
|
||||
#ifdef QESP_NO_WARN
|
||||
# define QESP_WARNING while (false)qWarning
|
||||
#else
|
||||
# define QESP_WARNING qWarning
|
||||
#endif /*QESP_NOWARN*/
|
||||
|
||||
#endif // QEXTSERIALPORT_GLOBAL_H
|
||||
|
||||
277
tool/3rd_qextserialport/qextserialport_p.h
Normal file
@@ -0,0 +1,277 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** 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 _QEXTSERIALPORT_P_H_
|
||||
#define _QEXTSERIALPORT_P_H_
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the QESP API. It exists for the convenience
|
||||
// of other QESP classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qextserialport.h"
|
||||
#include <QtCore/QReadWriteLock>
|
||||
#ifdef Q_OS_UNIX
|
||||
# include <termios.h>
|
||||
#elif (defined Q_OS_WIN)
|
||||
# include <QtCore/qt_windows.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
// This is QextSerialPort's read buffer, needed by posix system.
|
||||
// ref: QRingBuffer & QIODevicePrivateLinearBuffer
|
||||
class QextReadBuffer
|
||||
{
|
||||
public:
|
||||
inline QextReadBuffer(size_t growth = 4096)
|
||||
: len(0), first(0), buf(0), capacity(0), basicBlockSize(growth)
|
||||
{
|
||||
}
|
||||
|
||||
~QextReadBuffer()
|
||||
{
|
||||
delete buf;
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
first = buf;
|
||||
len = 0;
|
||||
}
|
||||
|
||||
inline int size() const
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
inline bool isEmpty() const
|
||||
{
|
||||
return len == 0;
|
||||
}
|
||||
|
||||
inline int read(char *target, int size)
|
||||
{
|
||||
int r = qMin(size, len);
|
||||
|
||||
if (r == 1) {
|
||||
*target = *first;
|
||||
--len;
|
||||
++first;
|
||||
} else {
|
||||
memcpy(target, first, r);
|
||||
len -= r;
|
||||
first += r;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline char *reserve(size_t size)
|
||||
{
|
||||
if ((first - buf) + len + size > capacity) {
|
||||
size_t newCapacity = qMax(capacity, basicBlockSize);
|
||||
|
||||
while (newCapacity < len + size) {
|
||||
newCapacity *= 2;
|
||||
}
|
||||
|
||||
if (newCapacity > capacity) {
|
||||
// allocate more space
|
||||
char *newBuf = new char[newCapacity];
|
||||
memmove(newBuf, first, len);
|
||||
delete buf;
|
||||
buf = newBuf;
|
||||
capacity = newCapacity;
|
||||
} else {
|
||||
// shift any existing data to make space
|
||||
memmove(buf, first, len);
|
||||
}
|
||||
|
||||
first = buf;
|
||||
}
|
||||
|
||||
char *writePtr = first + len;
|
||||
len += (int)size;
|
||||
return writePtr;
|
||||
}
|
||||
|
||||
inline void chop(int size)
|
||||
{
|
||||
if (size >= len) {
|
||||
clear();
|
||||
} else {
|
||||
len -= size;
|
||||
}
|
||||
}
|
||||
|
||||
inline void squeeze()
|
||||
{
|
||||
if (first != buf) {
|
||||
memmove(buf, first, len);
|
||||
first = buf;
|
||||
}
|
||||
|
||||
size_t newCapacity = basicBlockSize;
|
||||
|
||||
while (newCapacity < size_t(len)) {
|
||||
newCapacity *= 2;
|
||||
}
|
||||
|
||||
if (newCapacity < capacity) {
|
||||
char *tmp = static_cast<char *>(realloc(buf, newCapacity));
|
||||
|
||||
if (tmp) {
|
||||
buf = tmp;
|
||||
capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline QByteArray readAll()
|
||||
{
|
||||
char *f = first;
|
||||
int l = len;
|
||||
clear();
|
||||
return QByteArray(f, l);
|
||||
}
|
||||
|
||||
inline int readLine(char *target, int size)
|
||||
{
|
||||
int r = qMin(size, len);
|
||||
char *eol = static_cast<char *>(memchr(first, '\n', r));
|
||||
|
||||
if (eol) {
|
||||
r = 1 + (eol - first);
|
||||
}
|
||||
|
||||
memcpy(target, first, r);
|
||||
len -= r;
|
||||
first += r;
|
||||
return int(r);
|
||||
}
|
||||
|
||||
inline bool canReadLine() const
|
||||
{
|
||||
return memchr(first, '\n', len);
|
||||
}
|
||||
|
||||
private:
|
||||
int len;
|
||||
char *first;
|
||||
char *buf;
|
||||
size_t capacity;
|
||||
size_t basicBlockSize;
|
||||
};
|
||||
|
||||
class QWinEventNotifier;
|
||||
class QReadWriteLock;
|
||||
class QSocketNotifier;
|
||||
|
||||
class QextSerialPortPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QextSerialPort)
|
||||
public:
|
||||
QextSerialPortPrivate(QextSerialPort *q);
|
||||
~QextSerialPortPrivate();
|
||||
enum DirtyFlagEnum {
|
||||
DFE_BaudRate = 0x0001,
|
||||
DFE_Parity = 0x0002,
|
||||
DFE_StopBits = 0x0004,
|
||||
DFE_DataBits = 0x0008,
|
||||
DFE_Flow = 0x0010,
|
||||
DFE_TimeOut = 0x0100,
|
||||
DFE_ALL = 0x0fff,
|
||||
DFE_Settings_Mask = 0x00ff //without TimeOut
|
||||
};
|
||||
mutable QReadWriteLock lock;
|
||||
QString port;
|
||||
PortSettings settings;
|
||||
QextReadBuffer readBuffer;
|
||||
int settingsDirtyFlags;
|
||||
ulong lastErr;
|
||||
QextSerialPort::QueryMode queryMode;
|
||||
|
||||
// platform specific members
|
||||
#ifdef Q_OS_UNIX
|
||||
int fd;
|
||||
QSocketNotifier *readNotifier;
|
||||
struct termios currentTermios;
|
||||
struct termios oldTermios;
|
||||
#elif (defined Q_OS_WIN)
|
||||
HANDLE handle;
|
||||
OVERLAPPED overlap;
|
||||
COMMCONFIG commConfig;
|
||||
COMMTIMEOUTS commTimeouts;
|
||||
QWinEventNotifier *winEventNotifier;
|
||||
DWORD eventMask;
|
||||
QList<OVERLAPPED *> pendingWrites;
|
||||
QReadWriteLock *bytesToWriteLock;
|
||||
#endif
|
||||
|
||||
/*fill PortSettings*/
|
||||
void setBaudRate(BaudRateType baudRate, bool update = true);
|
||||
void setDataBits(DataBitsType dataBits, bool update = true);
|
||||
void setParity(ParityType parity, bool update = true);
|
||||
void setStopBits(StopBitsType stopbits, bool update = true);
|
||||
void setFlowControl(FlowType flow, bool update = true);
|
||||
void setTimeout(long millisec, bool update = true);
|
||||
void setPortSettings(const PortSettings &settings, bool update = true);
|
||||
|
||||
void platformSpecificDestruct();
|
||||
void platformSpecificInit();
|
||||
void translateError(ulong error);
|
||||
void updatePortSettings();
|
||||
|
||||
qint64 readData_sys(char *data, qint64 maxSize);
|
||||
qint64 writeData_sys(const char *data, qint64 maxSize);
|
||||
void setDtr_sys(bool set = true);
|
||||
void setRts_sys(bool set = true);
|
||||
bool open_sys(QIODevice::OpenMode mode);
|
||||
bool close_sys();
|
||||
bool flush_sys();
|
||||
ulong lineStatus_sys();
|
||||
qint64 bytesAvailable_sys() const;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
void _q_onWinEvent(HANDLE h);
|
||||
#endif
|
||||
void _q_canRead();
|
||||
|
||||
QextSerialPort *q_ptr;
|
||||
};
|
||||
|
||||
#endif //_QEXTSERIALPORT_P_H_
|
||||
559
tool/3rd_qextserialport/qextserialport_unix.cpp
Normal file
@@ -0,0 +1,559 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** 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 "qextserialport.h"
|
||||
#include "qextserialport_p.h"
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <QtCore/QMutexLocker>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSocketNotifier>
|
||||
|
||||
void QextSerialPortPrivate::platformSpecificInit()
|
||||
{
|
||||
fd = 0;
|
||||
readNotifier = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Standard destructor.
|
||||
*/
|
||||
void QextSerialPortPrivate::platformSpecificDestruct()
|
||||
{
|
||||
}
|
||||
|
||||
static QString fullPortName(const QString &name)
|
||||
{
|
||||
if (name.startsWith(QLatin1Char('/'))) {
|
||||
return name;
|
||||
}
|
||||
|
||||
return QLatin1String("/dev/") + name;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode)
|
||||
{
|
||||
Q_Q(QextSerialPort);
|
||||
|
||||
//note: linux 2.6.21 seems to ignore O_NDELAY flag
|
||||
if ((fd = ::open(fullPortName(port).toLatin1() , O_RDWR | O_NOCTTY | O_NDELAY)) != -1) {
|
||||
|
||||
/*In the Private class, We can not call QIODevice::open()*/
|
||||
q->setOpenMode(mode); // Flag the port as opened
|
||||
::tcgetattr(fd, &oldTermios); // Save the old termios
|
||||
currentTermios = oldTermios; // Make a working copy
|
||||
::cfmakeraw(¤tTermios); // Enable raw access
|
||||
|
||||
/*set up other port settings*/
|
||||
currentTermios.c_cflag |= CREAD | CLOCAL;
|
||||
currentTermios.c_lflag &= (~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG));
|
||||
currentTermios.c_iflag &= (~(INPCK | IGNPAR | PARMRK | ISTRIP | ICRNL | IXANY));
|
||||
currentTermios.c_oflag &= (~OPOST);
|
||||
currentTermios.c_cc[VMIN] = 0;
|
||||
#ifdef _POSIX_VDISABLE // Is a disable character available on this system?
|
||||
// Some systems allow for per-device disable-characters, so get the
|
||||
// proper value for the configured device
|
||||
const long vdisable = ::fpathconf(fd, _PC_VDISABLE);
|
||||
currentTermios.c_cc[VINTR] = vdisable;
|
||||
currentTermios.c_cc[VQUIT] = vdisable;
|
||||
currentTermios.c_cc[VSTART] = vdisable;
|
||||
currentTermios.c_cc[VSTOP] = vdisable;
|
||||
currentTermios.c_cc[VSUSP] = vdisable;
|
||||
#endif //_POSIX_VDISABLE
|
||||
settingsDirtyFlags = DFE_ALL;
|
||||
updatePortSettings();
|
||||
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q);
|
||||
q->connect(readNotifier, SIGNAL(activated(int)), q, SLOT(_q_canRead()));
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
translateError(errno);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::close_sys()
|
||||
{
|
||||
// Force a flush and then restore the original termios
|
||||
flush_sys();
|
||||
// Using both TCSAFLUSH and TCSANOW here discards any pending input
|
||||
::tcsetattr(fd, TCSAFLUSH | TCSANOW, &oldTermios); // Restore termios
|
||||
::close(fd);
|
||||
|
||||
if (readNotifier) {
|
||||
delete readNotifier;
|
||||
readNotifier = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::flush_sys()
|
||||
{
|
||||
::tcdrain(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
qint64 QextSerialPortPrivate::bytesAvailable_sys() const
|
||||
{
|
||||
int bytesQueued;
|
||||
|
||||
if (::ioctl(fd, FIONREAD, &bytesQueued) == -1) {
|
||||
return (qint64) - 1;
|
||||
}
|
||||
|
||||
return bytesQueued;
|
||||
}
|
||||
|
||||
/*!
|
||||
Translates a system-specific error code to a QextSerialPort error code. Used internally.
|
||||
*/
|
||||
void QextSerialPortPrivate::translateError(ulong error)
|
||||
{
|
||||
switch (error) {
|
||||
case EBADF:
|
||||
case ENOTTY:
|
||||
lastErr = E_INVALID_FD;
|
||||
break;
|
||||
|
||||
case EINTR:
|
||||
lastErr = E_CAUGHT_NON_BLOCKED_SIGNAL;
|
||||
break;
|
||||
|
||||
case ENOMEM:
|
||||
lastErr = E_NO_MEMORY;
|
||||
break;
|
||||
|
||||
case EACCES:
|
||||
lastErr = E_PERMISSION_DENIED;
|
||||
break;
|
||||
|
||||
case EAGAIN:
|
||||
lastErr = E_AGAIN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::setDtr_sys(bool set)
|
||||
{
|
||||
int status;
|
||||
::ioctl(fd, TIOCMGET, &status);
|
||||
|
||||
if (set) {
|
||||
status |= TIOCM_DTR;
|
||||
} else {
|
||||
status &= ~TIOCM_DTR;
|
||||
}
|
||||
|
||||
::ioctl(fd, TIOCMSET, &status);
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::setRts_sys(bool set)
|
||||
{
|
||||
int status;
|
||||
::ioctl(fd, TIOCMGET, &status);
|
||||
|
||||
if (set) {
|
||||
status |= TIOCM_RTS;
|
||||
} else {
|
||||
status &= ~TIOCM_RTS;
|
||||
}
|
||||
|
||||
::ioctl(fd, TIOCMSET, &status);
|
||||
}
|
||||
|
||||
unsigned long QextSerialPortPrivate::lineStatus_sys()
|
||||
{
|
||||
unsigned long Status = 0, Temp = 0;
|
||||
::ioctl(fd, TIOCMGET, &Temp);
|
||||
|
||||
if (Temp & TIOCM_CTS) {
|
||||
Status |= LS_CTS;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_DSR) {
|
||||
Status |= LS_DSR;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_RI) {
|
||||
Status |= LS_RI;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_CD) {
|
||||
Status |= LS_DCD;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_DTR) {
|
||||
Status |= LS_DTR;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_RTS) {
|
||||
Status |= LS_RTS;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_ST) {
|
||||
Status |= LS_ST;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_SR) {
|
||||
Status |= LS_SR;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*!
|
||||
Reads a block of data from the serial port. This function will read at most maxSize bytes from
|
||||
the serial port and place them in the buffer pointed to by data. Return value is the number of
|
||||
bytes actually read, or -1 on error.
|
||||
|
||||
\warning before calling this function ensure that serial port associated with this class
|
||||
is currently open (use isOpen() function to check if port is open).
|
||||
*/
|
||||
qint64 QextSerialPortPrivate::readData_sys(char *data, qint64 maxSize)
|
||||
{
|
||||
int retVal = ::read(fd, data, maxSize);
|
||||
|
||||
if (retVal == -1) {
|
||||
lastErr = E_READ_FAILED;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*!
|
||||
Writes a block of data to the serial port. This function will write maxSize bytes
|
||||
from the buffer pointed to by data to the serial port. Return value is the number
|
||||
of bytes actually written, or -1 on error.
|
||||
|
||||
\warning before calling this function ensure that serial port associated with this class
|
||||
is currently open (use isOpen() function to check if port is open).
|
||||
*/
|
||||
qint64 QextSerialPortPrivate::writeData_sys(const char *data, qint64 maxSize)
|
||||
{
|
||||
int retVal = ::write(fd, data, maxSize);
|
||||
|
||||
if (retVal == -1) {
|
||||
lastErr = E_WRITE_FAILED;
|
||||
}
|
||||
|
||||
return (qint64)retVal;
|
||||
}
|
||||
|
||||
static void setBaudRate2Termios(termios *config, int baudRate)
|
||||
{
|
||||
#ifdef CBAUD
|
||||
config->c_cflag &= (~CBAUD);
|
||||
config->c_cflag |= baudRate;
|
||||
#else
|
||||
::cfsetispeed(config, baudRate);
|
||||
::cfsetospeed(config, baudRate);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
All the platform settings was performed in this function.
|
||||
*/
|
||||
void QextSerialPortPrivate::updatePortSettings()
|
||||
{
|
||||
if (!q_func()->isOpen() || !settingsDirtyFlags) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_BaudRate) {
|
||||
switch (settings.BaudRate) {
|
||||
case BAUD50:
|
||||
setBaudRate2Termios(¤tTermios, B50);
|
||||
break;
|
||||
|
||||
case BAUD75:
|
||||
setBaudRate2Termios(¤tTermios, B75);
|
||||
break;
|
||||
|
||||
case BAUD110:
|
||||
setBaudRate2Termios(¤tTermios, B110);
|
||||
break;
|
||||
|
||||
case BAUD134:
|
||||
setBaudRate2Termios(¤tTermios, B134);
|
||||
break;
|
||||
|
||||
case BAUD150:
|
||||
setBaudRate2Termios(¤tTermios, B150);
|
||||
break;
|
||||
|
||||
case BAUD200:
|
||||
setBaudRate2Termios(¤tTermios, B200);
|
||||
break;
|
||||
|
||||
case BAUD300:
|
||||
setBaudRate2Termios(¤tTermios, B300);
|
||||
break;
|
||||
|
||||
case BAUD600:
|
||||
setBaudRate2Termios(¤tTermios, B600);
|
||||
break;
|
||||
|
||||
case BAUD1200:
|
||||
setBaudRate2Termios(¤tTermios, B1200);
|
||||
break;
|
||||
|
||||
case BAUD1800:
|
||||
setBaudRate2Termios(¤tTermios, B1800);
|
||||
break;
|
||||
|
||||
case BAUD2400:
|
||||
setBaudRate2Termios(¤tTermios, B2400);
|
||||
break;
|
||||
|
||||
case BAUD4800:
|
||||
setBaudRate2Termios(¤tTermios, B4800);
|
||||
break;
|
||||
|
||||
case BAUD9600:
|
||||
setBaudRate2Termios(¤tTermios, B9600);
|
||||
break;
|
||||
|
||||
case BAUD19200:
|
||||
setBaudRate2Termios(¤tTermios, B19200);
|
||||
break;
|
||||
|
||||
case BAUD38400:
|
||||
setBaudRate2Termios(¤tTermios, B38400);
|
||||
break;
|
||||
|
||||
case BAUD57600:
|
||||
setBaudRate2Termios(¤tTermios, B57600);
|
||||
break;
|
||||
#ifdef B76800
|
||||
|
||||
case BAUD76800:
|
||||
setBaudRate2Termios(¤tTermios, B76800);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case BAUD115200:
|
||||
setBaudRate2Termios(¤tTermios, B115200);
|
||||
break;
|
||||
#if defined(B230400) && defined(B4000000)
|
||||
|
||||
case BAUD230400:
|
||||
setBaudRate2Termios(¤tTermios, B230400);
|
||||
break;
|
||||
|
||||
case BAUD460800:
|
||||
setBaudRate2Termios(¤tTermios, B460800);
|
||||
break;
|
||||
|
||||
case BAUD500000:
|
||||
setBaudRate2Termios(¤tTermios, B500000);
|
||||
break;
|
||||
|
||||
case BAUD576000:
|
||||
setBaudRate2Termios(¤tTermios, B576000);
|
||||
break;
|
||||
|
||||
case BAUD921600:
|
||||
setBaudRate2Termios(¤tTermios, B921600);
|
||||
break;
|
||||
|
||||
case BAUD1000000:
|
||||
setBaudRate2Termios(¤tTermios, B1000000);
|
||||
break;
|
||||
|
||||
case BAUD1152000:
|
||||
setBaudRate2Termios(¤tTermios, B1152000);
|
||||
break;
|
||||
|
||||
case BAUD1500000:
|
||||
setBaudRate2Termios(¤tTermios, B1500000);
|
||||
break;
|
||||
|
||||
case BAUD2000000:
|
||||
setBaudRate2Termios(¤tTermios, B2000000);
|
||||
break;
|
||||
|
||||
case BAUD2500000:
|
||||
setBaudRate2Termios(¤tTermios, B2500000);
|
||||
break;
|
||||
|
||||
case BAUD3000000:
|
||||
setBaudRate2Termios(¤tTermios, B3000000);
|
||||
break;
|
||||
|
||||
case BAUD3500000:
|
||||
setBaudRate2Termios(¤tTermios, B3500000);
|
||||
break;
|
||||
|
||||
case BAUD4000000:
|
||||
setBaudRate2Termios(¤tTermios, B4000000);
|
||||
break;
|
||||
#endif
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
default:
|
||||
setBaudRate2Termios(¤tTermios, settings.BaudRate);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_Parity) {
|
||||
switch (settings.Parity) {
|
||||
case PAR_SPACE:
|
||||
/*space parity not directly supported - add an extra data bit to simulate it*/
|
||||
settingsDirtyFlags |= DFE_DataBits;
|
||||
break;
|
||||
|
||||
case PAR_NONE:
|
||||
currentTermios.c_cflag &= (~PARENB);
|
||||
break;
|
||||
|
||||
case PAR_EVEN:
|
||||
currentTermios.c_cflag &= (~PARODD);
|
||||
currentTermios.c_cflag |= PARENB;
|
||||
break;
|
||||
|
||||
case PAR_ODD:
|
||||
currentTermios.c_cflag |= (PARENB | PARODD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*must after Parity settings*/
|
||||
if (settingsDirtyFlags & DFE_DataBits) {
|
||||
if (settings.Parity != PAR_SPACE) {
|
||||
currentTermios.c_cflag &= (~CSIZE);
|
||||
|
||||
switch (settings.DataBits) {
|
||||
case DATA_5:
|
||||
currentTermios.c_cflag |= CS5;
|
||||
break;
|
||||
|
||||
case DATA_6:
|
||||
currentTermios.c_cflag |= CS6;
|
||||
break;
|
||||
|
||||
case DATA_7:
|
||||
currentTermios.c_cflag |= CS7;
|
||||
break;
|
||||
|
||||
case DATA_8:
|
||||
currentTermios.c_cflag |= CS8;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/*space parity not directly supported - add an extra data bit to simulate it*/
|
||||
currentTermios.c_cflag &= ~(PARENB | CSIZE);
|
||||
|
||||
switch (settings.DataBits) {
|
||||
case DATA_5:
|
||||
currentTermios.c_cflag |= CS6;
|
||||
break;
|
||||
|
||||
case DATA_6:
|
||||
currentTermios.c_cflag |= CS7;
|
||||
break;
|
||||
|
||||
case DATA_7:
|
||||
currentTermios.c_cflag |= CS8;
|
||||
break;
|
||||
|
||||
case DATA_8:
|
||||
/*this will never happen, put here to Suppress an warning*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_StopBits) {
|
||||
switch (settings.StopBits) {
|
||||
case STOP_1:
|
||||
currentTermios.c_cflag &= (~CSTOPB);
|
||||
break;
|
||||
|
||||
case STOP_2:
|
||||
currentTermios.c_cflag |= CSTOPB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_Flow) {
|
||||
switch (settings.FlowControl) {
|
||||
case FLOW_OFF:
|
||||
currentTermios.c_cflag &= (~CRTSCTS);
|
||||
currentTermios.c_iflag &= (~(IXON | IXOFF | IXANY));
|
||||
break;
|
||||
|
||||
case FLOW_XONXOFF:
|
||||
/*software (XON/XOFF) flow control*/
|
||||
currentTermios.c_cflag &= (~CRTSCTS);
|
||||
currentTermios.c_iflag |= (IXON | IXOFF | IXANY);
|
||||
break;
|
||||
|
||||
case FLOW_HARDWARE:
|
||||
currentTermios.c_cflag |= CRTSCTS;
|
||||
currentTermios.c_iflag &= (~(IXON | IXOFF | IXANY));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*if any thing in currentTermios changed, flush*/
|
||||
if (settingsDirtyFlags & DFE_Settings_Mask) {
|
||||
::tcsetattr(fd, TCSAFLUSH, ¤tTermios);
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_TimeOut) {
|
||||
int millisec = settings.Timeout_Millisec;
|
||||
|
||||
if (millisec == -1) {
|
||||
::fcntl(fd, F_SETFL, O_NDELAY);
|
||||
} else {
|
||||
//O_SYNC should enable blocking ::write()
|
||||
//however this seems not working on Linux 2.6.21 (works on OpenBSD 4.2)
|
||||
::fcntl(fd, F_SETFL, O_SYNC);
|
||||
}
|
||||
|
||||
::tcgetattr(fd, ¤tTermios);
|
||||
currentTermios.c_cc[VTIME] = millisec / 100;
|
||||
::tcsetattr(fd, TCSAFLUSH, ¤tTermios);
|
||||
}
|
||||
|
||||
settingsDirtyFlags = 0;
|
||||
}
|
||||
482
tool/3rd_qextserialport/qextserialport_win.cpp
Normal file
@@ -0,0 +1,482 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** 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 "qextserialport.h"
|
||||
#include "qextserialport_p.h"
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QReadWriteLock>
|
||||
#include <QtCore/QMutexLocker>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QMetaType>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
#include <QtCore/QWinEventNotifier>
|
||||
#else
|
||||
#include <QtCore/private/qwineventnotifier_p.h>
|
||||
#endif
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QtCore5Compat/QRegExp>
|
||||
#else
|
||||
#include <QtCore/QRegExp>
|
||||
#endif
|
||||
|
||||
void QextSerialPortPrivate::platformSpecificInit()
|
||||
{
|
||||
handle = INVALID_HANDLE_VALUE;
|
||||
ZeroMemory(&overlap, sizeof(OVERLAPPED));
|
||||
overlap.hEvent = CreateEvent(NULL, true, false, NULL);
|
||||
winEventNotifier = 0;
|
||||
bytesToWriteLock = new QReadWriteLock;
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::platformSpecificDestruct()
|
||||
{
|
||||
CloseHandle(overlap.hEvent);
|
||||
delete bytesToWriteLock;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\internal
|
||||
COM ports greater than 9 need \\.\ prepended
|
||||
|
||||
This is only need when open the port.
|
||||
*/
|
||||
static QString fullPortNameWin(const QString &name)
|
||||
{
|
||||
QRegExp rx(QLatin1String("^COM(\\d+)"));
|
||||
QString fullName(name);
|
||||
if (rx.indexIn(fullName) >= 0) {
|
||||
fullName.prepend(QLatin1String("\\\\.\\"));
|
||||
}
|
||||
|
||||
return fullName;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode)
|
||||
{
|
||||
Q_Q(QextSerialPort);
|
||||
DWORD confSize = sizeof(COMMCONFIG);
|
||||
commConfig.dwSize = confSize;
|
||||
DWORD dwFlagsAndAttributes = 0;
|
||||
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;
|
||||
}
|
||||
|
||||
/*open the port*/
|
||||
handle = CreateFileW((wchar_t *)fullPortNameWin(port).utf16(), GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
q->setOpenMode(mode);
|
||||
/*configure port settings*/
|
||||
GetCommConfig(handle, &commConfig, &confSize);
|
||||
GetCommState(handle, &(commConfig.dcb));
|
||||
|
||||
/*set up parameters*/
|
||||
commConfig.dcb.fBinary = TRUE;
|
||||
commConfig.dcb.fInX = FALSE;
|
||||
commConfig.dcb.fOutX = FALSE;
|
||||
commConfig.dcb.fAbortOnError = FALSE;
|
||||
commConfig.dcb.fNull = FALSE;
|
||||
/* Dtr default to true. See Issue 122*/
|
||||
commConfig.dcb.fDtrControl = TRUE;
|
||||
/*flush all settings*/
|
||||
settingsDirtyFlags = DFE_ALL;
|
||||
updatePortSettings();
|
||||
|
||||
//init event driven approach
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
if (!SetCommMask(handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) {
|
||||
QESP_WARNING() << "failed to set Comm Mask. Error code:" << GetLastError();
|
||||
return false;
|
||||
}
|
||||
|
||||
winEventNotifier = new QWinEventNotifier(overlap.hEvent, q);
|
||||
qRegisterMetaType<HANDLE>("HANDLE");
|
||||
q->connect(winEventNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_onWinEvent(HANDLE)), Qt::DirectConnection);
|
||||
WaitCommEvent(handle, &eventMask, &overlap);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::close_sys()
|
||||
{
|
||||
flush_sys();
|
||||
CancelIo(handle);
|
||||
|
||||
if (CloseHandle(handle)) {
|
||||
handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (winEventNotifier) {
|
||||
winEventNotifier->setEnabled(false);
|
||||
winEventNotifier->deleteLater();
|
||||
winEventNotifier = 0;
|
||||
}
|
||||
|
||||
foreach (OVERLAPPED *o, pendingWrites) {
|
||||
CloseHandle(o->hEvent);
|
||||
delete o;
|
||||
}
|
||||
|
||||
pendingWrites.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::flush_sys()
|
||||
{
|
||||
FlushFileBuffers(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
qint64 QextSerialPortPrivate::bytesAvailable_sys() const
|
||||
{
|
||||
DWORD Errors;
|
||||
COMSTAT Status;
|
||||
|
||||
if (ClearCommError(handle, &Errors, &Status)) {
|
||||
return Status.cbInQue;
|
||||
}
|
||||
|
||||
return (qint64) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Translates a system-specific error code to a QextSerialPort error code. Used internally.
|
||||
*/
|
||||
void QextSerialPortPrivate::translateError(ulong error)
|
||||
{
|
||||
if (error & CE_BREAK) {
|
||||
lastErr = E_BREAK_CONDITION;
|
||||
} else if (error & CE_FRAME) {
|
||||
lastErr = E_FRAMING_ERROR;
|
||||
} else if (error & CE_IOE) {
|
||||
lastErr = E_IO_ERROR;
|
||||
} else if (error & CE_MODE) {
|
||||
lastErr = E_INVALID_FD;
|
||||
} else if (error & CE_OVERRUN) {
|
||||
lastErr = E_BUFFER_OVERRUN;
|
||||
} else if (error & CE_RXPARITY) {
|
||||
lastErr = E_RECEIVE_PARITY_ERROR;
|
||||
} else if (error & CE_RXOVER) {
|
||||
lastErr = E_RECEIVE_OVERFLOW;
|
||||
} else if (error & CE_TXFULL) {
|
||||
lastErr = E_TRANSMIT_OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Reads a block of data from the serial port. This function will read at most maxlen bytes from
|
||||
the serial port and place them in the buffer pointed to by data. Return value is the number of
|
||||
bytes actually read, or -1 on error.
|
||||
|
||||
\warning before calling this function ensure that serial port associated with this class
|
||||
is currently open (use isOpen() function to check if port is open).
|
||||
*/
|
||||
qint64 QextSerialPortPrivate::readData_sys(char *data, qint64 maxSize)
|
||||
{
|
||||
DWORD bytesRead = 0;
|
||||
bool failed = false;
|
||||
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
OVERLAPPED overlapRead;
|
||||
ZeroMemory(&overlapRead, sizeof(OVERLAPPED));
|
||||
|
||||
if (!ReadFile(handle, (void *)data, (DWORD)maxSize, &bytesRead, &overlapRead)) {
|
||||
if (GetLastError() == ERROR_IO_PENDING) {
|
||||
GetOverlappedResult(handle, &overlapRead, &bytesRead, true);
|
||||
} else {
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
} else if (!ReadFile(handle, (void *)data, (DWORD)maxSize, &bytesRead, NULL)) {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
return (qint64)bytesRead;
|
||||
}
|
||||
|
||||
lastErr = E_READ_FAILED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
Writes a block of data to the serial port. This function will write len bytes
|
||||
from the buffer pointed to by data to the serial port. Return value is the number
|
||||
of bytes actually written, or -1 on error.
|
||||
|
||||
\warning before calling this function ensure that serial port associated with this class
|
||||
is currently open (use isOpen() function to check if port is open).
|
||||
*/
|
||||
qint64 QextSerialPortPrivate::writeData_sys(const char *data, qint64 maxSize)
|
||||
{
|
||||
DWORD bytesWritten = 0;
|
||||
bool failed = false;
|
||||
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
OVERLAPPED *newOverlapWrite = new OVERLAPPED;
|
||||
ZeroMemory(newOverlapWrite, sizeof(OVERLAPPED));
|
||||
newOverlapWrite->hEvent = CreateEvent(NULL, true, false, NULL);
|
||||
|
||||
if (WriteFile(handle, (void *)data, (DWORD)maxSize, &bytesWritten, newOverlapWrite)) {
|
||||
CloseHandle(newOverlapWrite->hEvent);
|
||||
delete newOverlapWrite;
|
||||
} else if (GetLastError() == ERROR_IO_PENDING) {
|
||||
// writing asynchronously...not an error
|
||||
QWriteLocker writelocker(bytesToWriteLock);
|
||||
pendingWrites.append(newOverlapWrite);
|
||||
} else {
|
||||
QESP_WARNING() << "QextSerialPort write error:" << GetLastError();
|
||||
failed = true;
|
||||
|
||||
if (!CancelIo(newOverlapWrite->hEvent)) {
|
||||
QESP_WARNING("QextSerialPort: couldn't cancel IO");
|
||||
}
|
||||
|
||||
if (!CloseHandle(newOverlapWrite->hEvent)) {
|
||||
QESP_WARNING("QextSerialPort: couldn't close OVERLAPPED handle");
|
||||
}
|
||||
|
||||
delete newOverlapWrite;
|
||||
}
|
||||
} else if (!WriteFile(handle, (void *)data, (DWORD)maxSize, &bytesWritten, NULL)) {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
return (qint64)bytesWritten;
|
||||
}
|
||||
|
||||
lastErr = E_WRITE_FAILED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::setDtr_sys(bool set)
|
||||
{
|
||||
EscapeCommFunction(handle, set ? SETDTR : CLRDTR);
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::setRts_sys(bool set)
|
||||
{
|
||||
EscapeCommFunction(handle, set ? SETRTS : CLRRTS);
|
||||
}
|
||||
|
||||
ulong QextSerialPortPrivate::lineStatus_sys(void)
|
||||
{
|
||||
unsigned long Status = 0, Temp = 0;
|
||||
GetCommModemStatus(handle, &Temp);
|
||||
|
||||
if (Temp & MS_CTS_ON) {
|
||||
Status |= LS_CTS;
|
||||
}
|
||||
|
||||
if (Temp & MS_DSR_ON) {
|
||||
Status |= LS_DSR;
|
||||
}
|
||||
|
||||
if (Temp & MS_RING_ON) {
|
||||
Status |= LS_RI;
|
||||
}
|
||||
|
||||
if (Temp & MS_RLSD_ON) {
|
||||
Status |= LS_DCD;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
Triggered when there's activity on our HANDLE.
|
||||
*/
|
||||
void QextSerialPortPrivate::_q_onWinEvent(HANDLE h)
|
||||
{
|
||||
Q_Q(QextSerialPort);
|
||||
|
||||
if (h == overlap.hEvent) {
|
||||
if (eventMask & EV_RXCHAR) {
|
||||
if (q->sender() != q && bytesAvailable_sys() > 0) {
|
||||
_q_canRead();
|
||||
}
|
||||
}
|
||||
|
||||
if (eventMask & EV_TXEMPTY) {
|
||||
/*
|
||||
A write completed. Run through the list of OVERLAPPED writes, and if
|
||||
they completed successfully, take them off the list and delete them.
|
||||
Otherwise, leave them on there so they can finish.
|
||||
*/
|
||||
qint64 totalBytesWritten = 0;
|
||||
QList<OVERLAPPED *> overlapsToDelete;
|
||||
|
||||
foreach (OVERLAPPED *o, pendingWrites) {
|
||||
DWORD numBytes = 0;
|
||||
|
||||
if (GetOverlappedResult(handle, o, &numBytes, false)) {
|
||||
overlapsToDelete.append(o);
|
||||
totalBytesWritten += numBytes;
|
||||
} else if (GetLastError() != ERROR_IO_INCOMPLETE) {
|
||||
overlapsToDelete.append(o);
|
||||
QESP_WARNING() << "CommEvent overlapped write error:" << GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
if (q->sender() != q && totalBytesWritten > 0) {
|
||||
QWriteLocker writelocker(bytesToWriteLock);
|
||||
Q_EMIT q->bytesWritten(totalBytesWritten);
|
||||
}
|
||||
|
||||
foreach (OVERLAPPED *o, overlapsToDelete) {
|
||||
OVERLAPPED *toDelete = pendingWrites.takeAt(pendingWrites.indexOf(o));
|
||||
CloseHandle(toDelete->hEvent);
|
||||
delete toDelete;
|
||||
}
|
||||
}
|
||||
|
||||
if (eventMask & EV_DSR) {
|
||||
if (lineStatus_sys() & LS_DSR) {
|
||||
Q_EMIT q->dsrChanged(true);
|
||||
} else {
|
||||
Q_EMIT q->dsrChanged(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WaitCommEvent(handle, &eventMask, &overlap);
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::updatePortSettings()
|
||||
{
|
||||
if (!q_ptr->isOpen() || !settingsDirtyFlags) {
|
||||
return;
|
||||
}
|
||||
|
||||
//fill struct : COMMCONFIG
|
||||
if (settingsDirtyFlags & DFE_BaudRate) {
|
||||
commConfig.dcb.BaudRate = settings.BaudRate;
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_Parity) {
|
||||
commConfig.dcb.Parity = (BYTE)settings.Parity;
|
||||
commConfig.dcb.fParity = (settings.Parity == PAR_NONE) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_DataBits) {
|
||||
commConfig.dcb.ByteSize = (BYTE)settings.DataBits;
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_StopBits) {
|
||||
switch (settings.StopBits) {
|
||||
case STOP_1:
|
||||
commConfig.dcb.StopBits = ONESTOPBIT;
|
||||
break;
|
||||
|
||||
case STOP_1_5:
|
||||
commConfig.dcb.StopBits = ONE5STOPBITS;
|
||||
break;
|
||||
|
||||
case STOP_2:
|
||||
commConfig.dcb.StopBits = TWOSTOPBITS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_Flow) {
|
||||
switch (settings.FlowControl) {
|
||||
/*no flow control*/
|
||||
case FLOW_OFF:
|
||||
commConfig.dcb.fOutxCtsFlow = FALSE;
|
||||
commConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
commConfig.dcb.fInX = FALSE;
|
||||
commConfig.dcb.fOutX = FALSE;
|
||||
break;
|
||||
|
||||
/*software (XON/XOFF) flow control*/
|
||||
case FLOW_XONXOFF:
|
||||
commConfig.dcb.fOutxCtsFlow = FALSE;
|
||||
commConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
commConfig.dcb.fInX = TRUE;
|
||||
commConfig.dcb.fOutX = TRUE;
|
||||
break;
|
||||
|
||||
/*hardware flow control*/
|
||||
case FLOW_HARDWARE:
|
||||
commConfig.dcb.fOutxCtsFlow = TRUE;
|
||||
commConfig.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
||||
commConfig.dcb.fInX = FALSE;
|
||||
commConfig.dcb.fOutX = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//fill struct : COMMTIMEOUTS
|
||||
if (settingsDirtyFlags & DFE_TimeOut) {
|
||||
if (queryMode != QextSerialPort::EventDriven) {
|
||||
int millisec = settings.Timeout_Millisec;
|
||||
|
||||
if (millisec == -1) {
|
||||
commTimeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
commTimeouts.ReadTotalTimeoutConstant = 0;
|
||||
} else {
|
||||
commTimeouts.ReadIntervalTimeout = millisec;
|
||||
commTimeouts.ReadTotalTimeoutConstant = millisec;
|
||||
}
|
||||
|
||||
commTimeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
commTimeouts.WriteTotalTimeoutMultiplier = millisec;
|
||||
commTimeouts.WriteTotalTimeoutConstant = 0;
|
||||
} else {
|
||||
commTimeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
commTimeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
commTimeouts.ReadTotalTimeoutConstant = 0;
|
||||
commTimeouts.WriteTotalTimeoutMultiplier = 0;
|
||||
commTimeouts.WriteTotalTimeoutConstant = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (settingsDirtyFlags & DFE_Settings_Mask) {
|
||||
SetCommConfig(handle, &commConfig, sizeof(COMMCONFIG));
|
||||
}
|
||||
|
||||
if ((settingsDirtyFlags & DFE_TimeOut)) {
|
||||
SetCommTimeouts(handle, &commTimeouts);
|
||||
}
|
||||
|
||||
settingsDirtyFlags = 0;
|
||||
}
|
||||
28
tool/3rd_smtpclient/3rd_smtpclient.pri
Normal file
@@ -0,0 +1,28 @@
|
||||
HEADERS += \
|
||||
$$PWD/emailaddress.h \
|
||||
$$PWD/mimeattachment.h \
|
||||
$$PWD/mimecontentformatter.h \
|
||||
$$PWD/mimefile.h \
|
||||
$$PWD/mimehtml.h \
|
||||
$$PWD/mimeinlinefile.h \
|
||||
$$PWD/mimemessage.h \
|
||||
$$PWD/mimemultipart.h \
|
||||
$$PWD/mimepart.h \
|
||||
$$PWD/mimetext.h \
|
||||
$$PWD/quotedprintable.h \
|
||||
$$PWD/smtpclient.h \
|
||||
$$PWD/smtpmime.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/emailaddress.cpp \
|
||||
$$PWD/mimeattachment.cpp \
|
||||
$$PWD/mimecontentformatter.cpp \
|
||||
$$PWD/mimefile.cpp \
|
||||
$$PWD/mimehtml.cpp \
|
||||
$$PWD/mimeinlinefile.cpp \
|
||||
$$PWD/mimemessage.cpp \
|
||||
$$PWD/mimemultipart.cpp \
|
||||
$$PWD/mimepart.cpp \
|
||||
$$PWD/mimetext.cpp \
|
||||
$$PWD/quotedprintable.cpp \
|
||||
$$PWD/smtpclient.cpp
|
||||
31
tool/3rd_smtpclient/emailaddress.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "emailaddress.h"
|
||||
|
||||
EmailAddress::EmailAddress(const QString &address, const QString &name)
|
||||
{
|
||||
this->address = address;
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
EmailAddress::~EmailAddress()
|
||||
{
|
||||
}
|
||||
|
||||
void EmailAddress::setName(const QString &name)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
void EmailAddress::setAddress(const QString &address)
|
||||
{
|
||||
this->address = address;
|
||||
}
|
||||
|
||||
const QString &EmailAddress::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const QString &EmailAddress::getAddress() const
|
||||
{
|
||||
return address;
|
||||
}
|
||||
28
tool/3rd_smtpclient/emailaddress.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef EMAILADDRESS_H
|
||||
#define EMAILADDRESS_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class EmailAddress : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
EmailAddress();
|
||||
EmailAddress(const QString &address, const QString &name = "");
|
||||
|
||||
~EmailAddress();
|
||||
|
||||
void setName(const QString &name);
|
||||
void setAddress(const QString &address);
|
||||
|
||||
const QString &getName() const;
|
||||
const QString &getAddress() const;
|
||||
|
||||
private:
|
||||
QString name;
|
||||
QString address;
|
||||
|
||||
};
|
||||
|
||||
#endif // EMAILADDRESS_H
|
||||
17
tool/3rd_smtpclient/mimeattachment.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "mimeattachment.h"
|
||||
#include <QFileInfo>
|
||||
|
||||
MimeAttachment::MimeAttachment(QFile *file)
|
||||
: MimeFile(file)
|
||||
{
|
||||
}
|
||||
|
||||
MimeAttachment::~MimeAttachment()
|
||||
{
|
||||
}
|
||||
|
||||
void MimeAttachment::prepare()
|
||||
{
|
||||
this->header += "Content-disposition: attachment\r\n";
|
||||
MimeFile::prepare();
|
||||
}
|
||||
20
tool/3rd_smtpclient/mimeattachment.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef MIMEATTACHMENT_H
|
||||
#define MIMEATTACHMENT_H
|
||||
|
||||
#include <QFile>
|
||||
#include "mimepart.h"
|
||||
#include "mimefile.h"
|
||||
|
||||
class MimeAttachment : public MimeFile
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MimeAttachment(QFile *file);
|
||||
~MimeAttachment();
|
||||
|
||||
protected:
|
||||
virtual void prepare();
|
||||
|
||||
};
|
||||
|
||||
#endif // MIMEATTACHMENT_H
|
||||
51
tool/3rd_smtpclient/mimecontentformatter.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "mimecontentformatter.h"
|
||||
|
||||
MimeContentFormatter::MimeContentFormatter(int max_length) :
|
||||
max_length(max_length)
|
||||
{}
|
||||
|
||||
QString MimeContentFormatter::format(const QString &content, bool quotedPrintable) const
|
||||
{
|
||||
QString out;
|
||||
|
||||
int chars = 0;
|
||||
|
||||
for (int i = 0; i < content.length() ; ++i) {
|
||||
chars++;
|
||||
|
||||
if (!quotedPrintable) {
|
||||
if (chars > max_length) {
|
||||
out.append("\r\n");
|
||||
chars = 1;
|
||||
}
|
||||
} else {
|
||||
if (content.at(i) == '\n') { // new line
|
||||
out.append(content.at(i));
|
||||
chars = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((chars > max_length - 1)
|
||||
|| ((content.at(i) == '=') && (chars > max_length - 3))) {
|
||||
out.append('=');
|
||||
out.append("\r\n");
|
||||
chars = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
out.append(content.at(i));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void MimeContentFormatter::setMaxLength(int l)
|
||||
{
|
||||
max_length = l;
|
||||
}
|
||||
|
||||
int MimeContentFormatter::getMaxLength() const
|
||||
{
|
||||
return max_length;
|
||||
}
|
||||
23
tool/3rd_smtpclient/mimecontentformatter.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef MIMECONTENTFORMATTER_H
|
||||
#define MIMECONTENTFORMATTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
|
||||
class MimeContentFormatter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MimeContentFormatter(int max_length = 76);
|
||||
|
||||
void setMaxLength(int l);
|
||||
int getMaxLength() const;
|
||||
|
||||
QString format(const QString &content, bool quotedPrintable = false) const;
|
||||
|
||||
protected:
|
||||
int max_length;
|
||||
|
||||
};
|
||||
|
||||
#endif // MIMECONTENTFORMATTER_H
|
||||
23
tool/3rd_smtpclient/mimefile.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "mimefile.h"
|
||||
#include <QFileInfo>
|
||||
|
||||
MimeFile::MimeFile(QFile *file)
|
||||
{
|
||||
this->file = file;
|
||||
this->cType = "application/octet-stream";
|
||||
this->cName = QFileInfo(*file).fileName();
|
||||
this->cEncoding = Base64;
|
||||
}
|
||||
|
||||
MimeFile::~MimeFile()
|
||||
{
|
||||
delete file;
|
||||
}
|
||||
|
||||
void MimeFile::prepare()
|
||||
{
|
||||
file->open(QIODevice::ReadOnly);
|
||||
this->content = file->readAll();
|
||||
file->close();
|
||||
MimePart::prepare();
|
||||
}
|
||||
21
tool/3rd_smtpclient/mimefile.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef MIMEFILE_H
|
||||
#define MIMEFILE_H
|
||||
|
||||
#include "mimepart.h"
|
||||
#include <QFile>
|
||||
|
||||
class MimeFile : public MimePart
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
MimeFile(QFile *f);
|
||||
~MimeFile();
|
||||
|
||||
protected:
|
||||
QFile *file;
|
||||
virtual void prepare();
|
||||
|
||||
};
|
||||
|
||||
#endif // MIMEFILE_H
|
||||
23
tool/3rd_smtpclient/mimehtml.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "mimehtml.h"
|
||||
|
||||
MimeHtml::MimeHtml(const QString &html) : MimeText(html)
|
||||
{
|
||||
this->cType = "text/html";
|
||||
}
|
||||
|
||||
MimeHtml::~MimeHtml() {}
|
||||
|
||||
void MimeHtml::setHtml(const QString &html)
|
||||
{
|
||||
this->text = html;
|
||||
}
|
||||
|
||||
const QString &MimeHtml::getHtml() const
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
void MimeHtml::prepare()
|
||||
{
|
||||
MimeText::prepare();
|
||||
}
|
||||
21
tool/3rd_smtpclient/mimehtml.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef MIMEHTML_H
|
||||
#define MIMEHTML_H
|
||||
|
||||
#include "mimetext.h"
|
||||
|
||||
class MimeHtml : public MimeText
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MimeHtml(const QString &html = "");
|
||||
~MimeHtml();
|
||||
|
||||
void setHtml(const QString &html);
|
||||
const QString &getHtml() const;
|
||||
|
||||
protected:
|
||||
virtual void prepare();
|
||||
|
||||
};
|
||||
|
||||
#endif // MIMEHTML_H
|
||||
15
tool/3rd_smtpclient/mimeinlinefile.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "mimeinlinefile.h"
|
||||
|
||||
MimeInlineFile::MimeInlineFile(QFile *f)
|
||||
: MimeFile(f)
|
||||
{
|
||||
}
|
||||
|
||||
MimeInlineFile::~MimeInlineFile()
|
||||
{}
|
||||
|
||||
void MimeInlineFile::prepare()
|
||||
{
|
||||
this->header += "Content-Disposition: inline\r\n";
|
||||
MimeFile::prepare();
|
||||
}
|
||||
18
tool/3rd_smtpclient/mimeinlinefile.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef MIMEINLINEFILE_H
|
||||
#define MIMEINLINEFILE_H
|
||||
|
||||
#include "mimefile.h"
|
||||
|
||||
class MimeInlineFile : public MimeFile
|
||||
{
|
||||
public:
|
||||
|
||||
MimeInlineFile(QFile *f);
|
||||
~MimeInlineFile();
|
||||
|
||||
protected:
|
||||
virtual void prepare();
|
||||
|
||||
};
|
||||
|
||||
#endif // MIMEINLINEFILE_H
|
||||
223
tool/3rd_smtpclient/mimemessage.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
#include "mimemessage.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include "quotedprintable.h"
|
||||
#include <typeinfo>
|
||||
|
||||
MimeMessage::MimeMessage(bool createAutoMimeContent) :
|
||||
hEncoding(MimePart::_8Bit)
|
||||
{
|
||||
if (createAutoMimeContent) {
|
||||
this->content = new MimeMultiPart();
|
||||
}
|
||||
}
|
||||
|
||||
MimeMessage::~MimeMessage()
|
||||
{
|
||||
}
|
||||
|
||||
MimePart &MimeMessage::getContent()
|
||||
{
|
||||
return *content;
|
||||
}
|
||||
|
||||
void MimeMessage::setContent(MimePart *content)
|
||||
{
|
||||
this->content = content;
|
||||
}
|
||||
|
||||
void MimeMessage::setSender(EmailAddress *e)
|
||||
{
|
||||
this->sender = e;
|
||||
}
|
||||
|
||||
void MimeMessage::addRecipient(EmailAddress *rcpt, RecipientType type)
|
||||
{
|
||||
switch (type) {
|
||||
case To:
|
||||
recipientsTo << rcpt;
|
||||
break;
|
||||
|
||||
case Cc:
|
||||
recipientsCc << rcpt;
|
||||
break;
|
||||
|
||||
case Bcc:
|
||||
recipientsBcc << rcpt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MimeMessage::addTo(EmailAddress *rcpt)
|
||||
{
|
||||
this->recipientsTo << rcpt;
|
||||
}
|
||||
|
||||
void MimeMessage::addCc(EmailAddress *rcpt)
|
||||
{
|
||||
this->recipientsCc << rcpt;
|
||||
}
|
||||
|
||||
void MimeMessage::addBcc(EmailAddress *rcpt)
|
||||
{
|
||||
this->recipientsBcc << rcpt;
|
||||
}
|
||||
|
||||
void MimeMessage::setSubject(const QString &subject)
|
||||
{
|
||||
this->subject = subject;
|
||||
}
|
||||
|
||||
void MimeMessage::addPart(MimePart *part)
|
||||
{
|
||||
if (typeid(*content) == typeid(MimeMultiPart)) {
|
||||
((MimeMultiPart *) content)->addPart(part);
|
||||
};
|
||||
}
|
||||
|
||||
void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc)
|
||||
{
|
||||
this->hEncoding = hEnc;
|
||||
}
|
||||
|
||||
const EmailAddress &MimeMessage::getSender() const
|
||||
{
|
||||
return *sender;
|
||||
}
|
||||
|
||||
const QList<EmailAddress *> &MimeMessage::getRecipients(RecipientType type) const
|
||||
{
|
||||
switch (type) {
|
||||
default:
|
||||
case To:
|
||||
return recipientsTo;
|
||||
|
||||
case Cc:
|
||||
return recipientsCc;
|
||||
|
||||
case Bcc:
|
||||
return recipientsBcc;
|
||||
}
|
||||
}
|
||||
|
||||
const QString &MimeMessage::getSubject() const
|
||||
{
|
||||
return subject;
|
||||
}
|
||||
|
||||
const QList<MimePart *> &MimeMessage::getParts() const
|
||||
{
|
||||
if (typeid(*content) == typeid(MimeMultiPart)) {
|
||||
return ((MimeMultiPart *) content)->getParts();
|
||||
} else {
|
||||
QList<MimePart *> *res = new QList<MimePart *>();
|
||||
res->append(content);
|
||||
return *res;
|
||||
}
|
||||
}
|
||||
|
||||
QString MimeMessage::toString()
|
||||
{
|
||||
QString mime;
|
||||
mime = "From:";
|
||||
|
||||
QByteArray name = sender->getName().toUtf8();
|
||||
if (name != "") {
|
||||
switch (hEncoding) {
|
||||
case MimePart::Base64:
|
||||
mime += " =?utf-8?B?" + QByteArray().append(name).toBase64() + "?=";
|
||||
break;
|
||||
|
||||
case MimePart::QuotedPrintable:
|
||||
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(name)).replace(' ', "_").replace(':', "=3A") + "?=";
|
||||
break;
|
||||
|
||||
default:
|
||||
mime += " " + name;
|
||||
}
|
||||
}
|
||||
|
||||
mime += " <" + sender->getAddress() + ">\r\n";
|
||||
|
||||
mime += "To:";
|
||||
QList<EmailAddress *>::iterator it;
|
||||
int i;
|
||||
|
||||
for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i) {
|
||||
if (i != 0) {
|
||||
mime += ",";
|
||||
}
|
||||
|
||||
QByteArray name = (*it)->getName().toUtf8();
|
||||
if (name != "") {
|
||||
switch (hEncoding) {
|
||||
case MimePart::Base64:
|
||||
mime += " =?utf-8?B?" + QByteArray().append(name).toBase64() + "?=";
|
||||
break;
|
||||
|
||||
case MimePart::QuotedPrintable:
|
||||
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(name)).replace(' ', "_").replace(':', "=3A") + "?=";
|
||||
break;
|
||||
|
||||
default:
|
||||
mime += " " + name;
|
||||
}
|
||||
}
|
||||
|
||||
mime += " <" + (*it)->getAddress() + ">";
|
||||
}
|
||||
|
||||
mime += "\r\n";
|
||||
if (recipientsCc.size() != 0) {
|
||||
mime += "Cc:";
|
||||
}
|
||||
|
||||
for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i) {
|
||||
if (i != 0) {
|
||||
mime += ",";
|
||||
}
|
||||
|
||||
QByteArray name = (*it)->getName().toUtf8();
|
||||
if (name != "") {
|
||||
switch (hEncoding) {
|
||||
case MimePart::Base64:
|
||||
mime += " =?utf-8?B?" + QByteArray().append(name).toBase64() + "?=";
|
||||
break;
|
||||
|
||||
case MimePart::QuotedPrintable:
|
||||
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(name)).replace(' ', "_").replace(':', "=3A") + "?=";
|
||||
break;
|
||||
|
||||
default:
|
||||
mime += " " + name;
|
||||
}
|
||||
}
|
||||
|
||||
mime += " <" + (*it)->getAddress() + ">";
|
||||
}
|
||||
|
||||
if (recipientsCc.size() != 0) {
|
||||
mime += "\r\n";
|
||||
}
|
||||
|
||||
mime += "Subject: ";
|
||||
|
||||
switch (hEncoding) {
|
||||
case MimePart::Base64:
|
||||
mime += "=?utf-8?B?" + QByteArray().append(subject.toUtf8()).toBase64() + "?=";
|
||||
break;
|
||||
|
||||
case MimePart::QuotedPrintable:
|
||||
mime += "=?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(subject.toUtf8())).replace(' ', "_").replace(':', "=3A") + "?=";
|
||||
break;
|
||||
|
||||
default:
|
||||
mime += subject;
|
||||
}
|
||||
|
||||
mime += "\r\n";
|
||||
mime += "MIME-Version: 1.0\r\n";
|
||||
|
||||
mime += content->toString();
|
||||
return mime;
|
||||
}
|
||||
54
tool/3rd_smtpclient/mimemessage.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef MIMEMESSAGE_H
|
||||
#define MIMEMESSAGE_H
|
||||
|
||||
#include "mimepart.h"
|
||||
#include "mimemultipart.h"
|
||||
#include "emailaddress.h"
|
||||
#include <QList>
|
||||
|
||||
class MimeMessage : public QObject
|
||||
{
|
||||
public:
|
||||
|
||||
enum RecipientType {
|
||||
To, // primary
|
||||
Cc, // carbon copy
|
||||
Bcc // blind carbon copy
|
||||
};
|
||||
|
||||
|
||||
MimeMessage(bool createAutoMimeConent = true);
|
||||
~MimeMessage();
|
||||
|
||||
void setSender(EmailAddress *e);
|
||||
void addRecipient(EmailAddress *rcpt, RecipientType type = To);
|
||||
void addTo(EmailAddress *rcpt);
|
||||
void addCc(EmailAddress *rcpt);
|
||||
void addBcc(EmailAddress *rcpt);
|
||||
void setSubject(const QString &subject);
|
||||
void addPart(MimePart *part);
|
||||
|
||||
void setHeaderEncoding(MimePart::Encoding);
|
||||
|
||||
const EmailAddress &getSender() const;
|
||||
const QList<EmailAddress *> &getRecipients(RecipientType type = To) const;
|
||||
const QString &getSubject() const;
|
||||
const QList<MimePart *> &getParts() const;
|
||||
|
||||
MimePart &getContent();
|
||||
void setContent(MimePart *content);
|
||||
|
||||
virtual QString toString();
|
||||
|
||||
|
||||
protected:
|
||||
EmailAddress *sender;
|
||||
QList<EmailAddress *> recipientsTo, recipientsCc, recipientsBcc;
|
||||
QString subject;
|
||||
MimePart *content;
|
||||
|
||||
MimePart::Encoding hEncoding;
|
||||
|
||||
};
|
||||
|
||||
#endif // MIMEMESSAGE_H
|
||||
66
tool/3rd_smtpclient/mimemultipart.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "mimemultipart.h"
|
||||
#include "stdlib.h"
|
||||
#include <QTime>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
const QString MULTI_PART_NAMES[] = {
|
||||
"multipart/mixed", // Mixed
|
||||
"multipart/digest", // Digest
|
||||
"multipart/alternative", // Alternative
|
||||
"multipart/related", // Related
|
||||
"multipart/report", // Report
|
||||
"multipart/signed", // Signed
|
||||
"multipart/encrypted" // Encrypted
|
||||
};
|
||||
|
||||
MimeMultiPart::MimeMultiPart(MultiPartType type)
|
||||
{
|
||||
this->type = type;
|
||||
this->cType = MULTI_PART_NAMES[this->type];
|
||||
this->cEncoding = _8Bit;
|
||||
|
||||
QCryptographicHash md5(QCryptographicHash::Md5);
|
||||
md5.addData(QByteArray().append(rand()));
|
||||
cBoundary = md5.result().toHex();
|
||||
}
|
||||
|
||||
MimeMultiPart::~MimeMultiPart()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MimeMultiPart::addPart(MimePart *part)
|
||||
{
|
||||
parts.append(part);
|
||||
}
|
||||
|
||||
const QList<MimePart *> &MimeMultiPart::getParts() const
|
||||
{
|
||||
return parts;
|
||||
}
|
||||
|
||||
void MimeMultiPart::prepare()
|
||||
{
|
||||
QList<MimePart *>::iterator it;
|
||||
content = "";
|
||||
|
||||
for (it = parts.begin(); it != parts.end(); it++) {
|
||||
content += "--" + cBoundary.toUtf8() + "\r\n";
|
||||
(*it)->prepare();
|
||||
content += (*it)->toString().toUtf8();
|
||||
};
|
||||
|
||||
content += "--" + cBoundary.toUtf8() + "--\r\n";
|
||||
MimePart::prepare();
|
||||
}
|
||||
|
||||
void MimeMultiPart::setMimeType(const MultiPartType type)
|
||||
{
|
||||
this->type = type;
|
||||
this->cType = MULTI_PART_NAMES[type];
|
||||
}
|
||||
|
||||
MimeMultiPart::MultiPartType MimeMultiPart::getMimeType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
37
tool/3rd_smtpclient/mimemultipart.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef MIMEMULTIPART_H
|
||||
#define MIMEMULTIPART_H
|
||||
|
||||
#include "mimepart.h"
|
||||
|
||||
class MimeMultiPart : public MimePart
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum MultiPartType {
|
||||
Mixed = 0, // RFC 2046, section 5.1.3
|
||||
Digest = 1, // RFC 2046, section 5.1.5
|
||||
Alternative = 2, // RFC 2046, section 5.1.4
|
||||
Related = 3, // RFC 2387
|
||||
Report = 4, // RFC 6522
|
||||
Signed = 5, // RFC 1847, section 2.1
|
||||
Encrypted = 6 // RFC 1847, section 2.2
|
||||
};
|
||||
|
||||
MimeMultiPart(const MultiPartType type = Related);
|
||||
~MimeMultiPart();
|
||||
|
||||
void setMimeType(const MultiPartType type);
|
||||
MultiPartType getMimeType() const;
|
||||
|
||||
const QList<MimePart *> &getParts() const;
|
||||
|
||||
void addPart(MimePart *part);
|
||||
virtual void prepare();
|
||||
|
||||
protected:
|
||||
QList<MimePart *> parts;
|
||||
MultiPartType type;
|
||||
|
||||
};
|
||||
|
||||
#endif // MIMEMULTIPART_H
|
||||
171
tool/3rd_smtpclient/mimepart.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#include "mimepart.h"
|
||||
#include "quotedprintable.h"
|
||||
|
||||
MimePart::MimePart()
|
||||
{
|
||||
cEncoding = _7Bit;
|
||||
prepared = false;
|
||||
cBoundary = "";
|
||||
}
|
||||
|
||||
MimePart::~MimePart()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void MimePart::setContent(const QByteArray &content)
|
||||
{
|
||||
this->content = content;
|
||||
}
|
||||
|
||||
void MimePart::setHeader(const QString &header)
|
||||
{
|
||||
this->header = header;
|
||||
}
|
||||
|
||||
void MimePart::addHeaderLine(const QString &line)
|
||||
{
|
||||
this->header += line + "\r\n";
|
||||
}
|
||||
|
||||
const QString &MimePart::getHeader() const
|
||||
{
|
||||
return header;
|
||||
}
|
||||
|
||||
const QByteArray &MimePart::getContent() const
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
void MimePart::setContentId(const QString &cId)
|
||||
{
|
||||
this->cId = cId;
|
||||
}
|
||||
|
||||
const QString &MimePart::getContentId() const
|
||||
{
|
||||
return this->cId;
|
||||
}
|
||||
|
||||
void MimePart::setContentName(const QString &cName)
|
||||
{
|
||||
this->cName = cName;
|
||||
}
|
||||
|
||||
const QString &MimePart::getContentName() const
|
||||
{
|
||||
return this->cName;
|
||||
}
|
||||
|
||||
void MimePart::setContentType(const QString &cType)
|
||||
{
|
||||
this->cType = cType;
|
||||
}
|
||||
|
||||
const QString &MimePart::getContentType() const
|
||||
{
|
||||
return this->cType;
|
||||
}
|
||||
|
||||
void MimePart::setCharset(const QString &charset)
|
||||
{
|
||||
this->cCharset = charset;
|
||||
}
|
||||
|
||||
const QString &MimePart::getCharset() const
|
||||
{
|
||||
return this->cCharset;
|
||||
}
|
||||
|
||||
void MimePart::setEncoding(Encoding enc)
|
||||
{
|
||||
this->cEncoding = enc;
|
||||
}
|
||||
|
||||
MimePart::Encoding MimePart::getEncoding() const
|
||||
{
|
||||
return this->cEncoding;
|
||||
}
|
||||
|
||||
MimeContentFormatter &MimePart::getContentFormatter()
|
||||
{
|
||||
return this->formatter;
|
||||
}
|
||||
|
||||
QString MimePart::toString()
|
||||
{
|
||||
if (!prepared) {
|
||||
prepare();
|
||||
}
|
||||
|
||||
return mimeString;
|
||||
}
|
||||
|
||||
void MimePart::prepare()
|
||||
{
|
||||
mimeString = QString();
|
||||
|
||||
mimeString.append("Content-Type: ").append(cType);
|
||||
|
||||
if (cName != "") {
|
||||
mimeString.append("; name=\"").append(cName).append("\"");
|
||||
}
|
||||
|
||||
if (cCharset != "") {
|
||||
mimeString.append("; charset=").append(cCharset);
|
||||
}
|
||||
|
||||
if (cBoundary != "") {
|
||||
mimeString.append("; boundary=").append(cBoundary);
|
||||
}
|
||||
|
||||
mimeString.append("\r\n");
|
||||
|
||||
mimeString.append("Content-Transfer-Encoding: ");
|
||||
|
||||
switch (cEncoding) {
|
||||
case _7Bit:
|
||||
mimeString.append("7bit\r\n");
|
||||
break;
|
||||
|
||||
case _8Bit:
|
||||
mimeString.append("8bit\r\n");
|
||||
break;
|
||||
|
||||
case Base64:
|
||||
mimeString.append("base64\r\n");
|
||||
break;
|
||||
|
||||
case QuotedPrintable:
|
||||
mimeString.append("quoted-printable\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (cId.toInt() != 0) {
|
||||
mimeString.append("Content-ID: <").append(cId).append(">\r\n");
|
||||
}
|
||||
|
||||
mimeString.append(header).append("\r\n");
|
||||
|
||||
switch (cEncoding) {
|
||||
case _7Bit:
|
||||
mimeString.append(QString(content).toLatin1());
|
||||
break;
|
||||
|
||||
case _8Bit:
|
||||
mimeString.append(content);
|
||||
break;
|
||||
|
||||
case Base64:
|
||||
mimeString.append(formatter.format(content.toBase64()));
|
||||
break;
|
||||
|
||||
case QuotedPrintable:
|
||||
mimeString.append(formatter.format(QuotedPrintable::encode(content), true));
|
||||
break;
|
||||
}
|
||||
|
||||
mimeString.append("\r\n");
|
||||
prepared = true;
|
||||
}
|
||||
67
tool/3rd_smtpclient/mimepart.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef MIMEPART_H
|
||||
#define MIMEPART_H
|
||||
|
||||
#include <QObject>
|
||||
#include "mimecontentformatter.h"
|
||||
|
||||
class MimePart : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Encoding {
|
||||
_7Bit,
|
||||
_8Bit,
|
||||
Base64,
|
||||
QuotedPrintable
|
||||
};
|
||||
|
||||
MimePart();
|
||||
~MimePart();
|
||||
|
||||
const QString &getHeader() const;
|
||||
const QByteArray &getContent() const;
|
||||
|
||||
void setContent(const QByteArray &content);
|
||||
void setHeader(const QString &header);
|
||||
|
||||
void addHeaderLine(const QString &line);
|
||||
|
||||
void setContentId(const QString &cId);
|
||||
const QString &getContentId() const;
|
||||
|
||||
void setContentName(const QString &cName);
|
||||
const QString &getContentName() const;
|
||||
|
||||
void setContentType(const QString &cType);
|
||||
const QString &getContentType() const;
|
||||
|
||||
void setCharset(const QString &charset);
|
||||
const QString &getCharset() const;
|
||||
|
||||
void setEncoding(Encoding enc);
|
||||
Encoding getEncoding() const;
|
||||
|
||||
MimeContentFormatter &getContentFormatter();
|
||||
|
||||
virtual QString toString();
|
||||
virtual void prepare();
|
||||
|
||||
protected:
|
||||
QString header;
|
||||
QByteArray content;
|
||||
|
||||
QString cId;
|
||||
QString cName;
|
||||
QString cType;
|
||||
QString cCharset;
|
||||
QString cBoundary;
|
||||
Encoding cEncoding;
|
||||
|
||||
QString mimeString;
|
||||
bool prepared;
|
||||
|
||||
MimeContentFormatter formatter;
|
||||
|
||||
};
|
||||
|
||||
#endif // MIMEPART_H
|
||||
28
tool/3rd_smtpclient/mimetext.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "mimetext.h"
|
||||
|
||||
MimeText::MimeText(const QString &txt)
|
||||
{
|
||||
this->text = txt;
|
||||
this->cType = "text/plain";
|
||||
this->cCharset = "utf-8";
|
||||
this->cEncoding = _8Bit;
|
||||
}
|
||||
|
||||
MimeText::~MimeText() { }
|
||||
|
||||
void MimeText::setText(const QString &text)
|
||||
{
|
||||
this->text = text;
|
||||
}
|
||||
|
||||
const QString &MimeText::getText() const
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
void MimeText::prepare()
|
||||
{
|
||||
this->content.clear();
|
||||
this->content.append(text.toUtf8());
|
||||
MimePart::prepare();
|
||||
}
|
||||
22
tool/3rd_smtpclient/mimetext.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef MIMETEXT_H
|
||||
#define MIMETEXT_H
|
||||
|
||||
#include "mimepart.h"
|
||||
|
||||
class MimeText : public MimePart
|
||||
{
|
||||
public:
|
||||
|
||||
MimeText(const QString &text = "");
|
||||
~MimeText();
|
||||
|
||||
void setText(const QString &text);
|
||||
const QString &getText() const;
|
||||
|
||||
protected:
|
||||
QString text;
|
||||
void prepare();
|
||||
|
||||
};
|
||||
|
||||
#endif // MIMETEXT_H
|
||||
43
tool/3rd_smtpclient/quotedprintable.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "quotedprintable.h"
|
||||
|
||||
QString &QuotedPrintable::encode(const QByteArray &input)
|
||||
{
|
||||
QString *output = new QString();
|
||||
|
||||
char byte;
|
||||
const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
for (int i = 0; i < input.length() ; ++i) {
|
||||
byte = input.at(i);
|
||||
|
||||
if ((byte == 0x20) || ((byte >= 33) && (byte <= 126) && (byte != 61))) {
|
||||
output->append(byte);
|
||||
} else {
|
||||
output->append('=');
|
||||
output->append(hex[((byte >> 4) & 0x0F)]);
|
||||
output->append(hex[(byte & 0x0F)]);
|
||||
}
|
||||
}
|
||||
|
||||
return *output;
|
||||
}
|
||||
|
||||
|
||||
QByteArray &QuotedPrintable::decode(const QString &input)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F
|
||||
const int hexVal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
|
||||
|
||||
QByteArray *output = new QByteArray();
|
||||
|
||||
for (int i = 0; i < input.length(); ++i) {
|
||||
if (input.at(i).toLatin1() == '=') {
|
||||
int index = ++i;
|
||||
output->append((hexVal[input.at(index).toLatin1() - '0'] << 4) + hexVal[input.at(++i).toLatin1() - '0']);
|
||||
} else {
|
||||
output->append(input.at(i).toLatin1());
|
||||
}
|
||||
}
|
||||
|
||||
return *output;
|
||||
}
|
||||
19
tool/3rd_smtpclient/quotedprintable.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef QUOTEDPRINTABLE_H
|
||||
#define QUOTEDPRINTABLE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
|
||||
class QuotedPrintable : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
static QString &encode(const QByteArray &input);
|
||||
static QByteArray &decode(const QString &input);
|
||||
|
||||
private:
|
||||
QuotedPrintable();
|
||||
};
|
||||
|
||||
#endif // QUOTEDPRINTABLE_H
|
||||
390
tool/3rd_smtpclient/smtpclient.cpp
Normal file
@@ -0,0 +1,390 @@
|
||||
#include "smtpclient.h"
|
||||
|
||||
SmtpClient::SmtpClient(const QString &host, int port, ConnectionType connectionType) :
|
||||
name("localhost"),
|
||||
authMethod(AuthPlain),
|
||||
connectionTimeout(5000),
|
||||
responseTimeout(5000)
|
||||
{
|
||||
setConnectionType(connectionType);
|
||||
|
||||
this->host = host;
|
||||
this->port = port;
|
||||
}
|
||||
|
||||
SmtpClient::~SmtpClient() {}
|
||||
|
||||
void SmtpClient::setUser(const QString &user)
|
||||
{
|
||||
this->user = user;
|
||||
}
|
||||
|
||||
void SmtpClient::setPassword(const QString &password)
|
||||
{
|
||||
this->password = password;
|
||||
}
|
||||
|
||||
void SmtpClient::setAuthMethod(AuthMethod method)
|
||||
{
|
||||
this->authMethod = method;
|
||||
}
|
||||
|
||||
void SmtpClient::setHost(QString &host)
|
||||
{
|
||||
this->host = host;
|
||||
}
|
||||
|
||||
void SmtpClient::setPort(int port)
|
||||
{
|
||||
this->port = port;
|
||||
}
|
||||
|
||||
void SmtpClient::setConnectionType(ConnectionType ct)
|
||||
{
|
||||
this->connectionType = ct;
|
||||
|
||||
switch (connectionType) {
|
||||
case TcpConnection:
|
||||
socket = new QTcpSocket(this);
|
||||
break;
|
||||
#ifdef ssl
|
||||
case SslConnection:
|
||||
case TlsConnection:
|
||||
socket = new QSslSocket(this);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
const QString &SmtpClient::getHost() const
|
||||
{
|
||||
return this->host;
|
||||
}
|
||||
|
||||
const QString &SmtpClient::getUser() const
|
||||
{
|
||||
return this->user;
|
||||
}
|
||||
|
||||
const QString &SmtpClient::getPassword() const
|
||||
{
|
||||
return this->password;
|
||||
}
|
||||
|
||||
SmtpClient::AuthMethod SmtpClient::getAuthMethod() const
|
||||
{
|
||||
return this->authMethod;
|
||||
}
|
||||
|
||||
int SmtpClient::getPort() const
|
||||
{
|
||||
return this->port;
|
||||
}
|
||||
|
||||
SmtpClient::ConnectionType SmtpClient::getConnectionType() const
|
||||
{
|
||||
return connectionType;
|
||||
}
|
||||
|
||||
const QString &SmtpClient::getName() const
|
||||
{
|
||||
return this->name;
|
||||
}
|
||||
|
||||
void SmtpClient::setName(const QString &name)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
const QString &SmtpClient::getResponseText() const
|
||||
{
|
||||
return responseText;
|
||||
}
|
||||
|
||||
int SmtpClient::getResponseCode() const
|
||||
{
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
QTcpSocket *SmtpClient::getSocket()
|
||||
{
|
||||
return socket;
|
||||
}
|
||||
|
||||
int SmtpClient::getConnectionTimeout() const
|
||||
{
|
||||
return connectionTimeout;
|
||||
}
|
||||
|
||||
void SmtpClient::setConnectionTimeout(int msec)
|
||||
{
|
||||
connectionTimeout = msec;
|
||||
}
|
||||
|
||||
int SmtpClient::getResponseTimeout() const
|
||||
{
|
||||
return responseTimeout;
|
||||
}
|
||||
|
||||
void SmtpClient::setResponseTimeout(int msec)
|
||||
{
|
||||
responseTimeout = msec;
|
||||
}
|
||||
|
||||
bool SmtpClient::connectToHost()
|
||||
{
|
||||
switch (connectionType) {
|
||||
case TlsConnection:
|
||||
case TcpConnection:
|
||||
socket->connectToHost(host, port);
|
||||
break;
|
||||
#ifdef ssl
|
||||
case SslConnection:
|
||||
((QSslSocket *) socket)->connectToHostEncrypted(host, port);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!socket->waitForConnected(connectionTimeout)) {
|
||||
emit smtpError(ConnectionTimeoutError);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// Wait for the server's response
|
||||
waitForResponse();
|
||||
|
||||
// If the response code is not 220 (Service ready)
|
||||
// means that is something wrong with the server
|
||||
if (responseCode != 220) {
|
||||
emit smtpError(ServerError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a EHLO/HELO message to the server
|
||||
// The client's first command must be EHLO/HELO
|
||||
sendMessage("EHLO " + name);
|
||||
|
||||
// Wait for the server's response
|
||||
waitForResponse();
|
||||
|
||||
// The response code needs to be 250.
|
||||
if (responseCode != 250) {
|
||||
emit smtpError(ServerError);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (connectionType == TlsConnection) {
|
||||
// send a request to start TLS handshake
|
||||
sendMessage("STARTTLS");
|
||||
|
||||
// Wait for the server's response
|
||||
waitForResponse();
|
||||
|
||||
// The response code needs to be 220.
|
||||
if (responseCode != 220) {
|
||||
emit smtpError(ServerError);
|
||||
return false;
|
||||
};
|
||||
#ifdef ssl
|
||||
((QSslSocket *) socket)->startClientEncryption();
|
||||
if (!((QSslSocket *) socket)->waitForEncrypted(connectionTimeout)) {
|
||||
qDebug() << ((QSslSocket *) socket)->errorString();
|
||||
emit smtpError(ConnectionTimeoutError);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
// Send ELHO one more time
|
||||
sendMessage("EHLO " + name);
|
||||
|
||||
// Wait for the server's response
|
||||
waitForResponse();
|
||||
|
||||
// The response code needs to be 250.
|
||||
if (responseCode != 250) {
|
||||
emit smtpError(ServerError);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (ResponseTimeoutException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SmtpClient::login()
|
||||
{
|
||||
return login(user, password, authMethod);
|
||||
}
|
||||
|
||||
bool SmtpClient::login(const QString &user, const QString &password, AuthMethod method)
|
||||
{
|
||||
try {
|
||||
if (method == AuthPlain) {
|
||||
// Sending command: AUTH PLAIN base64('\0' + username + '\0' + password)
|
||||
sendMessage("AUTH PLAIN " + QByteArray().append((char) 0).append(user.toUtf8()).append((char) 0).append(password.toUtf8()).toBase64());
|
||||
|
||||
// Wait for the server's response
|
||||
waitForResponse();
|
||||
|
||||
// If the response is not 235 then the authentication was faild
|
||||
if (responseCode != 235) {
|
||||
emit smtpError(AuthenticationFailedError);
|
||||
return false;
|
||||
}
|
||||
} else if (method == AuthLogin) {
|
||||
// Sending command: AUTH LOGIN
|
||||
sendMessage("AUTH LOGIN");
|
||||
|
||||
// Wait for 334 response code
|
||||
waitForResponse();
|
||||
|
||||
if (responseCode != 334) {
|
||||
emit smtpError(AuthenticationFailedError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the username in base64
|
||||
sendMessage(QByteArray().append(user.toUtf8()).toBase64());
|
||||
|
||||
// Wait for 334
|
||||
waitForResponse();
|
||||
|
||||
if (responseCode != 334) {
|
||||
emit smtpError(AuthenticationFailedError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the password in base64
|
||||
sendMessage(QByteArray().append(password.toUtf8()).toBase64());
|
||||
|
||||
// Wait for the server's responce
|
||||
waitForResponse();
|
||||
|
||||
// If the response is not 235 then the authentication was faild
|
||||
if (responseCode != 235) {
|
||||
emit smtpError(AuthenticationFailedError);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (ResponseTimeoutException e) {
|
||||
// Responce Timeout exceeded
|
||||
emit smtpError(AuthenticationFailedError);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SmtpClient::sendMail(MimeMessage &email)
|
||||
{
|
||||
try {
|
||||
// Send the MAIL command with the sender
|
||||
sendMessage("MAIL FROM: <" + email.getSender().getAddress() + ">");
|
||||
|
||||
waitForResponse();
|
||||
|
||||
if (responseCode != 250) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send RCPT command for each recipient
|
||||
QList<EmailAddress *>::const_iterator it, itEnd;
|
||||
|
||||
// To (primary recipients)
|
||||
for (it = email.getRecipients().begin(), itEnd = email.getRecipients().end();
|
||||
it != itEnd; ++it) {
|
||||
sendMessage("RCPT TO: <" + (*it)->getAddress() + ">");
|
||||
waitForResponse();
|
||||
|
||||
if (responseCode != 250) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Cc (carbon copy)
|
||||
for (it = email.getRecipients(MimeMessage::Cc).begin(), itEnd = email.getRecipients(MimeMessage::Cc).end();
|
||||
it != itEnd; ++it) {
|
||||
sendMessage("RCPT TO: <" + (*it)->getAddress() + ">");
|
||||
waitForResponse();
|
||||
|
||||
if (responseCode != 250) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Bcc (blind carbon copy)
|
||||
for (it = email.getRecipients(MimeMessage::Bcc).begin(), itEnd = email.getRecipients(MimeMessage::Bcc).end();
|
||||
it != itEnd; ++it) {
|
||||
sendMessage("RCPT TO: <" + (*it)->getAddress() + ">");
|
||||
waitForResponse();
|
||||
|
||||
if (responseCode != 250) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Send DATA command
|
||||
sendMessage("DATA");
|
||||
waitForResponse();
|
||||
|
||||
if (responseCode != 354) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sendMessage(email.toString());
|
||||
|
||||
// Send \r\n.\r\n to end the mail data
|
||||
sendMessage(".");
|
||||
|
||||
waitForResponse();
|
||||
|
||||
if (responseCode != 250) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResponseTimeoutException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SmtpClient::quit()
|
||||
{
|
||||
sendMessage("QUIT");
|
||||
}
|
||||
|
||||
void SmtpClient::waitForResponse()
|
||||
{
|
||||
do {
|
||||
if (!socket->waitForReadyRead(responseTimeout)) {
|
||||
emit smtpError(ResponseTimeoutError);
|
||||
throw ResponseTimeoutException();
|
||||
}
|
||||
|
||||
while (socket->canReadLine()) {
|
||||
// Save the server's response
|
||||
responseText = socket->readLine();
|
||||
|
||||
// Extract the respose code from the server's responce (first 3 digits)
|
||||
responseCode = responseText.left(3).toInt();
|
||||
|
||||
if (responseCode / 100 == 4) {
|
||||
emit smtpError(ServerError);
|
||||
}
|
||||
|
||||
if (responseCode / 100 == 5) {
|
||||
emit smtpError(ClientError);
|
||||
}
|
||||
|
||||
if (responseText.at(3) == ' ') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
void SmtpClient::sendMessage(const QString &text)
|
||||
{
|
||||
socket->write(text.toUtf8() + "\r\n");
|
||||
}
|
||||
103
tool/3rd_smtpclient/smtpclient.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifndef SMTPCLIENT_H
|
||||
#define SMTPCLIENT_H
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtNetwork>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
#include <QtWidgets>
|
||||
#endif
|
||||
#include "mimemessage.h"
|
||||
|
||||
class SmtpClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum AuthMethod {
|
||||
AuthPlain,
|
||||
AuthLogin
|
||||
};
|
||||
|
||||
enum SmtpError {
|
||||
ConnectionTimeoutError,
|
||||
ResponseTimeoutError,
|
||||
AuthenticationFailedError,
|
||||
ServerError, // 4xx smtp error
|
||||
ClientError // 5xx smtp error
|
||||
};
|
||||
|
||||
enum ConnectionType {
|
||||
TcpConnection,
|
||||
SslConnection,
|
||||
TlsConnection // STARTTLS
|
||||
};
|
||||
|
||||
SmtpClient(const QString &host = "locahost", int port = 25, ConnectionType ct = TcpConnection);
|
||||
|
||||
~SmtpClient();
|
||||
|
||||
const QString &getHost() const;
|
||||
void setHost(QString &host);
|
||||
|
||||
int getPort() const;
|
||||
void setPort(int port);
|
||||
|
||||
const QString &getName() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
ConnectionType getConnectionType() const;
|
||||
void setConnectionType(ConnectionType ct);
|
||||
|
||||
const QString &getUser() const;
|
||||
void setUser(const QString &host);
|
||||
|
||||
const QString &getPassword() const;
|
||||
void setPassword(const QString &password);
|
||||
|
||||
SmtpClient::AuthMethod getAuthMethod() const;
|
||||
void setAuthMethod(AuthMethod method);
|
||||
|
||||
const QString &getResponseText() const;
|
||||
int getResponseCode() const;
|
||||
|
||||
int getConnectionTimeout() const;
|
||||
void setConnectionTimeout(int msec);
|
||||
|
||||
int getResponseTimeout() const;
|
||||
void setResponseTimeout(int msec);
|
||||
|
||||
QTcpSocket *getSocket();
|
||||
|
||||
bool connectToHost();
|
||||
bool login();
|
||||
bool login(const QString &user, const QString &password, AuthMethod method = AuthLogin);
|
||||
|
||||
bool sendMail(MimeMessage &email);
|
||||
void quit();
|
||||
|
||||
protected:
|
||||
QTcpSocket *socket;
|
||||
QString host;
|
||||
int port;
|
||||
ConnectionType connectionType;
|
||||
QString name;
|
||||
|
||||
QString user;
|
||||
QString password;
|
||||
AuthMethod authMethod;
|
||||
|
||||
int connectionTimeout;
|
||||
int responseTimeout;
|
||||
|
||||
QString responseText;
|
||||
int responseCode;
|
||||
|
||||
class ResponseTimeoutException {};
|
||||
void waitForResponse();
|
||||
void sendMessage(const QString &text);
|
||||
|
||||
signals:
|
||||
void smtpError(SmtpError e);
|
||||
|
||||
};
|
||||
|
||||
#endif // SMTPCLIENT_H
|
||||
13
tool/3rd_smtpclient/smtpmime.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef SMTPMIME_H
|
||||
#define SMTPMIME_H
|
||||
|
||||
#include "smtpclient.h"
|
||||
#include "mimepart.h"
|
||||
#include "mimehtml.h"
|
||||
#include "mimeattachment.h"
|
||||
#include "mimemessage.h"
|
||||
#include "mimetext.h"
|
||||
#include "mimeinlinefile.h"
|
||||
#include "mimefile.h"
|
||||
|
||||
#endif // SMTPMIME_H
|
||||
41
tool/base64helper/base64helper.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "base64helper.h"
|
||||
#include "qbuffer.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
QString Base64Helper::imageToBase64(const QImage &image)
|
||||
{
|
||||
return QString(imageToBase64x(image));
|
||||
}
|
||||
|
||||
QByteArray Base64Helper::imageToBase64x(const QImage &image)
|
||||
{
|
||||
//这个转换可能比较耗时建议在线程中执行
|
||||
QByteArray data;
|
||||
QBuffer buffer(&data);
|
||||
image.save(&buffer, "JPG");
|
||||
data = data.toBase64();
|
||||
return data;
|
||||
}
|
||||
|
||||
QImage Base64Helper::base64ToImage(const QString &data)
|
||||
{
|
||||
return base64ToImagex(data.toUtf8());
|
||||
}
|
||||
|
||||
QImage Base64Helper::base64ToImagex(const QByteArray &data)
|
||||
{
|
||||
//这个转换可能比较耗时建议在线程中执行
|
||||
QImage image;
|
||||
image.loadFromData(QByteArray::fromBase64(data));
|
||||
return image;
|
||||
}
|
||||
|
||||
QString Base64Helper::textToBase64(const QString &text)
|
||||
{
|
||||
return QString(text.toLocal8Bit().toBase64());
|
||||
}
|
||||
|
||||
QString Base64Helper::base64ToText(const QString &text)
|
||||
{
|
||||
return QString(QByteArray::fromBase64(text.toLocal8Bit()));
|
||||
}
|
||||
37
tool/base64helper/base64helper.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef BASE64HELPER_H
|
||||
#define BASE64HELPER_H
|
||||
|
||||
/**
|
||||
* base64编码转换类 作者:feiyangqingyun(QQ:517216493) 2016-12-16
|
||||
* 1. 图片转base64字符串。
|
||||
* 2. base64字符串转图片。
|
||||
* 3. 字符转base64字符串。
|
||||
* 4. base64字符串转字符。
|
||||
* 5. 后期增加数据压缩。
|
||||
* 6. Qt6对base64编码转换进行了重写效率提升至少200%。
|
||||
*/
|
||||
|
||||
#include <QImage>
|
||||
|
||||
#ifdef quc
|
||||
class Q_DECL_EXPORT Base64Helper
|
||||
#else
|
||||
class Base64Helper
|
||||
#endif
|
||||
|
||||
{
|
||||
public:
|
||||
//图片转base64字符串
|
||||
static QString imageToBase64(const QImage &image);
|
||||
static QByteArray imageToBase64x(const QImage &image);
|
||||
|
||||
//base64字符串转图片
|
||||
static QImage base64ToImage(const QString &data);
|
||||
static QImage base64ToImagex(const QByteArray &data);
|
||||
|
||||
//字符串与base64互转
|
||||
static QString textToBase64(const QString &text);
|
||||
static QString base64ToText(const QString &text);
|
||||
};
|
||||
|
||||
#endif // BASE64HELPER_H
|
||||
19
tool/base64helper/base64helper.pro
Normal file
@@ -0,0 +1,19 @@
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
|
||||
|
||||
TARGET = base64helper
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
||||
SOURCES += frmbase64helper.cpp
|
||||
SOURCES += base64helper.cpp
|
||||
|
||||
HEADERS += frmbase64helper.h
|
||||
HEADERS += base64helper.h
|
||||
|
||||
FORMS += frmbase64helper.ui
|
||||
|
||||
97
tool/base64helper/frmbase64helper.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmbase64helper.h"
|
||||
#include "ui_frmbase64helper.h"
|
||||
#include "base64helper.h"
|
||||
#include "qfiledialog.h"
|
||||
#include "qelapsedtimer.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
frmBase64Helper::frmBase64Helper(QWidget *parent) : QWidget(parent), ui(new Ui::frmBase64Helper)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
frmBase64Helper::~frmBase64Helper()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmBase64Helper::on_btnOpen_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, "选择文件", "", "图片(*.png *.bmp *.jpg)");
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->txtFile->setText(fileName);
|
||||
QPixmap pix(fileName);
|
||||
pix = pix.scaled(ui->labImage->size() - QSize(4, 4), Qt::KeepAspectRatio);
|
||||
ui->labImage->setPixmap(pix);
|
||||
}
|
||||
}
|
||||
|
||||
void frmBase64Helper::on_btnClear_clicked()
|
||||
{
|
||||
ui->txtFile->clear();
|
||||
ui->txtText->clear();
|
||||
ui->txtBase64->clear();
|
||||
ui->labImage->clear();
|
||||
}
|
||||
|
||||
void frmBase64Helper::on_btnImageToBase64_clicked()
|
||||
{
|
||||
//计时
|
||||
QElapsedTimer time;
|
||||
time.start();
|
||||
|
||||
QString fileName = ui->txtFile->text().trimmed();
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->txtBase64->setText(Base64Helper::imageToBase64(QImage(fileName)));
|
||||
}
|
||||
|
||||
//统计用时
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0))
|
||||
double elapsed = (double)time.nsecsElapsed() / 1000000;
|
||||
#else
|
||||
double elapsed = (double)time.elapsed();
|
||||
#endif
|
||||
QString strTime = QString::number(elapsed, 'f', 3);
|
||||
qDebug() << QString("用时 %1 毫秒").arg(strTime);
|
||||
}
|
||||
|
||||
void frmBase64Helper::on_btnBase64ToImage_clicked()
|
||||
{
|
||||
//计时
|
||||
QElapsedTimer time;
|
||||
time.start();
|
||||
|
||||
QString text = ui->txtBase64->toPlainText().trimmed();
|
||||
if (!text.isEmpty()) {
|
||||
QPixmap pix = QPixmap::fromImage(Base64Helper::base64ToImage(text));
|
||||
pix = pix.scaled(ui->labImage->size() - QSize(4, 4), Qt::KeepAspectRatio);
|
||||
ui->labImage->setPixmap(pix);
|
||||
}
|
||||
|
||||
//统计用时
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0))
|
||||
double elapsed = (double)time.nsecsElapsed() / 1000000;
|
||||
#else
|
||||
double elapsed = (double)time.elapsed();
|
||||
#endif
|
||||
QString strTime = QString::number(elapsed, 'f', 3);
|
||||
qDebug() << QString("用时 %1 毫秒").arg(strTime);
|
||||
}
|
||||
|
||||
void frmBase64Helper::on_btnTextToBase64_clicked()
|
||||
{
|
||||
QString text = ui->txtText->text().trimmed();
|
||||
if (!text.isEmpty()) {
|
||||
ui->txtBase64->setText(Base64Helper::textToBase64(text));
|
||||
}
|
||||
}
|
||||
|
||||
void frmBase64Helper::on_btnBase64ToText_clicked()
|
||||
{
|
||||
QString text = ui->txtBase64->toPlainText().trimmed();
|
||||
if (!text.isEmpty()) {
|
||||
ui->txtText->setText(Base64Helper::base64ToText(text));
|
||||
}
|
||||
}
|
||||
30
tool/base64helper/frmbase64helper.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef FRMBASE64HELPER_H
|
||||
#define FRMBASE64HELPER_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class frmBase64Helper;
|
||||
}
|
||||
|
||||
class frmBase64Helper : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmBase64Helper(QWidget *parent = 0);
|
||||
~frmBase64Helper();
|
||||
|
||||
private:
|
||||
Ui::frmBase64Helper *ui;
|
||||
|
||||
private slots:
|
||||
void on_btnOpen_clicked();
|
||||
void on_btnClear_clicked();
|
||||
void on_btnImageToBase64_clicked();
|
||||
void on_btnBase64ToImage_clicked();
|
||||
void on_btnTextToBase64_clicked();
|
||||
void on_btnBase64ToText_clicked();
|
||||
};
|
||||
|
||||
#endif // FRMBASE64HELPER_H
|
||||
139
tool/base64helper/frmbase64helper.ui
Normal file
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmBase64Helper</class>
|
||||
<widget class="QWidget" name="frmBase64Helper">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Widget</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLineEdit" name="txtFile">
|
||||
<property name="text">
|
||||
<string>E:/myFile/美女图片/2.jpg</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="btnOpen">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>打开文件</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="btnImageToBase64">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>图片转base64</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="btnBase64ToImage">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>base64转图片</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLineEdit" name="txtText">
|
||||
<property name="text">
|
||||
<string>游龙 feiyangqingyun QQ: 517216493</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="btnClear">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>清空数据</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="btnTextToBase64">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>文字转base64</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="btnBase64ToText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>base64转文字</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QLabel" name="labImage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="4">
|
||||
<widget class="QTextEdit" name="txtBase64"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
31
tool/base64helper/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmbase64helper.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmBase64Helper w;
|
||||
w.setWindowTitle("图片文字base64编码互换");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
11
tool/comtool/api/api.pri
Normal file
@@ -0,0 +1,11 @@
|
||||
HEADERS += \
|
||||
$$PWD/appconfig.h \
|
||||
$$PWD/appdata.h \
|
||||
$$PWD/quihelper.h \
|
||||
$$PWD/quihelperdata.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/appconfig.cpp \
|
||||
$$PWD/appdata.cpp \
|
||||
$$PWD/quihelper.cpp \
|
||||
$$PWD/quihelperdata.cpp
|
||||
99
tool/comtool/api/appconfig.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "appconfig.h"
|
||||
#include "quihelper.h"
|
||||
|
||||
QString AppConfig::ConfigFile = "config.ini";
|
||||
QString AppConfig::SendFileName = "send.txt";
|
||||
QString AppConfig::DeviceFileName = "device.txt";
|
||||
|
||||
QString AppConfig::PortName = "COM1";
|
||||
int AppConfig::BaudRate = 9600;
|
||||
int AppConfig::DataBit = 8;
|
||||
QString AppConfig::Parity = QString::fromUtf8("无");
|
||||
double AppConfig::StopBit = 1;
|
||||
|
||||
bool AppConfig::HexSend = false;
|
||||
bool AppConfig::HexReceive = false;
|
||||
bool AppConfig::Debug = false;
|
||||
bool AppConfig::AutoClear = false;
|
||||
|
||||
bool AppConfig::AutoSend = false;
|
||||
int AppConfig::SendInterval = 1000;
|
||||
bool AppConfig::AutoSave = false;
|
||||
int AppConfig::SaveInterval = 5000;
|
||||
|
||||
QString AppConfig::Mode = "Tcp_Client";
|
||||
QString AppConfig::ServerIP = "127.0.0.1";
|
||||
int AppConfig::ServerPort = 6000;
|
||||
int AppConfig::ListenPort = 6000;
|
||||
int AppConfig::SleepTime = 100;
|
||||
bool AppConfig::AutoConnect = false;
|
||||
|
||||
void AppConfig::readConfig()
|
||||
{
|
||||
QSettings set(AppConfig::ConfigFile, QSettings::IniFormat);
|
||||
|
||||
set.beginGroup("ComConfig");
|
||||
AppConfig::PortName = set.value("PortName", AppConfig::PortName).toString();
|
||||
AppConfig::BaudRate = set.value("BaudRate", AppConfig::BaudRate).toInt();
|
||||
AppConfig::DataBit = set.value("DataBit", AppConfig::DataBit).toInt();
|
||||
AppConfig::Parity = set.value("Parity", AppConfig::Parity).toString();
|
||||
AppConfig::StopBit = set.value("StopBit", AppConfig::StopBit).toInt();
|
||||
|
||||
AppConfig::HexSend = set.value("HexSend", AppConfig::HexSend).toBool();
|
||||
AppConfig::HexReceive = set.value("HexReceive", AppConfig::HexReceive).toBool();
|
||||
AppConfig::Debug = set.value("Debug", AppConfig::Debug).toBool();
|
||||
AppConfig::AutoClear = set.value("AutoClear", AppConfig::AutoClear).toBool();
|
||||
|
||||
AppConfig::AutoSend = set.value("AutoSend", AppConfig::AutoSend).toBool();
|
||||
AppConfig::SendInterval = set.value("SendInterval", AppConfig::SendInterval).toInt();
|
||||
AppConfig::AutoSave = set.value("AutoSave", AppConfig::AutoSave).toBool();
|
||||
AppConfig::SaveInterval = set.value("SaveInterval", AppConfig::SaveInterval).toInt();
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("NetConfig");
|
||||
AppConfig::Mode = set.value("Mode", AppConfig::Mode).toString();
|
||||
AppConfig::ServerIP = set.value("ServerIP", AppConfig::ServerIP).toString();
|
||||
AppConfig::ServerPort = set.value("ServerPort", AppConfig::ServerPort).toInt();
|
||||
AppConfig::ListenPort = set.value("ListenPort", AppConfig::ListenPort).toInt();
|
||||
AppConfig::SleepTime = set.value("SleepTime", AppConfig::SleepTime).toInt();
|
||||
AppConfig::AutoConnect = set.value("AutoConnect", AppConfig::AutoConnect).toBool();
|
||||
set.endGroup();
|
||||
|
||||
//配置文件不存在或者不全则重新生成
|
||||
if (!QUIHelper::checkIniFile(AppConfig::ConfigFile)) {
|
||||
writeConfig();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void AppConfig::writeConfig()
|
||||
{
|
||||
QSettings set(AppConfig::ConfigFile, QSettings::IniFormat);
|
||||
|
||||
set.beginGroup("ComConfig");
|
||||
set.setValue("PortName", AppConfig::PortName);
|
||||
set.setValue("BaudRate", AppConfig::BaudRate);
|
||||
set.setValue("DataBit", AppConfig::DataBit);
|
||||
set.setValue("Parity", AppConfig::Parity);
|
||||
set.setValue("StopBit", AppConfig::StopBit);
|
||||
|
||||
set.setValue("HexSend", AppConfig::HexSend);
|
||||
set.setValue("HexReceive", AppConfig::HexReceive);
|
||||
set.setValue("Debug", AppConfig::Debug);
|
||||
set.setValue("AutoClear", AppConfig::AutoClear);
|
||||
|
||||
set.setValue("AutoSend", AppConfig::AutoSend);
|
||||
set.setValue("SendInterval", AppConfig::SendInterval);
|
||||
set.setValue("AutoSave", AppConfig::AutoSave);
|
||||
set.setValue("SaveInterval", AppConfig::SaveInterval);
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("NetConfig");
|
||||
set.setValue("Mode", AppConfig::Mode);
|
||||
set.setValue("ServerIP", AppConfig::ServerIP);
|
||||
set.setValue("ServerPort", AppConfig::ServerPort);
|
||||
set.setValue("ListenPort", AppConfig::ListenPort);
|
||||
set.setValue("SleepTime", AppConfig::SleepTime);
|
||||
set.setValue("AutoConnect", AppConfig::AutoConnect);
|
||||
set.endGroup();
|
||||
}
|
||||
41
tool/comtool/api/appconfig.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef APPCONFIG_H
|
||||
#define APPCONFIG_H
|
||||
|
||||
#include "head.h"
|
||||
|
||||
class AppConfig
|
||||
{
|
||||
public:
|
||||
static QString ConfigFile; //配置文件路径
|
||||
static QString SendFileName; //发送配置文件名
|
||||
static QString DeviceFileName; //模拟设备数据文件名
|
||||
|
||||
static QString PortName; //串口号
|
||||
static int BaudRate; //波特率
|
||||
static int DataBit; //数据位
|
||||
static QString Parity; //校验位
|
||||
static double StopBit; //停止位
|
||||
|
||||
static bool HexSend; //16进制发送
|
||||
static bool HexReceive; //16进制接收
|
||||
static bool Debug; //模拟设备
|
||||
static bool AutoClear; //自动清空
|
||||
|
||||
static bool AutoSend; //自动发送
|
||||
static int SendInterval; //自动发送间隔
|
||||
static bool AutoSave; //自动保存
|
||||
static int SaveInterval; //自动保存间隔
|
||||
|
||||
static QString Mode; //转换模式
|
||||
static QString ServerIP; //服务器IP
|
||||
static int ServerPort; //服务器端口
|
||||
static int ListenPort; //监听端口
|
||||
static int SleepTime; //延时时间
|
||||
static bool AutoConnect; //自动重连
|
||||
|
||||
//读写配置参数
|
||||
static void readConfig(); //读取配置参数
|
||||
static void writeConfig(); //写入配置参数
|
||||
};
|
||||
|
||||
#endif // APPCONFIG_H
|
||||
122
tool/comtool/api/appdata.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "appdata.h"
|
||||
#include "quihelper.h"
|
||||
|
||||
QStringList AppData::Intervals = QStringList();
|
||||
QStringList AppData::Datas = QStringList();
|
||||
QStringList AppData::Keys = QStringList();
|
||||
QStringList AppData::Values = QStringList();
|
||||
|
||||
QString AppData::SendFileName = "send.txt";
|
||||
void AppData::readSendData()
|
||||
{
|
||||
//读取发送数据列表
|
||||
AppData::Datas.clear();
|
||||
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(AppData::SendFileName);
|
||||
QFile file(fileName);
|
||||
if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) {
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
line = line.trimmed();
|
||||
line = line.replace("\r", "");
|
||||
line = line.replace("\n", "");
|
||||
if (!line.isEmpty()) {
|
||||
AppData::Datas.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
//没有的时候主动添加点免得太空
|
||||
if (AppData::Datas.count() == 0) {
|
||||
AppData::Datas << "16 FF 01 01 E0 E1" << "16 FF 01 01 E1 E2";
|
||||
}
|
||||
}
|
||||
|
||||
QString AppData::DeviceFileName = "device.txt";
|
||||
void AppData::readDeviceData()
|
||||
{
|
||||
//读取转发数据列表
|
||||
AppData::Keys.clear();
|
||||
AppData::Values.clear();
|
||||
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(AppData::DeviceFileName);
|
||||
QFile file(fileName);
|
||||
if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) {
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
line = line.trimmed();
|
||||
line = line.replace("\r", "");
|
||||
line = line.replace("\n", "");
|
||||
if (!line.isEmpty()) {
|
||||
QStringList list = line.split(";");
|
||||
QString key = list.at(0);
|
||||
QString value;
|
||||
for (int i = 1; i < list.count(); i++) {
|
||||
value += QString("%1;").arg(list.at(i));
|
||||
}
|
||||
|
||||
//去掉末尾分号
|
||||
value = value.mid(0, value.length() - 1);
|
||||
AppData::Keys.append(key);
|
||||
AppData::Values.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void AppData::saveData(const QString &data)
|
||||
{
|
||||
if (data.length() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString fileName = QString("%1/%2.txt").arg(QUIHelper::appPath()).arg(STRDATETIME);
|
||||
QFile file(fileName);
|
||||
if (file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
file.write(data.toUtf8());
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void AppData::loadIP(QComboBox *cbox)
|
||||
{
|
||||
//获取本机所有IP
|
||||
static QStringList ips;
|
||||
if (ips.count() == 0) {
|
||||
#ifdef emsdk
|
||||
ips << "127.0.0.1";
|
||||
#else
|
||||
QList<QNetworkInterface> netInterfaces = QNetworkInterface::allInterfaces();
|
||||
foreach (const QNetworkInterface &netInterface, netInterfaces) {
|
||||
//移除虚拟机和抓包工具的虚拟网卡
|
||||
QString humanReadableName = netInterface.humanReadableName().toLower();
|
||||
if (humanReadableName.startsWith("vmware network adapter") || humanReadableName.startsWith("npcap loopback adapter")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//过滤当前网络接口
|
||||
bool flag = (netInterface.flags() == (QNetworkInterface::IsUp | QNetworkInterface::IsRunning | QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast));
|
||||
if (flag) {
|
||||
QList<QNetworkAddressEntry> addrs = netInterface.addressEntries();
|
||||
foreach (QNetworkAddressEntry addr, addrs) {
|
||||
//只取出IPV4的地址
|
||||
if (addr.ip().protocol() == QAbstractSocket::IPv4Protocol) {
|
||||
QString ip4 = addr.ip().toString();
|
||||
if (ip4 != "127.0.0.1") {
|
||||
ips << ip4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cbox->clear();
|
||||
cbox->addItems(ips);
|
||||
if (!ips.contains("127.0.0.1")) {
|
||||
cbox->addItem("127.0.0.1");
|
||||
}
|
||||
}
|
||||
30
tool/comtool/api/appdata.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef APPDATA_H
|
||||
#define APPDATA_H
|
||||
|
||||
#include "head.h"
|
||||
|
||||
class AppData
|
||||
{
|
||||
public:
|
||||
//全局变量
|
||||
static QStringList Intervals;
|
||||
static QStringList Datas;
|
||||
static QStringList Keys;
|
||||
static QStringList Values;
|
||||
|
||||
//读取发送数据列表
|
||||
static QString SendFileName;
|
||||
static void readSendData();
|
||||
|
||||
//读取转发数据列表
|
||||
static QString DeviceFileName;
|
||||
static void readDeviceData();
|
||||
|
||||
//保存数据到文件
|
||||
static void saveData(const QString &data);
|
||||
|
||||
//添加网卡IP地址到下拉框
|
||||
static void loadIP(QComboBox *cbox);
|
||||
};
|
||||
|
||||
#endif // APPDATA_H
|
||||
420
tool/comtool/api/quihelper.cpp
Normal file
@@ -0,0 +1,420 @@
|
||||
#include "quihelper.h"
|
||||
|
||||
int QUIHelper::getScreenIndex()
|
||||
{
|
||||
//需要对多个屏幕进行处理
|
||||
int screenIndex = 0;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
int screenCount = qApp->screens().count();
|
||||
#else
|
||||
int screenCount = qApp->desktop()->screenCount();
|
||||
#endif
|
||||
|
||||
if (screenCount > 1) {
|
||||
//找到当前鼠标所在屏幕
|
||||
QPoint pos = QCursor::pos();
|
||||
for (int i = 0; i < screenCount; ++i) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
if (qApp->screens().at(i)->geometry().contains(pos)) {
|
||||
#else
|
||||
if (qApp->desktop()->screenGeometry(i).contains(pos)) {
|
||||
#endif
|
||||
screenIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return screenIndex;
|
||||
}
|
||||
|
||||
QRect QUIHelper::getScreenRect(bool available)
|
||||
{
|
||||
QRect rect;
|
||||
int screenIndex = QUIHelper::getScreenIndex();
|
||||
if (available) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
rect = qApp->screens().at(screenIndex)->availableGeometry();
|
||||
#else
|
||||
rect = qApp->desktop()->availableGeometry(screenIndex);
|
||||
#endif
|
||||
} else {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
rect = qApp->screens().at(screenIndex)->geometry();
|
||||
#else
|
||||
rect = qApp->desktop()->screenGeometry(screenIndex);
|
||||
#endif
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
int QUIHelper::deskWidth()
|
||||
{
|
||||
return getScreenRect().width();
|
||||
}
|
||||
|
||||
int QUIHelper::deskHeight()
|
||||
{
|
||||
return getScreenRect().height();
|
||||
}
|
||||
|
||||
QWidget *QUIHelper::centerBaseForm = 0;
|
||||
void QUIHelper::setFormInCenter(QWidget *form)
|
||||
{
|
||||
int formWidth = form->width();
|
||||
int formHeight = form->height();
|
||||
|
||||
//如果=0表示采用系统桌面屏幕为参照
|
||||
QRect rect;
|
||||
if (centerBaseForm == 0) {
|
||||
rect = getScreenRect();
|
||||
} else {
|
||||
rect = centerBaseForm->geometry();
|
||||
}
|
||||
|
||||
int deskWidth = rect.width();
|
||||
int deskHeight = rect.height();
|
||||
QPoint movePoint(deskWidth / 2 - formWidth / 2 + rect.x(), deskHeight / 2 - formHeight / 2 + rect.y());
|
||||
form->move(movePoint);
|
||||
}
|
||||
|
||||
QString QUIHelper::appName()
|
||||
{
|
||||
//没有必要每次都获取,只有当变量为空时才去获取一次
|
||||
static QString name;
|
||||
if (name.isEmpty()) {
|
||||
name = qApp->applicationFilePath();
|
||||
//下面的方法主要为了过滤安卓的路径 lib程序名_armeabi-v7a
|
||||
QStringList list = name.split("/");
|
||||
name = list.at(list.count() - 1).split(".").at(0);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
QString QUIHelper::appPath()
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
//return QString("/sdcard/Android/%1").arg(appName());
|
||||
return QString("/storage/emulated/0/%1").arg(appName());
|
||||
#else
|
||||
return qApp->applicationDirPath();
|
||||
#endif
|
||||
}
|
||||
|
||||
QString QUIHelper::getUuid()
|
||||
{
|
||||
QString uuid = QUuid::createUuid().toString();
|
||||
uuid.replace("{", "");
|
||||
uuid.replace("}", "");
|
||||
return uuid;
|
||||
}
|
||||
|
||||
void QUIHelper::initRand()
|
||||
{
|
||||
//初始化随机数种子
|
||||
QTime t = QTime::currentTime();
|
||||
srand(t.msec() + t.second() * 1000);
|
||||
}
|
||||
|
||||
void QUIHelper::newDir(const QString &dirName)
|
||||
{
|
||||
QString strDir = dirName;
|
||||
|
||||
//如果路径中包含斜杠字符则说明是绝对路径
|
||||
//linux系统路径字符带有 / windows系统 路径字符带有 :/
|
||||
if (!strDir.startsWith("/") && !strDir.contains(":/")) {
|
||||
strDir = QString("%1/%2").arg(QUIHelper::appPath()).arg(strDir);
|
||||
}
|
||||
|
||||
QDir dir(strDir);
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(strDir);
|
||||
}
|
||||
}
|
||||
|
||||
void QUIHelper::sleep(int msec)
|
||||
{
|
||||
if (msec <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
QThread::msleep(msec);
|
||||
#else
|
||||
QTime endTime = QTime::currentTime().addMSecs(msec);
|
||||
while (QTime::currentTime() < endTime) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void QUIHelper::setStyle()
|
||||
{
|
||||
//打印下所有内置风格的名字
|
||||
qDebug() << "Qt内置的样式" << QStyleFactory::keys();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
#else
|
||||
qApp->setStyle(QStyleFactory::create("Cleanlooks"));
|
||||
#endif
|
||||
//qApp->setPalette(QPalette("#FFFFFF"));
|
||||
}
|
||||
|
||||
void QUIHelper::setFont(int fontSize)
|
||||
{
|
||||
QFont font;
|
||||
font.setFamily("MicroSoft Yahei");
|
||||
#ifdef Q_OS_ANDROID
|
||||
font.setPixelSize(15);
|
||||
#elif __arm__
|
||||
font.setPixelSize(25);
|
||||
#else
|
||||
font.setPixelSize(fontSize);
|
||||
#endif
|
||||
|
||||
#ifndef rk3399
|
||||
qApp->setFont(font);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QUIHelper::setCode(bool utf8)
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
//如果想要控制台打印信息中文正常就注释掉这个设置
|
||||
if (utf8) {
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
}
|
||||
#else
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QUIHelper::setTranslator(const QString &qmFile)
|
||||
{
|
||||
//过滤下不存在的就不用设置了
|
||||
if (!QFile(qmFile).exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTranslator *translator = new QTranslator(qApp);
|
||||
translator->load(qmFile);
|
||||
qApp->installTranslator(translator);
|
||||
}
|
||||
|
||||
void QUIHelper::initAll()
|
||||
{
|
||||
//初始化随机数种子
|
||||
QUIHelper::initRand();
|
||||
//设置样式风格
|
||||
QUIHelper::setStyle();
|
||||
//设置字体
|
||||
QUIHelper::setFont(13);
|
||||
//设置编码
|
||||
QUIHelper::setCode();
|
||||
//设置翻译文件支持多个
|
||||
QUIHelper::setTranslator(":/qm/widgets.qm");
|
||||
QUIHelper::setTranslator(":/qm/qt_zh_CN.qm");
|
||||
QUIHelper::setTranslator(":/qm/designer_zh_CN.qm");
|
||||
}
|
||||
|
||||
void QUIHelper::setFramelessForm(QWidget *widgetMain, bool tool, bool top, bool menu)
|
||||
{
|
||||
widgetMain->setProperty("form", true);
|
||||
widgetMain->setProperty("canMove", true);
|
||||
|
||||
//根据设定逐个追加属性
|
||||
#ifdef __arm__
|
||||
widgetMain->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
|
||||
#else
|
||||
widgetMain->setWindowFlags(Qt::FramelessWindowHint);
|
||||
#endif
|
||||
if (tool) {
|
||||
widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::Tool);
|
||||
}
|
||||
if (top) {
|
||||
widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
}
|
||||
if (menu) {
|
||||
//如果是其他系统比如neokylin会产生系统边框
|
||||
#ifdef Q_OS_WIN
|
||||
widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int QUIHelper::showMessageBox(const QString &info, int type, int closeSec, bool exec)
|
||||
{
|
||||
int result = 0;
|
||||
if (type == 0) {
|
||||
showMessageBoxInfo(info, closeSec, exec);
|
||||
} else if (type == 1) {
|
||||
showMessageBoxError(info, closeSec, exec);
|
||||
} else if (type == 2) {
|
||||
result = showMessageBoxQuestion(info);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void QUIHelper::showMessageBoxInfo(const QString &info, int closeSec, bool exec)
|
||||
{
|
||||
QMessageBox box(QMessageBox::Information, "提示", info);
|
||||
box.setStandardButtons(QMessageBox::Yes);
|
||||
box.setButtonText(QMessageBox::Yes, QString("确 定"));
|
||||
box.exec();
|
||||
//QMessageBox::information(0, "提示", info, QMessageBox::Yes);
|
||||
}
|
||||
|
||||
void QUIHelper::showMessageBoxError(const QString &info, int closeSec, bool exec)
|
||||
{
|
||||
QMessageBox box(QMessageBox::Critical, "错误", info);
|
||||
box.setStandardButtons(QMessageBox::Yes);
|
||||
box.setButtonText(QMessageBox::Yes, QString("确 定"));
|
||||
box.exec();
|
||||
//QMessageBox::critical(0, "错误", info, QMessageBox::Yes);
|
||||
}
|
||||
|
||||
int QUIHelper::showMessageBoxQuestion(const QString &info)
|
||||
{
|
||||
QMessageBox box(QMessageBox::Question, "询问", info);
|
||||
box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
box.setButtonText(QMessageBox::Yes, QString("确 定"));
|
||||
box.setButtonText(QMessageBox::No, QString("取 消"));
|
||||
return box.exec();
|
||||
//return QMessageBox::question(0, "询问", info, QMessageBox::Yes | QMessageBox::No);
|
||||
}
|
||||
|
||||
QString QUIHelper::getXorEncryptDecrypt(const QString &value, char key)
|
||||
{
|
||||
//矫正范围外的数据
|
||||
if (key < 0 || key >= 127) {
|
||||
key = 127;
|
||||
}
|
||||
|
||||
QString result = value;
|
||||
int count = result.count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
result[i] = QChar(result.at(i).toLatin1() ^ key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uchar QUIHelper::getOrCode(const QByteArray &data)
|
||||
{
|
||||
int len = data.length();
|
||||
uchar result = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
result ^= data.at(i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uchar QUIHelper::getCheckCode(const QByteArray &data)
|
||||
{
|
||||
int len = data.length();
|
||||
uchar temp = 0;
|
||||
for (uchar i = 0; i < len; i++) {
|
||||
temp += data.at(i);
|
||||
}
|
||||
|
||||
return temp % 256;
|
||||
}
|
||||
|
||||
void QUIHelper::initTableView(QTableView *tableView, int rowHeight, bool headVisible, bool edit, bool stretchLast)
|
||||
{
|
||||
//取消自动换行
|
||||
tableView->setWordWrap(false);
|
||||
//超出文本不显示省略号
|
||||
tableView->setTextElideMode(Qt::ElideNone);
|
||||
//奇数偶数行颜色交替
|
||||
tableView->setAlternatingRowColors(false);
|
||||
//垂直表头是否可见
|
||||
tableView->verticalHeader()->setVisible(headVisible);
|
||||
//选中一行表头是否加粗
|
||||
tableView->horizontalHeader()->setHighlightSections(false);
|
||||
//最后一行拉伸填充
|
||||
tableView->horizontalHeader()->setStretchLastSection(stretchLast);
|
||||
//行标题最小宽度尺寸
|
||||
tableView->horizontalHeader()->setMinimumSectionSize(0);
|
||||
//行标题最小高度,等同于和默认行高一致
|
||||
tableView->horizontalHeader()->setFixedHeight(rowHeight);
|
||||
//默认行高
|
||||
tableView->verticalHeader()->setDefaultSectionSize(rowHeight);
|
||||
//选中时一行整体选中
|
||||
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
//只允许选择单个
|
||||
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
//表头不可单击
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
tableView->horizontalHeader()->setSectionsClickable(false);
|
||||
#else
|
||||
tableView->horizontalHeader()->setClickable(false);
|
||||
#endif
|
||||
|
||||
//鼠标按下即进入编辑模式
|
||||
if (edit) {
|
||||
tableView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::DoubleClicked);
|
||||
} else {
|
||||
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
}
|
||||
}
|
||||
|
||||
void QUIHelper::openFile(const QString &fileName, const QString &msg)
|
||||
{
|
||||
#ifdef __arm__
|
||||
return;
|
||||
#endif
|
||||
if (fileName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (QUIHelper::showMessageBoxQuestion(msg + "成功!确定现在就打开吗?") == QMessageBox::Yes) {
|
||||
QString url = QString("file:///%1").arg(fileName);
|
||||
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
|
||||
}
|
||||
}
|
||||
|
||||
bool QUIHelper::checkIniFile(const QString &iniFile)
|
||||
{
|
||||
//如果配置文件大小为0,则以初始值继续运行,并生成配置文件
|
||||
QFile file(iniFile);
|
||||
if (file.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//如果配置文件不完整,则以初始值继续运行,并生成配置文件
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
bool ok = true;
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
line.replace("\r", "");
|
||||
line.replace("\n", "");
|
||||
QStringList list = line.split("=");
|
||||
|
||||
if (list.count() == 2) {
|
||||
if (list.at(1) == "") {
|
||||
qDebug() << "ini node no value" << list.at(0);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
70
tool/comtool/api/quihelper.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef QUIHELPER2_H
|
||||
#define QUIHELPER2_H
|
||||
|
||||
#include "head.h"
|
||||
|
||||
class QUIHelper
|
||||
{
|
||||
public:
|
||||
//获取当前鼠标所在屏幕索引+尺寸
|
||||
static int getScreenIndex();
|
||||
static QRect getScreenRect(bool available = true);
|
||||
|
||||
//获取桌面宽度高度+居中显示
|
||||
static int deskWidth();
|
||||
static int deskHeight();
|
||||
|
||||
//居中显示窗体
|
||||
//定义标志位指定是以桌面为参照还是主程序界面为参照
|
||||
static QWidget *centerBaseForm;
|
||||
static void setFormInCenter(QWidget *form);
|
||||
|
||||
//程序文件名称+当前所在路径
|
||||
static QString appName();
|
||||
static QString appPath();
|
||||
|
||||
//获取uuid+初始化随机数种子+新建目录+延时
|
||||
static QString getUuid();
|
||||
static void initRand();
|
||||
static void newDir(const QString &dirName);
|
||||
static void sleep(int msec);
|
||||
|
||||
//设置样式+字体+编码+居中+翻译
|
||||
static void setStyle();
|
||||
static void setFont(int fontSize = 12);
|
||||
static void setCode(bool utf8 = true);
|
||||
static void setTranslator(const QString &qmFile);
|
||||
//一次性设置所有
|
||||
static void initAll();
|
||||
|
||||
//设置无边框
|
||||
static void setFramelessForm(QWidget *widgetMain, bool tool = false, bool top = false, bool menu = true);
|
||||
|
||||
//弹出框
|
||||
static int showMessageBox(const QString &info, int type = 0, int closeSec = 0, bool exec = false);
|
||||
//弹出消息框
|
||||
static void showMessageBoxInfo(const QString &info, int closeSec = 0, bool exec = false);
|
||||
//弹出错误框
|
||||
static void showMessageBoxError(const QString &info, int closeSec = 0, bool exec = false);
|
||||
//弹出询问框
|
||||
static int showMessageBoxQuestion(const QString &info);
|
||||
|
||||
//异或加密-只支持字符,如果是中文需要将其转换base64编码
|
||||
static QString getXorEncryptDecrypt(const QString &value, char key);
|
||||
//异或校验
|
||||
static uchar getOrCode(const QByteArray &data);
|
||||
//计算校验码
|
||||
static uchar getCheckCode(const QByteArray &data);
|
||||
|
||||
//初始化表格
|
||||
static void initTableView(QTableView *tableView, int rowHeight = 25,
|
||||
bool headVisible = false, bool edit = false,
|
||||
bool stretchLast = true);
|
||||
//打开文件带提示框
|
||||
static void openFile(const QString &fileName, const QString &msg);
|
||||
|
||||
//检查ini配置文件
|
||||
static bool checkIniFile(const QString &iniFile);
|
||||
};
|
||||
|
||||
#endif // QUIHELPER2_H
|
||||
450
tool/comtool/api/quihelperdata.cpp
Normal file
@@ -0,0 +1,450 @@
|
||||
#include "quihelperdata.h"
|
||||
#include "quihelper.h"
|
||||
|
||||
int QUIHelperData::strHexToDecimal(const QString &strHex)
|
||||
{
|
||||
bool ok;
|
||||
return strHex.toInt(&ok, 16);
|
||||
}
|
||||
|
||||
int QUIHelperData::strDecimalToDecimal(const QString &strDecimal)
|
||||
{
|
||||
bool ok;
|
||||
return strDecimal.toInt(&ok, 10);
|
||||
}
|
||||
|
||||
int QUIHelperData::strBinToDecimal(const QString &strBin)
|
||||
{
|
||||
bool ok;
|
||||
return strBin.toInt(&ok, 2);
|
||||
}
|
||||
|
||||
QString QUIHelperData::strHexToStrBin(const QString &strHex)
|
||||
{
|
||||
uchar decimal = strHexToDecimal(strHex);
|
||||
QString bin = QString::number(decimal, 2);
|
||||
uchar len = bin.length();
|
||||
|
||||
if (len < 8) {
|
||||
for (int i = 0; i < 8 - len; i++) {
|
||||
bin = "0" + bin;
|
||||
}
|
||||
}
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
||||
QString QUIHelperData::decimalToStrBin1(int decimal)
|
||||
{
|
||||
QString bin = QString::number(decimal, 2);
|
||||
uchar len = bin.length();
|
||||
if (len <= 8) {
|
||||
for (int i = 0; i < 8 - len; i++) {
|
||||
bin = "0" + bin;
|
||||
}
|
||||
}
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
||||
QString QUIHelperData::decimalToStrBin2(int decimal)
|
||||
{
|
||||
QString bin = QString::number(decimal, 2);
|
||||
uchar len = bin.length();
|
||||
if (len <= 16) {
|
||||
for (int i = 0; i < 16 - len; i++) {
|
||||
bin = "0" + bin;
|
||||
}
|
||||
}
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
||||
QString QUIHelperData::decimalToStrHex(int decimal)
|
||||
{
|
||||
QString temp = QString::number(decimal, 16);
|
||||
if (temp.length() == 1) {
|
||||
temp = "0" + temp;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
QByteArray QUIHelperData::intToByte(int data)
|
||||
{
|
||||
QByteArray result;
|
||||
result.resize(4);
|
||||
result[3] = (uchar)(0x000000ff & data);
|
||||
result[2] = (uchar)((0x0000ff00 & data) >> 8);
|
||||
result[1] = (uchar)((0x00ff0000 & data) >> 16);
|
||||
result[0] = (uchar)((0xff000000 & data) >> 24);
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray QUIHelperData::intToByteRec(int data)
|
||||
{
|
||||
QByteArray result;
|
||||
result.resize(4);
|
||||
result[0] = (uchar)(0x000000ff & data);
|
||||
result[1] = (uchar)((0x0000ff00 & data) >> 8);
|
||||
result[2] = (uchar)((0x00ff0000 & data) >> 16);
|
||||
result[3] = (uchar)((0xff000000 & data) >> 24);
|
||||
return result;
|
||||
}
|
||||
|
||||
int QUIHelperData::byteToInt(const QByteArray &data)
|
||||
{
|
||||
int i = data.at(3) & 0x000000ff;
|
||||
i |= ((data.at(2) << 8) & 0x0000ff00);
|
||||
i |= ((data.at(1) << 16) & 0x00ff0000);
|
||||
i |= ((data.at(0) << 24) & 0xff000000);
|
||||
return i;
|
||||
}
|
||||
|
||||
int QUIHelperData::byteToIntRec(const QByteArray &data)
|
||||
{
|
||||
int i = data.at(0) & 0x000000ff;
|
||||
i |= ((data.at(1) << 8) & 0x0000ff00);
|
||||
i |= ((data.at(2) << 16) & 0x00ff0000);
|
||||
i |= ((data.at(3) << 24) & 0xff000000);
|
||||
return i;
|
||||
}
|
||||
|
||||
quint32 QUIHelperData::byteToUInt(const QByteArray &data)
|
||||
{
|
||||
quint32 i = data.at(3) & 0x000000ff;
|
||||
i |= ((data.at(2) << 8) & 0x0000ff00);
|
||||
i |= ((data.at(1) << 16) & 0x00ff0000);
|
||||
i |= ((data.at(0) << 24) & 0xff000000);
|
||||
return i;
|
||||
}
|
||||
|
||||
quint32 QUIHelperData::byteToUIntRec(const QByteArray &data)
|
||||
{
|
||||
quint32 i = data.at(0) & 0x000000ff;
|
||||
i |= ((data.at(1) << 8) & 0x0000ff00);
|
||||
i |= ((data.at(2) << 16) & 0x00ff0000);
|
||||
i |= ((data.at(3) << 24) & 0xff000000);
|
||||
return i;
|
||||
}
|
||||
|
||||
QByteArray QUIHelperData::ushortToByte(ushort data)
|
||||
{
|
||||
QByteArray result;
|
||||
result.resize(2);
|
||||
result[1] = (uchar)(0x000000ff & data);
|
||||
result[0] = (uchar)((0x0000ff00 & data) >> 8);
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray QUIHelperData::ushortToByteRec(ushort data)
|
||||
{
|
||||
QByteArray result;
|
||||
result.resize(2);
|
||||
result[0] = (uchar)(0x000000ff & data);
|
||||
result[1] = (uchar)((0x0000ff00 & data) >> 8);
|
||||
return result;
|
||||
}
|
||||
|
||||
int QUIHelperData::byteToUShort(const QByteArray &data)
|
||||
{
|
||||
int i = data.at(1) & 0x000000FF;
|
||||
i |= ((data.at(0) << 8) & 0x0000FF00);
|
||||
if (i >= 32768) {
|
||||
i = i - 65536;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int QUIHelperData::byteToUShortRec(const QByteArray &data)
|
||||
{
|
||||
int i = data.at(0) & 0x000000FF;
|
||||
i |= ((data.at(1) << 8) & 0x0000FF00);
|
||||
if (i >= 32768) {
|
||||
i = i - 65536;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
QString QUIHelperData::getValue(quint8 value)
|
||||
{
|
||||
QString result = QString::number(value);
|
||||
if (result.length() <= 1) {
|
||||
result = QString("0%1").arg(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString QUIHelperData::getXorEncryptDecrypt(const QString &value, char key)
|
||||
{
|
||||
//矫正范围外的数据
|
||||
if (key < 0 || key >= 127) {
|
||||
key = 127;
|
||||
}
|
||||
|
||||
QString result = value;
|
||||
int count = result.count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
result[i] = QChar(result.at(i).toLatin1() ^ key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uchar QUIHelperData::getOrCode(const QByteArray &data)
|
||||
{
|
||||
int len = data.length();
|
||||
uchar result = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
result ^= data.at(i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uchar QUIHelperData::getCheckCode(const QByteArray &data)
|
||||
{
|
||||
int len = data.length();
|
||||
uchar temp = 0;
|
||||
for (uchar i = 0; i < len; i++) {
|
||||
temp += data.at(i);
|
||||
}
|
||||
|
||||
return temp % 256;
|
||||
}
|
||||
|
||||
//函数功能:计算CRC16
|
||||
//参数1:*data 16位CRC校验数据,
|
||||
//参数2:len 数据流长度
|
||||
//参数3:init 初始化值
|
||||
//参数4:table 16位CRC查找表
|
||||
|
||||
//正序CRC计算
|
||||
quint16 QUIHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint16 *table)
|
||||
{
|
||||
quint16 crc_16 = init;
|
||||
quint8 temp;
|
||||
while (len-- > 0) {
|
||||
temp = crc_16 & 0xff;
|
||||
crc_16 = (crc_16 >> 8) ^ table[(temp ^ *data++) & 0xff];
|
||||
}
|
||||
|
||||
return crc_16;
|
||||
}
|
||||
|
||||
//逆序CRC计算
|
||||
quint16 QUIHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table)
|
||||
{
|
||||
quint16 crc_16 = init;
|
||||
quint8 temp;
|
||||
while (len-- > 0) {
|
||||
temp = crc_16 >> 8;
|
||||
crc_16 = (crc_16 << 8) ^ table[(temp ^ *data++) & 0xff];
|
||||
}
|
||||
|
||||
return crc_16;
|
||||
}
|
||||
|
||||
//Modbus CRC16校验
|
||||
quint16 QUIHelperData::getModbus16(quint8 *data, int len)
|
||||
{
|
||||
//MODBUS CRC-16表 8005 逆序
|
||||
const quint16 table_16[256] = {
|
||||
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
|
||||
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
|
||||
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
|
||||
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
|
||||
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
|
||||
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
|
||||
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
|
||||
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
|
||||
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
|
||||
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
|
||||
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
|
||||
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
|
||||
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
|
||||
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
|
||||
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
|
||||
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
|
||||
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
|
||||
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
|
||||
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
|
||||
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
|
||||
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
|
||||
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
|
||||
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
|
||||
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
|
||||
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
|
||||
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
|
||||
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
|
||||
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
|
||||
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
|
||||
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
|
||||
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
|
||||
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
|
||||
};
|
||||
|
||||
return getCrc16(data, len, 0xFFFF, table_16);
|
||||
}
|
||||
|
||||
//CRC16校验
|
||||
QByteArray QUIHelperData::getCrcCode(const QByteArray &data)
|
||||
{
|
||||
quint16 result = getModbus16((quint8 *)data.data(), data.length());
|
||||
return QUIHelperData::ushortToByteRec(result);
|
||||
}
|
||||
|
||||
static QMap<char, QString> listChar;
|
||||
void QUIHelperData::initAscii()
|
||||
{
|
||||
//0x20为空格,空格以下都是不可见字符
|
||||
if (listChar.count() == 0) {
|
||||
listChar.insert(0, "\\NUL");
|
||||
listChar.insert(1, "\\SOH");
|
||||
listChar.insert(2, "\\STX");
|
||||
listChar.insert(3, "\\ETX");
|
||||
listChar.insert(4, "\\EOT");
|
||||
listChar.insert(5, "\\ENQ");
|
||||
listChar.insert(6, "\\ACK");
|
||||
listChar.insert(7, "\\BEL");
|
||||
listChar.insert(8, "\\BS");
|
||||
listChar.insert(9, "\\HT");
|
||||
listChar.insert(10, "\\LF");
|
||||
listChar.insert(11, "\\VT");
|
||||
listChar.insert(12, "\\FF");
|
||||
listChar.insert(13, "\\CR");
|
||||
listChar.insert(14, "\\SO");
|
||||
listChar.insert(15, "\\SI");
|
||||
listChar.insert(16, "\\DLE");
|
||||
listChar.insert(17, "\\DC1");
|
||||
listChar.insert(18, "\\DC2");
|
||||
listChar.insert(19, "\\DC3");
|
||||
listChar.insert(20, "\\DC4");
|
||||
listChar.insert(21, "\\NAK");
|
||||
listChar.insert(22, "\\SYN");
|
||||
listChar.insert(23, "\\ETB");
|
||||
listChar.insert(24, "\\CAN");
|
||||
listChar.insert(25, "\\EM");
|
||||
listChar.insert(26, "\\SUB");
|
||||
listChar.insert(27, "\\ESC");
|
||||
listChar.insert(28, "\\FS");
|
||||
listChar.insert(29, "\\GS");
|
||||
listChar.insert(30, "\\RS");
|
||||
listChar.insert(31, "\\US");
|
||||
listChar.insert(0x5C, "\\");
|
||||
listChar.insert(0x7F, "\\DEL");
|
||||
}
|
||||
}
|
||||
|
||||
QString QUIHelperData::byteArrayToAsciiStr(const QByteArray &data)
|
||||
{
|
||||
//先初始化字符表
|
||||
initAscii();
|
||||
|
||||
QString temp;
|
||||
int len = data.size();
|
||||
for (int i = 0; i < len; i++) {
|
||||
char byte = data.at(i);
|
||||
QString value = listChar.value(byte);
|
||||
if (!value.isEmpty()) {
|
||||
} else if (byte >= 0 && byte <= 0x7F) {
|
||||
value = QString("%1").arg(byte);
|
||||
} else {
|
||||
value = decimalToStrHex((quint8)byte);
|
||||
value = QString("\\x%1").arg(value.toUpper());
|
||||
}
|
||||
|
||||
temp += value;
|
||||
}
|
||||
|
||||
return temp.trimmed();
|
||||
}
|
||||
|
||||
QByteArray QUIHelperData::asciiStrToByteArray(const QString &data)
|
||||
{
|
||||
//先初始化字符表
|
||||
initAscii();
|
||||
|
||||
QByteArray buffer;
|
||||
QStringList list = data.split("\\");
|
||||
|
||||
int count = list.count();
|
||||
for (int i = 1; i < count; i++) {
|
||||
QString str = list.at(i);
|
||||
int key = 0;
|
||||
if (str.contains("x")) {
|
||||
key = strHexToDecimal(str.mid(1, 2));
|
||||
} else {
|
||||
key = listChar.key("\\" + str);
|
||||
}
|
||||
|
||||
buffer.append(key);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char QUIHelperData::hexStrToChar(char data)
|
||||
{
|
||||
if ((data >= '0') && (data <= '9')) {
|
||||
return data - 0x30;
|
||||
} else if ((data >= 'A') && (data <= 'F')) {
|
||||
return data - 'A' + 10;
|
||||
} else if ((data >= 'a') && (data <= 'f')) {
|
||||
return data - 'a' + 10;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray QUIHelperData::hexStrToByteArray(const QString &data)
|
||||
{
|
||||
QByteArray senddata;
|
||||
int hexdata, lowhexdata;
|
||||
int hexdatalen = 0;
|
||||
int len = data.length();
|
||||
senddata.resize(len / 2);
|
||||
char lstr, hstr;
|
||||
|
||||
for (int i = 0; i < len;) {
|
||||
hstr = data.at(i).toLatin1();
|
||||
if (hstr == ' ') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
i++;
|
||||
if (i >= len) {
|
||||
break;
|
||||
}
|
||||
|
||||
lstr = data.at(i).toLatin1();
|
||||
hexdata = hexStrToChar(hstr);
|
||||
lowhexdata = hexStrToChar(lstr);
|
||||
|
||||
if ((hexdata == 16) || (lowhexdata == 16)) {
|
||||
break;
|
||||
} else {
|
||||
hexdata = hexdata * 16 + lowhexdata;
|
||||
}
|
||||
|
||||
i++;
|
||||
senddata[hexdatalen] = (char)hexdata;
|
||||
hexdatalen++;
|
||||
}
|
||||
|
||||
senddata.resize(hexdatalen);
|
||||
return senddata;
|
||||
}
|
||||
|
||||
QString QUIHelperData::byteArrayToHexStr(const QByteArray &data)
|
||||
{
|
||||
QString temp = "";
|
||||
QString hex = data.toHex();
|
||||
for (int i = 0; i < hex.length(); i = i + 2) {
|
||||
temp += hex.mid(i, 2) + " ";
|
||||
}
|
||||
|
||||
return temp.trimmed().toUpper();
|
||||
}
|
||||
70
tool/comtool/api/quihelperdata.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef QUIHELPERDATA_H
|
||||
#define QUIHELPERDATA_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QUIHelperData
|
||||
{
|
||||
public:
|
||||
//16进制字符串转10进制
|
||||
static int strHexToDecimal(const QString &strHex);
|
||||
//10进制字符串转10进制
|
||||
static int strDecimalToDecimal(const QString &strDecimal);
|
||||
//2进制字符串转10进制
|
||||
static int strBinToDecimal(const QString &strBin);
|
||||
|
||||
//16进制字符串转2进制字符串
|
||||
static QString strHexToStrBin(const QString &strHex);
|
||||
//10进制转2进制字符串一个字节
|
||||
static QString decimalToStrBin1(int decimal);
|
||||
//10进制转2进制字符串两个字节
|
||||
static QString decimalToStrBin2(int decimal);
|
||||
//10进制转16进制字符串,补零.
|
||||
static QString decimalToStrHex(int decimal);
|
||||
|
||||
//int转字节数组
|
||||
static QByteArray intToByte(int data);
|
||||
static QByteArray intToByteRec(int data);
|
||||
|
||||
//字节数组转int
|
||||
static int byteToInt(const QByteArray &data);
|
||||
static int byteToIntRec(const QByteArray &data);
|
||||
static quint32 byteToUInt(const QByteArray &data);
|
||||
static quint32 byteToUIntRec(const QByteArray &data);
|
||||
|
||||
//ushort转字节数组
|
||||
static QByteArray ushortToByte(ushort data);
|
||||
static QByteArray ushortToByteRec(ushort data);
|
||||
|
||||
//字节数组转ushort
|
||||
static int byteToUShort(const QByteArray &data);
|
||||
static int byteToUShortRec(const QByteArray &data);
|
||||
|
||||
//字符串补全
|
||||
static QString getValue(quint8 value);
|
||||
|
||||
//异或加密-只支持字符,如果是中文需要将其转换base64编码
|
||||
static QString getXorEncryptDecrypt(const QString &value, char key);
|
||||
//异或校验
|
||||
static uchar getOrCode(const QByteArray &data);
|
||||
//计算校验码
|
||||
static uchar getCheckCode(const QByteArray &data);
|
||||
|
||||
//CRC校验
|
||||
static quint16 getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table);
|
||||
static quint16 getCrc16(quint8 *data, int len, quint16 init, const quint16 *table);
|
||||
static quint16 getModbus16(quint8 *data, int len);
|
||||
static QByteArray getCrcCode(const QByteArray &data);
|
||||
|
||||
//字节数组与Ascii字符串互转
|
||||
static void initAscii();
|
||||
static QString byteArrayToAsciiStr(const QByteArray &data);
|
||||
static QByteArray asciiStrToByteArray(const QString &data);
|
||||
|
||||
//16进制字符串与字节数组互转
|
||||
static char hexStrToChar(char data);
|
||||
static QByteArray hexStrToByteArray(const QString &data);
|
||||
static QString byteArrayToHexStr(const QByteArray &data);
|
||||
};
|
||||
|
||||
#endif // QUIHELPERDATA_H
|
||||
23
tool/comtool/comtool.pro
Normal file
@@ -0,0 +1,23 @@
|
||||
QT += core gui network
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
|
||||
|
||||
TARGET = comtool
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
RC_FILE = qrc/main.rc
|
||||
|
||||
HEADERS += head.h
|
||||
SOURCES += main.cpp
|
||||
RESOURCES += qrc/main.qrc
|
||||
CONFIG += warn_off
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD/api
|
||||
INCLUDEPATH += $$PWD/form
|
||||
|
||||
include ($$PWD/api/api.pri)
|
||||
include ($$PWD/form/form.pri)
|
||||
|
||||
INCLUDEPATH += $$PWD/../3rd_qextserialport
|
||||
include ($$PWD/../3rd_qextserialport/3rd_qextserialport.pri)
|
||||
1
tool/comtool/file/device.txt
Normal file
@@ -0,0 +1 @@
|
||||
01 03 00 00 00 06 C5 C8;01 03 0C 00 01 00 01 00 00 00 01 00 01 00 01 37 DC
|
||||
17
tool/comtool/file/send.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
16 FF 01 01 E0 E1
|
||||
16 FF 01 01 E1 E2
|
||||
16 01 02 DF BC 16 01 02 DF BC 16 01 02 DF BC 12 13 14 15
|
||||
16 00 00 04 D0 F0 F1 65 C4
|
||||
16 00 00 04 D0 05 AB 5A C4
|
||||
16 01 10 02 F0 03 06 16 01 11 02 F0 03 06 16 01 12 02 F0 03 06 16 01 13 02 F0 03 06 16 01
|
||||
14 02 F0 03 06 16 01 15 02 F0 03 06 16 01 16 02 F0 03 06
|
||||
16 11 01 03 E8 01 10 0E
|
||||
16 11 01 03 E8 01 12 10
|
||||
16 11 01 03 E8 01 14 12
|
||||
16 11 01 03 E8 01 15 13
|
||||
DISARMEDALL
|
||||
BURGLARY 012
|
||||
BYPASS 012
|
||||
DISARMED 012
|
||||
16 00 01 01 D1 D3
|
||||
16 01 11 11
|
||||
8
tool/comtool/form/form.pri
Normal file
@@ -0,0 +1,8 @@
|
||||
FORMS += \
|
||||
$$PWD/frmcomtool.ui
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/frmcomtool.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/frmcomtool.cpp
|
||||
588
tool/comtool/form/frmcomtool.cpp
Normal file
@@ -0,0 +1,588 @@
|
||||
#include "frmcomtool.h"
|
||||
#include "ui_frmcomtool.h"
|
||||
#include "quihelper.h"
|
||||
#include "quihelperdata.h"
|
||||
|
||||
frmComTool::frmComTool(QWidget *parent) : QWidget(parent), ui(new Ui::frmComTool)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
this->initConfig();
|
||||
QUIHelper::setFormInCenter(this);
|
||||
}
|
||||
|
||||
frmComTool::~frmComTool()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmComTool::initForm()
|
||||
{
|
||||
comOk = false;
|
||||
com = 0;
|
||||
sleepTime = 10;
|
||||
receiveCount = 0;
|
||||
sendCount = 0;
|
||||
isShow = true;
|
||||
|
||||
ui->cboxSendInterval->addItems(AppData::Intervals);
|
||||
ui->cboxData->addItems(AppData::Datas);
|
||||
|
||||
//读取数据
|
||||
timerRead = new QTimer(this);
|
||||
timerRead->setInterval(100);
|
||||
connect(timerRead, SIGNAL(timeout()), this, SLOT(readData()));
|
||||
|
||||
//发送数据
|
||||
timerSend = new QTimer(this);
|
||||
connect(timerSend, SIGNAL(timeout()), this, SLOT(sendData()));
|
||||
connect(ui->btnSend, SIGNAL(clicked()), this, SLOT(sendData()));
|
||||
|
||||
//保存数据
|
||||
timerSave = new QTimer(this);
|
||||
connect(timerSave, SIGNAL(timeout()), this, SLOT(saveData()));
|
||||
connect(ui->btnSave, SIGNAL(clicked()), this, SLOT(saveData()));
|
||||
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
changeEnable(false);
|
||||
|
||||
tcpOk = false;
|
||||
socket = new QTcpSocket(this);
|
||||
socket->abort();
|
||||
connect(socket, SIGNAL(readyRead()), this, SLOT(readDataNet()));
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(readErrorNet()));
|
||||
#else
|
||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(readErrorNet()));
|
||||
#endif
|
||||
|
||||
timerConnect = new QTimer(this);
|
||||
connect(timerConnect, SIGNAL(timeout()), this, SLOT(connectNet()));
|
||||
timerConnect->setInterval(3000);
|
||||
timerConnect->start();
|
||||
|
||||
#ifdef __arm__
|
||||
ui->widgetRight->setFixedWidth(280);
|
||||
#endif
|
||||
}
|
||||
|
||||
void frmComTool::initConfig()
|
||||
{
|
||||
QStringList comList;
|
||||
for (int i = 1; i <= 20; i++) {
|
||||
comList << QString("COM%1").arg(i);
|
||||
}
|
||||
|
||||
comList << "ttyUSB0" << "ttyS0" << "ttyS1" << "ttyS2" << "ttyS3" << "ttyS4";
|
||||
comList << "ttymxc1" << "ttymxc2" << "ttymxc3" << "ttymxc4";
|
||||
comList << "ttySAC1" << "ttySAC2" << "ttySAC3" << "ttySAC4";
|
||||
ui->cboxPortName->addItems(comList);
|
||||
ui->cboxPortName->setCurrentIndex(ui->cboxPortName->findText(AppConfig::PortName));
|
||||
connect(ui->cboxPortName, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList baudList;
|
||||
baudList << "50" << "75" << "100" << "134" << "150" << "200" << "300" << "600" << "1200"
|
||||
<< "1800" << "2400" << "4800" << "9600" << "14400" << "19200" << "38400"
|
||||
<< "56000" << "57600" << "76800" << "115200" << "128000" << "256000";
|
||||
|
||||
ui->cboxBaudRate->addItems(baudList);
|
||||
ui->cboxBaudRate->setCurrentIndex(ui->cboxBaudRate->findText(QString::number(AppConfig::BaudRate)));
|
||||
connect(ui->cboxBaudRate, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList dataBitsList;
|
||||
dataBitsList << "5" << "6" << "7" << "8";
|
||||
|
||||
ui->cboxDataBit->addItems(dataBitsList);
|
||||
ui->cboxDataBit->setCurrentIndex(ui->cboxDataBit->findText(QString::number(AppConfig::DataBit)));
|
||||
connect(ui->cboxDataBit, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList parityList;
|
||||
parityList << "无" << "奇" << "偶";
|
||||
#ifdef Q_OS_WIN
|
||||
parityList << "标志";
|
||||
#endif
|
||||
parityList << "空格";
|
||||
|
||||
ui->cboxParity->addItems(parityList);
|
||||
ui->cboxParity->setCurrentIndex(ui->cboxParity->findText(AppConfig::Parity));
|
||||
connect(ui->cboxParity, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList stopBitsList;
|
||||
stopBitsList << "1";
|
||||
#ifdef Q_OS_WIN
|
||||
stopBitsList << "1.5";
|
||||
#endif
|
||||
stopBitsList << "2";
|
||||
|
||||
ui->cboxStopBit->addItems(stopBitsList);
|
||||
ui->cboxStopBit->setCurrentIndex(ui->cboxStopBit->findText(QString::number(AppConfig::StopBit)));
|
||||
connect(ui->cboxStopBit, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckHexSend->setChecked(AppConfig::HexSend);
|
||||
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckHexReceive->setChecked(AppConfig::HexReceive);
|
||||
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckDebug->setChecked(AppConfig::Debug);
|
||||
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoClear->setChecked(AppConfig::AutoClear);
|
||||
connect(ui->ckAutoClear, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoSend->setChecked(AppConfig::AutoSend);
|
||||
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoSave->setChecked(AppConfig::AutoSave);
|
||||
connect(ui->ckAutoSave, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList sendInterval;
|
||||
QStringList saveInterval;
|
||||
sendInterval << "100" << "300" << "500";
|
||||
|
||||
for (int i = 1000; i <= 10000; i = i + 1000) {
|
||||
sendInterval << QString::number(i);
|
||||
saveInterval << QString::number(i);
|
||||
}
|
||||
|
||||
ui->cboxSendInterval->addItems(sendInterval);
|
||||
ui->cboxSaveInterval->addItems(saveInterval);
|
||||
|
||||
ui->cboxSendInterval->setCurrentIndex(ui->cboxSendInterval->findText(QString::number(AppConfig::SendInterval)));
|
||||
connect(ui->cboxSendInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
ui->cboxSaveInterval->setCurrentIndex(ui->cboxSaveInterval->findText(QString::number(AppConfig::SaveInterval)));
|
||||
connect(ui->cboxSaveInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
timerSend->setInterval(AppConfig::SendInterval);
|
||||
timerSave->setInterval(AppConfig::SaveInterval);
|
||||
|
||||
if (AppConfig::AutoSend) {
|
||||
timerSend->start();
|
||||
}
|
||||
|
||||
if (AppConfig::AutoSave) {
|
||||
timerSave->start();
|
||||
}
|
||||
|
||||
//串口转网络部分
|
||||
ui->cboxMode->setCurrentIndex(ui->cboxMode->findText(AppConfig::Mode));
|
||||
connect(ui->cboxMode, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->txtServerIP->setText(AppConfig::ServerIP);
|
||||
connect(ui->txtServerIP, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->txtServerPort->setText(QString::number(AppConfig::ServerPort));
|
||||
connect(ui->txtServerPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->txtListenPort->setText(QString::number(AppConfig::ListenPort));
|
||||
connect(ui->txtListenPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList values;
|
||||
values << "0" << "10" << "50";
|
||||
|
||||
for (int i = 100; i < 1000; i = i + 100) {
|
||||
values << QString("%1").arg(i);
|
||||
}
|
||||
|
||||
ui->cboxSleepTime->addItems(values);
|
||||
|
||||
ui->cboxSleepTime->setCurrentIndex(ui->cboxSleepTime->findText(QString::number(AppConfig::SleepTime)));
|
||||
connect(ui->cboxSleepTime, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoConnect->setChecked(AppConfig::AutoConnect);
|
||||
connect(ui->ckAutoConnect, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
}
|
||||
|
||||
void frmComTool::saveConfig()
|
||||
{
|
||||
AppConfig::PortName = ui->cboxPortName->currentText();
|
||||
AppConfig::BaudRate = ui->cboxBaudRate->currentText().toInt();
|
||||
AppConfig::DataBit = ui->cboxDataBit->currentText().toInt();
|
||||
AppConfig::Parity = ui->cboxParity->currentText();
|
||||
AppConfig::StopBit = ui->cboxStopBit->currentText().toDouble();
|
||||
|
||||
AppConfig::HexSend = ui->ckHexSend->isChecked();
|
||||
AppConfig::HexReceive = ui->ckHexReceive->isChecked();
|
||||
AppConfig::Debug = ui->ckDebug->isChecked();
|
||||
AppConfig::AutoClear = ui->ckAutoClear->isChecked();
|
||||
|
||||
AppConfig::AutoSend = ui->ckAutoSend->isChecked();
|
||||
AppConfig::AutoSave = ui->ckAutoSave->isChecked();
|
||||
|
||||
int sendInterval = ui->cboxSendInterval->currentText().toInt();
|
||||
if (sendInterval != AppConfig::SendInterval) {
|
||||
AppConfig::SendInterval = sendInterval;
|
||||
timerSend->setInterval(AppConfig::SendInterval);
|
||||
}
|
||||
|
||||
int saveInterval = ui->cboxSaveInterval->currentText().toInt();
|
||||
if (saveInterval != AppConfig::SaveInterval) {
|
||||
AppConfig::SaveInterval = saveInterval;
|
||||
timerSave->setInterval(AppConfig::SaveInterval);
|
||||
}
|
||||
|
||||
AppConfig::Mode = ui->cboxMode->currentText();
|
||||
AppConfig::ServerIP = ui->txtServerIP->text().trimmed();
|
||||
AppConfig::ServerPort = ui->txtServerPort->text().toInt();
|
||||
AppConfig::ListenPort = ui->txtListenPort->text().toInt();
|
||||
AppConfig::SleepTime = ui->cboxSleepTime->currentText().toInt();
|
||||
AppConfig::AutoConnect = ui->ckAutoConnect->isChecked();
|
||||
|
||||
AppConfig::writeConfig();
|
||||
}
|
||||
|
||||
void frmComTool::changeEnable(bool b)
|
||||
{
|
||||
ui->cboxBaudRate->setEnabled(!b);
|
||||
ui->cboxDataBit->setEnabled(!b);
|
||||
ui->cboxParity->setEnabled(!b);
|
||||
ui->cboxPortName->setEnabled(!b);
|
||||
ui->cboxStopBit->setEnabled(!b);
|
||||
ui->btnSend->setEnabled(b);
|
||||
ui->ckAutoSend->setEnabled(b);
|
||||
ui->ckAutoSave->setEnabled(b);
|
||||
}
|
||||
|
||||
void frmComTool::append(int type, const QString &data, bool clear)
|
||||
{
|
||||
static int currentCount = 0;
|
||||
static int maxCount = 100;
|
||||
|
||||
if (clear) {
|
||||
ui->txtMain->clear();
|
||||
currentCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentCount >= maxCount) {
|
||||
ui->txtMain->clear();
|
||||
currentCount = 0;
|
||||
}
|
||||
|
||||
if (!isShow) {
|
||||
return;
|
||||
}
|
||||
|
||||
//过滤回车换行符
|
||||
QString strData = data;
|
||||
strData = strData.replace("\r", "");
|
||||
strData = strData.replace("\n", "");
|
||||
|
||||
//不同类型不同颜色显示
|
||||
QString strType;
|
||||
if (type == 0) {
|
||||
strType = "串口发送 >>";
|
||||
ui->txtMain->setTextColor(QColor("dodgerblue"));
|
||||
} else if (type == 1) {
|
||||
strType = "串口接收 <<";
|
||||
ui->txtMain->setTextColor(QColor("red"));
|
||||
} else if (type == 2) {
|
||||
strType = "处理延时 >>";
|
||||
ui->txtMain->setTextColor(QColor("gray"));
|
||||
} else if (type == 3) {
|
||||
strType = "正在校验 >>";
|
||||
ui->txtMain->setTextColor(QColor("green"));
|
||||
} else if (type == 4) {
|
||||
strType = "网络发送 >>";
|
||||
ui->txtMain->setTextColor(QColor(24, 189, 155));
|
||||
} else if (type == 5) {
|
||||
strType = "网络接收 <<";
|
||||
ui->txtMain->setTextColor(QColor(255, 107, 107));
|
||||
} else if (type == 6) {
|
||||
strType = "提示信息 >>";
|
||||
ui->txtMain->setTextColor(QColor(100, 184, 255));
|
||||
}
|
||||
|
||||
strData = QString("时间[%1] %2 %3").arg(TIMEMS).arg(strType).arg(strData);
|
||||
ui->txtMain->append(strData);
|
||||
currentCount++;
|
||||
}
|
||||
|
||||
void frmComTool::readData()
|
||||
{
|
||||
if (com->bytesAvailable() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QUIHelper::sleep(sleepTime);
|
||||
QByteArray data = com->readAll();
|
||||
int dataLen = data.length();
|
||||
if (dataLen <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isShow) {
|
||||
QString buffer;
|
||||
if (ui->ckHexReceive->isChecked()) {
|
||||
buffer = QUIHelperData::byteArrayToHexStr(data);
|
||||
} else {
|
||||
//buffer = QUIHelperData::byteArrayToAsciiStr(data);
|
||||
buffer = QString::fromLocal8Bit(data);
|
||||
}
|
||||
|
||||
//启用调试则模拟调试数据
|
||||
if (ui->ckDebug->isChecked()) {
|
||||
int count = AppData::Keys.count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (buffer.startsWith(AppData::Keys.at(i))) {
|
||||
sendData(AppData::Values.at(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
append(1, buffer);
|
||||
receiveCount = receiveCount + data.size();
|
||||
ui->btnReceiveCount->setText(QString("接收 : %1 字节").arg(receiveCount));
|
||||
|
||||
//启用网络转发则调用网络发送数据
|
||||
if (tcpOk) {
|
||||
socket->write(data);
|
||||
append(4, QString(buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::sendData()
|
||||
{
|
||||
QString str = ui->cboxData->currentText();
|
||||
if (str.isEmpty()) {
|
||||
ui->cboxData->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
sendData(str);
|
||||
|
||||
if (ui->ckAutoClear->isChecked()) {
|
||||
ui->cboxData->setCurrentIndex(-1);
|
||||
ui->cboxData->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::sendData(QString data)
|
||||
{
|
||||
if (com == 0 || !com->isOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//短信猫调试
|
||||
if (data.startsWith("AT")) {
|
||||
data += "\r";
|
||||
}
|
||||
|
||||
QByteArray buffer;
|
||||
if (ui->ckHexSend->isChecked()) {
|
||||
buffer = QUIHelperData::hexStrToByteArray(data);
|
||||
} else {
|
||||
buffer = QUIHelperData::asciiStrToByteArray(data);
|
||||
}
|
||||
|
||||
com->write(buffer);
|
||||
append(0, data);
|
||||
sendCount = sendCount + buffer.size();
|
||||
ui->btnSendCount->setText(QString("发送 : %1 字节").arg(sendCount));
|
||||
}
|
||||
|
||||
void frmComTool::saveData()
|
||||
{
|
||||
QString tempData = ui->txtMain->toPlainText();
|
||||
|
||||
if (tempData == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QString name = now.toString("yyyy-MM-dd-HH-mm-ss");
|
||||
QString fileName = QString("%1/%2.txt").arg(QUIHelper::appPath()).arg(name);
|
||||
|
||||
QFile file(fileName);
|
||||
file.open(QFile::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
out << tempData;
|
||||
file.close();
|
||||
|
||||
on_btnClear_clicked();
|
||||
}
|
||||
|
||||
void frmComTool::on_btnOpen_clicked()
|
||||
{
|
||||
if (ui->btnOpen->text() == "打开串口") {
|
||||
com = new QextSerialPort(ui->cboxPortName->currentText(), QextSerialPort::Polling);
|
||||
comOk = com->open(QIODevice::ReadWrite);
|
||||
|
||||
if (comOk) {
|
||||
//清空缓冲区
|
||||
com->flush();
|
||||
//设置波特率
|
||||
com->setBaudRate((BaudRateType)ui->cboxBaudRate->currentText().toInt());
|
||||
//设置数据位
|
||||
com->setDataBits((DataBitsType)ui->cboxDataBit->currentText().toInt());
|
||||
//设置校验位
|
||||
com->setParity((ParityType)ui->cboxParity->currentIndex());
|
||||
//设置停止位
|
||||
com->setStopBits((StopBitsType)ui->cboxStopBit->currentIndex());
|
||||
com->setFlowControl(FLOW_OFF);
|
||||
com->setTimeout(10);
|
||||
|
||||
changeEnable(true);
|
||||
ui->btnOpen->setText("关闭串口");
|
||||
timerRead->start();
|
||||
}
|
||||
} else {
|
||||
timerRead->stop();
|
||||
com->close();
|
||||
com->deleteLater();
|
||||
|
||||
changeEnable(false);
|
||||
ui->btnOpen->setText("打开串口");
|
||||
on_btnClear_clicked();
|
||||
comOk = false;
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_btnSendCount_clicked()
|
||||
{
|
||||
sendCount = 0;
|
||||
ui->btnSendCount->setText("发送 : 0 字节");
|
||||
}
|
||||
|
||||
void frmComTool::on_btnReceiveCount_clicked()
|
||||
{
|
||||
receiveCount = 0;
|
||||
ui->btnReceiveCount->setText("接收 : 0 字节");
|
||||
}
|
||||
|
||||
void frmComTool::on_btnStopShow_clicked()
|
||||
{
|
||||
if (ui->btnStopShow->text() == "停止显示") {
|
||||
isShow = false;
|
||||
ui->btnStopShow->setText("开始显示");
|
||||
} else {
|
||||
isShow = true;
|
||||
ui->btnStopShow->setText("停止显示");
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_btnData_clicked()
|
||||
{
|
||||
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg("send.txt");
|
||||
QFile file(fileName);
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ui->btnData->text() == "管理数据") {
|
||||
ui->txtMain->setReadOnly(false);
|
||||
ui->txtMain->clear();
|
||||
file.open(QFile::ReadOnly | QIODevice::Text);
|
||||
QTextStream in(&file);
|
||||
ui->txtMain->setText(in.readAll());
|
||||
file.close();
|
||||
ui->btnData->setText("保存数据");
|
||||
} else {
|
||||
ui->txtMain->setReadOnly(true);
|
||||
file.open(QFile::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
out << ui->txtMain->toPlainText();
|
||||
file.close();
|
||||
ui->txtMain->clear();
|
||||
ui->btnData->setText("管理数据");
|
||||
AppData::readSendData();
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_btnClear_clicked()
|
||||
{
|
||||
append(0, "", true);
|
||||
}
|
||||
|
||||
void frmComTool::on_btnStart_clicked()
|
||||
{
|
||||
if (ui->btnStart->text() == "启动") {
|
||||
if (AppConfig::ServerIP == "" || AppConfig::ServerPort == 0) {
|
||||
append(6, "IP地址和远程端口不能为空");
|
||||
return;
|
||||
}
|
||||
|
||||
socket->connectToHost(AppConfig::ServerIP, AppConfig::ServerPort);
|
||||
if (socket->waitForConnected(100)) {
|
||||
ui->btnStart->setText("停止");
|
||||
append(6, "连接服务器成功");
|
||||
tcpOk = true;
|
||||
}
|
||||
} else {
|
||||
socket->disconnectFromHost();
|
||||
if (socket->state() == QAbstractSocket::UnconnectedState || socket->waitForDisconnected(100)) {
|
||||
ui->btnStart->setText("启动");
|
||||
append(6, "断开服务器成功");
|
||||
tcpOk = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_ckAutoSend_stateChanged(int arg1)
|
||||
{
|
||||
if (arg1 == 0) {
|
||||
ui->cboxSendInterval->setEnabled(false);
|
||||
timerSend->stop();
|
||||
} else {
|
||||
ui->cboxSendInterval->setEnabled(true);
|
||||
timerSend->start();
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_ckAutoSave_stateChanged(int arg1)
|
||||
{
|
||||
if (arg1 == 0) {
|
||||
ui->cboxSaveInterval->setEnabled(false);
|
||||
timerSave->stop();
|
||||
} else {
|
||||
ui->cboxSaveInterval->setEnabled(true);
|
||||
timerSave->start();
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::connectNet()
|
||||
{
|
||||
if (!tcpOk && AppConfig::AutoConnect && ui->btnStart->text() == "启动") {
|
||||
if (AppConfig::ServerIP != "" && AppConfig::ServerPort != 0) {
|
||||
socket->connectToHost(AppConfig::ServerIP, AppConfig::ServerPort);
|
||||
if (socket->waitForConnected(100)) {
|
||||
ui->btnStart->setText("停止");
|
||||
append(6, "连接服务器成功");
|
||||
tcpOk = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::readDataNet()
|
||||
{
|
||||
if (socket->bytesAvailable() > 0) {
|
||||
QUIHelper::sleep(AppConfig::SleepTime);
|
||||
QByteArray data = socket->readAll();
|
||||
|
||||
QString buffer;
|
||||
if (ui->ckHexReceive->isChecked()) {
|
||||
buffer = QUIHelperData::byteArrayToHexStr(data);
|
||||
} else {
|
||||
buffer = QUIHelperData::byteArrayToAsciiStr(data);
|
||||
}
|
||||
|
||||
append(5, buffer);
|
||||
|
||||
//将收到的网络数据转发给串口
|
||||
if (comOk) {
|
||||
com->write(data);
|
||||
append(0, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::readErrorNet()
|
||||
{
|
||||
ui->btnStart->setText("启动");
|
||||
append(6, QString("连接服务器失败,%1").arg(socket->errorString()));
|
||||
socket->disconnectFromHost();
|
||||
tcpOk = false;
|
||||
}
|
||||
68
tool/comtool/form/frmcomtool.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef FRMCOMTOOL_H
|
||||
#define FRMCOMTOOL_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "qtcpsocket.h"
|
||||
#include "qextserialport.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class frmComTool;
|
||||
}
|
||||
|
||||
class frmComTool : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmComTool(QWidget *parent = 0);
|
||||
~frmComTool();
|
||||
|
||||
private:
|
||||
Ui::frmComTool *ui;
|
||||
|
||||
bool comOk; //串口是否打开
|
||||
QextSerialPort *com; //串口通信对象
|
||||
QTimer *timerRead; //定时读取串口数据
|
||||
QTimer *timerSend; //定时发送串口数据
|
||||
QTimer *timerSave; //定时保存串口数据
|
||||
|
||||
int sleepTime; //接收延时时间
|
||||
int sendCount; //发送数据计数
|
||||
int receiveCount; //接收数据计数
|
||||
bool isShow; //是否显示数据
|
||||
|
||||
bool tcpOk; //网络是否正常
|
||||
QTcpSocket *socket; //网络连接对象
|
||||
QTimer *timerConnect; //定时器重连
|
||||
|
||||
private slots:
|
||||
void initForm(); //初始化窗体数据
|
||||
void initConfig(); //初始化配置文件
|
||||
void saveConfig(); //保存配置文件
|
||||
void readData(); //读取串口数据
|
||||
void sendData(); //发送串口数据
|
||||
void sendData(QString data);//发送串口数据带参数
|
||||
void saveData(); //保存串口数据
|
||||
|
||||
void changeEnable(bool b); //改变状态
|
||||
void append(int type, const QString &data, bool clear = false);
|
||||
|
||||
private slots:
|
||||
void connectNet();
|
||||
void readDataNet();
|
||||
void readErrorNet();
|
||||
|
||||
private slots:
|
||||
void on_btnOpen_clicked();
|
||||
void on_btnStopShow_clicked();
|
||||
void on_btnSendCount_clicked();
|
||||
void on_btnReceiveCount_clicked();
|
||||
void on_btnClear_clicked();
|
||||
void on_btnData_clicked();
|
||||
void on_btnStart_clicked();
|
||||
void on_ckAutoSend_stateChanged(int arg1);
|
||||
void on_ckAutoSave_stateChanged(int arg1);
|
||||
};
|
||||
|
||||
#endif // FRMCOMTOOL_H
|
||||
533
tool/comtool/form/frmcomtool.ui
Normal file
@@ -0,0 +1,533 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmComTool</class>
|
||||
<widget class="QWidget" name="frmComTool">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="txtMain">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<widget class="QWidget" name="widgetRight" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<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="QFrame" name="frameTop">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labPortName">
|
||||
<property name="text">
|
||||
<string>串口号</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cboxPortName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labBaudRate">
|
||||
<property name="text">
|
||||
<string>波特率</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cboxBaudRate">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labDataBit">
|
||||
<property name="text">
|
||||
<string>数据位</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cboxDataBit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labParity">
|
||||
<property name="text">
|
||||
<string>校验位</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="cboxParity">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labStopBit">
|
||||
<property name="text">
|
||||
<string>停止位</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="cboxStopBit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnOpen">
|
||||
<property name="text">
|
||||
<string>打开串口</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="tabPosition">
|
||||
<enum>QTabWidget::South</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>串口配置</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="ckHexSend">
|
||||
<property name="text">
|
||||
<string>Hex发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="ckHexReceive">
|
||||
<property name="text">
|
||||
<string>Hex接收</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="ckDebug">
|
||||
<property name="text">
|
||||
<string>模拟设备</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="ckAutoClear">
|
||||
<property name="text">
|
||||
<string>自动清空</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="ckAutoSend">
|
||||
<property name="text">
|
||||
<string>自动发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cboxSendInterval">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="ckAutoSave">
|
||||
<property name="text">
|
||||
<string>自动保存</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cboxSaveInterval">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnSendCount">
|
||||
<property name="text">
|
||||
<string>发送 : 0 字节</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnReceiveCount">
|
||||
<property name="text">
|
||||
<string>接收 : 0 字节</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnStopShow">
|
||||
<property name="text">
|
||||
<string>停止显示</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnSave">
|
||||
<property name="text">
|
||||
<string>保存数据</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnData">
|
||||
<property name="text">
|
||||
<string>管理数据</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnClear">
|
||||
<property name="text">
|
||||
<string>清空数据</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>2</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>网络配置</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labListenPort">
|
||||
<property name="text">
|
||||
<string>监听端口</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labServerIP">
|
||||
<property name="text">
|
||||
<string>远程地址</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="cboxSleepTime"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="txtServerIP">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labServerPort">
|
||||
<property name="text">
|
||||
<string>远程端口</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="txtServerPort">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labSleepTime">
|
||||
<property name="text">
|
||||
<string>延时时间</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="txtListenPort"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labMode">
|
||||
<property name="text">
|
||||
<string>转换模式</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cboxMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tcp_Client</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tcp_Server</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Udp_Client</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Udp_Server</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnStart">
|
||||
<property name="text">
|
||||
<string>启动</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>59</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="ckAutoConnect">
|
||||
<property name="text">
|
||||
<string>自动重连网络</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<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="QComboBox" name="cboxData">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="duplicatesEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSend">
|
||||
<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>发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
18
tool/comtool/head.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QtNetwork>
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
|
||||
#include <QtWidgets>
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
#include <QtCore5Compat>
|
||||
#endif
|
||||
|
||||
#pragma execution_character_set("utf-8")
|
||||
#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
|
||||
#define STRDATETIME qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss"))
|
||||
|
||||
#include "appconfig.h"
|
||||
#include "appdata.h"
|
||||
26
tool/comtool/main.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "frmcomtool.h"
|
||||
#include "quihelper.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setWindowIcon(QIcon(":/main.ico"));
|
||||
|
||||
//设置编码以及加载中文翻译文件
|
||||
QUIHelper::initAll();
|
||||
//读取配置文件
|
||||
AppConfig::ConfigFile = QString("%1/%2.ini").arg(QUIHelper::appPath()).arg(QUIHelper::appName());
|
||||
AppConfig::readConfig();
|
||||
|
||||
AppData::Intervals << "1" << "10" << "20" << "50" << "100" << "200" << "300" << "500" << "1000" << "1500" << "2000" << "3000" << "5000" << "10000";
|
||||
AppData::readSendData();
|
||||
AppData::readDeviceData();
|
||||
|
||||
frmComTool w;
|
||||
w.setWindowTitle("串口调试助手 V2022 (QQ: 517216493 WX: feiyangqingyun)");
|
||||
w.resize(900, 650);
|
||||
QUIHelper::setFormInCenter(&w);
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
BIN
tool/comtool/qrc/main.ico
Normal file
|
After Width: | Height: | Size: 91 KiB |
7
tool/comtool/qrc/main.qrc
Normal file
@@ -0,0 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.ico</file>
|
||||
<file>qm/qt_zh_CN.qm</file>
|
||||
<file>qm/widgets.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
1
tool/comtool/qrc/main.rc
Normal file
@@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "main.ico"
|
||||
BIN
tool/comtool/qrc/qm/qt_zh_CN.qm
Normal file
BIN
tool/comtool/qrc/qm/widgets.qm
Normal file
18
tool/comtool/readme.md
Normal file
@@ -0,0 +1,18 @@
|
||||
**<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
|
||||
1. ֧<><D6A7>16<31><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD><DDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ա<EFBFBD>
|
||||
2. ֧<><D6A7>windows<77><73>COM9<4D><39><EFBFBD>ϵĴ<CFB5><C4B4><EFBFBD>ͨ<EFBFBD>š<EFBFBD>
|
||||
3. ʵʱ<CAB5><CAB1>ʾ<EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڴ<D6BD>С<EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC>
|
||||
4. ֧<><D6A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>qt<71>汾<EFBFBD><E6B1BE><EFBFBD>ײ<EFBFBD>4.7.0 <20><> 6.1<EFBFBD><EFBFBD>
|
||||
5. ֧<>ִ<EFBFBD><D6B4><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><D5B7><EFBFBD>
|
||||
|
||||
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
|
||||
1. <20><><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD>ݣ<EFBFBD>ÿ<EFBFBD><C3BF>ֻҪ<D6BB><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><DDBC>ɣ<EFBFBD><C9A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD>
|
||||
2. <20><>ģ<EFBFBD><C4A3><EFBFBD>豸<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>濪<EFBFBD><E6BFAA>ģ<EFBFBD><C4A3><EFBFBD>豸<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD>ݡ<EFBFBD><DDA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>úõ<C3BA>ָ<EFBFBD><D6B8>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD>õĻظ<C4BB>ָ<EFBFBD><EFBFBD><EEA1A3><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>յ<EFBFBD>0x16 0x00 0xFF 0x01<30><31>Ҫ<EFBFBD>ظ<EFBFBD>0x16 0x00 0xFE 0x01<30><31><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>Ҫ<EFBFBD><D2AA>SendData.txt<78><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>16 00 FF 01:16 00 FE 01<30><31><EFBFBD>ɡ<EFBFBD>
|
||||
3. <20>ɶ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݺͱ<DDBA><CDB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5>ı<EFBFBD><C4B1>ļ<EFBFBD>:<3A><>Ĭ<EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD>5<EFBFBD><35><EFBFBD>ӣ<EFBFBD><D3A3>ɸ<EFBFBD><C9B8>ļ<EFBFBD><C4BC><EFBFBD>ʱ<EFBFBD>䡣
|
||||
4. <20>ڲ<EFBFBD><DAB2>Ͻ<EFBFBD><CFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鿴<EFBFBD><E9BFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>̨<EFBFBD><CCA8>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>رմ<D8B1><D5B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鿴<EFBFBD>ѽ<EFBFBD><D1BD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD>
|
||||
5. ÿ<><C3BF><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD><DDB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѽڵģ<DAB5><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
6. һ<><D2BB>Դ<EFBFBD><D4B4><EFBFBD>洦<EFBFBD><E6B4A6><EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD>࣬<EFBFBD><E0A3AC><EFBFBD><EFBFBD>XP/WIN7/UBUNTU/ARMLINUXϵͳ<CFB5>³ɹ<C2B3><C9B9><EFBFBD><EFBFBD>벢<EFBFBD><EBB2A2><EFBFBD>С<EFBFBD>
|
||||
|
||||
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>**
|
||||
1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뽫Դ<EBBDAB><D4B4><EFBFBD>µ<EFBFBD>fileĿ¼<C4BF>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD>ļ<EFBFBD>ͬһĿ¼<C4BF><C2BC>
|
||||
2. <20><><EFBFBD><EFBFBD><EFBFBD>и<EFBFBD><D0B8>õĽ<C3B5><C4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>лл<D0BB><D0BB>
|
||||
14
tool/countcode/countcode.pro
Normal file
@@ -0,0 +1,14 @@
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
|
||||
|
||||
TARGET = countcode
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmcountcode.cpp
|
||||
HEADERS += frmcountcode.h
|
||||
FORMS += frmcountcode.ui
|
||||
|
||||
279
tool/countcode/frmcountcode.cpp
Normal file
@@ -0,0 +1,279 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmcountcode.h"
|
||||
#include "ui_frmcountcode.h"
|
||||
#include "qfile.h"
|
||||
#include "qtextstream.h"
|
||||
#include "qfiledialog.h"
|
||||
#include "qfileinfo.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
frmCountCode::frmCountCode(QWidget *parent) : QWidget(parent), ui(new Ui::frmCountCode)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
on_btnClear_clicked();
|
||||
}
|
||||
|
||||
frmCountCode::~frmCountCode()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmCountCode::initForm()
|
||||
{
|
||||
QStringList headText;
|
||||
headText << "文件名" << "类型" << "大小" << "总行数" << "代码行数" << "注释行数" << "空白行数" << "路径";
|
||||
QList<int> columnWidth;
|
||||
columnWidth << 130 << 50 << 70 << 80 << 70 << 70 << 70 << 150;
|
||||
|
||||
int columnCount = headText.count();
|
||||
ui->tableWidget->setColumnCount(columnCount);
|
||||
ui->tableWidget->setHorizontalHeaderLabels(headText);
|
||||
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
ui->tableWidget->verticalHeader()->setVisible(false);
|
||||
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
|
||||
ui->tableWidget->horizontalHeader()->setHighlightSections(false);
|
||||
ui->tableWidget->verticalHeader()->setDefaultSectionSize(20);
|
||||
ui->tableWidget->verticalHeader()->setHighlightSections(false);
|
||||
|
||||
for (int i = 0; i < columnCount; i++) {
|
||||
ui->tableWidget->setColumnWidth(i, columnWidth.at(i));
|
||||
}
|
||||
|
||||
//设置前景色
|
||||
ui->txtCount->setStyleSheet("color:#17A086;");
|
||||
ui->txtSize->setStyleSheet("color:#CA5AA6;");
|
||||
ui->txtRow->setStyleSheet("color:#CD1B19;");
|
||||
ui->txtCode->setStyleSheet("color:#22A3A9;");
|
||||
ui->txtNote->setStyleSheet("color:#D64D54;");
|
||||
ui->txtBlank->setStyleSheet("color:#A279C5;");
|
||||
|
||||
//设置字体加粗
|
||||
QFont font;
|
||||
font.setBold(true);
|
||||
if (font.pointSize() > 0) {
|
||||
font.setPointSize(font.pointSize() + 1);
|
||||
} else {
|
||||
font.setPixelSize(font.pixelSize() + 2);
|
||||
}
|
||||
|
||||
ui->txtCount->setFont(font);
|
||||
ui->txtSize->setFont(font);
|
||||
ui->txtRow->setFont(font);
|
||||
ui->txtCode->setFont(font);
|
||||
ui->txtNote->setFont(font);
|
||||
ui->txtBlank->setFont(font);
|
||||
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(4,7,0))
|
||||
ui->txtFilter->setPlaceholderText("中间空格隔开,例如 *.h *.cpp *.c");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool frmCountCode::checkFile(const QString &fileName)
|
||||
{
|
||||
if (fileName.startsWith("moc_") || fileName.startsWith("ui_") || fileName.startsWith("qrc_")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QFileInfo file(fileName);
|
||||
QString suffix = "*." + file.suffix();
|
||||
QString filter = ui->txtFilter->text().trimmed();
|
||||
QStringList filters = filter.split(" ");
|
||||
return filters.contains(suffix);
|
||||
}
|
||||
|
||||
void frmCountCode::countCode(const QString &filePath)
|
||||
{
|
||||
QDir dir(filePath);
|
||||
QFileInfoList fileInfos = dir.entryInfoList();
|
||||
foreach (QFileInfo fileInfo, fileInfos) {
|
||||
QString fileName = fileInfo.fileName();
|
||||
if (fileInfo.isFile()) {
|
||||
if (checkFile(fileName)) {
|
||||
listFile << fileInfo.filePath();
|
||||
}
|
||||
} else {
|
||||
if (fileName == "." || fileName == "..") {
|
||||
continue;
|
||||
}
|
||||
|
||||
//递归找出文件
|
||||
countCode(fileInfo.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmCountCode::countCode(const QStringList &files)
|
||||
{
|
||||
int lineCode;
|
||||
int lineBlank;
|
||||
int lineNotes;
|
||||
int count = files.count();
|
||||
on_btnClear_clicked();
|
||||
ui->tableWidget->setRowCount(count);
|
||||
|
||||
quint32 totalLines = 0;
|
||||
quint32 totalBytes = 0;
|
||||
quint32 totalCodes = 0;
|
||||
quint32 totalNotes = 0;
|
||||
quint32 totalBlanks = 0;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
QFileInfo fileInfo(files.at(i));
|
||||
countCode(fileInfo.filePath(), lineCode, lineBlank, lineNotes);
|
||||
int lineAll = lineCode + lineBlank + lineNotes;
|
||||
|
||||
QTableWidgetItem *itemName = new QTableWidgetItem;
|
||||
itemName->setText(fileInfo.fileName());
|
||||
|
||||
QTableWidgetItem *itemSuffix = new QTableWidgetItem;
|
||||
itemSuffix->setText(fileInfo.suffix());
|
||||
|
||||
QTableWidgetItem *itemSize = new QTableWidgetItem;
|
||||
itemSize->setText(QString::number(fileInfo.size()));
|
||||
|
||||
QTableWidgetItem *itemLine = new QTableWidgetItem;
|
||||
itemLine->setText(QString::number(lineAll));
|
||||
|
||||
QTableWidgetItem *itemCode = new QTableWidgetItem;
|
||||
itemCode->setText(QString::number(lineCode));
|
||||
|
||||
QTableWidgetItem *itemNote = new QTableWidgetItem;
|
||||
itemNote->setText(QString::number(lineNotes));
|
||||
|
||||
QTableWidgetItem *itemBlank = new QTableWidgetItem;
|
||||
itemBlank->setText(QString::number(lineBlank));
|
||||
|
||||
QTableWidgetItem *itemPath = new QTableWidgetItem;
|
||||
itemPath->setText(fileInfo.filePath());
|
||||
|
||||
itemSuffix->setTextAlignment(Qt::AlignCenter);
|
||||
itemSize->setTextAlignment(Qt::AlignCenter);
|
||||
itemLine->setTextAlignment(Qt::AlignCenter);
|
||||
itemCode->setTextAlignment(Qt::AlignCenter);
|
||||
itemNote->setTextAlignment(Qt::AlignCenter);
|
||||
itemBlank->setTextAlignment(Qt::AlignCenter);
|
||||
|
||||
ui->tableWidget->setItem(i, 0, itemName);
|
||||
ui->tableWidget->setItem(i, 1, itemSuffix);
|
||||
ui->tableWidget->setItem(i, 2, itemSize);
|
||||
ui->tableWidget->setItem(i, 3, itemLine);
|
||||
ui->tableWidget->setItem(i, 4, itemCode);
|
||||
ui->tableWidget->setItem(i, 5, itemNote);
|
||||
ui->tableWidget->setItem(i, 6, itemBlank);
|
||||
ui->tableWidget->setItem(i, 7, itemPath);
|
||||
|
||||
totalBytes += fileInfo.size();
|
||||
totalLines += lineAll;
|
||||
totalCodes += lineCode;
|
||||
totalNotes += lineNotes;
|
||||
totalBlanks += lineBlank;
|
||||
|
||||
if (i % 100 == 0) {
|
||||
qApp->processEvents();
|
||||
}
|
||||
}
|
||||
|
||||
//显示统计结果
|
||||
listFile.clear();
|
||||
ui->txtCount->setText(QString::number(count));
|
||||
ui->txtSize->setText(QString::number(totalBytes));
|
||||
ui->txtRow->setText(QString::number(totalLines));
|
||||
ui->txtCode->setText(QString::number(totalCodes));
|
||||
ui->txtNote->setText(QString::number(totalNotes));
|
||||
ui->txtBlank->setText(QString::number(totalBlanks));
|
||||
|
||||
//计算百分比
|
||||
double percent = 0.0;
|
||||
//代码行所占百分比
|
||||
percent = ((double)totalCodes / totalLines) * 100;
|
||||
ui->labPercentCode->setText(QString("%1%").arg(percent, 5, 'f', 2, QChar(' ')));
|
||||
//注释行所占百分比
|
||||
percent = ((double)totalNotes / totalLines) * 100;
|
||||
ui->labPercentNote->setText(QString("%1%").arg(percent, 5, 'f', 2, QChar(' ')));
|
||||
//空行所占百分比
|
||||
percent = ((double)totalBlanks / totalLines) * 100;
|
||||
ui->labPercentBlank->setText(QString("%1%").arg(percent, 5, 'f', 2, QChar(' ')));
|
||||
}
|
||||
|
||||
void frmCountCode::countCode(const QString &fileName, int &lineCode, int &lineBlank, int &lineNotes)
|
||||
{
|
||||
lineCode = lineBlank = lineNotes = 0;
|
||||
QFile file(fileName);
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
QTextStream out(&file);
|
||||
QString line;
|
||||
bool isNote = false;
|
||||
while (!out.atEnd()) {
|
||||
line = out.readLine();
|
||||
|
||||
//移除前面的空行
|
||||
if (line.startsWith(" ")) {
|
||||
line.remove(" ");
|
||||
}
|
||||
|
||||
//判断当前行是否是注释
|
||||
if (line.startsWith("/*")) {
|
||||
isNote = true;
|
||||
}
|
||||
|
||||
//注释部分
|
||||
if (isNote) {
|
||||
lineNotes++;
|
||||
} else {
|
||||
if (line.startsWith("//")) { //注释行
|
||||
lineNotes++;
|
||||
} else if (line.isEmpty()) { //空白行
|
||||
lineBlank++;
|
||||
} else { //代码行
|
||||
lineCode++;
|
||||
}
|
||||
}
|
||||
|
||||
//注释结束
|
||||
if (line.endsWith("*/")) {
|
||||
isNote = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmCountCode::on_btnOpenFile_clicked()
|
||||
{
|
||||
QString filter = QString("代码文件(%1)").arg(ui->txtFilter->text().trimmed());
|
||||
QStringList files = QFileDialog::getOpenFileNames(this, "选择文件", "./", filter);
|
||||
if (files.size() > 0) {
|
||||
ui->txtFile->setText(files.join("|"));
|
||||
countCode(files);
|
||||
}
|
||||
}
|
||||
|
||||
void frmCountCode::on_btnOpenPath_clicked()
|
||||
{
|
||||
QString path = QFileDialog::getExistingDirectory(this, "选择目录", "./", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
if (!path.isEmpty()) {
|
||||
ui->txtPath->setText(path);
|
||||
listFile.clear();
|
||||
countCode(path);
|
||||
countCode(listFile);
|
||||
}
|
||||
}
|
||||
|
||||
void frmCountCode::on_btnClear_clicked()
|
||||
{
|
||||
ui->txtCount->setText("0");
|
||||
ui->txtSize->setText("0");
|
||||
ui->txtRow->setText("0");
|
||||
|
||||
ui->txtCode->setText("0");
|
||||
ui->txtNote->setText("0");
|
||||
ui->txtBlank->setText("0");
|
||||
|
||||
ui->labPercentCode->setText("0%");
|
||||
ui->labPercentNote->setText("0%");
|
||||
ui->labPercentBlank->setText("0%");
|
||||
ui->tableWidget->setRowCount(0);
|
||||
}
|
||||
35
tool/countcode/frmcountcode.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef FRMCOUNTCODE_H
|
||||
#define FRMCOUNTCODE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class frmCountCode;
|
||||
}
|
||||
|
||||
class frmCountCode : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmCountCode(QWidget *parent = 0);
|
||||
~frmCountCode();
|
||||
|
||||
private:
|
||||
Ui::frmCountCode *ui;
|
||||
QStringList listFile;
|
||||
|
||||
private:
|
||||
void initForm();
|
||||
bool checkFile(const QString &fileName);
|
||||
void countCode(const QString &filePath);
|
||||
void countCode(const QStringList &files);
|
||||
void countCode(const QString &fileName, int &lineCode, int &lineBlank, int &lineNotes);
|
||||
|
||||
private slots:
|
||||
void on_btnOpenFile_clicked();
|
||||
void on_btnOpenPath_clicked();
|
||||
void on_btnClear_clicked();
|
||||
};
|
||||
|
||||
#endif // FRMCOUNTCODE_H
|
||||
411
tool/countcode/frmcountcode.ui
Normal file
@@ -0,0 +1,411 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmCountCode</class>
|
||||
<widget class="QWidget" name="frmCountCode">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidget"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<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 row="0" column="0" rowspan="3">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="3">
|
||||
<widget class="QLineEdit" name="txtCode">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="txtRow">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="txtNote">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLineEdit" name="txtBlank">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="txtCount">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="labPercentCode">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="labBlank">
|
||||
<property name="text">
|
||||
<string>空白行数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="txtSize">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<widget class="QLabel" name="labFilter">
|
||||
<property name="text">
|
||||
<string>过滤</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="labFile">
|
||||
<property name="text">
|
||||
<string>文件</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QLineEdit" name="txtPath">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<widget class="QLineEdit" name="txtFile">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLabel" name="labPath">
|
||||
<property name="text">
|
||||
<string>目录</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QLineEdit" name="txtFilter">
|
||||
<property name="text">
|
||||
<string>*.h *.cpp *.c *.cs *.java *.js</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="labPercentNote">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QLabel" name="labPercentBlank">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labCount">
|
||||
<property name="text">
|
||||
<string>文件数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="labCode">
|
||||
<property name="text">
|
||||
<string>代码行数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="labNote">
|
||||
<property name="text">
|
||||
<string>注释行数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labSize">
|
||||
<property name="text">
|
||||
<string>字节数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labRow">
|
||||
<property name="text">
|
||||
<string>总行数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="btnOpenFile">
|
||||
<property name="text">
|
||||
<string>打开文件</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="btnOpenPath">
|
||||
<property name="text">
|
||||
<string>打开目录</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="btnClear">
|
||||
<property name="text">
|
||||
<string>清空结果</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionOpen">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_files.png</normaloff>:/images/toolbar/ic_files.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择文件</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+O</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpenDir">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_folder.png</normaloff>:/images/toolbar/ic_folder.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择目录</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+O</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAbout">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_about.png</normaloff>:/images/toolbar/ic_about.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>关于</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClearModel">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_clean.png</normaloff>:/images/toolbar/ic_clean.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>清空列表</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClearModelLine">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_delete.png</normaloff>:/images/toolbar/ic_delete.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>删除选中行</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionChinese">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>中文</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnglish">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>English</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUTF8">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>UTF8</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGB18030">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>GB18030</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQuit">
|
||||
<property name="text">
|
||||
<string>退出</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Q</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>btnOpenFile</tabstop>
|
||||
<tabstop>btnOpenPath</tabstop>
|
||||
<tabstop>btnClear</tabstop>
|
||||
<tabstop>tableWidget</tabstop>
|
||||
<tabstop>txtCount</tabstop>
|
||||
<tabstop>txtSize</tabstop>
|
||||
<tabstop>txtRow</tabstop>
|
||||
<tabstop>txtCode</tabstop>
|
||||
<tabstop>txtNote</tabstop>
|
||||
<tabstop>txtBlank</tabstop>
|
||||
<tabstop>txtFile</tabstop>
|
||||
<tabstop>txtPath</tabstop>
|
||||
<tabstop>txtFilter</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
31
tool/countcode/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmcountcode.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmCountCode w;
|
||||
w.setWindowTitle("代码行数统计");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
17
tool/emailtool/emailtool.pro
Normal file
@@ -0,0 +1,17 @@
|
||||
QT += core gui network
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
|
||||
|
||||
TARGET = emailtool
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmemailtool.cpp sendemailthread.cpp
|
||||
HEADERS += frmemailtool.h sendemailthread.h
|
||||
FORMS += frmemailtool.ui
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD/../3rd_smtpclient
|
||||
include ($$PWD/../3rd_smtpclient/3rd_smtpclient.pri)
|
||||
104
tool/emailtool/frmemailtool.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmemailtool.h"
|
||||
#include "ui_frmemailtool.h"
|
||||
#include "qfiledialog.h"
|
||||
#include "qmessagebox.h"
|
||||
#include "sendemailthread.h"
|
||||
|
||||
frmEmailTool::frmEmailTool(QWidget *parent) : QWidget(parent), ui(new Ui::frmEmailTool)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
}
|
||||
|
||||
frmEmailTool::~frmEmailTool()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmEmailTool::initForm()
|
||||
{
|
||||
ui->cboxServer->setCurrentIndex(1);
|
||||
connect(SendEmailThread::Instance(), SIGNAL(receiveEmailResult(QString)),
|
||||
this, SLOT(receiveEmailResult(QString)));
|
||||
SendEmailThread::Instance()->start();
|
||||
}
|
||||
|
||||
void frmEmailTool::on_btnSend_clicked()
|
||||
{
|
||||
if (!check()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SendEmailThread::Instance()->setEmailTitle(ui->txtTitle->text());
|
||||
SendEmailThread::Instance()->setSendEmailAddr(ui->txtSenderAddr->text());
|
||||
SendEmailThread::Instance()->setSendEmailPwd(ui->txtSenderPwd->text());
|
||||
SendEmailThread::Instance()->setReceiveEmailAddr(ui->txtReceiverAddr->text());
|
||||
|
||||
//设置好上述配置后,以后只要调用Append方法即可发送邮件
|
||||
SendEmailThread::Instance()->append(ui->txtContent->toHtml(), ui->txtFileName->text());
|
||||
}
|
||||
|
||||
void frmEmailTool::on_btnSelect_clicked()
|
||||
{
|
||||
QFileDialog dialog(this);
|
||||
dialog.setFileMode(QFileDialog::ExistingFiles);
|
||||
|
||||
if (dialog.exec()) {
|
||||
ui->txtFileName->clear();
|
||||
QStringList files = dialog.selectedFiles();
|
||||
ui->txtFileName->setText(files.join(";"));
|
||||
}
|
||||
}
|
||||
|
||||
bool frmEmailTool::check()
|
||||
{
|
||||
if (ui->txtSenderAddr->text() == "") {
|
||||
QMessageBox::critical(this, "错误", "用户名不能为空!");
|
||||
ui->txtSenderAddr->setFocus();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ui->txtSenderPwd->text() == "") {
|
||||
QMessageBox::critical(this, "错误", "用户密码不能为空!");
|
||||
ui->txtSenderPwd->setFocus();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ui->txtSenderAddr->text() == "") {
|
||||
QMessageBox::critical(this, "错误", "发件人不能为空!");
|
||||
ui->txtSenderAddr->setFocus();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ui->txtReceiverAddr->text() == "") {
|
||||
QMessageBox::critical(this, "错误", "收件人不能为空!");
|
||||
ui->txtReceiverAddr->setFocus();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ui->txtTitle->text() == "") {
|
||||
QMessageBox::critical(this, "错误", "邮件标题不能为空!");
|
||||
ui->txtTitle->setFocus();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void frmEmailTool::on_cboxServer_currentIndexChanged(int index)
|
||||
{
|
||||
if (index == 2) {
|
||||
ui->cboxPort->setCurrentIndex(1);
|
||||
ui->ckSSL->setChecked(true);
|
||||
} else {
|
||||
ui->cboxPort->setCurrentIndex(0);
|
||||
ui->ckSSL->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
void frmEmailTool::receiveEmailResult(QString result)
|
||||
{
|
||||
QMessageBox::information(this, "提示", result);
|
||||
}
|
||||
35
tool/emailtool/frmemailtool.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef FRMEMAILTOOL_H
|
||||
#define FRMEMAILTOOL_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class frmEmailTool;
|
||||
}
|
||||
|
||||
class frmEmailTool : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmEmailTool(QWidget *parent = 0);
|
||||
~frmEmailTool();
|
||||
|
||||
private:
|
||||
Ui::frmEmailTool *ui;
|
||||
|
||||
private:
|
||||
bool check();
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
void receiveEmailResult(QString result);
|
||||
|
||||
private slots:
|
||||
void on_btnSend_clicked();
|
||||
void on_btnSelect_clicked();
|
||||
void on_cboxServer_currentIndexChanged(int index);
|
||||
};
|
||||
|
||||
#endif // FRMEMAILTOOL_H
|
||||
221
tool/emailtool/frmemailtool.ui
Normal file
@@ -0,0 +1,221 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmEmailTool</class>
|
||||
<widget class="QWidget" name="frmEmailTool">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>764</width>
|
||||
<height>578</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="4">
|
||||
<widget class="QPushButton" name="btnSend">
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QComboBox" name="cboxPort">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>25</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>465</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>587</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QCheckBox" name="ckSSL">
|
||||
<property name="text">
|
||||
<string>SSL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="labPort">
|
||||
<property name="text">
|
||||
<string>服务端口</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QPushButton" name="btnSelect">
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>浏览</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLineEdit" name="txtReceiverAddr">
|
||||
<property name="text">
|
||||
<string>feiyangqingyun@163.com;517216493@qq.com</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="3">
|
||||
<widget class="QLineEdit" name="txtFileName"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labTitle">
|
||||
<property name="text">
|
||||
<string>邮件标题</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="txtTitle">
|
||||
<property name="text">
|
||||
<string>测试邮件</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cboxServer">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>smtp.163.com</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>smtp.126.com</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>smtp.qq.com</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>smt.sina.com</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>smtp.sohu.com</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>smtp.139.com</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>smtp.189.com</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="labReceiverAddr">
|
||||
<property name="text">
|
||||
<string>收件地址</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labFileName">
|
||||
<property name="text">
|
||||
<string>选择附件</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labServer">
|
||||
<property name="text">
|
||||
<string>服务地址</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labSenderAddr">
|
||||
<property name="text">
|
||||
<string>用户名称</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="txtSenderAddr">
|
||||
<property name="text">
|
||||
<string>feiyangqingyun@126.com</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="labSenderPwd">
|
||||
<property name="text">
|
||||
<string>用户密码</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLineEdit" name="txtSenderPwd">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="txtContent">
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'SimSun'; font-size:9.07563pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'宋体'; font-size:11pt;">1</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、最短的爱情哲理小说:“</span><span style=" font-family:'宋体'; font-size:11pt;">你应该嫁给我啦?</span><span style=" font-family:'Times New Roman'; font-size:11pt;">” “ </span><span style=" font-family:'宋体'; font-size:11pt;">不</span><span style=" font-family:'Times New Roman'; font-size:11pt;">” </span><span style=" font-family:'宋体'; font-size:11pt;">于是他俩又继续幸福地生活在一起</span><span style=" font-family:'Times New Roman'; font-size:11pt;">!<br /></span><span style=" font-family:'宋体'; font-size:11pt;">2</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、近年来中国最精彩的写实小说,全文八个字:</span><span style=" font-family:'Times New Roman'; font-size:16pt; font-weight:600; font-style:italic; color:#ff007f;">此地钱多人傻速来</span><span style=" font-family:'Times New Roman'; font-size:11pt;"> 据说是发自杭州市宝石山下一出租房的汇款单上的简短附言,是该按摩女给家乡妹妹汇 款时随手涂鸦的,令无数专业作家汗颜!<br /></span><span style=" font-family:'宋体'; font-size:11pt;">3</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、最短的幽默小说 《夜》 男:疼么?女:恩!男:算了?女:别!</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'宋体'; font-size:11pt;">4</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、最短的荒诞小说:有一个面包走在街上,它觉得自己很饿,就把自己吃了。<br /></span><span style=" font-family:'宋体'; font-size:11pt;">5</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、世界最短言情小说:他死的那天,孩子出生了。<br /></span><span style=" font-family:'宋体'; font-size:11pt;">6</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、世界最短武侠小说:</span><span style=" font-family:'Times New Roman'; font-size:11pt; font-weight:600; color:#00aa00;">高手被豆腐砸死了</span><span style=" font-family:'Times New Roman'; font-size:11pt;">。<br /></span><span style=" font-family:'宋体'; font-size:11pt;">7</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、世界最短科幻小说:最后一个地球人坐在家里,突然响起了敲门声。<br /></span><span style=" font-family:'宋体'; font-size:11pt;">8</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、世界最短悬疑小说:生,死,生。<br /></span><span style=" font-family:'宋体'; font-size:11pt;">9</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、世界最短推理小说:他死了,一定曾经活过。 <br />1</span><span style=" font-family:'宋体'; font-size:11pt;">0</span><span style=" font-family:'Times New Roman'; font-size:11pt;">、世界最短恐怖小说:惊醒,身边躺着自己的尸体。</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>txtSenderAddr</tabstop>
|
||||
<tabstop>txtSenderPwd</tabstop>
|
||||
<tabstop>cboxServer</tabstop>
|
||||
<tabstop>cboxPort</tabstop>
|
||||
<tabstop>ckSSL</tabstop>
|
||||
<tabstop>txtTitle</tabstop>
|
||||
<tabstop>txtReceiverAddr</tabstop>
|
||||
<tabstop>btnSend</tabstop>
|
||||
<tabstop>txtFileName</tabstop>
|
||||
<tabstop>btnSelect</tabstop>
|
||||
<tabstop>txtContent</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
31
tool/emailtool/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmemailtool.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmEmailTool w;
|
||||
w.setWindowTitle("串口调试助手 V2021 (QQ: 517216493 WX: feiyangqingyun)");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
1
tool/emailtool/readme.txt
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>163<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>126<EFBFBD><EFBFBD><EFBFBD>䣬<EFBFBD><EFBFBD><EFBFBD>Ͷ˿ڶ<EFBFBD><EFBFBD><EFBFBD>25<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>SSLЭ<EFBFBD>飬<EFBFBD><EFBFBD>QQ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>SSLЭ<EFBFBD>飬<EFBFBD>˿<EFBFBD>Ϊ465<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>QQ<EFBFBD><EFBFBD><EFBFBD>䷢<EFBFBD>͵Ļ<EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>QQ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD>smtpЭ<EFBFBD>鿪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>QQ<EFBFBD><EFBFBD><EFBFBD>䷢<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ð<EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><EFBFBD>QQ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>п<EFBFBD><EFBFBD><EFBFBD>SMTP<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
150
tool/emailtool/sendemailthread.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include "sendemailthread.h"
|
||||
#include "smtpmime.h"
|
||||
|
||||
#pragma execution_character_set("utf-8")
|
||||
#define TIMEMS qPrintable(QTime::currentTime().toString("hh:mm:ss zzz"))
|
||||
|
||||
QScopedPointer<SendEmailThread> SendEmailThread::self;
|
||||
SendEmailThread *SendEmailThread::Instance()
|
||||
{
|
||||
if (self.isNull()) {
|
||||
static QMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
if (self.isNull()) {
|
||||
self.reset(new SendEmailThread);
|
||||
}
|
||||
}
|
||||
|
||||
return self.data();
|
||||
}
|
||||
|
||||
SendEmailThread::SendEmailThread(QObject *parent) : QThread(parent)
|
||||
{
|
||||
stopped = false;
|
||||
emialTitle = "邮件标题";
|
||||
sendEmailAddr = "feiyangqingyun@126.com";
|
||||
sendEmailPwd = "123456789";
|
||||
receiveEmailAddr = "feiyangqingyun@163.com;517216493@qq.com";
|
||||
contents.clear();
|
||||
fileNames.clear();
|
||||
}
|
||||
|
||||
SendEmailThread::~SendEmailThread()
|
||||
{
|
||||
this->stop();
|
||||
this->wait(1000);
|
||||
}
|
||||
|
||||
void SendEmailThread::run()
|
||||
{
|
||||
while (!stopped) {
|
||||
int count = contents.count();
|
||||
if (count > 0) {
|
||||
mutex.lock();
|
||||
QString content = contents.takeFirst();
|
||||
QString fileName = fileNames.takeFirst();
|
||||
mutex.unlock();
|
||||
|
||||
QString result;
|
||||
QStringList list = sendEmailAddr.split("@");
|
||||
QString tempSMTP = list.at(1).split(".").at(0);
|
||||
int tempPort = 25;
|
||||
|
||||
//QQ邮箱端口号为465,必须启用SSL协议.
|
||||
if (tempSMTP.toUpper() == "QQ") {
|
||||
tempPort = 465;
|
||||
}
|
||||
|
||||
SmtpClient smtp(QString("smtp.%1.com").arg(tempSMTP), tempPort, tempPort == 25 ? SmtpClient::TcpConnection : SmtpClient::SslConnection);
|
||||
smtp.setUser(sendEmailAddr);
|
||||
smtp.setPassword(sendEmailPwd);
|
||||
|
||||
//构建邮件主题,包含发件人收件人附件等.
|
||||
MimeMessage message;
|
||||
message.setSender(new EmailAddress(sendEmailAddr));
|
||||
|
||||
//逐个添加收件人
|
||||
QStringList receiver = receiveEmailAddr.split(';');
|
||||
for (int i = 0; i < receiver.size(); i++) {
|
||||
message.addRecipient(new EmailAddress(receiver.at(i)));
|
||||
}
|
||||
|
||||
//构建邮件标题
|
||||
message.setSubject(emialTitle);
|
||||
|
||||
//构建邮件正文
|
||||
MimeHtml text;
|
||||
text.setHtml(content);
|
||||
message.addPart(&text);
|
||||
|
||||
//构建附件-报警图像
|
||||
if (fileName.length() > 0) {
|
||||
QStringList attas = fileName.split(";");
|
||||
foreach (QString tempAtta, attas) {
|
||||
QFile *file = new QFile(tempAtta);
|
||||
if (file->exists()) {
|
||||
message.addPart(new MimeAttachment(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!smtp.connectToHost()) {
|
||||
result = "邮件服务器连接失败";
|
||||
} else {
|
||||
if (!smtp.login()) {
|
||||
result = "邮件用户登录失败";
|
||||
} else {
|
||||
if (!smtp.sendMail(message)) {
|
||||
result = "邮件发送失败";
|
||||
} else {
|
||||
result = "邮件发送成功";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
smtp.quit();
|
||||
if (!result.isEmpty()) {
|
||||
emit receiveEmailResult(result);
|
||||
}
|
||||
|
||||
msleep(1000);
|
||||
}
|
||||
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
stopped = false;
|
||||
}
|
||||
|
||||
void SendEmailThread::stop()
|
||||
{
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
void SendEmailThread::setEmailTitle(const QString &emailTitle)
|
||||
{
|
||||
this->emialTitle = emailTitle;
|
||||
}
|
||||
|
||||
void SendEmailThread::setSendEmailAddr(const QString &sendEmailAddr)
|
||||
{
|
||||
this->sendEmailAddr = sendEmailAddr;
|
||||
}
|
||||
|
||||
void SendEmailThread::setSendEmailPwd(const QString &sendEmailPwd)
|
||||
{
|
||||
this->sendEmailPwd = sendEmailPwd;
|
||||
}
|
||||
|
||||
void SendEmailThread::setReceiveEmailAddr(const QString &receiveEmailAddr)
|
||||
{
|
||||
this->receiveEmailAddr = receiveEmailAddr;
|
||||
}
|
||||
|
||||
void SendEmailThread::append(const QString &content, const QString &fileName)
|
||||
{
|
||||
mutex.lock();
|
||||
contents.append(content);
|
||||
fileNames.append(fileName);
|
||||
mutex.unlock();
|
||||
}
|
||||
44
tool/emailtool/sendemailthread.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef SENDEMAILTHREAD_H
|
||||
#define SENDEMAILTHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QStringList>
|
||||
|
||||
class SendEmailThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static SendEmailThread *Instance();
|
||||
explicit SendEmailThread(QObject *parent = 0);
|
||||
~SendEmailThread();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
static QScopedPointer<SendEmailThread> self;
|
||||
QMutex mutex;
|
||||
volatile bool stopped;
|
||||
|
||||
QString emialTitle; //邮件标题
|
||||
QString sendEmailAddr; //发件人邮箱
|
||||
QString sendEmailPwd; //发件人密码
|
||||
QString receiveEmailAddr; //收件人邮箱,可多个中间;隔开
|
||||
QStringList contents; //正文内容
|
||||
QStringList fileNames; //附件
|
||||
|
||||
signals:
|
||||
void receiveEmailResult(const QString &result);
|
||||
|
||||
public slots:
|
||||
void stop();
|
||||
void setEmailTitle(const QString &emailTitle);
|
||||
void setSendEmailAddr(const QString &sendEmailAddr);
|
||||
void setSendEmailPwd(const QString &sendEmailPwd);
|
||||
void setReceiveEmailAddr(const QString &receiveEmailAddr);
|
||||
void append(const QString &content, const QString &fileName);
|
||||
|
||||
};
|
||||
|
||||
#endif // SENDEMAILTHREAD_H
|
||||
122
tool/keydemo/appkey.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "appkey.h"
|
||||
#include "qmutex.h"
|
||||
#include "qfile.h"
|
||||
#include "qtimer.h"
|
||||
#include "qdatetime.h"
|
||||
#include "qapplication.h"
|
||||
#include "qmessagebox.h"
|
||||
|
||||
AppKey *AppKey::self = NULL;
|
||||
AppKey *AppKey::Instance()
|
||||
{
|
||||
if (!self) {
|
||||
QMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
if (!self) {
|
||||
self = new AppKey;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
AppKey::AppKey(QObject *parent) : QObject(parent)
|
||||
{
|
||||
keyData = "";
|
||||
keyUseDate = false;
|
||||
keyDate = "2017-01-01";
|
||||
keyUseRun = false;
|
||||
keyRun = 1;
|
||||
keyUseCount = false;
|
||||
keyCount = 10;
|
||||
|
||||
timer = new QTimer(this);
|
||||
timer->setInterval(1000);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(checkTime()));
|
||||
startTime = QDateTime::currentDateTime();
|
||||
}
|
||||
|
||||
void AppKey::start()
|
||||
{
|
||||
//判断密钥文件是否存在,不存在则从资源文件复制出来,同时需要设置文件写权限
|
||||
QString keyName = qApp->applicationDirPath() + "/key.db";
|
||||
QFile keyFile(keyName);
|
||||
if (!keyFile.exists() || keyFile.size() == 0) {
|
||||
QMessageBox::critical(0, "错误", "密钥文件丢失,请联系供应商!");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//读取密钥文件
|
||||
keyFile.open(QFile::ReadOnly);
|
||||
keyData = keyFile.readLine();
|
||||
keyFile.close();
|
||||
|
||||
//将从注册码文件中的密文解密,与当前时间比较是否到期
|
||||
keyData = getXorEncryptDecrypt(keyData, 110);
|
||||
QStringList data = keyData.split("|");
|
||||
|
||||
if (data.count() != 6) {
|
||||
QMessageBox::critical(0, "错误", "注册码文件已损坏,程序将自动关闭!");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
keyUseDate = (data.at(0) == "1");
|
||||
keyDate = data.at(1);
|
||||
keyUseRun = (data.at(2) == "1");
|
||||
keyRun = data.at(3).toInt();
|
||||
keyUseCount = (data.at(4) == "1");
|
||||
keyCount = data.at(5).toInt();
|
||||
|
||||
//如果启用了时间限制
|
||||
if (keyUseDate) {
|
||||
QString nowDate = QDate::currentDate().toString("yyyy-MM-dd");
|
||||
if (nowDate > keyDate) {
|
||||
QMessageBox::critical(0, "错误", "软件已到期,请联系供应商更新注册码!");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
//如果启用了运行时间显示
|
||||
if (keyUseRun) {
|
||||
timer->start();
|
||||
}
|
||||
}
|
||||
|
||||
void AppKey::stop()
|
||||
{
|
||||
timer->stop();
|
||||
}
|
||||
|
||||
void AppKey::checkTime()
|
||||
{
|
||||
//找出当前时间与首次启动时间比较
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
if (startTime.secsTo(now) >= (keyRun * 60)) {
|
||||
QMessageBox::critical(0, "错误", "试运行时间已到,请联系供应商更新注册码!");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
QString AppKey::getXorEncryptDecrypt(const QString &data, char key)
|
||||
{
|
||||
//采用异或加密,也可以自行更改算法
|
||||
QByteArray buffer = data.toLatin1();
|
||||
int size = buffer.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
buffer[i] = buffer.at(i) ^ key;
|
||||
}
|
||||
|
||||
return QLatin1String(buffer);
|
||||
}
|
||||
|
||||
bool AppKey::checkCount(int count)
|
||||
{
|
||||
if (keyUseCount) {
|
||||
if (count >= keyCount) {
|
||||
QMessageBox::critical(0, "错误", "设备数量超过限制,请联系供应商更新注册码!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
40
tool/keydemo/appkey.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef APPKEY_H
|
||||
#define APPKEY_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
|
||||
class QTimer;
|
||||
|
||||
class AppKey : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static AppKey *Instance();
|
||||
explicit AppKey(QObject *parent = 0);
|
||||
|
||||
private:
|
||||
static AppKey *self;
|
||||
|
||||
QString keyData; //注册码密文
|
||||
bool keyUseDate; //是否启用运行日期时间限制
|
||||
QString keyDate; //到期时间字符串
|
||||
bool keyUseRun; //是否启用可运行时间限制
|
||||
int keyRun; //可运行时间
|
||||
bool keyUseCount; //是否启用设备数量限制
|
||||
int keyCount; //设备限制数量
|
||||
|
||||
QTimer *timer; //定时器判断是否运行超时
|
||||
QDateTime startTime; //程序启动时间
|
||||
|
||||
private slots:
|
||||
void checkTime();
|
||||
QString getXorEncryptDecrypt(const QString &data, char key);
|
||||
|
||||
public slots:
|
||||
void start();
|
||||
void stop();
|
||||
bool checkCount(int count);
|
||||
};
|
||||
|
||||
#endif // APPKEY_H
|
||||
22
tool/keydemo/frmmain.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "frmmain.h"
|
||||
#include "ui_frmmain.h"
|
||||
#include "appkey.h"
|
||||
|
||||
frmMain::frmMain(QWidget *parent) : QWidget(parent), ui(new Ui::frmMain)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
frmMain::~frmMain()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmMain::on_btnAdd_clicked()
|
||||
{
|
||||
QString name = ui->lineEdit->text().trimmed();
|
||||
ui->listWidget->addItem(name);
|
||||
|
||||
//计算当前设备数量多少
|
||||
AppKey::Instance()->checkCount(ui->listWidget->count());
|
||||
}
|
||||
25
tool/keydemo/frmmain.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef FRMMAIN_H
|
||||
#define FRMMAIN_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class frmMain;
|
||||
}
|
||||
|
||||
class frmMain : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmMain(QWidget *parent = 0);
|
||||
~frmMain();
|
||||
|
||||
private:
|
||||
Ui::frmMain *ui;
|
||||
|
||||
private slots:
|
||||
void on_btnAdd_clicked();
|
||||
};
|
||||
|
||||
#endif // FRMMAIN_H
|
||||
39
tool/keydemo/frmmain.ui
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmMain</class>
|
||||
<widget class="QWidget" name="frmMain">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>frmMain</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QListWidget" name="listWidget"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLineEdit" name="lineEdit">
|
||||
<property name="text">
|
||||
<string>测试设备</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="btnAdd">
|
||||
<property name="text">
|
||||
<string>添加</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
18
tool/keydemo/keydemo.pro
Normal file
@@ -0,0 +1,18 @@
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
|
||||
|
||||
TARGET = keydemo
|
||||
TEMPLATE = app
|
||||
MOC_DIR = temp/moc
|
||||
RCC_DIR = temp/rcc
|
||||
UI_DIR = temp/ui
|
||||
OBJECTS_DIR = temp/obj
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmmain.cpp appkey.cpp
|
||||
HEADERS += frmmain.h appkey.h
|
||||
FORMS += frmmain.ui
|
||||
|
||||
34
tool/keydemo/main.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
#include "frmmain.h"
|
||||
#include "appkey.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
//启动密钥服务类
|
||||
AppKey::Instance()->start();
|
||||
|
||||
frmMain w;
|
||||
w.setWindowTitle("密钥使用示例");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
112
tool/keytool/frmmain.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "frmmain.h"
|
||||
#include "ui_frmmain.h"
|
||||
#include "qmessagebox.h"
|
||||
#include "qfile.h"
|
||||
#include "qprocess.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
frmMain::frmMain(QWidget *parent) : QWidget(parent), ui(new Ui::frmMain)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
qDebug() << this->getCpuName() << this->getCpuId() << this->getDiskNum();
|
||||
}
|
||||
|
||||
frmMain::~frmMain()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmMain::initForm()
|
||||
{
|
||||
QStringList min;
|
||||
min << "1" << "5" << "10" << "20" << "30";
|
||||
for (int i = 1; i <= 24; i++) {
|
||||
min << QString::number(i * 60);
|
||||
}
|
||||
|
||||
ui->cboxMin->addItems(min);
|
||||
ui->cboxMin->setCurrentIndex(1);
|
||||
ui->dateEdit->setDate(QDate::currentDate());
|
||||
|
||||
for (int i = 5; i <= 150; i = i + 5) {
|
||||
ui->cboxCount->addItem(QString("%1").arg(i));
|
||||
}
|
||||
}
|
||||
|
||||
QString frmMain::getWMIC(const QString &cmd)
|
||||
{
|
||||
//获取cpu名称:wmic cpu get Name
|
||||
//获取cpu核心数:wmic cpu get NumberOfCores
|
||||
//获取cpu线程数:wmic cpu get NumberOfLogicalProcessors
|
||||
//查询cpu序列号:wmic cpu get processorid
|
||||
//查询主板序列号:wmic baseboard get serialnumber
|
||||
//查询BIOS序列号:wmic bios get serialnumber
|
||||
//查看硬盘:wmic diskdrive get serialnumber
|
||||
QProcess p;
|
||||
p.start(cmd);
|
||||
p.waitForFinished();
|
||||
QString result = QString::fromLocal8Bit(p.readAllStandardOutput());
|
||||
QStringList list = cmd.split(" ");
|
||||
result = result.remove(list.last(), Qt::CaseInsensitive);
|
||||
result = result.replace("\r", "");
|
||||
result = result.replace("\n", "");
|
||||
result = result.simplified();
|
||||
return result;
|
||||
}
|
||||
|
||||
QString frmMain::getCpuName()
|
||||
{
|
||||
return getWMIC("wmic cpu get name");
|
||||
}
|
||||
|
||||
QString frmMain::getCpuId()
|
||||
{
|
||||
return getWMIC("wmic cpu get processorid");
|
||||
}
|
||||
|
||||
QString frmMain::getDiskNum()
|
||||
{
|
||||
return getWMIC("wmic diskdrive where index=0 get serialnumber");
|
||||
}
|
||||
|
||||
QString frmMain::getXorEncryptDecrypt(const QString &data, char key)
|
||||
{
|
||||
//采用异或加密,也可以自行更改算法
|
||||
QByteArray buffer = data.toLatin1();
|
||||
int size = buffer.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
buffer[i] = buffer.at(i) ^ key;
|
||||
}
|
||||
|
||||
return QLatin1String(buffer);
|
||||
}
|
||||
|
||||
void frmMain::on_btnOk_clicked()
|
||||
{
|
||||
bool useDate = ui->ckDate->isChecked();
|
||||
bool useRun = ui->ckRun->isChecked();
|
||||
bool useCount = ui->ckCount->isChecked();
|
||||
|
||||
if (!useDate && !useRun && !useCount) {
|
||||
if (QMessageBox::question(this, "询问", "确定要生成没有任何限制的密钥吗?") != QMessageBox::Yes) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QString strDate = ui->dateEdit->date().toString("yyyy-MM-dd");
|
||||
QString strRun = ui->cboxMin->currentText();
|
||||
QString strCount = ui->cboxCount->currentText();
|
||||
QString key = QString("%1|%2|%3|%4|%5|%6").arg(useDate).arg(strDate).arg(useRun).arg(strRun).arg(useCount).arg(strCount);
|
||||
|
||||
QFile file(QApplication::applicationDirPath() + "/key.db");
|
||||
file.open(QFile::WriteOnly | QIODevice::Text);
|
||||
file.write(getXorEncryptDecrypt(key, 110).toLatin1());
|
||||
file.close();
|
||||
QMessageBox::information(this, "提示", "生成密钥成功,将 key.db 文件拷贝到对应目录即可!");
|
||||
}
|
||||
|
||||
void frmMain::on_btnClose_clicked()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
34
tool/keytool/frmmain.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef FRMMAIN_H
|
||||
#define FRMMAIN_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class frmMain;
|
||||
}
|
||||
|
||||
class frmMain : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmMain(QWidget *parent = 0);
|
||||
~frmMain();
|
||||
|
||||
private:
|
||||
Ui::frmMain *ui;
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
QString getWMIC(const QString &cmd);
|
||||
QString getCpuName();
|
||||
QString getCpuId();
|
||||
QString getDiskNum();
|
||||
QString getXorEncryptDecrypt(const QString &data, char key);
|
||||
|
||||
private slots:
|
||||
void on_btnOk_clicked();
|
||||
void on_btnClose_clicked();
|
||||
};
|
||||
|
||||
#endif // FRMMAIN_H
|
||||
156
tool/keytool/frmmain.ui
Normal file
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmMain</class>
|
||||
<widget class="QWidget" name="frmMain">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>334</width>
|
||||
<height>129</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>frmMain</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1" rowspan="2" colspan="2">
|
||||
<widget class="QDateEdit" name="dateEdit">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="displayFormat">
|
||||
<string>yyyy年MM月dd日</string>
|
||||
</property>
|
||||
<property name="calendarPopup">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" rowspan="2">
|
||||
<widget class="QPushButton" name="btnOk">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>生成</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="ckDate">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>时间限制</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="ckCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>数量限制</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="cboxCount">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="btnClose">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>关闭</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="ckRun">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>运行限制</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="cboxMin">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>分钟自动关闭</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="4" rowspan="5">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>108</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||