Client app template and ui

This commit is contained in:
pokamest
2020-11-23 16:20:25 +03:00
parent 3006c67472
commit f68415f08e
53 changed files with 4280 additions and 0 deletions
+102
View File
@@ -0,0 +1,102 @@
QT += widgets core gui network xml
TARGET = amnezia-client
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
win32 {
#win32-g++ {
# QMAKE_CXXFLAGS += -Werror
#}
#win32-msvc*{
# QMAKE_CXXFLAGS += /WX
#}
FORMS += ui/mainwindow.ui
RESOURCES += \
res.qrc
OTHER_FILES += platform_win/vpnclient.rc
RC_FILE = platform_win/vpnclient.rc
HEADERS += publib/winhelp.h
SOURCES += publib/winhelp.cpp
CONFIG -= embed_manifest_exe
DEFINES += _CRT_SECURE_NO_WARNINGS VPNCLIENT_TAPSIGNED
#QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
VERSION = 1.1.1.1
QMAKE_TARGET_COMPANY = "AmneziaVPN"
QMAKE_TARGET_PRODUCT = "AmneziaVPN"
CONFIG -= embed_manifest_exe
LIBS += -luser32 \
-lrasapi32 \
-lshlwapi \
-liphlpapi \
-lws2_32 \
-liphlpapi \
-lgdi32
MT_PATH = \"C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/bin/x64/mt.exe\"
WIN_PWD = $$replace(PWD, /, \\)
OUT_PWD_WIN = $$replace(OUT_PWD, /, \\)
!win32-g++: QMAKE_POST_LINK = "$$MT_PATH -manifest $$quote($$WIN_PWD\\platform_win\\$$basename(TARGET).exe.manifest) -outputresource:$$quote($$OUT_PWD_WIN\\$(DESTDIR_TARGET);1)"
else: QMAKE_POST_LINK = "$$MT_PATH -manifest $$PWD/platform_win/$$basename(TARGET).exe.manifest -outputresource:$$OUT_PWD/$(DESTDIR_TARGET)"
}
macx {
OBJECTIVE_HEADERS +=
OBJECTIVE_SOURCES += publib/macos_functions.mm
HEADERS += \
SOURCES += \
QMAKE_OBJECTIVE_CFLAGS += -F/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks
FORMS += ui/mainwindow_mac.ui
LIBS += -framework CoreServices -framework Foundation -framework AppKit
RESOURCES += \
res_mac.qrc
ICON = images/main.icns
}
SOURCES += main.cpp\
publib/debug.cpp \
publib/runguard.cpp \
publib/winhelp.cpp \
ui/Controls/SlidingStackedWidget.cpp \
ui/mainwindow.cpp \
ui/customshadoweffect.cpp
HEADERS += ui/mainwindow.h \
publib/debug.h \
publib/runguard.h \
publib/winhelp.h \
ui/customshadoweffect.h \
ui/Controls/SlidingStackedWidget.h
FORMS += ui/mainwindow.ui
TRANSLATIONS = translations/amneziavpn.en.ts \
translations/amneziavpn.ru.ts
win32: LIBS += -L$$PWD/../../../../../../../OpenSSL-Win32/lib/ -llibcrypto
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

+109
View File
@@ -0,0 +1,109 @@
#include <QApplication>
#include <QFontDatabase>
#include <QCommandLineParser>
#include <QMessageBox>
#include <QFile>
#include <QTranslator>
#include <QLibraryInfo>
#include "publib/runguard.h"
#include "publib/debug.h"
#include "ui/mainwindow.h"
#ifdef Q_OS_WIN
#include <Windows.h>
#endif
#define ApplicationName "AmneziaVPN"
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(res);
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
RunGuard::instance(ApplicationName).activate();
QApplication app(argc, argv);
if (! RunGuard::instance().tryToRun()) {
qDebug() << "Tried to run second instance. Exiting...";
QMessageBox::information(NULL, QObject::tr("Notify"), QObject::tr("AmneziaVPN is already running."));
return 0;
}
QFontDatabase::addApplicationFont(":/fonts/Lato-Black.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-BlackItalic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Bold.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-BoldItalic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Italic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Light.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-LightItalic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Regular.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Thin.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-ThinItalic.ttf");
{
QTranslator *translator = new QTranslator;
QLocale ru(QLocale("ru_RU"));
QLocale::setDefault(ru);
if (translator->load(QLocale(), "amnezia-client", ".", QLatin1String(":/translations"))) {
bool ok = qApp->installTranslator(translator);
qDebug().noquote() << "Main: Installing translator for locale" << ru.name() << ok;
}
else {
qDebug().noquote() << "Main: Failed to install translator for locale" << ru.name();
}
}
app.setOrganizationName("AmneziaVPN");
app.setOrganizationDomain("AmneziaVPN.ORG");
app.setApplicationName(ApplicationName);
app.setApplicationDisplayName(ApplicationName);
app.setApplicationVersion("1.0.0.0");
//app.setQuitOnLastWindowClosed(false);
QCommandLineParser parser;
parser.setApplicationDescription("AmneziaVPN");
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption debugToConsoleOption("d", QCoreApplication::translate("main", "Output to console instead log file"));
parser.addOption(debugToConsoleOption);
#ifdef Q_OS_MAC
QCommandLineOption forceUseBrightIconsOption("b", QCoreApplication::translate("main", "Force use bright icons"));
parser.addOption(forceUseBrightIconsOption);
#endif
// Process the actual command line arguments given by the user
parser.process(app);
bool debugToConsole = parser.isSet(debugToConsoleOption);
bool forceUseBrightIcons = false;
#ifdef Q_OS_MAC
forceUseBrightIcons = parser.isSet(forceUseBrightIconsOption);
#endif
qDebug() << "Set output to console: " << debugToConsole;
if (!debugToConsole) {
if (!Debug::init()) {
qCritical() << "Initialization of debug subsystem failed";
}
}
QFont f("Lato Regular", 10);
f.setStyleStrategy(QFont::PreferAntialias);
app.setFont(f);
MainWindow mainWindow(forceUseBrightIcons);
mainWindow.show();
return app.exec();
}
+48
View File
@@ -0,0 +1,48 @@
#include <windows.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDI_ICON1 ICON "../images/main.ico"
#define VER_FILEVERSION 1,1,1,1
#define VER_FILEVERSION_STR "1.1.1.1\0"
#define VER_PRODUCTVERSION 1,1,1,1
#define VER_PRODUCTVERSION_STR "1.1.1.1\0"
#define VER_COMPANYNAME_STR "AmneziaVPN"
#define VER_FILEDESCRIPTION_STR "AmneziaVPN"
#define VER_INTERNALNAME_STR "AmneziaVPN"
#define VER_LEGALCOPYRIGHT_STR "AmneziaVPN."
#define VER_LEGALTRADEMARKS1_STR "All Rights Reserved"
#define VER_LEGALTRADEMARKS2_STR VER_LEGALTRADEMARKS1_STR
#define VER_ORIGINALFILENAME_STR "amneziavpn.exe"
#define VER_PRODUCTNAME_STR "AmneziaVPN"
#define VER_COMPANYDOMAIN_STR "http://amnezia.org/"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", VER_COMPANYNAME_STR
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", VER_INTERNALNAME_STR
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
VALUE "LegalTrademarks1", VER_LEGALTRADEMARKS1_STR
VALUE "LegalTrademarks2", VER_LEGALTRADEMARKS2_STR
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
VALUE "ProductName", VER_PRODUCTNAME_STR
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
+130
View File
@@ -0,0 +1,130 @@
#include "debug.h"
#include <QDir>
#include <QStandardPaths>
#include <QDebug>
#include <QCoreApplication>
#include <QDateTime>
#define LOGS_DIR "logs"
#define CLIENT_LOG_SUFFIX "amneziavpn.log"
#define MAX_LOG_FILES 5
#define FORMAT_STRING "yyyy-MM-dd--hh-mm-ss"
QFile Debug::m_clientLog;
QTextStream Debug::m_clientLogTextStream;
QString Debug::m_clientLogName;
void debugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// Skip Qt warnings
if (msg.contains("known incorrect sRGB profile")) return;
if (msg.contains("libpng warning")) return;
if (msg.contains("Unknown property ffont")) return;
Debug::m_clientLogTextStream << qFormatLogMessage(type, context, msg) << endl << flush;
}
bool Debug::init()
{
QString path = qApp->applicationDirPath();
QDir appDir(path);
// init function is called before exec application, so data location folder may not exist
if (!appDir.exists())
{
qWarning() << "Debug: init: log directory doesn't exist or mkpath command error:" << path;
return false;
}
if (!appDir.exists(LOGS_DIR) && !appDir.mkdir(LOGS_DIR))
{
qWarning() << "Debug: init: log directory doesn't exist or mkdir command error:" << path << LOGS_DIR;
return false;
}
if (!appDir.cd(LOGS_DIR))
{
qWarning() << "Debug: init: cd command error:" << path << LOGS_DIR;
return false;
}
//delete older log files
auto clientLogsCount = 0;
QFileInfoList logDirList = appDir.entryInfoList(
QDir::Files | QDir::NoDotAndDotDot,
QDir::Time);
for (auto fileInfo : logDirList)
{
if ((fileInfo.completeSuffix() == CLIENT_LOG_SUFFIX &&
++clientLogsCount > MAX_LOG_FILES))
{
appDir.remove(fileInfo.filePath());
}
}
//prepare log file names
auto currentDateTime = QDateTime::currentDateTime().toString(FORMAT_STRING);
m_clientLogName = QString("%1.%2").arg(currentDateTime).arg(CLIENT_LOG_SUFFIX);
return init(appDir);
}
bool Debug::init(QDir& appDir)
{
Q_UNUSED(appDir)
qSetMessagePattern("[%{time}|%{type}] %{message}");
#ifndef QT_DEBUG
m_clientLog.setFileName(appDir.filePath(m_clientLogName));
if (!m_clientLog.open(QIODevice::WriteOnly | QIODevice::Append)) {
qWarning() << "Debug::init - failed to open m_clientLog file:" << m_clientLogName;
return false;
}
m_clientLog.setTextModeEnabled(true);
m_clientLogTextStream.setDevice(&m_clientLog);
qInstallMessageHandler(debugMessageHandler);
#else
#ifdef DEBUG_OUTPUT_TWO_DIRECTIONAL
m_clientLog.setFileName(appDir.filePath(m_clientLogName));
if (!m_clientLog.open(QIODevice::WriteOnly | QIODevice::Append))
return false;
m_clientLog.setTextModeEnabled(true);
m_clientLogTextStream.setDevice(&m_clientLog);
defaultMessageHandler = qInstallMessageHandler(debugMessageHandler);
#endif
#endif
#ifndef Q_OS_WIN
if (!fixOvpnLogPermissions())
qWarning() << "Debug: permissions for ovpn.log were not fixed";
#endif
return true;
}
QString Debug::getPathToClientLog()
{
QString path = qApp->applicationDirPath();
QDir appDir(path);
if (!appDir.exists(LOGS_DIR) || !appDir.cd(LOGS_DIR))
{
qWarning() << "Debug: log directory doesn't exist or cd command error:" << path;
return "";
}
return appDir.filePath(m_clientLogName);
}
QString Debug::getPathToLogsDir()
{
QString path = qApp->applicationDirPath();
QDir appDir(path);
if (!appDir.exists(LOGS_DIR) || !appDir.cd(LOGS_DIR))
{
qWarning() << "Debug: log directory doesn't exist or cd command error" << path;
return "";
}
return appDir.absolutePath();
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef DEBUG_H
#define DEBUG_H
#include <QFile>
#include <QTextStream>
#include <QString>
#include <QDir>
class Debug
{
public:
static bool init();
static QString getPathToClientLog();
static QString getPathToLogsDir();
private:
static bool init(QDir& appDir);
private:
static QFile m_clientLog;
static QTextStream m_clientLogTextStream;
static QString m_clientLogName;
friend void debugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
};
#endif // DEBUG_H
+88
View File
@@ -0,0 +1,88 @@
#include "runguard.h"
#include <QCryptographicHash>
namespace
{
QString generateKeyHash( const QString& key, const QString& salt )
{
QByteArray data;
data.append( key.toUtf8() );
data.append( salt.toUtf8() );
data = QCryptographicHash::hash( data, QCryptographicHash::Sha1 ).toHex();
return data;
}
}
RunGuard::RunGuard(const QString& key)
: key( key )
, memLockKey( generateKeyHash( key, "_memLockKey" ) )
, sharedmemKey( generateKeyHash( key, "_sharedmemKey" ) )
, sharedMem( sharedmemKey )
, memLock( memLockKey, 1 )
{
qDebug() << "RunGuard::RunGuard key" << key;
}
RunGuard &RunGuard::instance(const QString& key)
{
static RunGuard s(key);
return s;
}
void RunGuard::activate()
{
memLock.acquire();
{
QSharedMemory fix(sharedmemKey); // Fix for *nix: http://habrahabr.ru/post/173281/
fix.attach();
}
memLock.release();
}
RunGuard::~RunGuard()
{
release();
}
bool RunGuard::isAnotherRunning() const
{
if ( sharedMem.isAttached() )
return false;
memLock.acquire();
const bool isRunning = sharedMem.attach();
if ( isRunning )
sharedMem.detach();
memLock.release();
return isRunning;
}
bool RunGuard::tryToRun()
{
if ( isAnotherRunning() ) // Extra check
return false;
memLock.acquire();
const bool result = sharedMem.create( sizeof( quint64 ) );
memLock.release();
if ( !result )
{
release();
return false;
}
return true;
}
void RunGuard::release()
{
memLock.acquire();
if ( sharedMem.isAttached() )
sharedMem.detach();
memLock.release();
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef RUNGUARD_H
#define RUNGUARD_H
#include <QObject>
#include <QSharedMemory>
#include <QSystemSemaphore>
#include <QDebug>
/**
* @brief The RunGuard class - The application single instance (via shared memory)
*/
class RunGuard
{
public:
static RunGuard &instance(const QString& key = QString());
~RunGuard();
void activate();
bool isAnotherRunning() const;
bool tryToRun();
void release();
private:
RunGuard(const QString& key);
Q_DISABLE_COPY( RunGuard )
const QString key;
const QString memLockKey;
const QString sharedmemKey;
mutable QSharedMemory sharedMem;
mutable QSystemSemaphore memLock;
};
#endif // RUNGUARD_H
+261
View File
@@ -0,0 +1,261 @@
#include "winhelp.h"
#include <stdio.h>
#include <Windows.h>
#include <Shlwapi.h>
#include <TlHelp32.h>
#include <Ras.h>
#include <iphlpapi.h>
#define REG_AUTORUN_PATH "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
int winhelpGetRegistry(const char *name, const char *reg, char *value)
{
unsigned long nType = REG_SZ, nData = MAX_PATH;
if(ERROR_SUCCESS != SHGetValueA(HKEY_CURRENT_USER, reg,
name, &nType, value, &nData))
return -1;
return 1;
}
int winhelpSetRegistry(const char *name, const char *reg, const char *value)
{
if(ERROR_SUCCESS != SHSetValueA(HKEY_CURRENT_USER, reg,
name, REG_SZ, value, (DWORD)strlen(value)))
return -1;
return 1;
}
int winhelpLaunchStartupRegister(const char *name, int enable, const char *p)
{
char path[MAX_PATH] = {0};
if(p && strlen(p) == 0)
p = NULL;
if(p) {
if(enable)
strcpy(path, "\"");
else
strcpy(path, ";\"");
GetModuleFileNameA(NULL, path + strlen(path), MAX_PATH);
strcat(path, "\" ");
strcat(path, p);
} else {
if(enable)
strcpy(path, "");
else
strcpy(path, ";");
GetModuleFileNameA(NULL, path + strlen(path), MAX_PATH);
}
if(winhelpSetRegistry(name, REG_AUTORUN_PATH, path) < 0)
return -1;
return 1;
}
/* use the task scheduler, we do not need to care about UAC when start up */
int winhelpLaunchStartupTaskScheduler(const char *name, int enable, const char *p)
{
char cmd[MAX_PATH * 10] = {0};
char path[MAX_PATH] = {0};
UINT i = 0;
GetModuleFileNameA(NULL, path, MAX_PATH);
if (QString(path).contains("build-vpn-")) {
qDebug() << "winhelpLaunchStartupTaskScheduler : skipping auto launch for build dir";
return 0;
}
if(enable) {
if(p == NULL)
p = "";
sprintf(cmd, "schtasks /create /sc onlogon /tr \"\\\"%s\\\" %s\" "
"/tn \"%s\" /f /rl highest", path, p, name);
} else {
sprintf(cmd, "schtasks /delete /tn \"%s\" /f", name);
}
qDebug().noquote() << "winhelpLaunchStartupTaskScheduler cmd:" << cmd;
i = WinExec(cmd, SW_HIDE);
return 1;
}
int winhelpLaunchStartup(const char *name, int enable, const char *p)
{
OSVERSIONINFOA info = {0};
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if(GetVersionExA(&info) < 0)
return -2;
if(info.dwMajorVersion >= 6)
return winhelpLaunchStartupTaskScheduler(name, enable, p);
else
return winhelpLaunchStartupRegister(name, enable, p);
}
int str2int(const char *s)
{
int r = 0;
while(*s && *(s + 1) && *(s + 2) && *(s + 3)) {
r += ((const int *)s)[0];
s += 4;
}
return r;
}
int winhelpOneProcess()
{
char path[MAX_PATH] = {0};
int i = 0, size = 0, cur = 0;
GetModuleFileNameA(NULL, path, MAX_PATH);
size = strlen(path);
for(i = size; i >= 0 && path[i] != '\\' ; i--);
cur = i + 1;
while(path[i] != '.' && path[i])i++;
path[i] = '\0';
sprintf(path, "ONE_%s", path + cur);
CreateEventA(NULL, FALSE, FALSE, path);
if(GetLastError())
return 0;
return 1;
}
int winhelpSystemBits()
{
typedef BOOL (WINAPI *LPFN_ISWOW64)(HANDLE, PBOOL);
int b64 = FALSE;
LPFN_ISWOW64 fnIsWow64 = (LPFN_ISWOW64)GetProcAddress(
GetModuleHandleA("kernel32"), "IsWow64Process");
if(NULL != fnIsWow64) {
if(!fnIsWow64(GetCurrentProcess(),&b64)) {
return -1;
}
}
return b64 ? 64 : 86;
}
bool winhelpIsSystem_x64()
{
typedef BOOL (WINAPI *LPFN_ISWOW64)(HANDLE, PBOOL);
int b64 = FALSE;
LPFN_ISWOW64 fnIsWow64 = (LPFN_ISWOW64)GetProcAddress(
GetModuleHandleA("kernel32"), "IsWow64Process");
if(NULL != fnIsWow64) {
if(!fnIsWow64(GetCurrentProcess(),&b64)) {
return false;
}
}
return b64 ? true : false;
}
typedef struct _PROCESS_QUERY
{
HANDLE h;
PROCESSENTRY32 d;
}PROCESS_QUERY;
int winhelpProcessQuery(void **p)
{
PROCESS_QUERY *q = (PROCESS_QUERY *)malloc(sizeof(PROCESS_QUERY));
if(q == NULL)
return -2;
q->h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(q->h == INVALID_HANDLE_VALUE) {
free(q);
return -1;
}
if(FALSE == Process32First(q->h, &q->d)) {
CloseHandle(q->h);
free(q);
return -3;
}
*p = (void *)q;
return 1;
}
int winhelpProcessNext(void *h, char *name)
{
PROCESS_QUERY *q = (PROCESS_QUERY *)h;
int pid = 0;
if(q == NULL)
return 0;
if(q->h == NULL) {
free(q);
return 0;
}
if(name)
wsprintfA(name, "%ls", q->d.szExeFile);
pid = (int)q->d.th32ProcessID;
if(FALSE == Process32Next(q->h, &q->d)) {
CloseHandle(q->h);
q->h = NULL;
}
return pid;
}
int winhelpRecvEvent(const char *event)
{
HANDLE hEvent = CreateEventA(NULL, FALSE, FALSE, event);
if(hEvent == NULL)
return 0;
WaitForSingleObject(hEvent, INFINITE);
CloseHandle(hEvent);
return 1;
}
int winhelpSendEvent(const char *event)
{
HANDLE hEvent = OpenEventA(EVENT_ALL_ACCESS, FALSE, event);
if(hEvent == NULL)
return 0;
SetEvent(hEvent);
CloseHandle(hEvent);
return 1;
}
int winhelpSystemVersion()
{
OSVERSIONINFOA ver = {0};
int version = 0;
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
GetVersionExA(&ver);
version = ver.dwMajorVersion * 0x100 + ver.dwMinorVersion;
return version;
}
int winhelperSetMTUSize(const char *subname, int size)
{
char cmd[MAX_PATH] = {0};
sprintf(cmd, "netsh interface ipv4 set subinterface \"%s\" mtu=%d store=persistent",
subname, size);
return (int)WinExec(cmd, SW_HIDE);
}
int winhelpRecvSendBytes(const char *dev, int *recv, int *send)
{
MIB_IFTABLE *it = NULL;
DWORD size = sizeof(MIB_IFTABLE), ret = 0, i = 0;
DWORD tr = 0, ts = 0;
if(it = (MIB_IFTABLE *)malloc(sizeof (MIB_IFTABLE)), it == NULL)
return -1;
if(GetIfTable(it, &size, FALSE) == ERROR_INSUFFICIENT_BUFFER) {
free(it);
if(it = (MIB_IFTABLE *)malloc(size), it == NULL)
return -2;
}
if(ret = GetIfTable(it, &size, FALSE), ret != NO_ERROR) {
free(it);
return -3;
}
for(i = 0; i < it->dwNumEntries; i++) {
MIB_IFROW *ir = &it->table[i];
if(strstr((const char *)ir->bDescr, dev) == 0)
continue;
tr += (int)ir->dwInOctets;
ts += (int)ir->dwOutOctets;
}
*recv = tr;
*send = ts;
free(it);
return 1;
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef WINHELP_H
#define WINHELP_H
#include <QDebug>
#ifdef __cplusplus
extern "C" {
#endif
extern int winhelpLaunchStartup(const char *, int, const char *);
extern int winhelpOneProcess();
extern int winhelpSystemBits();
extern bool winhelpIsSystem_x64();
extern int winhelpProcessQuery(void **);
extern int winhelpProcessNext(void *, char *);
extern int winhelpRecvEvent(const char *);
extern int winhelpSendEvent(const char *);
extern int winhelpSystemVersion();
extern int winhelperSetMTUSize(const char *, int);
extern int winhelpRecvSendBytes(const char *, int *, int *);
#ifdef __cplusplus
}
#endif
#endif /* WINHELP_H */
+39
View File
@@ -0,0 +1,39 @@
<RCC>
<qresource prefix="/">
<file>images/close.png</file>
<file>images/listitembg.png</file>
<file>images/settings.png</file>
<file>images/underline.png</file>
<file>images/min.png</file>
<file>images/favorites_disabled.png</file>
<file>images/favorites_enabled.png</file>
<file>images/favorites_hover.png</file>
<file>images/controls/check_off.png</file>
<file>images/controls/check_on.png</file>
<file>images/controls/radio_off.png</file>
<file>images/controls/radio_on.png</file>
<file>images/connected_line.png</file>
<file>images/download.png</file>
<file>images/upload.png</file>
<file>images/controls/checkbox_hover.png</file>
<file>images/controls/checkbox_unchecked.png</file>
<file>images/tray/active.png</file>
<file>images/tray/default.png</file>
<file>images/tray/error.png</file>
<file>images/arrow_left.png</file>
<file>images/connect_button_connected.png</file>
<file>images/connect_button_disconnected.png</file>
<file>fonts/Lato-Black.ttf</file>
<file>fonts/Lato-BlackItalic.ttf</file>
<file>fonts/Lato-Bold.ttf</file>
<file>fonts/Lato-BoldItalic.ttf</file>
<file>fonts/Lato-Italic.ttf</file>
<file>fonts/Lato-Light.ttf</file>
<file>fonts/Lato-LightItalic.ttf</file>
<file>fonts/Lato-Regular.ttf</file>
<file>fonts/Lato-Thin.ttf</file>
<file>fonts/Lato-ThinItalic.ttf</file>
<file>images/Line.png</file>
<file>images/AmneziaVPN.png</file>
</qresource>
</RCC>
+193
View File
@@ -0,0 +1,193 @@
#include "SlidingStackedWidget.h"
SlidingStackedWidget::SlidingStackedWidget(QWidget *parent)
: QStackedWidget(parent)
{
if (parent != 0) {
m_mainwindow = parent;
}
else {
m_mainwindow = this;
qDebug().noquote() << "ATTENTION: untested mainwindow case !";
}
// parent should not be 0; not tested for any other case yet !!
#ifdef Q_OS_SYMBIAN
#ifndef __S60_50__
qDebug().noquote() << "WARNING: ONLY TESTED AND 5TH EDITION";
#endif // __S60_50__
#endif // Q_OS_SYMBIAN
// Now, initialize some private variables with default values
m_vertical = false;
// setVerticalMode(true);
m_speed = 500;
m_animationtype = QEasingCurve::OutBack; // check out the QEasingCurve documentation for different styles
m_now = 0;
m_next = 0;
m_wrap = false;
m_pnow = QPoint(0,0);
m_active = false;
}
SlidingStackedWidget::~SlidingStackedWidget() {
}
void SlidingStackedWidget::setVerticalMode(bool vertical) {
m_vertical = vertical;
}
void SlidingStackedWidget::setSpeed(int speed) {
m_speed = speed;
}
void SlidingStackedWidget::setAnimation(enum QEasingCurve::Type animationtype) {
m_animationtype = animationtype;
}
void SlidingStackedWidget::setWrap(bool wrap) {
m_wrap = wrap;
}
void SlidingStackedWidget::slideInNext() {
int now = currentIndex();
if (m_wrap || (now < count() - 1))
// count is inherit from QStackedWidget
slideInIdx(now + 1);
}
void SlidingStackedWidget::slideInPrev() {
int now = currentIndex();
if (m_wrap || (now > 0))
slideInIdx(now - 1);
}
void SlidingStackedWidget::slideInIdx(int idx, enum t_direction direction) {
// int idx, t_direction direction=AUTOMATIC
if (idx > count() - 1) {
direction = m_vertical ? TOP2BOTTOM : RIGHT2LEFT;
idx = (idx) % count();
}
else if (idx < 0) {
direction = m_vertical ? BOTTOM2TOP: LEFT2RIGHT;
idx = (idx + count()) % count();
}
slideInWgtImpl(widget(idx), direction);
// widget() is a function inherited from QStackedWidget
}
void SlidingStackedWidget::slideInWidget(QWidget *widget, SlidingStackedWidget::t_direction direction)
{
Q_UNUSED(direction);
#ifdef Q_OS_WIN
int idx = indexOf(widget);
slideInIdx(idx, direction);
#endif
#ifdef Q_OS_MAC
setCurrentWidget(widget);
#endif
}
void SlidingStackedWidget::slideInWgtImpl(QWidget * newwidget, enum t_direction direction) {
if (m_active) {
return;
}
else m_active = true;
enum t_direction directionhint;
int now = currentIndex(); // currentIndex() is a function inherited from QStackedWidget
int next = indexOf(newwidget);
if (now == next) {
m_active = false;
return;
}
else if (now < next) {
directionhint = m_vertical ? TOP2BOTTOM : RIGHT2LEFT;
}
else {
directionhint = m_vertical ? BOTTOM2TOP : LEFT2RIGHT;
}
if (direction == AUTOMATIC) {
direction = directionhint;
}
// NOW....
// calculate the shifts
int offsetx = frameRect().width(); // inherited from mother
int offsety = frameRect().height(); // inherited from mother
// the following is important, to ensure that the new widget
// has correct geometry information when sliding in first time
widget(next)->setGeometry(0, 0, offsetx, offsety);
if (direction == BOTTOM2TOP) {
offsetx = 0;
offsety = -offsety;
}
else if (direction == TOP2BOTTOM) {
offsetx = 0;
// offsety = offsety;
}
else if (direction == RIGHT2LEFT) {
offsetx = -offsetx;
offsety = 0;
}
else if (direction == LEFT2RIGHT) {
// offsetx = offsetx;
offsety = 0;
}
// re-position the next widget outside/aside of the display area
QPoint pnext = widget(next)->pos();
QPoint pnow = widget(now)->pos();
m_pnow = pnow;
widget(next)->move(pnext.x() - offsetx, pnext.y() - offsety);
// make it visible/show
widget(next)->show();
widget(next)->raise();
// animate both, the now and next widget to the side, using animation framework
QPropertyAnimation *animnow = new QPropertyAnimation(widget(now), "pos");
animnow->setDuration(m_speed);
animnow->setEasingCurve(m_animationtype);
animnow->setStartValue(QPoint(pnow.x(), pnow.y()));
animnow->setEndValue(QPoint(offsetx + pnow.x(), offsety + pnow.y()));
QPropertyAnimation *animnext = new QPropertyAnimation(widget(next), "pos");
animnext->setDuration(m_speed);
animnext->setEasingCurve(m_animationtype);
animnext->setStartValue(QPoint(-offsetx + pnext.x(), offsety + pnext.y()));
animnext->setEndValue(QPoint(pnext.x(), pnext.y()));
QParallelAnimationGroup *animgroup = new QParallelAnimationGroup;
animgroup->addAnimation(animnow);
animgroup->addAnimation(animnext);
QObject::connect(animgroup, SIGNAL(finished()),this,SLOT(animationDoneSlot()));
m_next = next;
m_now = now;
m_active = true;
animgroup->start();
// note; the rest is done via a connect from the animation ready;
// animation->finished() provides a signal when animation is done;
// so we connect this to some post processing slot,
// that we implement here below in animationDoneSlot.
}
void SlidingStackedWidget::animationDoneSlot(void) {
// when ready, call the QStackedWidget slot setCurrentIndex(int)
setCurrentIndex(m_next); // this function is inherited from QStackedWidget
// then hide the outshifted widget now, and (may be done already implicitely by QStackedWidget)
widget(m_now)->hide();
// then set the position of the outshifted widget now back to its original
widget(m_now)->move(m_pnow);
// so that the application could also still call the QStackedWidget original functions/slots for changings
// widget(m_now)->update();
// setCurrentIndex(m_next); // this function is inherit from QStackedWidget
m_active = false;
emit animationFinished();
}
+76
View File
@@ -0,0 +1,76 @@
#ifndef SLIDINGSTACKEDWIDGET_H
#define SLIDINGSTACKEDWIDGET_H
#include <QStackedWidget>
#include <QWidget>
#include <QDebug>
#include <QEasingCurve>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
/* Description
SlidingStackedWidget is a class that is derived from QtStackedWidget
and allows smooth side shifting of widgets, in addition
to the original hard switching from one to another as offered by
QStackedWidget itself.
*/
class SlidingStackedWidget : public QStackedWidget {
Q_OBJECT
public:
// This enumeration is used to define the animation direction
enum t_direction {
LEFT2RIGHT,
RIGHT2LEFT,
TOP2BOTTOM,
BOTTOM2TOP,
AUTOMATIC
};
// The Constructor and Destructor
SlidingStackedWidget(QWidget *parent);
~SlidingStackedWidget(void);
public slots:
// Some basic settings API
void setSpeed(int speed); // animation duration in milliseconds
void setAnimation(enum QEasingCurve::Type animationtype); // check out the QEasingCurve documentation for different styles
void setVerticalMode(bool vertical=true);
void setWrap(bool wrap); // wrapping is related to slideInNext/Prev;it defines the behaviour when reaching last/first page
// The Animation / Page Change API
void slideInNext();
void slideInPrev();
void slideInIdx(int idx, enum t_direction direction = AUTOMATIC);
void slideInWidget(QWidget *widget, enum t_direction direction = AUTOMATIC);
signals:
// this is used for internal purposes in the class engine
void animationFinished(void);
protected slots:
// this is used for internal purposes in the class engine
void animationDoneSlot(void);
protected:
// this is used for internal purposes in the class engine
void slideInWgtImpl(QWidget *widget, enum t_direction direction = AUTOMATIC);
QWidget *m_mainwindow;
int m_speed;
enum QEasingCurve::Type m_animationtype;
bool m_vertical;
int m_now;
int m_next;
bool m_wrap;
QPoint m_pnow;
bool m_active;
QList<QWidget*> blockedPageList;
};
#endif // SLIDINGSTACKEDWIDGET_H
+76
View File
@@ -0,0 +1,76 @@
#include "customshadoweffect.h"
#include <QPainter>
CustomShadowEffect::CustomShadowEffect(QObject *parent) :
QGraphicsEffect(parent),
_distance(4.0f),
_blurRadius(10.0f),
_color(0, 0, 0, 80)
{
}
QT_BEGIN_NAMESPACE
extern Q_WIDGETS_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0 );
QT_END_NAMESPACE
void CustomShadowEffect::draw(QPainter* painter)
{
// if nothing to show outside the item, just draw source
if ((blurRadius() + distance()) <= 0) {
drawSource(painter);
return;
}
PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect;
QPoint offset;
const QPixmap px = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
// return if no source
if (px.isNull())
return;
// save world transform
QTransform restoreTransform = painter->worldTransform();
painter->setWorldTransform(QTransform());
// Calculate size for the background image
QSize szi(px.size().width() + 2 * distance(), px.size().height() + 2 * distance());
QImage tmp(szi, QImage::Format_ARGB32_Premultiplied);
QPixmap scaled = px.scaled(szi);
tmp.fill(0);
QPainter tmpPainter(&tmp);
tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
tmpPainter.drawPixmap(QPointF(-distance(), -distance()), scaled);
tmpPainter.end();
// blur the alpha channel
QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
blurred.fill(0);
QPainter blurPainter(&blurred);
qt_blurImage(&blurPainter, tmp, blurRadius(), false, true);
blurPainter.end();
tmp = blurred;
// blacken the image...
tmpPainter.begin(&tmp);
tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
tmpPainter.fillRect(tmp.rect(), color());
tmpPainter.end();
// draw the blurred shadow...
painter->drawImage(offset, tmp);
// draw the actual pixmap...
painter->drawPixmap(offset, px, QRectF());
// restore world transform
painter->setWorldTransform(restoreTransform);
}
QRectF CustomShadowEffect::boundingRectFor(const QRectF& rect) const
{
qreal delta = blurRadius() + distance();
return rect.united(rect.adjusted(-delta, -delta, delta, delta));
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef CUSTOMSHADOWEFFECT_H
#define CUSTOMSHADOWEFFECT_H
#include <QGraphicsDropShadowEffect>
#include <QGraphicsEffect>
class CustomShadowEffect : public QGraphicsEffect
{
Q_OBJECT
public:
explicit CustomShadowEffect(QObject *parent = 0);
void draw(QPainter* painter);
QRectF boundingRectFor(const QRectF& rect) const;
inline void setDistance(qreal distance) { _distance = distance; updateBoundingRect(); }
inline qreal distance() const { return _distance; }
inline void setBlurRadius(qreal blurRadius) { _blurRadius = blurRadius; updateBoundingRect(); }
inline qreal blurRadius() const { return _blurRadius; }
inline void setColor(const QColor& color) { _color = color; }
inline QColor color() const { return _color; }
private:
qreal _distance;
qreal _blurRadius;
QColor _color;
};
#endif // CUSTOMSHADOWEFFECT_H
+36
View File
@@ -0,0 +1,36 @@
#include <QMetaEnum>
#include <QMovie>
#include <QMessageBox>
#include <QMouseEvent>
#include <QScroller>
#include <QScrollBar>
#include <QDesktopWidget>
#include <QDesktopServices>
#include <QGridLayout>
#include <QTime>
#include "mainwindow.h"
#ifdef Q_OS_WIN
#include "ui_mainwindow.h"
#endif
#ifdef Q_OS_MAC
#include "ui_mainwindow_mac.h"
#include "publib/macos_functions.h"
#endif
MainWindow::MainWindow(bool useForceUseBrightIcons, QWidget *parent) : QMainWindow(parent),
ui(new Ui::MainWindow),
forceUseBrightIcons(useForceUseBrightIcons)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
+43
View File
@@ -0,0 +1,43 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QAction>
#include <QMenu>
#include <QJsonDocument>
#include <QClipboard>
#include <QStringListModel>
#include <QDataStream>
#include <QGraphicsBlurEffect>
#include "customshadoweffect.h"
namespace Ui {
class MainWindow;
}
/**
* @brief The MainWindow class - Main application window
*/
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(bool setForceUseBrightIcons = false, QWidget *parent = nullptr);
~MainWindow();
public slots:
private slots:
private:
Ui::MainWindow *ui;
bool forceUseBrightIcons = false;
};
#endif // MAINWINDOW_H
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff