diff --git a/src/QtScrcpy.pro b/src/QtScrcpy.pro
new file mode 100644
index 0000000..98eae6d
--- /dev/null
+++ b/src/QtScrcpy.pro
@@ -0,0 +1,39 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2018-10-07T12:36:10
+#
+#-------------------------------------------------
+
+QT += core gui
+QT += network
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = QtScrcpy
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+
+SOURCES += \
+ main.cpp \
+ dialog.cpp \
+ adbprocess.cpp \
+ server.cpp
+
+HEADERS += \
+ dialog.h \
+ adbprocess.h \
+ server.h
+
+FORMS += \
+ dialog.ui
diff --git a/src/QtScrcpy.pro.user b/src/QtScrcpy.pro.user
new file mode 100644
index 0000000..d29803c
--- /dev/null
+++ b/src/QtScrcpy.pro.user
@@ -0,0 +1,318 @@
+
+
+
+
+
+ EnvironmentId
+ {49c3991c-71bb-4f46-826d-1d1cf5cba2d4}
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ true
+ false
+ true
+
+ Cpp
+
+ CppGlobal
+
+
+
+ QmlJS
+
+ QmlJSGlobal
+
+
+ 2
+ UTF-8
+ false
+ 4
+ false
+ 80
+ true
+ true
+ 1
+ true
+ false
+ 0
+ true
+ true
+ 0
+ 8
+ true
+ 1
+ true
+ true
+ true
+ false
+
+
+
+ ProjectExplorer.Project.PluginSettings
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ Desktop Qt 5.9.6 MSVC2015 32bit
+ Desktop Qt 5.9.6 MSVC2015 32bit
+ qt.596.win32_msvc2015_kit
+ 0
+ 0
+ 0
+
+ G:/QT/code/build-QtScrcpy-Desktop_Qt_5_9_6_MSVC2015_32bit-Debug
+
+
+ true
+ qmake
+
+ QtProjectManager.QMakeBuildStep
+ true
+
+ false
+ false
+ false
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ false
+
+
+
+ 2
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ true
+ clean
+
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Debug
+ Debug
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 2
+ true
+
+
+ G:/QT/code/build-QtScrcpy-Desktop_Qt_5_9_6_MSVC2015_32bit-Release
+
+
+ true
+ qmake
+
+ QtProjectManager.QMakeBuildStep
+ false
+
+ false
+ false
+ false
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ false
+
+
+
+ 2
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ true
+ clean
+
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Release
+ Release
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ true
+
+
+ G:/QT/code/build-QtScrcpy-Desktop_Qt_5_9_6_MSVC2015_32bit-Profile
+
+
+ true
+ qmake
+
+ QtProjectManager.QMakeBuildStep
+ true
+
+ false
+ true
+ false
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ false
+
+
+
+ 2
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ true
+ clean
+
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Profile
+ Profile
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ true
+
+ 3
+
+
+ 0
+ 部署
+
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+ 部署设置
+
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+
+ false
+ false
+ 1000
+
+ true
+
+ false
+ false
+ false
+ false
+ true
+ 0.01
+ 10
+ true
+ 1
+ 25
+
+ 1
+ true
+ false
+ true
+ valgrind
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+
+ 2
+
+ QtScrcpy
+
+ Qt4ProjectManager.Qt4RunConfiguration:G:/QT/code/QtScrcpy/QtScrcpy.pro
+ true
+
+ QtScrcpy.pro
+ false
+
+ G:/QT/code/build-QtScrcpy-Desktop_Qt_5_9_6_MSVC2015_32bit-Debug
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+ 1
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 1
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 18
+
+
+ Version
+ 18
+
+
diff --git a/src/adbprocess.cpp b/src/adbprocess.cpp
new file mode 100644
index 0000000..036a38a
--- /dev/null
+++ b/src/adbprocess.cpp
@@ -0,0 +1,160 @@
+#include "adbprocess.h"
+
+#include
+#include
+#include
+
+QString AdbProcess::s_adbPath = "";
+
+AdbProcess::AdbProcess(QObject *parent)
+ : QProcess(parent)
+{
+ initSignals();
+}
+
+AdbProcess::~AdbProcess()
+{
+ if (isRuning()) {
+ close();
+ }
+}
+
+const QString& AdbProcess::getAdbPath()
+{
+ if (s_adbPath.isEmpty()) {
+ s_adbPath = QString::fromLocal8Bit(qgetenv("QTSCRCPY_ADB_PATH"));
+ if (s_adbPath.isEmpty()) {
+ s_adbPath = "adb";
+ }
+ }
+ return s_adbPath;
+}
+
+void AdbProcess::initSignals()
+{
+ // aboutToQuit not exit event loop, so deletelater is ok
+ //connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &AdbProcess::deleteLater);
+
+ connect(this, static_cast(&QProcess::finished), this,
+ [this](int exitCode, QProcess::ExitStatus exitStatus){
+ if (NormalExit == exitStatus && 0 == exitCode) {
+ emit adbProcessResult(AER_SUCCESS);
+ } else {
+ emit adbProcessResult(AER_ERROR_CMD);
+ }
+
+ qDebug() << ">>>>>>>>" << __FUNCTION__;
+ qDebug() << "adb return " << exitCode << "exit status " << exitStatus;
+ });
+
+ connect(this, &QProcess::errorOccurred, this,
+ [this](QProcess::ProcessError error){
+ if (QProcess::FailedToStart == error) {
+ emit adbProcessResult(AER_ERROR_MISSING_BINARY);
+ } else {
+ emit adbProcessResult(AER_ERROR_START);
+ QString err = QString("qprocess start error:%1 %2").arg(program()).arg(arguments().join(" "));
+ qCritical(err.toStdString().c_str());
+ }
+ });
+
+ connect(this, &QProcess::readyReadStandardError, this,
+ [this](){
+ qDebug() << ">>>>>>>>" << __FUNCTION__;
+ qDebug() << QString::fromLocal8Bit(readAllStandardError());
+ });
+
+ connect(this, &QProcess::readyReadStandardOutput, this,
+ [this](){
+ qDebug() << ">>>>>>>>" << __FUNCTION__;
+ qDebug() << QString::fromLocal8Bit(readAllStandardOutput());
+ });
+
+ connect(this, &QProcess::started, this,
+ [this](){
+
+ });
+}
+
+void AdbProcess::execute(const QString& serial, const QStringList& args)
+{
+ QStringList adbArgs;
+ if (!serial.isEmpty()) {
+ adbArgs << "-s" << serial;
+ }
+ adbArgs << args;
+ start(getAdbPath(), adbArgs);
+ //start("C:\\Users\\Barry\\Desktop\\sockettool.exe", Q_NULLPTR);
+}
+
+bool AdbProcess::isRuning()
+{
+ if (QProcess::NotRunning == state()) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+void AdbProcess::forward(const QString& serial, quint16 localPort, const QString& deviceSocketName)
+{
+ QStringList adbArgs;
+ adbArgs << "forward";
+ adbArgs << QString("tcp:%1").arg(localPort);
+ adbArgs << QString("localabstract:%1").arg(deviceSocketName);
+ execute(serial, adbArgs);
+}
+
+void AdbProcess::forwardRemove(const QString& serial, quint16 localPort)
+{
+ QStringList adbArgs;
+ adbArgs << "forward";
+ adbArgs << "--remove";
+ adbArgs << QString("tcp:%1").arg(localPort);
+ execute(serial, adbArgs);
+}
+
+void AdbProcess::reverse(const QString& serial, const QString& deviceSocketName, quint16 localPort)
+{
+ QStringList adbArgs;
+ adbArgs << "reverse";
+ adbArgs << QString("localabstract:%1").arg(deviceSocketName);
+ adbArgs << QString("tcp:%1").arg(localPort);
+ execute(serial, adbArgs);
+}
+
+void AdbProcess::reverseRemove(const QString& serial, const QString& deviceSocketName)
+{
+ QStringList adbArgs;
+ adbArgs << "reverse";
+ adbArgs << "--remove";
+ adbArgs << QString("localabstract:%1").arg(deviceSocketName);
+ execute(serial, adbArgs);
+}
+
+void AdbProcess::push(const QString& serial, const QString& local, const QString& remote)
+{
+ QStringList adbArgs;
+ adbArgs << "push";
+ adbArgs << local;
+ adbArgs << remote;
+ execute(serial, adbArgs);
+}
+
+void AdbProcess::install(const QString& serial, const QString& local)
+{
+ QStringList adbArgs;
+ adbArgs << "install";
+ adbArgs << "-r";
+ adbArgs << local;
+ execute(serial, adbArgs);
+}
+
+void AdbProcess::removePath(const QString& serial, const QString& path)
+{
+ QStringList adbArgs;
+ adbArgs << "shell";
+ adbArgs << "rm";
+ adbArgs << path;
+ execute(serial, adbArgs);
+}
diff --git a/src/adbprocess.h b/src/adbprocess.h
new file mode 100644
index 0000000..698dd1a
--- /dev/null
+++ b/src/adbprocess.h
@@ -0,0 +1,42 @@
+#ifndef ADBPROCESS_H
+#define ADBPROCESS_H
+
+#include
+
+class AdbProcess : public QProcess
+{
+ Q_OBJECT
+
+public:
+ enum ADB_EXEC_RESULT {
+ AER_SUCCESS, // 执行成功
+ AER_ERROR_START, // 启动失败
+ AER_ERROR_CMD, // 命令执行失败
+ AER_ERROR_MISSING_BINARY, // 找不到文件
+ };
+
+ explicit AdbProcess(QObject *parent = nullptr);
+ ~AdbProcess();
+
+ void execute(const QString& serial, const QStringList& args);
+ void forward(const QString& serial, quint16 localPort, const QString& deviceSocketName);
+ void forwardRemove(const QString& serial, quint16 localPort);
+ void reverse(const QString& serial, const QString& deviceSocketName, quint16 localPort);
+ void reverseRemove(const QString& serial, const QString& deviceSocketName);
+ void push(const QString& serial, const QString& local, const QString& remote);
+ void install(const QString& serial, const QString& local);
+ void removePath(const QString& serial, const QString& path);
+ bool isRuning();
+
+ static const QString& getAdbPath();
+
+signals:
+ void adbProcessResult(ADB_EXEC_RESULT processResult);
+
+private:
+ void initSignals();
+
+ static QString s_adbPath;
+};
+
+#endif // ADBPROCESS_H
diff --git a/src/dialog.cpp b/src/dialog.cpp
new file mode 100644
index 0000000..1a2c7db
--- /dev/null
+++ b/src/dialog.cpp
@@ -0,0 +1,24 @@
+#include "dialog.h"
+#include "ui_dialog.h"
+#include "adbprocess.h"
+
+Dialog::Dialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::Dialog)
+{
+ ui->setupUi(this);
+}
+
+Dialog::~Dialog()
+{
+ delete ui;
+}
+
+void Dialog::on_adbProcess_clicked()
+{
+ AdbProcess* adb = new AdbProcess();
+ connect(adb, &AdbProcess::adbProcessResult, this, [this](AdbProcess::ADB_EXEC_RESULT processResult){
+ sender()->deleteLater();
+ });
+ adb->execute("", QStringList() << "devices");
+}
diff --git a/src/dialog.h b/src/dialog.h
new file mode 100644
index 0000000..4152a2c
--- /dev/null
+++ b/src/dialog.h
@@ -0,0 +1,25 @@
+#ifndef DIALOG_H
+#define DIALOG_H
+
+#include
+
+namespace Ui {
+class Dialog;
+}
+
+class Dialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit Dialog(QWidget *parent = 0);
+ ~Dialog();
+
+private slots:
+ void on_adbProcess_clicked();
+
+private:
+ Ui::Dialog *ui;
+};
+
+#endif // DIALOG_H
diff --git a/src/dialog.ui b/src/dialog.ui
new file mode 100644
index 0000000..7f52460
--- /dev/null
+++ b/src/dialog.ui
@@ -0,0 +1,33 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Dialog
+
+
+
+
+ 30
+ 20
+ 93
+ 28
+
+
+
+ PushButton
+
+
+
+
+
+
+
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..99e9f01
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,17 @@
+#include "dialog.h"
+
+#include
+#include
+
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+
+ qputenv("QTSCRCPY_ADB_PATH", "C:\\Users\\Barry\\Desktop\\scrcpy-win64\\adb.exe");
+
+ Dialog w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/src/server.cpp b/src/server.cpp
new file mode 100644
index 0000000..f4172de
--- /dev/null
+++ b/src/server.cpp
@@ -0,0 +1,221 @@
+#include
+
+#include "server.h"
+
+#define DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar"
+#define SOCKET_NAME "qtscrcpy"
+
+Server::Server(QObject *parent) : QObject(parent)
+{
+ connect(&m_workProcess, &AdbProcess::adbProcessResult, this, &Server::onWorkProcessResult);
+}
+
+const QString& Server::getServerPath()
+{
+ if (m_serverPath.isEmpty()) {
+ m_serverPath = QString::fromLocal8Bit(qgetenv("QTSCRCPY_SERVER_PATH"));
+ if (m_serverPath.isEmpty()) {
+ m_serverPath = "scrcpy-server.jar";
+ }
+ }
+ return m_serverPath;
+}
+
+bool Server::pushServer()
+{
+ if (m_workProcess.isRuning()) {
+ m_workProcess.kill();
+ }
+ m_workProcess.push(m_serial, getServerPath(), DEVICE_SERVER_PATH);
+ return true;
+}
+
+bool Server::removeServer()
+{
+ if (m_workProcess.isRuning()) {
+ m_workProcess.kill();
+ }
+ m_workProcess.removePath(m_serial, DEVICE_SERVER_PATH);
+ return true;
+}
+
+bool Server::enableTunnelReverse()
+{
+ if (m_workProcess.isRuning()) {
+ m_workProcess.kill();
+ }
+ m_workProcess.reverse(m_serial, SOCKET_NAME, m_localPort);
+ return true;
+}
+
+bool Server::disableTunnelReverse()
+{
+ if (m_workProcess.isRuning()) {
+ m_workProcess.kill();
+ }
+ m_workProcess.reverseRemove(m_serial, SOCKET_NAME);
+ return true;
+}
+
+bool Server::enableTunnelForward()
+{
+ if (m_workProcess.isRuning()) {
+ m_workProcess.kill();
+ }
+ m_workProcess.forward(m_serial, m_localPort, SOCKET_NAME);
+ return true;
+}
+bool Server::disableTunnelForward()
+{
+ if (m_workProcess.isRuning()) {
+ m_workProcess.kill();
+ }
+ m_workProcess.forwardRemove(m_serial, m_localPort);
+ return true;
+}
+
+bool Server::execute()
+{
+ AdbProcess* adb = new AdbProcess();
+ if (!adb) {
+ return false;
+ }
+ QStringList args;
+ args << "shell";
+ args << QString("CLASSPATH=%1").arg(DEVICE_SERVER_PATH);
+ args << "app_process";
+ args << "/"; // unused;
+ args << "com.genymobile.scrcpy.Server";
+ args << QString::number(m_maxSize);
+ args << QString::number(m_bitRate);
+ args << (m_tunnelForward ? "true" : "false");
+ args << (m_crop.isEmpty() ? "" : m_crop);
+
+ connect(adb, &AdbProcess::adbProcessResult, this, [this](AdbProcess::ADB_EXEC_RESULT processResult){
+ if (AdbProcess::AER_SUCCESS == processResult) {
+
+ }
+ sender()->deleteLater();
+ });
+ adb->execute(m_serial, args);
+ return true;
+}
+
+bool Server::start(const QString& serial, quint16 localPort, quint16 maxSize, quint32 bitRate, const QString& crop)
+{
+ if (serial.isEmpty()) {
+ return false;
+ }
+
+ m_localPort = localPort;
+ m_maxSize = maxSize;
+ m_bitRate = bitRate;
+ m_crop = crop;
+
+ m_serverStartStep = SSS_PUSH;
+ return startServerByStep();
+}
+
+bool Server::startServerByStep()
+{
+ // push, enable tunnel et start the server
+ if (SSS_NULL != m_serverStartStep) {
+ switch (m_serverStartStep) {
+ case SSS_PUSH:
+ return pushServer();
+ case SSS_ENABLE_TUNNEL_REVERSE:
+ return enableTunnelReverse();
+ break;
+ case SSS_ENABLE_TUNNEL_FORWARD:
+ return enableTunnelForward();
+ break;
+ case SSS_EXECUTE_SERVER:
+ // if "adb reverse" does not work (e.g. over "adb connect"), it fallbacks to
+ // "adb forward", so the app socket is the client
+ if (m_tunnelForward) {
+ // At the application level, the device part is "the server" because it
+ // serves video stream and control. However, at the network level, the
+ // client listens and the server connects to the client. That way, the
+ // client can listen before starting the server app, so there is no need to
+ // try to connect until the server socket is listening on the device.
+ m_serverSocket.setMaxPendingConnections(1);
+ if (!m_serverSocket.listen(QHostAddress::LocalHost, m_localPort)) {
+ qCritical(QString("Could not listen on port %1").arg(m_localPort).toStdString().c_str());
+ m_serverStartStep = SSS_NULL;
+ if (m_tunnelForward) {
+ disableTunnelForward();
+ } else {
+ disableTunnelReverse();
+ }
+ emit serverStartResult(false);
+ return false;
+ }
+ }
+ // server will connect to our server socket
+ return execute();
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
+void Server::onWorkProcessResult(AdbProcess::ADB_EXEC_RESULT processResult)
+{
+ if (SSS_NULL != m_serverStartStep) {
+ switch (m_serverStartStep) {
+ case SSS_PUSH:
+ if (AdbProcess::AER_SUCCESS != processResult) {
+ qCritical("adb push");
+ m_serverStartStep = SSS_NULL;
+ emit serverStartResult(false);
+ } else {
+ m_serverCopiedToDevice = true;
+ m_serverStartStep = SSS_ENABLE_TUNNEL_REVERSE;
+ startServerByStep();
+ }
+ break;
+ case SSS_ENABLE_TUNNEL_REVERSE:
+ if (AdbProcess::AER_SUCCESS != processResult) {
+ qCritical("adb reverse");
+ m_tunnelForward = true;
+ m_serverStartStep = SSS_ENABLE_TUNNEL_FORWARD;
+ startServerByStep();
+ } else {
+ m_serverStartStep = SSS_EXECUTE_SERVER;
+ startServerByStep();
+ }
+ break;
+ case SSS_ENABLE_TUNNEL_FORWARD:
+ if (AdbProcess::AER_SUCCESS != processResult) {
+ qCritical("adb forward");
+ m_serverStartStep = SSS_NULL;
+ emit serverStartResult(false);
+ } else {
+ m_serverStartStep = SSS_EXECUTE_SERVER;
+ startServerByStep();
+ }
+ break;
+ case SSS_EXECUTE_SERVER:
+ if (AdbProcess::AER_SUCCESS != processResult) {
+ if (!m_tunnelForward) {
+ m_serverSocket.close();
+ disableTunnelReverse();
+ } else {
+ disableTunnelForward();
+ }
+ qCritical("adb shell start server failed");
+ m_serverStartStep = SSS_NULL;
+ emit serverStartResult(false);
+ } else {
+ m_serverStartStep = SSS_NULL;
+ m_tunnelEnabled = true;
+ emit serverStartResult(true);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/src/server.h b/src/server.h
new file mode 100644
index 0000000..7c77bec
--- /dev/null
+++ b/src/server.h
@@ -0,0 +1,62 @@
+#ifndef SERVER_H
+#define SERVER_H
+
+#include
+#include
+#include
+
+#include "adbprocess.h"
+
+class Server : public QObject
+{
+ Q_OBJECT
+
+ enum SERVER_START_STEP {
+ SSS_NULL,
+ SSS_PUSH,
+ SSS_ENABLE_TUNNEL_REVERSE,
+ SSS_ENABLE_TUNNEL_FORWARD,
+ SSS_EXECUTE_SERVER,
+ };
+public:
+ explicit Server(QObject *parent = nullptr);
+
+ bool start(const QString& serial, quint16 localPort, quint16 maxSize, quint32 bitRate, const QString& crop);
+
+ bool pushServer();
+ bool removeServer();
+ bool enableTunnelReverse();
+ bool disableTunnelReverse();
+ bool enableTunnelForward();
+ bool disableTunnelForward();
+
+ bool execute();
+
+signals:
+ void serverStartResult(bool success);
+
+public slots:
+ void onWorkProcessResult(AdbProcess::ADB_EXEC_RESULT processResult);
+
+private:
+ const QString& getServerPath();
+ bool startServerByStep();
+
+ QString m_serverPath = "";
+ AdbProcess m_workProcess;
+ QString m_serial = "";
+ AdbProcess m_serverProcess;
+ QTcpServer m_serverSocket; // only used if !tunnel_forward
+ QTcpSocket m_deviceSocket;
+ quint16 m_localPort = 0;
+ bool m_tunnelEnabled = false;
+ bool m_tunnelForward = false; // use "adb forward" instead of "adb reverse"
+ bool m_serverCopiedToDevice = false;
+ quint16 m_maxSize = 0;
+ quint32 m_bitRate = 0;
+ QString m_crop = "";
+
+ SERVER_START_STEP m_serverStartStep = SSS_NULL;
+};
+
+#endif // SERVER_H