Commit b747207d authored by Acker's avatar Acker

init commit

parents
Pipeline #8088 failed with stage
in 15 seconds
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
# TopLinker
# ----------------------------------------------------------------------------
**/dist/
!party3/QtitanDataGrid/bin/QtitanBase*.dll
!party3/QtitanDataGrid/bin/QtitanBase*.pdb
!party3/QtitanDataGrid/bin/QtitanGrid*.dll
!party3/QtitanDataGrid/bin/QtitanGrid*.pdb
!party3/QtitanDataGrid/bin/libQtitanBase.so.1.0.0
!party3/QtitanDataGrid/bin/libQtitanGrid.so.5.22.0
party3/QtitanDataGrid/bin/QtitanGridd5.exp
!src/lib/*.qm
# SINCPM
sincpm-lock.json
# Stages
stages:
- build
- test
- publish
# Cache
cache:
paths:
- dist/
# Jobs
windows_develop:
stage: build
only:
- develop
tags:
- windows7_cd
variables:
QT_BIN: C:/DevTools/Qt5.6.3/5.6.3/msvc2015/bin
QTCREATOR_BIN: C:/DevTools/Qt5.6.3/Tools/QtCreator/bin
script:
- python ci/build.py -p %CI_PROJECT_DIR%/src/%CI_PROJECT_NAME%.pro -b %CI_PROJECT_DIR%/build/%CI_COMMIT_REF_NAME%/%CI_JOB_NAME% -m release
linux_develop:
stage: build
only:
- develop
tags:
- centos6_cd
variables:
QT_BIN: /opt/Qt5.6.3/5.6.3/gcc_64/bin
script:
- python ci/build.py -p $CI_PROJECT_DIR/src/$CI_PROJECT_NAME.pro -b $CI_PROJECT_DIR/build/$CI_COMMIT_REF_NAME/$CI_JOB_NAME -m release
windows_master:
stage: build
only:
- master
tags:
- windows7_cd
variables:
QT_BIN: C:/DevTools/Qt5.6.3/5.6.3/msvc2015/bin
QTCREATOR_BIN: C:/DevTools/Qt5.6.3/Tools/QtCreator/bin
script:
- python ci/build.py -p %CI_PROJECT_DIR%/src/%CI_PROJECT_NAME%.pro -b %CI_PROJECT_DIR%/build/%CI_COMMIT_REF_NAME%/%CI_JOB_NAME% -m release
- python ci/build.py -p %CI_PROJECT_DIR%/src/%CI_PROJECT_NAME%.pro -b %CI_PROJECT_DIR%/build/%CI_COMMIT_REF_NAME%/%CI_JOB_NAME% -m debug
- python ci/publish.py -p topikm6-mqtt
- python ci/publish.py -p topikm6-mqtt-debug
linux_master:
stage: build
only:
- master
tags:
- centos6_cd
variables:
QT_BIN: /opt/Qt5.6.3/5.6.3/gcc_64/bin
script:
- python ci/build.py -p $CI_PROJECT_DIR/src/$CI_PROJECT_NAME.pro -b $CI_PROJECT_DIR/build/$CI_COMMIT_REF_NAME/$CI_JOB_NAME -m release
- python ci/publish.py -p topikm6-mqtt
# topikm6-twidget
[![pipeline status](http://gitlab.topibd.net/topikm6/topikm6-twidget/badges/master/pipeline.svg)](http://gitlab.topibd.net/topikm6/topikm6-twidget/commits/master)
[![pipeline status](http://gitlab.topibd.net/topikm6/topikm6-twidget/badges/develop/pipeline.svg)](http://gitlab.topibd.net/topikm6/topikm6-twidget/commits/develop)
## 如何发布?
### CI发布(推荐)
默认规则:当将代码从develop分支合并到master分支,进行包发布。
0. 修改sincpm.json中的版本号
1. 修改src/lib/lib.pro中的版本号
2. 在CHANGELOG.md中添加新版本的发布日志
3. 将代码从develop分支合并到master分支
### 手动发布(不推荐)
0. (若未安装sincpm) 安装[sincpm](http://gitlab.topibd.net/topsin/topsin-sincpm/releases),配置好环境变量
1. 修改sincpm.json中的版本号
2. 修改src/lib/lib.pro中的版本号
3. 在CHANGELOG.md中添加新版本的发布日志
4. 在根目录下打包
```bash
sincpm package xxx
sincpm package xxx-debug
```
5. 在sincpm的local目录下上传包,例如
```bash
cd local
cd xxx
sincpm upload [xxx]-[1.0.0]-[windows-x86-msvc2015]-[qt5.6.3]
```
\ No newline at end of file
'''
@File: build.py
@Description: CI Build Script
@Author: leon.li(l2m2lq@gmail.com)
@Date: 2019-09-12 08:53:45
'''
import argparse
import sys
import qtciutil
import os
import subprocess
def sincpm_bin(cmd):
return qtciutil.common_cmd('SINCPM_BIN', cmd)
def sincpm_update():
# check sincpm.json if exists
ci_script_dir = os.path.dirname(os.path.realpath(__file__))
filepath = os.path.join(ci_script_dir, "../sincpm.json")
if not os.path.isfile(filepath):
raise qtciutil.QtCiUtilError("no sincpm.json found.")
# get platform infomation
qt_verison_str = qtciutil.qt_version()
qmake_spec_str = qtciutil.qmake_spec()
compiler_str = qmake_spec_str.split('-')[1]
if compiler_str == 'g++':
compiler_str = 'gcc'
os_system = qtciutil.platform_system()
arch_str = 'x64'
if os_system == 'windows':
arch_str = 'x86'
# sincpm update
update_args = [sincpm_bin('sincpm'), 'update']
update_args.append('--os=%s' % os_system)
update_args.append('--qt=%s' % qt_verison_str)
update_args.append('--compiler=%s' % compiler_str)
update_args.append('--arch=%s' % arch_str)
print("update_args: ", update_args)
pinfo = subprocess.run(update_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if pinfo.returncode != 0:
raise qtciutil.QtCiUtilError("sincpm update failed.")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Build Arg Parser')
parser.add_argument('--pro_file', '-p', type=str, required=True,
help='pro path', metavar='$CI_PROJECT_DIR/src/something.pro')
parser.add_argument('--build_dir', '-b', type=str, required=True,
help='build directory', metavar='$CI_PROJECT_DIR/build')
parser.add_argument('--mode', '-m', type=str, required=True,
help='debug or release', metavar='release')
args = vars(parser.parse_args())
pro_file = args['pro_file']
build_dir = args['build_dir']
mode = args['mode']
sincpm_update()
qtciutil.build(pro_file, build_dir, mode)
'''
@File: publish.py
@Description: CI Publish Script
@Author: leon.li(l2m2lq@gmail.com)
@Date: 2019-09-12 14:05:07
'''
import platform
import os
import argparse
import sys
import subprocess
import glob
import re
import json
import qtciutil
def sincpm_bin(cmd):
return qtciutil.common_cmd('SINCPM_BIN', cmd)
def sincpm_publish(pkg_name):
# check sincpm.json if exists
ci_script_dir = os.path.dirname(os.path.realpath(__file__))
filepath = os.path.join(ci_script_dir, "../sincpm.json")
if not os.path.isfile(filepath):
raise qtciutil.QtCiUtilError("no sincpm.json found.")
# get platform infomation
qt_verison_str = qtciutil.qt_version()
qmake_spec_str = qtciutil.qmake_spec()
compiler_str = qmake_spec_str.split('-')[1]
if compiler_str == 'g++':
compiler_str = 'gcc'
os_system = qtciutil.platform_system()
arch_str = 'x64'
if os_system == 'windows':
arch_str = 'x86'
# sincpm package
package_args = [sincpm_bin('sincpm'), 'package']
package_args.append('--os=%s' % os_system)
package_args.append('--qt=%s' % qt_verison_str)
package_args.append('--compiler=%s' % compiler_str)
package_args.append('--arch=%s' % arch_str)
package_args.append(pkg_name)
print("package_args: ", package_args)
pinfo = subprocess.run(package_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if pinfo.returncode != 0:
raise qtciutil.QtCiUtilError("sincpm pakcage failed.")
output = pinfo.stdout.decode('utf-8')
print("sincpm pakcage output: %s" % output)
m = re.search(r'package to "(.*)/(.*)"', output)
if not m:
raise qtciutil.QtCiUtilError("sincpm package failed. No expected output.")
# sincpm upload
local_dir = m.group(1)
pkg_dir = m.group(2)
os.chdir(local_dir)
pinfo = subprocess.run([sincpm_bin('sincpm'), 'upload', pkg_dir],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if pinfo.returncode != 0:
raise qtciutil.QtCiUtilError("sincpm upload failed.")
m = re.search(r'error: ', pinfo.stdout.decode('utf-8'), re.IGNORECASE)
if m:
raise qtciutil.QtCiUtilError("The upload result contains an error message. %s" % pinfo.stdout.decode('utf-8'))
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Publish Arg Parser')
parser.add_argument('--package_name', '-p', type=str, required=True,
help='package name', metavar='topikm6-tpm')
args = vars(parser.parse_args())
package_name = args['package_name']
sincpm_publish(package_name)
print("Successfully published.")
\ No newline at end of file
'''
@File: test.py
@Description: CI Test Script
@Author: leon.li(l2m2lq@gmail.com)
@Date: 2019-09-12 14:04:39
'''
import argparse
import qtciutil
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Build Arg Parser')
parser.add_argument('--pro_file', '-p', type=str, required=True,
help='pro path', metavar='$CI_PROJECT_DIR/test/something.pro')
parser.add_argument('--build_dir', '-b', type=str, required=True,
help='build directory', metavar='$CI_PROJECT_DIR/build')
parser.add_argument('--dist_dir', '-d', type=str, required=True,
help='dist directory', metavar='$CI_PROJECT_DIR/dist')
args = vars(parser.parse_args())
pro_file = args['pro_file']
build_dir = args['build_dir']
dist_dir = args['dist_dir']
qtciutil.unit_test(pro_file, build_dir, dist_dir)
\ No newline at end of file
/*
* qmqtt.h - qmqtt library heaer
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_H
#define QMQTT_H
#include "qmqtt_message.h"
#include "qmqtt_client.h"
#endif // QMQTT_H
/*
* qmqtt_client.h - qmqtt client header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_CLIENT_H
#define QMQTT_CLIENT_H
#include "qmqtt_global.h"
#include <QObject>
#include <QString>
#include <QHostAddress>
#include <QByteArray>
#include <QAbstractSocket>
#include <QScopedPointer>
#ifdef QT_WEBSOCKETS_LIB
#include <QWebSocket>
#endif // QT_WEBSOCKETS_LIB
#ifndef QT_NO_SSL
QT_FORWARD_DECLARE_CLASS(QSslConfiguration)
#endif // QT_NO_SSL
namespace QMQTT {
static const quint8 LIBRARY_VERSION_MAJOR = 0;
static const quint8 LIBRARY_VERSION_MINOR = 3;
static const quint8 LIBRARY_VERSION_REVISION = 1;
//static const char* LIBRARY_VERSION = "0.3.1";
enum MQTTVersion
{
V3_1_0 = 3,
V3_1_1 = 4
};
enum ConnectionState
{
STATE_INIT = 0,
STATE_CONNECTING,
STATE_CONNECTED,
STATE_DISCONNECTED
};
enum ClientError
{
UnknownError = 0,
SocketConnectionRefusedError,
SocketRemoteHostClosedError,
SocketHostNotFoundError,
SocketAccessError,
SocketResourceError,
SocketTimeoutError,
SocketDatagramTooLargeError,
SocketNetworkError,
SocketAddressInUseError,
SocketAddressNotAvailableError,
SocketUnsupportedSocketOperationError,
SocketUnfinishedSocketOperationError,
SocketProxyAuthenticationRequiredError,
SocketSslHandshakeFailedError,
SocketProxyConnectionRefusedError,
SocketProxyConnectionClosedError,
SocketProxyConnectionTimeoutError,
SocketProxyNotFoundError,
SocketProxyProtocolError,
SocketOperationError,
SocketSslInternalError,
SocketSslInvalidUserDataError,
SocketTemporaryError,
MqttUnacceptableProtocolVersionError=1<<16,
MqttIdentifierRejectedError,
MqttServerUnavailableError,
MqttBadUserNameOrPasswordError,
MqttNotAuthorizedError,
MqttNoPingResponse
};
class ClientPrivate;
class Message;
class Frame;
class NetworkInterface;
class Q_MQTT_EXPORT Client : public QObject
{
Q_OBJECT
Q_PROPERTY(quint16 _port READ port WRITE setPort)
Q_PROPERTY(QHostAddress _host READ host WRITE setHost)
Q_PROPERTY(QString _hostName READ hostName WRITE setHostName)
Q_PROPERTY(QString _clientId READ clientId WRITE setClientId)
Q_PROPERTY(QString _username READ username WRITE setUsername)
Q_PROPERTY(QByteArray _password READ password WRITE setPassword)
Q_PROPERTY(quint16 _keepAlive READ keepAlive WRITE setKeepAlive)
Q_PROPERTY(MQTTVersion _version READ version WRITE setVersion)
Q_PROPERTY(bool _autoReconnect READ autoReconnect WRITE setAutoReconnect)
Q_PROPERTY(int _autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval)
Q_PROPERTY(bool _cleanSession READ cleanSession WRITE setCleanSession)
Q_PROPERTY(QString _willTopic READ willTopic WRITE setWillTopic)
Q_PROPERTY(quint8 _willQos READ willQos WRITE setWillQos)
Q_PROPERTY(bool _willRetain READ willRetain WRITE setWillRetain)
Q_PROPERTY(QByteArray _willMessage READ willMessage WRITE setWillMessage)
Q_PROPERTY(QString _connectionState READ connectionState)
public:
Client(const QHostAddress& host = QHostAddress::LocalHost,
const quint16 port = 1883,
QObject* parent = NULL);
#ifndef QT_NO_SSL
Client(const QString& hostName,
const quint16 port,
const QSslConfiguration& config,
const bool ignoreSelfSigned=false,
QObject* parent = NULL);
#endif // QT_NO_SSL
// This function is provided for backward compatibility with older versions of QMQTT.
// If the ssl parameter is true, this function will load a private key ('cert.key') and a local
// certificate ('cert.crt') from the current working directory. It will also set PeerVerifyMode
// to None. This may not be the safest way to set up a SSL connection.
Client(const QString& hostName,
const quint16 port,
const bool ssl,
const bool ignoreSelfSigned,
QObject* parent = NULL);
#ifdef QT_WEBSOCKETS_LIB
// Create a connection over websockets
Client(const QString& url,
const QString& origin,
QWebSocketProtocol::Version version,
bool ignoreSelfSigned = false,
QObject* parent = NULL);
Client(const QString& url,
const QString& origin,
QWebSocketProtocol::Version version,
const QSslConfiguration& config,
const bool ignoreSelfSigned = false,
QObject* parent = NULL);
#endif // QT_WEBSOCKETS_LIB
// for testing purposes only
Client(NetworkInterface* network,
const QHostAddress& host = QHostAddress::LocalHost,
const quint16 port = 1883,
QObject* parent = NULL);
virtual ~Client();
QHostAddress host() const;
QString hostName() const;
quint16 port() const;
QString clientId() const;
QString username() const;
QByteArray password() const;
QMQTT::MQTTVersion version() const;
quint16 keepAlive() const;
bool cleanSession() const;
bool autoReconnect() const;
int autoReconnectInterval() const;
ConnectionState connectionState() const;
QString willTopic() const;
quint8 willQos() const;
bool willRetain() const;
QByteArray willMessage() const;
bool isConnectedToHost() const;
public slots:
void setHost(const QHostAddress& host);
void setHostName(const QString& hostName);
void setPort(const quint16 port);
void setClientId(const QString& clientId);
void setUsername(const QString& username);
void setPassword(const QByteArray& password);
void setVersion(const MQTTVersion version);
void setKeepAlive(const quint16 keepAlive);
void setCleanSession(const bool cleanSession);
void setAutoReconnect(const bool value);
void setAutoReconnectInterval(const int autoReconnectInterval);
void setWillTopic(const QString& willTopic);
void setWillQos(const quint8 willQos);
void setWillRetain(const bool willRetain);
void setWillMessage(const QByteArray& willMessage);
void connectToHost();
void disconnectFromHost();
void subscribe(const QString& topic, const quint8 qos = 0);
void unsubscribe(const QString& topic);
quint16 publish(const QMQTT::Message& message);
signals:
void connected();
void disconnected();
void error(const QMQTT::ClientError error);
void subscribed(const QString& topic, const quint8 qos = 0);
void unsubscribed(const QString& topic);
void published(const QMQTT::Message& message, quint16 msgid = 0);
void received(const QMQTT::Message& message);
void pingresp();
protected slots:
void onNetworkConnected();
void onNetworkDisconnected();
void onNetworkReceived(const QMQTT::Frame& frame);
void onTimerPingReq();
void onPingTimeout();
void onNetworkError(QAbstractSocket::SocketError error);
protected:
QScopedPointer<ClientPrivate> d_ptr;
private:
Q_DISABLE_COPY(Client)
Q_DECLARE_PRIVATE(Client)
};
} // namespace QMQTT
Q_DECLARE_METATYPE(QMQTT::ClientError)
#endif // QMQTT_CLIENT_H
/*
* qmqtt_client_p.h - qmqtt client private header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_CLIENT_P_H
#define QMQTT_CLIENT_P_H
#include <qmqtt_client.h>
#include <QHostAddress>
#include <QString>
#include <QByteArray>
#include <QHash>
#include <QTimer>
#include <QAbstractSocket>
#ifdef QT_WEBSOCKETS_LIB
#include <QWebSocket>
#endif // QT_WEBSOCKETS_LIB
#ifndef QT_NO_SSL
QT_FORWARD_DECLARE_CLASS(QSslConfiguration)
#endif // QT_NO_SSL
namespace QMQTT {
class NetworkInterface;
class ClientPrivate
{
public:
ClientPrivate(Client* qq_ptr);
~ClientPrivate();
void init(const QHostAddress& host, const quint16 port, NetworkInterface* network = NULL);
#ifndef QT_NO_SSL
void init(const QString& hostName, const quint16 port, const QSslConfiguration& config,
const bool ignoreSelfSigned=false);
#endif // QT_NO_SSL
void init(const QString& hostName, const quint16 port, const bool ssl, const bool ignoreSelfSigned);
#ifdef QT_WEBSOCKETS_LIB
void init(const QString& url,
const QString& origin,
QWebSocketProtocol::Version version,
const QSslConfiguration* sslConfig,
bool ignoreSelfSigned);
#endif // QT_WEBSOCKETS_LIB
void init(NetworkInterface* network);
QHostAddress _host;
QString _hostName;
quint16 _port;
#ifdef QT_WEBSOCKETS_LIB
QWebSocketProtocol::Version _webSocketVersion;
#endif // QT_WEBSOCKETS_LIB
quint16 _gmid;
MQTTVersion _version;
QString _clientId;
QString _username;
QByteArray _password;
bool _cleanSession;
ConnectionState _connectionState;
QScopedPointer<NetworkInterface> _network;
QTimer _timer;
QTimer _pingResponseTimer;
QString _willTopic;
quint8 _willQos;
bool _willRetain;
QByteArray _willMessage;
QHash<quint16, QString> _midToTopic;
QHash<quint16, Message> _midToMessage;
Client* const q_ptr;
quint16 nextmid();
void connectToHost();
void sendConnect();
void onTimerPingReq();
void onPingTimeout();
quint16 sendUnsubscribe(const QString &topic);
quint16 sendSubscribe(const QString &topic, const quint8 qos);
quint16 sendPublish(const Message &message);
void sendPuback(const quint8 type, const quint16 mid);
void sendDisconnect();
void sendFrame(const Frame &frame);
void disconnectFromHost();
void stopKeepAlive();
void onNetworkConnected();
void onNetworkDisconnected();
quint16 publish(const Message& message);
void puback(const quint8 type, const quint16 msgid);
void subscribe(const QString& topic, const quint8 qos);
void unsubscribe(const QString& topic);
void onNetworkReceived(const QMQTT::Frame& frame);
void handleConnack(const quint8 ack);
void handlePublish(const Message& message);
void handlePuback(const quint8 type, const quint16 msgid);
void handleSuback(const QString& topic, const quint8 qos);
void handleUnsuback(const QString& topic);
void handlePingresp();
bool autoReconnect() const;
void setAutoReconnect(const bool autoReconnect);
int autoReconnectInterval() const;
void setAutoReconnectInterval(const int autoReconnectInterval);
bool isConnectedToHost() const;
QMQTT::ConnectionState connectionState() const;
void setCleanSession(const bool cleanSession);
bool cleanSession() const;
void setKeepAlive(const quint16 keepAlive);
quint16 keepAlive() const;
void setPassword(const QByteArray& password);
QByteArray password() const;
void setUsername(const QString& username);
QString username() const;
void setVersion(const MQTTVersion);
MQTTVersion version() const;
void setClientId(const QString& clientId);
QString clientId() const;
void setPort(const quint16 port);
quint16 port() const;
void setHost(const QHostAddress& host);
QHostAddress host() const;
void setHostName(const QString& hostName);
QString hostName() const;
void setWillTopic(const QString& willTopic);
void setWillQos(const quint8 willQos);
void setWillRetain(const bool willRetain);
void setWillMessage(const QByteArray& willMessage);
QString willTopic() const;
quint8 willQos() const;
bool willRetain() const;
QByteArray willMessage() const;
void onNetworkError(QAbstractSocket::SocketError error);
Q_DECLARE_PUBLIC(Client)
};
} // namespace QMQTT
#endif // QMQTT_CLIENT_P_H
/*
* qmqtt_frame.h - qmqtt frame heaer
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_FRAME_H
#define QMQTT_FRAME_H
#include "qmqtt_global.h"
#include <QMetaType>
#include <QByteArray>
#include <QString>
QT_FORWARD_DECLARE_CLASS(QDataStream)
#define PROTOCOL_MAGIC_3_1_0 "MQIsdp"
#define PROTOCOL_MAGIC_3_1_1 "MQTT"
#define RANDOM_CLIENT_PREFIX "QMQTT-"
#define CONNECT 0x10
#define CONNACK 0x20
#define PUBLISH 0x30
#define PUBACK 0x40
#define PUBREC 0x50
#define PUBREL 0x60
#define PUBCOMP 0x70
#define SUBSCRIBE 0x80
#define SUBACK 0x90
#define UNSUBSCRIBE 0xA0
#define UNSUBACK 0xB0
#define PINGREQ 0xC0
#define PINGRESP 0xD0
#define DISCONNECT 0xE0
#define LSB(A) quint8(A & 0x00FF)
#define MSB(A) quint8((A & 0xFF00) >> 8)
/*
|--------------------------------------
| 7 6 5 4 | 3 | 2 1 | 0 |
| Type | DUP flag | QoS | RETAIN |
|--------------------------------------
*/
#define GETTYPE(HDR) (HDR & 0xF0)
#define SETQOS(HDR, Q) (HDR | ((Q) << 1))
#define GETQOS(HDR) ((HDR & 0x06) >> 1)
#define SETDUP(HDR, D) (HDR | ((D) << 3))
#define GETDUP(HDR) ((HDR & 0x08) >> 3)
#define SETRETAIN(HDR, R) (HDR | (R))
#define GETRETAIN(HDR) (HDR & 0x01)
/*
|----------------------------------------------------------------------------------
| 7 | 6 | 5 | 4 3 | 2 | 1 | 0 |
| username | password | willretain | willqos | willflag | cleansession | reserved |
|----------------------------------------------------------------------------------
*/
#define FLAG_CLEANSESS(F, C) (F | ((C) << 1))
#define FLAG_WILL(F, W) (F | ((W) << 2))
#define FLAG_WILLQOS(F, Q) (F | ((Q) << 3))
#define FLAG_WILLRETAIN(F, R) (F | ((R) << 5))
#define FLAG_PASSWD(F, P) (F | ((P) << 6))
#define FLAG_USERNAME(F, U) (F | ((U) << 7))
namespace QMQTT {
class Q_MQTT_EXPORT Frame
{
public:
explicit Frame();
explicit Frame(const quint8 header);
explicit Frame(const quint8 header, const QByteArray &data);
virtual ~Frame();
Frame(const Frame& other);
Frame& operator=(const Frame& other);
bool operator==(const Frame& other) const;
inline bool operator!=(const Frame& other) const
{ return !operator==(other); }
quint8 header() const;
QByteArray data() const;
quint16 readInt();
quint8 readChar();
QByteArray readByteArray();
QString readString();
void writeInt(const quint16 i);
void writeChar(const quint8 c);
void writeByteArray(const QByteArray &data);
void writeString(const QString &string);
void writeRawData(const QByteArray &data);
//TODO: FIXME LATER
void write(QDataStream &stream) const;
bool encodeLength(QByteArray &lenbuf, int length) const;
private:
quint8 _header;
QByteArray _data;
};
} // namespace QMQTT
Q_DECLARE_METATYPE(QMQTT::Frame)
#endif // QMQTT_FRAME_H
/*
* qmqtt_global.h - qmqtt libray global
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_GLOBAL_H
#define QMQTT_GLOBAL_H
#include <QtGlobal>
#if !defined(QMQTT_STATIC)
# if defined(QMQTT_SHARED)
# define Q_MQTT_EXPORT Q_DECL_EXPORT
# else
# define Q_MQTT_EXPORT Q_DECL_IMPORT
# endif
#else
# define Q_MQTT_EXPORT
#endif
#endif // QMQTT_GLOBAL_H
/*
* qmqtt_message.h - qmqtt message header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_MESSAGE_H
#define QMQTT_MESSAGE_H
#include "qmqtt_global.h"
#include <QMetaType>
#include <QString>
#include <QByteArray>
#include <QSharedDataPointer>
namespace QMQTT {
class MessagePrivate;
class Q_MQTT_EXPORT Message
{
public:
Message();
explicit Message(const quint16 id, const QString &topic, const QByteArray &payload,
const quint8 qos = 0, const bool retain = false, const bool dup = false);
Message(const Message &other);
~Message();
Message &operator=(const Message &other);
#ifdef Q_COMPILER_RVALUE_REFS
inline Message &operator=(Message &&other) Q_DECL_NOTHROW
{ swap(other); return *this; }
#endif
bool operator==(const Message &other) const;
inline bool operator!=(const Message &other) const
{ return !operator==(other); }
inline void swap(Message &other) Q_DECL_NOTHROW
{ qSwap(d, other.d); }
quint16 id() const;
void setId(const quint16 id);
quint8 qos() const;
void setQos(const quint8 qos);
bool retain() const;
void setRetain(const bool retain);
bool dup() const;
void setDup(const bool dup);
QString topic() const;
void setTopic(const QString &topic);
QByteArray payload() const;
void setPayload(const QByteArray &payload);
private:
QSharedDataPointer<MessagePrivate> d;
};
} // namespace QMQTT
Q_DECLARE_SHARED(QMQTT::Message)
Q_DECLARE_METATYPE(QMQTT::Message)
#endif // QMQTT_MESSAGE_H
/*
* qmqtt_message.h - qmqtt message private header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_MESSAGE_P_H
#define QMQTT_MESSAGE_P_H
#include <QSharedData>
#include <QString>
#include <QByteArray>
namespace QMQTT {
class MessagePrivate : public QSharedData
{
public:
inline MessagePrivate()
: QSharedData(),
id(0),
qos(0),
retain(false),
dup(false)
{}
inline MessagePrivate(const MessagePrivate &other)
: QSharedData(other),
id(other.id),
qos(other.qos),
retain(other.retain),
dup(other.dup),
topic(other.topic),
payload(other.payload)
{}
inline MessagePrivate(quint16 id, const QString &topic, const QByteArray &payload,
quint8 qos, bool retain, bool dup)
: QSharedData(),
id(id),
qos(qos),
retain(retain),
dup(dup),
topic(topic),
payload(payload)
{}
quint16 id;
quint8 qos : 2;
quint8 retain: 1;
quint8 dup: 1;
QString topic;
QByteArray payload;
};
} // namespace QMQTT
#endif // QMQTT_MESSAGE_P_H
/*
* qmqtt_network_p.h - qmqtt network private header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_NETWORK_P_H
#define QMQTT_NETWORK_P_H
#include <qmqtt_networkinterface.h>
#include <QObject>
#include <QHostAddress>
#include <QString>
#include <QByteArray>
#ifdef QT_WEBSOCKETS_LIB
#include <QWebSocket>
#endif // QT_WEBSOCKETS_LIB
#ifndef QT_NO_SSL
QT_FORWARD_DECLARE_CLASS(QSslConfiguration)
#endif // QT_NO_SSL
namespace QMQTT {
class SocketInterface;
class TimerInterface;
class Frame;
class Network : public NetworkInterface
{
Q_OBJECT
public:
Network(QObject* parent = NULL);
#ifndef QT_NO_SSL
Network(const QSslConfiguration& config, bool ignoreSelfSigned, QObject* parent = NULL);
#endif // QT_NO_SSL
#ifdef QT_WEBSOCKETS_LIB
Network(const QString& origin,
QWebSocketProtocol::Version version,
const QSslConfiguration* sslConfig,
bool ignoreSelfSigned,
QObject* parent = NULL);
#endif // QT_WEBSOCKETS_LIB
Network(SocketInterface* socketInterface, TimerInterface* timerInterface,
QObject* parent = NULL);
~Network();
void sendFrame(const Frame &frame);
bool isConnectedToHost() const;
bool autoReconnect() const;
void setAutoReconnect(const bool autoReconnect);
QAbstractSocket::SocketState state() const;
int autoReconnectInterval() const;
void setAutoReconnectInterval(const int autoReconnectInterval);
public slots:
void connectToHost(const QHostAddress& host, const quint16 port);
void connectToHost(const QString& hostName, const quint16 port);
void disconnectFromHost();
protected slots:
void onSocketError(QAbstractSocket::SocketError socketError);
protected:
void initialize();
quint16 _port;
QHostAddress _host;
QString _hostName;
bool _autoReconnect;
int _autoReconnectInterval;
SocketInterface* _socket;
TimerInterface* _autoReconnectTimer;
enum ReadState {
Header,
Length,
PayLoad
};
ReadState _readState;
quint8 _header;
int _length;
int _shift;
QByteArray _data;
protected slots:
void onSocketReadReady();
void onDisconnected();
void connectToHost();
private:
Q_DISABLE_COPY(Network)
};
} // namespace QMQTT
#endif // QMQTT_NETWORK_P_H
/*
* qmqtt_networkinterface.h - qmqtt network interface header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_NETWORK_INTERFACE_H
#define QMQTT_NETWORK_INTERFACE_H
#include "qmqtt_global.h"
#include <QObject>
#include <QAbstractSocket>
#include <QHostAddress>
#include <QString>
namespace QMQTT {
class Frame;
class Q_MQTT_EXPORT NetworkInterface : public QObject
{
Q_OBJECT
public:
explicit NetworkInterface(QObject* parent = NULL) : QObject(parent) {}
virtual ~NetworkInterface() {}
virtual void sendFrame(const Frame& frame) = 0;
virtual bool isConnectedToHost() const = 0;
virtual bool autoReconnect() const = 0;
virtual void setAutoReconnect(const bool autoReconnect) = 0;
virtual int autoReconnectInterval() const = 0;
virtual void setAutoReconnectInterval(const int autoReconnectInterval) = 0;
virtual QAbstractSocket::SocketState state() const = 0;
public slots:
virtual void connectToHost(const QHostAddress& host, const quint16 port) = 0;
virtual void connectToHost(const QString& hostName, const quint16 port) = 0;
virtual void disconnectFromHost() = 0;
signals:
void connected();
void disconnected();
void received(const QMQTT::Frame& frame);
void error(QAbstractSocket::SocketError error);
};
} // namespace QMQTT
#endif // QMQTT_NETWORK_INTERFACE_H
/*
* qmqtt_router.h - qmqtt router
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* Router added by Niklas Wulf <nwulf at geenen-it-systeme dot de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_ROUTEDMESSAGE_H
#define QMQTT_ROUTEDMESSAGE_H
#include <qmqtt_message.h>
#include <QMetaType>
#include <QHash>
#include <QString>
namespace QMQTT {
class RouteSubscription;
class Q_MQTT_EXPORT RoutedMessage
{
public:
inline RoutedMessage()
{}
inline RoutedMessage(const Message &message)
: _message(message)
{}
inline const Message &message() const
{ return _message; }
inline QHash<QString, QString> parameters() const
{ return _parameters; }
private:
friend class RouteSubscription;
Message _message;
QHash<QString, QString> _parameters;
};
} // namespace QMQTT
Q_DECLARE_METATYPE(QMQTT::RoutedMessage)
#endif // QMQTT_ROUTEDMESSAGE_H
/*
* qmqtt_router.h - qmqtt router
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* Router added by Niklas Wulf <nwulf at geenen-it-systeme dot de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_ROUTER_H
#define QMQTT_ROUTER_H
#include "qmqtt_global.h"
#include <QObject>
namespace QMQTT {
class Client;
class RouteSubscription;
class Q_MQTT_EXPORT Router : public QObject
{
Q_OBJECT
public:
explicit Router(Client *parent = 0);
RouteSubscription *subscribe(const QString &route);
Client *client() const;
private:
Client *_client;
};
} // namespace QMQTT
#endif // QMQTT_ROUTER_H
/*
* qmqtt_router.h - qmqtt router
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* Router added by Niklas Wulf <nwulf at geenen-it-systeme dot de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_ROUTESUBSCRIPTION_H
#define QMQTT_ROUTESUBSCRIPTION_H
#include "qmqtt_global.h"
#include <QObject>
#include <QPointer>
#include <QString>
#include <QRegularExpression>
#include <QStringList>
namespace QMQTT {
class Client;
class Message;
class RoutedMessage;
class Router;
class Q_MQTT_EXPORT RouteSubscription : public QObject
{
Q_OBJECT
public:
~RouteSubscription();
QString route() const;
signals:
void received(const RoutedMessage &message);
private slots:
void routeMessage(const Message &message);
private:
friend class Router;
explicit RouteSubscription(Router *parent = 0);
void setRoute(const QString &route);
QPointer<Client> _client;
QString _topic;
QRegularExpression _regularExpression;
QStringList _parameterNames;
};
} // namespace QMQTT
#endif // QMQTT_ROUTESUBSCRIPTION_H
/*
* qmqtt_socket_p.h - qmqtt socket private header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_SOCKET_P_H
#define QMQTT_SOCKET_P_H
#include <qmqtt_socketinterface.h>
#include <QObject>
#include <QHostAddress>
#include <QString>
#include <QAbstractSocket>
#include <QScopedPointer>
QT_FORWARD_DECLARE_CLASS(QIODevice)
QT_FORWARD_DECLARE_CLASS(QTcpSocket)
namespace QMQTT
{
class Socket : public SocketInterface
{
Q_OBJECT
public:
explicit Socket(QObject* parent = NULL);
virtual ~Socket();
virtual QIODevice *ioDevice();
void connectToHost(const QHostAddress& address, quint16 port);
void connectToHost(const QString& hostName, quint16 port);
void disconnectFromHost();
QAbstractSocket::SocketState state() const;
QAbstractSocket::SocketError error() const;
protected:
QScopedPointer<QTcpSocket> _socket;
};
}
#endif // QMQTT_SOCKET_P_H
/*
* qmqtt_socketinterface.h - qmqtt socket interface header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_SOCKET_INTERFACE_H
#define QMQTT_SOCKET_INTERFACE_H
#include "qmqtt_global.h"
#include <QObject>
#include <QHostAddress>
#include <QString>
#include <QAbstractSocket>
QT_FORWARD_DECLARE_CLASS(QIODevice)
namespace QMQTT
{
class Q_MQTT_EXPORT SocketInterface : public QObject
{
Q_OBJECT
public:
explicit SocketInterface(QObject* parent = NULL) : QObject(parent) {}
virtual ~SocketInterface() {}
virtual QIODevice *ioDevice() = 0;
virtual void connectToHost(const QHostAddress& address, quint16 port) = 0;
virtual void connectToHost(const QString& hostName, quint16 port) = 0;
virtual void disconnectFromHost() = 0;
virtual QAbstractSocket::SocketState state() const = 0;
virtual QAbstractSocket::SocketError error() const = 0;
signals:
void connected();
void disconnected();
void error(QAbstractSocket::SocketError socketError);
};
}
#endif // QMQTT_SOCKET_INTERFACE_H
/*
* qmqtt_ssl_socket_p.h - qmqtt SSL socket private header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* Copyright (c) 2016 Matthias Dieter Wallnöfer
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_SSL_SOCKET_P_H
#define QMQTT_SSL_SOCKET_P_H
#ifndef QT_NO_SSL
#include <qmqtt_socketinterface.h>
#include <QObject>
#include <QHostAddress>
#include <QString>
#include <QList>
#include <QScopedPointer>
QT_FORWARD_DECLARE_CLASS(QSslSocket)
QT_FORWARD_DECLARE_CLASS(QSslError)
QT_FORWARD_DECLARE_CLASS(QSslConfiguration)
namespace QMQTT
{
class SslSocket : public SocketInterface
{
Q_OBJECT
public:
explicit SslSocket(const QSslConfiguration &config, bool ignoreSelfSigned, QObject* parent = NULL);
virtual ~SslSocket();
virtual QIODevice *ioDevice();
void connectToHost(const QHostAddress& address, quint16 port);
void connectToHost(const QString& hostName, quint16 port);
void disconnectFromHost();
QAbstractSocket::SocketState state() const;
QAbstractSocket::SocketError error() const;
protected slots:
void sslErrors(const QList<QSslError> &errors);
protected:
QScopedPointer<QSslSocket> _socket;
bool _ignoreSelfSigned;
};
}
#endif // QT_NO_SSL
#endif // QMQTT_SSL_SOCKET_P_H
/*
* qmqtt_timer_p.h - qmqtt timer private header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_TIMER_P_H
#define QMQTT_TIMER_P_H
#include <qmqtt_timerinterface.h>
#include <QObject>
#include <QTimer>
namespace QMQTT {
class Timer : public TimerInterface
{
Q_OBJECT
public:
explicit Timer(QObject *parent = 0);
virtual ~Timer();
bool isSingleShot() const;
void setSingleShot(bool singleShot);
int interval() const;
void setInterval(int msec);
void start();
void stop();
protected:
QTimer _timer;
};
}
#endif // QMQTT_TIMER_P_H
/*
* qmqtt_timerinterface.h - qmqtt timer interface header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_TIMER_INTERFACE_H
#define QMQTT_TIMER_INTERFACE_H
#include "qmqtt_global.h"
#include <QObject>
namespace QMQTT {
class Q_MQTT_EXPORT TimerInterface : public QObject
{
Q_OBJECT
public:
explicit TimerInterface(QObject* parent = NULL) : QObject(parent) {}
virtual ~TimerInterface() {}
virtual bool isSingleShot() const = 0;
virtual void setSingleShot(bool singleShot) = 0;
virtual int interval() const = 0;
virtual void setInterval(int msec) = 0;
virtual void start() = 0;
virtual void stop() = 0;
signals:
void timeout();
};
}
#endif // QMQTT_TIMER_INTERFACE_H
/*
* qmqtt_websocket_p.h - qmqtt socket private header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_WEBSOCKET_H
#define QMQTT_WEBSOCKET_H
#ifdef QT_WEBSOCKETS_LIB
#include <qmqtt_socketinterface.h>
#include <qmqtt_websocketiodevice_p.h>
#include <QObject>
#include <QWebSocket>
#include <QHostAddress>
#include <QString>
#include <QList>
#include <QAbstractSocket>
QT_FORWARD_DECLARE_CLASS(QIODevice)
QT_FORWARD_DECLARE_CLASS(QSslConfiguration)
QT_FORWARD_DECLARE_CLASS(QSslError)
namespace QMQTT
{
class WebSocket : public SocketInterface
{
Q_OBJECT
public:
WebSocket(const QString& origin,
QWebSocketProtocol::Version version,
const QSslConfiguration* sslConfig,
bool ignoreSelfSigned,
QObject* parent = NULL);
virtual ~WebSocket();
QIODevice *ioDevice()
{
return _ioDevice;
}
void connectToHost(const QHostAddress& address, quint16 port);
void connectToHost(const QString& hostName, quint16 port);
void disconnectFromHost();
QAbstractSocket::SocketState state() const;
QAbstractSocket::SocketError error() const;
private slots:
void sslErrors(const QList<QSslError> &errors);
private:
QWebSocket *_socket;
WebSocketIODevice *_ioDevice;
bool _ignoreSelfSigned;
};
}
#endif // QT_WEBSOCKETS_LIB
#endif // QMQTT_WEBSOCKET_H
/*
* qmqtt_socketinterface.h - qmqtt socket interface header
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef QMQTT_WEBSOCKETIODEVICE_H
#define QMQTT_WEBSOCKETIODEVICE_H
#ifdef QT_WEBSOCKETS_LIB
#include <QByteArray>
#include <QIODevice>
#include <QList>
#include <QAbstractSocket>
QT_FORWARD_DECLARE_CLASS(QWebSocket)
QT_FORWARD_DECLARE_CLASS(QNetworkRequest)
QT_FORWARD_DECLARE_CLASS(QSslError)
namespace QMQTT
{
class WebSocketIODevice : public QIODevice
{
Q_OBJECT
public:
explicit WebSocketIODevice(QWebSocket *socket, QObject *parent = NULL);
bool connectToHost(const QNetworkRequest &request);
virtual qint64 bytesAvailable() const;
signals:
void connected();
void disconnected();
void error(QAbstractSocket::SocketError error);
void sslErrors(const QList<QSslError> &errors);
protected:
virtual qint64 readData(char *data, qint64 maxSize);
virtual qint64 writeData(const char *data, qint64 maxSize);
private slots:
void binaryMessageReceived(const QByteArray &frame);
private:
QByteArray _buffer;
QWebSocket *_webSocket;
};
}
#endif // QT_WEBSOCKETS_LIB
#endif // QMQTT_WEBSOCKETIODEVICE_H
COPY=cp
win32: COPY=copy
SHELL_SUFFIX=sh
win32: SHELL_SUFFIX=bat
BUILD_TYPE = release
CONFIG(debug,debug|release):BUILD_TYPE=debug
CONFIG(release,debug|release):BUILD_TYPE=release
!exists($$system_path($${TOPIKM_SDKPATH})) {
mkpath($$system_path($${TOPIKM_SDKPATH}))
}
!exists($$system_path($${SDK_HEADER_PATH}/qmqtt/)) {
mkpath($$system_path($${SDK_HEADER_PATH}/qmqtt/))
}
# 复制qmqtt链接库
SRC_PATH = $$PWD/bin/$${BUILD_TYPE}/$${MISC_SUFFIX}/qmqtt$${DEBUG_SUFFIX}
win32 {
system($${COPY} $$system_path($${SRC_PATH}.dll) $$system_path($$DESTDIR/qmqtt$${DEBUG_SUFFIX}.dll))
system($${COPY} $$system_path($${SRC_PATH}.lib) $$system_path($$DESTDIR/qmqtt$${DEBUG_SUFFIX}.lib))
###导出header
system(copy $$system_path($$PWD/include/qmqtt/*.h) $$system_path($${SDK_HEADER_PATH}/qmqtt/))
}
linux {
system(cp $$PWD/bin/$${BUILD_TYPE}/$${MISC_SUFFIX}/libqmqtt.so.1.0.1) $$system_path($$DESTDIR/libqmqtt.so.1.0.1))
system("cd $${DESTDIR} && ln -s libqmqtt.so.1.0.1 libqmqtt.so")
system("cd $${DESTDIR} && ln -s libqmqtt.so.1.0.1 libqmqtt.so.1")
###导出header
system(cp $$system_path($$PWD/include/qmqtt/*.h) $$system_path($${SDK_HEADER_PATH}/qmqtt/))
}
include(../global/qt-module-defaults-offline.qdocconf)
# Name of the project which must match the outputdir. Determines the .index file
project = tmqtt
description = TopIKM6 MQTT
version = 0.0.1
depends += qtcore qtnetwork
outputformats=HTML
outputdir = ../html
imagedirs = ../images
tagfile = ../doc.tags
# The following parameters are for creating a qhp file, the qhelpgenerator
# program can convert the qhp file into a qch file which can be opened in
# Qt Assistant and/or Qt Creator.
# Defines the name of the project. You cannot use operators (+, =, -) in
# the name. Properties for this project are set using a qhp.<projectname>.property
# format.
qhp.projects = tmqtt
# Sets the name of the output qhp file.
qhp.tbaseutil.file = tmqtt.qhp
qhp.tbaseutil.namespace = net.topibd.topikm6.tmqtt.0.0.1
qhp.tbaseutil.virtualFolder = tmqtt
# Title for the package, will be the main title for the package in
# Assistant/Creator.
qhp.tbaseutil.indexTitle = tmqtt
# Only update the name of the project for the next variables.
qhp.tbaseutil.filterAttributes = tmqtt qtrefdoc
qhp.tbaseutil.customFilters.Qt.name = tmqtt
qhp.tbaseutil.subprojects = classes
qhp.tbaseutil.subprojects.classes.title = C++ Classes
qhp.tbaseutil.subprojects.classes.indexTitle = All Classes
qhp.tbaseutil.subprojects.classes.selectors = class fake:headerfile
qhp.tbaseutil.subprojects.classes.sortPages = true
headerdirs += ../src \
../../src/lib
sourcedirs = ../src \
../../src/lib
navigation.landingpage = "tmqtt"
navigation.cppclassespage = "tmqtt C++ Classes"
indexes += $TOPIKM6_DOCS/topikm6/topikm6.index
macro.0 = "\\\\0"
macro.n = "\\\\n"
macro.r = "\\\\r"
macro.img = "\\image"
macro.endquote = "\\endquotation"
macro.relatesto = "\\relates"
spurious = "Missing comma in .*" \
"Missing pattern .*"
#Include this file to inherit configuration related to Qt Project based modules.
dita.metadata.default.author = TopLinker
dita.metadata.default.permissions = all
dita.metadata.default.publisher = TopLinker Co., Ltd.
dita.metadata.default.copyryear = 2020
dita.metadata.default.copyrholder = TopLinker Co., Ltd.
dita.metadata.default.audience = programmer
#Set the main Qt index.html
navigation.homepage = "topikm6"
sourcedirs += includes
url = http://139.196.104.13:8888/topikm6-mqtt
# Include the external websites
sourcedirs += externalsites
This diff is collapsed.
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\externalpage http://qt.io/
\title Qt Homepage
*/
/*!
\externalpage http://bugreports.qt.io
\title Qt Bug Tracker
*/
/*!
\externalpage http://qt.io/download
\title Downloads
*/
/*!
\externalpage http://qt.io/licensing/
\title Qt Licensing Overview
*/
/*!
\externalpage http://doc.qt.io/archives/qq/
\title Qt Quarterly
*/
/*!
\externalpage http://doc.qt.io/archives/qq/qq19-plurals.html
\title Qt Quarterly: Plural Form in Translation
*/
/*!
\externalpage https://code.qt.io/
\title Public Qt Repository
*/
/*!
\externalpage https://code.qt.io/cgit/%7bnon-gerrit%7d/qt-labs/qtestlib-tools.git/
\title qtestlib-tools
*/
/*!
\externalpage http://wiki.qt.io/Qt_Coding_Style
\title Qt Coding Style
*/
/*!
\externalpage http://doc.qt.io/archives/qt-eclipse-1.6/index.html
\title Eclipse Plugin
*/
/*!
\externalpage http://doc.qt.io/archives/qq/qq11-events.html
\title Qt Quarterly: Another Look at Events
*/
/*!
\externalpage http://qt-project.org/videos/watch/livecoding-video-effects-with-qt5
\title Livecoding video effects with Qt5
*/
/*!
\externalpage http://blog.qt.io/2012/02/29/pimp-my-video-shader-effects-and-multimedia/
\title Pimp my video
*/
/*!
\externalpage http://wiki.qt.io/QtMediaHub
\title QtMediaHub
*/
/*!
\externalpage http://wiki.qt.io/Qt_RaspberryPi
\title QtonPi
*/
/*!
\externalpage http://wiki.qt.io/jom
\title jom
*/
/*!
\externalpage http://doc.qt.io/qt-4.8
\title Qt 4.8 Reference Documentation
*/
/*!
\externalpage http://doc.qt.io/qt-4.8/qtquick.html
\title Qt Quick 1 Reference Documentation
*/
/*!
\externalpage http://wiki.qt.io/Qt_Localization
\title external: Translating Qt Into Other Languages
*/
/*!
\externalpage http://wiki.qt.io/BlackBerry
\title Qt for BlackBerry
*/
/*!
\externalpage http://wiki.qt.io/Qt_Multimedia_Backends
\title Qt Multimedia Backends
*/
This diff is collapsed.
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\externalpage http://www.ietf.org/rfc/rfc1179.txt
\title RFC 1179
\keyword lpr
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc1738.txt
\title RFC 1738
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc1928.txt
\title RFC 1928
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc1929.txt
\title RFC 1929
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc2045.txt
\title RFC 2045
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc2109.txt
\title RFC 2109
HTTP State Management Mechanism
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc2965.txt
\title RFC 2965
HTTP State Management Mechanism
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc3174.txt
\title RFC 3174
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc3491.txt
\title RFC 3491
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc3986.txt
\title RFC 3986
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc2822.txt
\title RFC 2822
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc1036.txt
\title RFC 1036
*/
/*!
\externalpage http://www.rfc-editor.org/rfc/rfc850.txt
\title RFC 850
*/
naturallanguage = zhcn
outputencoding = UTF-8
sourceencoding = UTF-8
examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml *.css *.glsl"
examples.imageextensions = "*.png *.jpg *.gif"
headers.fileextensions = "*.ch *.h *.h++ *.hh *.hpp *.hxx"
sources.fileextensions = "*.c++ *.cc *.cpp *.cxx *.mm *.qml *.qdoc"
#Additional HTML settings
HTML.nonavigationbar = "false"
HTML.tocdepth = 2
HTML.extraimages += template/images/arrow_bc.png \
template/images/home.png \
template/images/ico_out.png \
template/images/ico_note.png \
template/images/ico_note_attention.png \
template/images/btn_prev.png \
template/images/btn_next.png \
template/images/bullet_dn.png \
template/images/bullet_sq.png \
template/images/bgrContent.png \
template/images/logo.png
#specify which files in the output directory should be packed into the qch file.
#these files are assumed to be in each module's output directory."qtquick/images/ico_out.png" for example.
qhp.extraFiles += images/arrow_bc.png \
images/home.png \
images/ico_out.png \
images/ico_note.png \
images/ico_note_attention.png \
images/btn_prev.png \
images/btn_next.png \
images/bullet_dn.png \
images/bullet_sq.png \
images/bgrContent.png \
images/logo.png
#Default HTML footer for QDoc builds.
HTML.footer = \
" </div>\n" \
" </div>\n" \
" </div>\n" \
" </div>\n" \
"</div>\n" \
"<div class=\"footer\">\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2020 TopLinker Co.,Ltd.\n" \
" Documentation contributions included herein are the copyrights of\n" \
" their respective owners.<br>" \
" <a href=\"http://www.topibd.com\">无锡东领智能科技股份有限公司" </a> \
"</div>\n" \
#Default HTML header for QDoc builds.
#specify the CSS file used by this template
HTML.stylesheets = template/style/offline.css
#for including files into the qch file
qhp.extraFiles += style/offline.css
HTML.headerstyles = \
" <link rel=\"stylesheet\" type=\"text/css\" href=\"style/offline.css\" />\n"
HTML.endheader = \
"</head>\n"
HTML.postheader = \
"<body>\n" \
"<div class=\"header\" id=\"qtdocheader\">\n"\
" <div class=\"main\">\n" \
" <div class=\"main-rounded\">\n" \
" <div class=\"navigationbar\">\n"\
" <ul>\n"\
HTML.postpostheader = \
" </ul>\n"\
" </div>\n" \
"</div>\n" \
"<div class=\"content\">\n" \
"<div class=\"line\">\n" \
"<div class=\"content mainContent\">\n" \
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page search-results.html
\title Search Results
\raw HTML
<link rel="stylesheet" type="text/css" href="style/gsc.css" />
<script type="text/javascript">
$(function(){ $(".title").append(": " + decodeURIComponent(location.search.split('=')[1]).substring(0,32)); });
</script>
<gcse:searchresults-only></gcse:searchresults-only>
\endraw
*/
\section1 Running the Example
To run the example from \l{Qt Creator Manual}{Qt Creator}, open the \gui Welcome
mode and select the example from \gui Examples. For more information, visit
\l{Qt Creator: Building and Running an Example}{Building and Running an Example}.
macro.aacute.HTML = "&aacute;"
macro.Aring.HTML = "&Aring;"
macro.aring.HTML = "&aring;"
macro.Auml.HTML = "&Auml;"
macro.author = "\\b{Author:}"
macro.BR.HTML = "<br />"
macro.copyright.HTML = "&copy;"
macro.eacute.HTML = "&eacute;"
macro.gui = "\\b"
macro.HR.HTML = "<hr />"
macro.iacute.HTML = "&iacute;"
macro.key = "\\b"
macro.macos = "macOS"
macro.menu = "\\b"
macro.oslash.HTML = "&oslash;"
macro.ouml.HTML = "&ouml;"
macro.QA = "\\e{Qt Assistant}"
macro.QD = "\\e{Qt Designer}"
macro.QL = "\\e{Qt Linguist}"
macro.QQV = "\\e{Qt QML Viewer}"
macro.param = "\\e"
macro.raisedaster.HTML = "<sup>*</sup>"
macro.rarrow.HTML = "&rarr;"
macro.reg.HTML = "<sup>&reg;</sup>"
macro.return = "Returns"
macro.starslash = "\\c{*/}"
macro.begincomment = "\\c{/*}"
macro.endcomment = "\\c{*/}"
macro.uuml.HTML = "&uuml;"
macro.mdash.HTML = "&mdash;"
macro.pi.HTML = "&Pi;"
macro.beginqdoc.HTML = "/*!"
macro.endqdoc.HTML = "*/"
macro.beginfloatleft.HTML = "<div style=\"float: left; margin-right: 2em\">"
macro.beginfloatright.HTML = "<div style=\"float: right; margin-left: 2em\">"
macro.endfloat.HTML = "</div>"
macro.clearfloat.HTML = "<br style=\"clear: both\" />"
macro.emptyspan.HTML = "<span></span>"
This diff is collapsed.
versionsym = QT_VERSION_STR
defines += Q_QDOC \
QT_.*_SUPPORT \
QT_.*_LIB \
QT_COMPAT \
QT_KEYPAD_NAVIGATION \
QT_NO_EGL \
QT3_SUPPORT \
Q_DEAD_CODE_FROM_QT4_.* \
Q_OS_.* \
Q_BYTE_ORDER \
QT_DEPRECATED \
QT_DEPRECATED_* \
Q_NO_USING_KEYWORD \
__cplusplus \
Q_COMPILER_INITIALIZER_LISTS \
Q_COMPILER_UNIFORM_INIT \
Q_COMPILER_RVALUE_REFS
Cpp.ignoretokens += \
ENGINIOCLIENT_EXPORT \
PHONON_EXPORT \
Q_AUTOTEST_EXPORT \
Q_BLUETOOTH_EXPORT \
Q_COMPAT_EXPORT \
Q_CORE_EXPORT \
Q_CORE_EXPORT_INLINE \
Q_DBUS_EXPORT \
Q_DECL_CONSTEXPR \
Q_DECL_RELAXED_CONSTEXPR \
Q_DECL_CONST_FUNCTION \
Q_DECL_DEPRECATED \
Q_DECL_NOEXCEPT \
Q_DECL_FINAL \
Q_DECL_OVERRIDE \
Q_DECL_NOTHROW \
Q_DECL_PURE_FUNCTION \
Q_DECL_UNUSED \
Q_DECL_CF_RETURNS_RETAINED \
Q_DECL_NS_RETURNS_AUTORELEASED \
Q_DECL_EQ_DEFAULT \
Q_DECLARATIVE_EXPORT \
Q_EXPLICIT \
Q_EXPORT \
Q_EXPORT_CODECS_CN \
Q_EXPORT_CODECS_JP \
Q_EXPORT_CODECS_KR \
Q_EXPORT_PLUGIN \
Q_EXPORT_PLUGIN2 \
Q_GADGET \
Q_GFX_INLINE \
Q_GUI_EXPORT \
Q_GUI_EXPORT_INLINE \
Q_GUI_EXPORT_STYLE_CDE \
Q_GUI_EXPORT_STYLE_COMPACT \
Q_GUI_EXPORT_STYLE_MAC \
Q_GUI_EXPORT_STYLE_MOTIF \
Q_GUI_EXPORT_STYLE_MOTIFPLUS \
Q_GUI_EXPORT_STYLE_PLATINUM \
Q_GUI_EXPORT_STYLE_POCKETPC \
Q_GUI_EXPORT_STYLE_SGI \
Q_GUI_EXPORT_STYLE_WINDOWS \
Q_GUI_EXPORT_STYLE_WINDOWSXP \
Q_INLINE_TEMPLATE \
Q_INTERNAL_WIN_NO_THROW \
Q_INVOKABLE \
Q_LOCATION_EXPORT \
Q_POSITIONING_EXPORT \
Q_MULTIMEDIA_EXPORT \
Q_NETWORK_EXPORT \
Q_NEVER_INLINE \
Q_NORETURN \
Q_OPENGL_EXPORT \
Q_OPENVG_EXPORT \
Q_OUTOFLINE_TEMPLATE \
Q_PRINTSUPPORT_EXPORT \
Q_QML_EXPORT \
Q_REQUIRED_RESULT \
Q_SCRIPT_EXPORT \
Q_SCRIPTTOOLS_EXPORT \
Q_SERIALBUS_EXPORT \
Q_SQL_EXPORT \
Q_SVG_EXPORT \
Q_TESTLIB_EXPORT \
Q_TYPENAME \
Q_WIDGETS_EXPORT \
Q_WINEXTRAS_EXPORT \
Q_XML_EXPORT \
Q_XMLPATTERNS_EXPORT \
Q_XMLSTREAM_EXPORT \
QAXFACTORY_EXPORT \
QDBUS_EXPORT \
QDESIGNER_COMPONENTS_LIBRARY \
QDESIGNER_EXTENSION_LIBRARY \
QDESIGNER_SDK_LIBRARY \
QDESIGNER_SHARED_LIBRARY \
QDESIGNER_UILIB_LIBRARY \
QHELP_EXPORT \
QM_AUTOTEST_EXPORT \
QM_EXPORT_CANVAS \
QM_EXPORT_DNS \
QM_EXPORT_DOM \
QM_EXPORT_FTP \
QM_EXPORT_HTTP \
QM_EXPORT_ICONVIEW \
QM_EXPORT_NETWORK \
QM_EXPORT_OPENGL \
QM_EXPORT_OPENVG \
QM_EXPORT_SQL \
QM_EXPORT_TABLE \
QM_EXPORT_WORKSPACE \
QM_EXPORT_XML \
QT_ASCII_CAST_WARN \
QT_ASCII_CAST_WARN_CONSTRUCTOR \
QT_BEGIN_INCLUDE_NAMESPACE \
QT_BEGIN_NAMESPACE \
QT_BOOTSTRAPPED \
QT_DESIGNER_STATIC \
QT_END_INCLUDE_NAMESPACE \
QT_END_NAMESPACE \
QT_FASTCALL \
QT_MUTEX_LOCK_NOEXCEPT \
QT_WARNING_PUSH \
QT_WARNING_POP \
QT_WIDGET_PLUGIN_EXPORT \
QWEBKIT_EXPORT
Cpp.ignoredirectives += \
__attribute__ \
K_DECLARE_PRIVATE \
PHONON_HEIR \
PHONON_OBJECT \
Q_CLASSINFO \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
Q_DECLARE_OPERATORS_FOR_FLAGS \
Q_DECLARE_PRIVATE \
Q_DECLARE_PRIVATE_D \
Q_DECLARE_PUBLIC \
Q_DECLARE_SHARED \
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6 \
Q_DECLARE_TR_FUNCTIONS \
Q_DECLARE_TYPEINFO \
Q_DECL_NOEXCEPT_EXPR \
QT_DEPRECATED_X \
Q_DISABLE_COPY \
Q_DUMMY_COMPARISON_OPERATOR \
Q_ENUM \
Q_ENUMS \
Q_FLAG \
Q_FLAGS \
Q_INTERFACES \
Q_PRIVATE_PROPERTY \
QT_FORWARD_DECLARE_CLASS \
Q_DECLARE_HANDLE \
Q_REVISION \
QT_WARNING_DISABLE_CLANG \
QT_WARNING_DISABLE_GCC \
QT_WARNING_DISABLE_INTEL \
QT_WARNING_DISABLE_MSVC \
Q_ATTRIBUTE_FORMAT_PRINTF \
Q_MV_IOS
# Qt 6: Remove
falsehoods += \
"QT_VERSION >= QT_VERSION_CHECK\\(6,0,0\\)"
# Specify a custom CSS file used by this template
HTML.stylesheets += template/style/offline-simple.css
qhp.extraFiles += style/offline-simple.css
# Override the header styles
HTML.headerstyles = \
" <link rel=\"stylesheet\" type=\"text/css\" href=\"style/offline-simple.css\" />\n" \
" <script type=\"text/javascript\">\n" \
" document.getElementsByTagName(\"link\").item(0).setAttribute(\"href\", \"style/offline.css\");\n" \
" </script>\n"
HTML.postheader = \
"<body>\n" \
"<div class=\"header\" id=\"qtdocheader\">\n"\
" <div class=\"main\">\n" \
" <div class=\"main-rounded\">\n" \
" <div class=\"navigationbar\">\n" \
" <table><tr>\n"
HTML.postpostheader = \
" </tr></table>\n"\
" </div>\n" \
" </div>\n" \
"<div class=\"content\">\n" \
"<div class=\"line\">\n" \
"<div class=\"content mainContent\">\n"
HTML.navigationseparator = \
"<span class=\"naviSeparator\"> &#9702; </span>\n"
# Add some padding around code snippets, as we cannot
# currectly style them for QTextBrowser using only CSS.
codeindent = 2
codeprefix = "\n\n"
codesuffix = "\n\n"
#include standard set of HTML header and footer.
include(html-config.qdocconf)
include(html-header-offline.qdocconf)
include(html-footer.qdocconf)
#uncomment if navigation bar is not wanted
#HTML.nonavigationbar = "true"
HTML.stylesheets = template/style/offline.css
HTML.extraimages += template/images/ico_out.png \
template/images/ico_note.png \
template/images/ico_note_attention.png \
template/images/btn_prev.png \
template/images/btn_next.png \
template/images/bullet_dn.png \
template/images/bullet_sq.png \
template/images/bgrContent.png
#specify which files in the output directory should be packed into the qch file.
qhp.extraFiles += style/offline.css \
images/ico_out.png \
images/ico_note.png \
images/ico_note_attention.png \
images/btn_prev.png \
images/btn_next.png \
images/bullet_dn.png \
images/bullet_sq.png \
images/bgrContent.png
# By default, include override definitions for a simplified template/CSS,
# suited for rendering HTML with QTextBrowser. Comment out this line to
# select the standard CSS.
include(qt-html-templates-offline-simple.qdocconf)
#The default configuration for a Qt 5 module, including Add-Ons and Tools.
#Include this file for a standard Qt 5 module; builds with the offline style.
#include standard set of macros and C++ defines and ignores
include(macros.qdocconf)
include(qt-cpp-defines.qdocconf)
include(compat.qdocconf)
#include(manifest-meta.qdocconf)
include(fileextensions.qdocconf)
include(qt-html-templates-offline.qdocconf)
#extra configuration data such as file extensions
include(config.qdocconf)
# Show Qt version as part of the navigation bar
buildversion = "TopIKM6 Reference Documentation"
var vOffset_init = 65;
var vOffset = vOffset_init;
var c = 'collapsed';
function toggleList(toggle, content, maxItems) {
if (toggle.css('display') == 'none') {
vOffset = vOffset_init;
toggle.removeClass(c);
content.show();
return;
} else
vOffset = 8;
if (maxItems > content.children().length)
return;
content.hide();
toggle.addClass(c);
}
$(function () {
$('a[href*=#]:not([href=#])').on('click', function (e) {
if (e.which == 2 || e.metaKey || e.ctrlKey || e.shiftKey)
return true;
var target = $(this.hash.replace(/(\.)/g, "\\$1"));
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
setTimeout(function () {
$('html, body').animate({scrollTop: target.offset().top - vOffset}, 50);}, 50);
}
});
});
$(window).load(function () {
var hashChanged = function() {
var h = window.location.hash;
var re = /[^a-z0-9_\.\#\-]/i
if (h.length > 1 && !re.test(h)) {
setTimeout(function () {
var tgt = $(h.replace(/(\.)/g, "\\$1"));
tgt = tgt.length ? tgt : $('[name=' + h.slice(1) + ']');
$(window).scrollTop(tgt.offset().top - vOffset);
}, 0);
}
}
$(window).bind('hashchange', hashChanged);
hashChanged.call();
if (!$('.sidebar toc').is(':empty')) {
$('<div id="toc-toggle"></div>').prependTo('.sidebar .toc');
var toc = $('.sidebar .toc ul');
var tocToggle = $('#toc-toggle');
var tocCallback = function() { toggleList(tocToggle, toc, 4); };
$('#toc-toggle').on('click', function(e) {
e.stopPropagation();
toc.toggle();
tocToggle.toggleClass(c);
});
tocCallback.call();
$(window).resize(tocCallback);
}
if (!$('#sidebar-content').is(':empty')) {
$('#sidebar-content h2').first().clone().prependTo('#sidebar-content');
$('<div id="sidebar-toggle"></div>').prependTo('#sidebar-content');
var sb = $('#sidebar-content .sectionlist');
var sbToggle = $('#sidebar-toggle');
var sbCallback = function() { toggleList(sbToggle, sb, 0); };
$('#sidebar-toggle').on('click', function(e) {
e.stopPropagation();
sb.toggle();
sbToggle.toggleClass(c);
});
sbCallback.call();
$(window).resize(sbCallback);
}
});
"use strict";
function createCookie(name, value, days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
} else {
expires = "";
}
document.cookie = escape(name) + "=" + escape(value) + expires + "; path=/";
$('.cookies_yum').click(function() {
$(this).fadeOut()
});
}
function readCookie(name) {
var nameEQ = escape(name) + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) === 0) return unescape(c.substring(nameEQ.length, c.length));
}
return null;
}
function eraseCookie(name) {
createCookie(name, "", -1);
}
function load_sdk(s, id, src) {
var js, fjs = document.getElementsByTagName(s)[0];
if (document.getElementById(id)) return;
js = document.createElement(s);
js.id = id;
js.src = src;
fjs.parentNode.insertBefore(js, fjs);
}
$(document).ready(function($) {
if (document.documentElement.clientWidth < 1280) {
oneQt.extraLinksToMain();
}
$('#menuextras .search').click(function(e){
e.preventDefault();
$('.big_bar.account').slideUp();
$('.big_bar.search').slideToggle();
$('.big_bar_search').focus();
$(this).toggleClass('open');
});
$('.cookies_yum').click(function() {
$('.cookies_yum').fadeOut();
createCookie("cookies_nom", "yum", 180);
var cookie_added = 1;
});
if (!(readCookie('cookies_nom') == 'yum')) {
$('.cookies_yum').fadeIn();
} else {
var cookie_added = 1;
}
Modernizr.load({test: Modernizr.input.placeholder,
nope: wpThemeFolder + '/js/placeholders.min.js'});
$('#navbar .navbar-toggle').click(function(e) {
e.preventDefault();
if ($(this).hasClass('opened')) {
$(this).removeClass('opened');
$('#navbar .navbar-menu').css('max-height', '0px');
}
else {
$(this).addClass('opened');
$('#navbar .navbar-menu').css('max-height', $('#navbar .navbar-menu ul').outerHeight() + 'px');
}
});
$(window).resize(function() {
oneQt.stickySidebar();
oneQt.footerPosition();
if (document.documentElement.clientWidth < 1280) {
oneQt.extraLinksToMain();
} else {
oneQt.mainLinkstoExtra();
}
});
$(window).scroll(function() {
oneQt.stickySidebar();
oneQt.stickyHeader();
});
oneQt.stickySidebar();
oneQt.footerPosition();
oneQt.tabContents();
});
$( window ).load(function() {
load_sdk('script', 'facebook-jssdk','//connect.facebook.net/en_US/sdk.js#xfbml=1&appId=207346529386114&version=v2.0');
load_sdk('script', 'twitter-wjs', '//platform.twitter.com/widgets.js');
$.getScript("//www.google.com/jsapi", function(){
google.load("feeds", "1", {"callback": oneQt.liveFeeds});
});
});
var oneQt = {
stickySidebar: function() {
if ($('#sidebar').length && $('#sidebar').outerHeight() > 20) {
var $sidebar = $('#sidebar');
var $win = $(window);
var $sidebarContainer = $sidebar.parent();
var headerHeight = $('#navbar').outerHeight();
if ($win.outerHeight() - headerHeight > $sidebar.innerHeight() &&
$win.scrollTop() > $sidebarContainer.offset().top) {
var newTop = headerHeight + $win.scrollTop() - $sidebarContainer.offset().top;
if (newTop + $sidebar.innerHeight() > $sidebarContainer.innerHeight())
newTop = $sidebarContainer.innerHeight() - $sidebar.innerHeight();
$sidebar.css({top: newTop +'px'})
}
else {
$sidebar.css({top: '0'})
}
}
},
footerPosition: function () {
$('#footerbar').removeClass('fixed');
if (($('.hbspt-form').length > 0) || ($('#customerInfo').length > 0) || ($('.purchase_bar').length > 0)) {
var footerBottomPos = $('#footerbar').offset().top + $('#footerbar').outerHeight();
if (footerBottomPos < $(window).height())
$('#footerbar').addClass('fixed');
}
},
stickyHeader: function () {
var originalHeaderHeight = 79;
if ($(window).scrollTop() > originalHeaderHeight) {
$('#navbar').addClass('fixed');
$('#bottom_header').fadeOut();
if (!(cookie_added == 1)) {
$('.cookies_yum').fadeOut();
createCookie("cookies_nom", "yum", 180);
var cookie_added = 1;
}
}
else {
$('#navbar').removeClass('fixed');
$('#bottom_header').fadeIn();
}
},
tabContents: function () {
$('.tab-container').each(function(i) {
var $el = $(this);
$el.find('.tab-titles li:eq(0)').addClass('active');
$el.find('.tab-contents .tab:eq(0)').addClass('active');
$el.find('.tab-titles a').click(function(e) {
e.preventDefault();
var index = $(this).parent().index();
$el.find('.tab-titles li').removeClass('active');
$el.find('.tab-contents .tab').removeClass('active');
$(this).parent().addClass('active');
$el.find('.tab-contents .tab').eq(index).addClass('active');
})
});
},
liveFeeds: function () {
$('.feed-container').each(function(i) {
var feedUrl = $(this).data('url');
if (feedUrl != "") oneQt.blogFeed($(this), feedUrl);
});
},
blogFeed: function ($container, feedUrl) {
var feed = new google.feeds.Feed(feedUrl);
feed.setNumEntries(3);
feed.load(function(result) {
$container.html('');
if (!result.error) {
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var $article = $('<article class="discussion-tile cf"></article>');
$container.append($article);
var html = ' <div class="author retina">';
html += ' <img src="'+wpThemeFolder+'/assets/images/author_placeholder.png" alt="">';
html += ' </div>';
html += ' <div class="discussion-item">';
html += ' <h4><a href="'+encodeURI(entry.link)+'"></a></h4>'
html += ' <h3><a href="'+encodeURI(entry.link)+'" target="_blank"></a></h3>'
html += ' <p><a href="'+encodeURI(entry.link)+'" target="_blank"></a></p>';
html += ' <ul class="taglist cf">';
html += ' </ul>';
html += ' </div>';
$article.append(html);
$article.find('h4 a').text(result.feed.title);
$article.find('h3 a').text(entry.title);
$article.find('p a').text(entry.author);
try {
for (var j=0; j<entry.categories.length; j++) {
var $li = $('<li><a href="'+encodeURI(entry.link)+'" target="_blank" class="btn btn-tag"></a></li>');
$li.find('a').text(entry.categories[j]);
$article.find('.taglist').append($li);
}
} catch(e) {}
}
if (result.feed.link && result.feed.link != "") {
var linkHtml = '<a href="'+encodeURI(result.feed.link)+'" class="text-lightgrey" target="_blank">Show all</a>';
$container.append(linkHtml);
}
}
});
},
extraLinksToMain: function() {
var extramenuLinks = $('#menuextras').find('li');
var mainmenu = $('#mainmenu');
var count = 0;
if ($(extramenuLinks).length > 2) {
$(extramenuLinks).each(function() {
if (count < 3) {
var newLink = $(this);
$(newLink).addClass('dynamic-add');
$(mainmenu).append(newLink);
}
count++;
});
}
},
mainLinkstoExtra: function() {
var mainmenuLinks = $('#mainmenu').find('.dynamic-add');
var extramenu = $('#menuextras');
var count = 0;
$(mainmenuLinks).each(function() {
var newLink = $(this);
$(extramenu).prepend(newLink);
count++;
});
}
}
.gsc-control-cse table, table td, table th {
border: none !important;
margin-bottom: 10px !important
}
.gsc-control-cse {
width: 100% !important;
box-sizing: border-box !important
}
.gsc-control-cse * {
font-family: 'Open Sans', Arial, Helvetica, sans-serif !important;
line-height: 1.5 !important;
font-weight: 300 !important
}
.gsc-control-cse,
.gsc-control-cse .gsc-table-result {
width: 100% !important;
font-family: 'Open Sans', Arial, Helvetica, sans-serif !important;
font-weight: 300 !important;
font-size: 13px !important
}
.gsc-resultsHeader {
width: 100% !important;
clear: both !important
}
.gsc-resultsHeader td.gsc-twiddleRegionCell {
width: 75% !important
}
.gsc-resultsbox-visible {
display: block !important
}
.gsc-resultsbox-invisible {
display: none !important
}
.gsc-results {
padding-bottom: 2px !important;
width: 99% !important
}
.gsc-result {
margin-bottom: 10px !important
}
.gsc-result .gs-title {
height: 1.4em !important;
overflow: hidden !important
}
.gsc-result div.gs-watermark {
display: none !important
}
.gsc-results .gsc-result img.gs-ad-marker {
display: none !important
}
.gsc-webResult:after {
content: "." !important;
display: block !important;
height: 0 !important;
clear: both !important;
visibility: hidden !important
}
.gsc-webResult {
zoom: 1 !important
}
.gsc-webResult .gsc-result {
margin: 0 !important;
padding: .5em 0 !important;
border-bottom: 1px solid #ebebeb !important
}
.gsc-above-wrapper-area {
border-bottom: 1px solid #E9E9E9 !important;
padding: 5px 0 5px 0 !important
}
.gsc-above-wrapper-area-invisible {
display: none !important
}
.gsc-above-wrapper-area-container {
width: 100% !important
}
.gsc-result-info {
text-align: left !important;
color: #676767 !important;
font-size: 13px !important;
padding-left: 8px !important;
margin: 10px 0 10px 0 !important
}
.gsc-result-info-container {
text-align: left !important
}
.gsc-result-info-invisible {
display: none !important
}
.gsc-orderby-container {
text-align: right !important;
background: transparent !important
}
.gsc-orderby-invisible {
display: none !important
}
.gsc-orderby-label {
color: #676767 !important;
padding: 5px 5px 6px 0 !important
}
.gsc-selected-option-container {
background-color: transparent !important;
border: 1px solid #eee !important;
border: 1px solid rgba(0, 0, 0, 0.1) !important;
border-radius: 2px !important;
box-shadow: none !important;
color: #444 !important;
cursor: default !important;
font-size: 11px !important;
font-weight: bold !important;
height: 20px !important;
line-height: 20px !important;
max-width: 90% !important;
min-width: 54px !important;
outline: 0 !important;
padding: 0 28px 0 6px !important;
position: relative !important;
text-align: center !important;
width: 50px !important !important
}
.gsc-selected-option {
position: relative !important;
width: 100% !important;
}
.gsc-control-cse .gsc-option-selector {
border: none !important;
height: 11px !important;
margin-top: -4px !important;
position: absolute !important;
right: 5px !important;
top: 8px !important;
width: 7px !important;
padding: 0 5px 0 5px !important;
background: url(//ssl.gstatic.com/ui/v1/disclosure/small-grey-disclosure-arrow-down.png) center no-repeat
}
.gsc-results .gsc-cursor-box .gsc-trailing-more-results {
margin-bottom: 0 !important;
display: inline !important
}
.gsc-results .gsc-cursor {
display: inline !important
}
.gsc-results .gsc-cursor-box {
margin: 10px 5px 10px !important
}
.gsc-results .gsc-cursor-box .gsc-cursor-page {
cursor: pointer !important;
color: #000000 !important;
text-decoration: underline !important;
margin-right: 8px !important;
display: inline !important
}
.gsc-results .gsc-cursor-box .gsc-cursor-current-page {
cursor: default !important;
color: white !important;
background-color: #5caa15 !important;
font-weight: bold !important;
text-decoration: none !important;
padding: 0 3px 0 3px !important;
margin-top: 10px !important;
cursor: pointer !important
}
.gs-result .gs-title,
.gs-result .gs-title * {
color: #5caa15 !important;
text-decoration: underline !important
}
.gs-webResult div.gs-visibleUrl-long,
.gs-promotion div.gs-visibleUrl-long {
overflow: hidden !important;
display: none !important
}
.gs-webResult div.gs-per-result-labels a.gs-label {
text-decoration: underline !important;
cursor: pointer !important;
padding: 3px !important;
color: #26282a !important
}
.gs-webResult div.gs-per-result-labels a.gs-label.gs-labelActive {
cursor: default !important;
text-decoration: none !important
}
.gsc-control-cse:after {
content: "." !important;
display: block !important;
clear: both !important;
height: 0 !important;
visibility: hidden !important
}
*:first-child + html .gsc-inline-block {
display: inline !important
}
This diff is collapsed.
pre, .LegaleseLeft {
background-color: #f0f0f0;
font-family: Courier, monospace;
font-weight: 600;
vertical-align: top;
margin: 15px 85px 15px 35px;
padding: 25px;
width: 90%;
overflow-x:auto;
}
pre a[href] {
color: #5caa15;
}
p {
width: 70%;
margin: 15px 0px 10px 15px;
}
table p {
margin: 0px;
padding: 0px;
}
a[href] {
color: #007330;
text-decoration: none;
}
/* Different color for ext. links */
a[href|="http://"], a[href|="https://"] {
color: #6bb8db;
}
h1.title {
margin-top: 30px;
margin-left: 6px;
padding: 6px;
}
h2, p.h2 {
background-color: #F2F3F4;
padding: 4px;
margin: 30px 0px 20px 10px;
}
h3 {
margin: 30px 0px 30px 6px;
}
ul, ol {
margin-top: 4px;
margin-bottom: 0px;
}
ul li, ol li {
margin-bottom: 8px;
}
.mainContent li.level2 {
margin-left: 16px;
}
.rightAlign {
text-align: right;
}
h3.fn, span.fn {
border-width: 3px;
border-style: solid;
border-color: #aaaaaa;
background-color: #eeeeee;
word-spacing: 3px;
padding: 5px;
text-decoration: none;
font-weight: 400;
margin: 45px 0px 0px 6px;
}
table {
max-width: 80%;
padding: 15px 45px 15px 15px;
}
table th {
text-align: left;
padding: 8px;
}
table td {
padding: 6px 10px 6px 10px;
}
table tr.odd {
background-color: #eeeeee;
}
table.qmlname td {
padding: 0px;
margin-left: 6px;
}
table.qmlname p .name,
h3.fn .name, h3.fn .type {
font-weight: bold;
}
.context h3.fn {
font-weight: 400;
}
.qmlreadonly, .qmldefault {
font-family: Courier, monospace;
margin-right: 6px;
}
code {
font-family: Courier, monospace;
font-weight: 400;
}
p.naviNextPrevious {
text-align: right;
margin-right: 20px;
}
span.naviSeparator {
white-space: pre;
}
.toc h3 {
margin: 0px 0px 10px 6px;
}
.toc ul {
list-style-type: none;
}
.navigationbar table {
padding: 0;
margin: 0;
}
.navigationbar table tr {
background-color: #eeeeee;
}
td#buildversion {
background-color: #ffffff;
}
.footer, .footer p {
padding: 5px 0px 5px 0px;
margin: 45px 15px 5px 15px;
font-size: 8.5pt;
background-color: #cccccc;
}
.footer p {
margin: 0px;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment