Compare commits
No commits in common. "1.10.x" and "1.1.1" have entirely different histories.
301 changed files with 13577 additions and 46945 deletions
33
.ci/app.rc
33
.ci/app.rc
|
|
@ -1,33 +0,0 @@
|
||||||
IDI_ICON1 ICON DISCARDABLE "5sync.ico"
|
|
||||||
#define RT_MANIFEST 24
|
|
||||||
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
|
|
||||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "gta5view.exe.manifest"
|
|
||||||
#include <windows.h>
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION MAJOR_VER, MINOR_VER, PATCH_VER, INT_BUILD_VER
|
|
||||||
PRODUCTVERSION MAJOR_VER, MINOR_VER, PATCH_VER, INT_BUILD_VER
|
|
||||||
FILEFLAGSMASK 0x3fL
|
|
||||||
FILEFLAGS 0
|
|
||||||
FILEOS VOS_NT_WINDOWS32
|
|
||||||
FILETYPE VFT_APP
|
|
||||||
FILESUBTYPE VFT2_UNKNOWN
|
|
||||||
BEGIN
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x0809, 1200
|
|
||||||
END
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "CompanyName", "Syping"
|
|
||||||
VALUE "FileDescription", "gta5view"
|
|
||||||
VALUE "FileVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER"
|
|
||||||
VALUE "InternalName", "gta5view"
|
|
||||||
VALUE "LegalCopyright", "Copyright © 2016-2023 Syping"
|
|
||||||
VALUE "OriginalFilename", "gta5view.exe"
|
|
||||||
VALUE "ProductName", "gta5view"
|
|
||||||
VALUE "ProductVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
END
|
|
||||||
72
.ci/ci.sh
72
.ci/ci.sh
|
|
@ -1,72 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
if [ $(git name-rev --tags --name-only $(git rev-parse HEAD)) == "undefined" ]; then
|
|
||||||
export APPLICATION_VERSION=$(lua -e 'for line in io.lines("config.h") do local m = string.match(line, "#define GTA5SYNC_APPVER \"(.+)\"$"); if m then print(m); os.exit(0) end end')
|
|
||||||
else
|
|
||||||
export APPLICATION_VERSION=$(git name-rev --tags --name-only $(git rev-parse HEAD))
|
|
||||||
fi
|
|
||||||
export PACKAGE_VERSION=$(grep -oE '^[^\-]*' <<< $APPLICATION_VERSION)
|
|
||||||
export PACKAGE_BUILD=$(grep -oP '\-\K.+' <<< $APPLICATION_VERSION)
|
|
||||||
export EXECUTABLE_VERSION=${PACKAGE_VERSION}${PACKAGE_BUILD}${EXECUTABLE_TAG}
|
|
||||||
|
|
||||||
export APPLICATION_MAJOR_VERSION=$(cut -d. -f1 <<< $APPLICATION_VERSION)
|
|
||||||
export APPLICATION_MINOR_VERSION=$(cut -d. -f2 <<< $APPLICATION_VERSION)
|
|
||||||
export APPLICATION_PATCH_VERSION=$(cut -d. -f3 <<< $APPLICATION_VERSION)
|
|
||||||
|
|
||||||
if [ "${PACKAGE_BUILD}" == "" ]; then
|
|
||||||
export PACKAGE_BUILD=1
|
|
||||||
else
|
|
||||||
export APPLICATION_BUILD_INT_VERSION=$(grep -oE '[1-9]*$' <<< $PACKAGE_BUILD)
|
|
||||||
export APPLICATION_BUILD_STR_VERSION=-${PACKAGE_BUILD}
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat ".ci/app.rc" | sed \
|
|
||||||
-e "s/MAJOR_VER/$APPLICATION_MAJOR_VERSION/g" \
|
|
||||||
-e "s/MINOR_VER/$APPLICATION_MINOR_VERSION/g" \
|
|
||||||
-e "s/PATCH_VER/$APPLICATION_PATCH_VERSION/g" \
|
|
||||||
-e "s/INT_BUILD_VER/0/g" \
|
|
||||||
-e "s/STR_BUILD_VER/$APPLICATION_BUILD_STR_VERSION/g" \
|
|
||||||
-e "s/STR_BUILD_VER/$APPLICATION_BUILD_STR_VERSION/g" \
|
|
||||||
> "res/app.rc"
|
|
||||||
|
|
||||||
if [ "${BUILD_TYPE}" == "ALPHA" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Alpha"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Alpha\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "Alpha" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Alpha"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Alpha\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "BETA" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Beta"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Beta\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "Beta" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Beta"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Beta\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "DEV" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Developer"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Developer\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "Development" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Developer"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Developer\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "DAILY" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Daily Build"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Daily Build\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "Daily" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Daily Build"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Daily Build\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "RC" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release Candidate"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release Candidate\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "Release Candidate" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release Candidate"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release Candidate\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "REL" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release\\\\\\\""
|
|
||||||
elif [ "${BUILD_TYPE}" == "Release" ]; then
|
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release"
|
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release\\\\\\\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
export PROJECT_DIR=$(pwd)
|
|
||||||
|
|
||||||
.ci/${BUILD_SCRIPT}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Creating folders
|
|
||||||
cd ${PROJECT_DIR} && \
|
|
||||||
echo "gta5view build version is ${APPLICATION_VERSION}" && \
|
|
||||||
mkdir -p build && \
|
|
||||||
mkdir -p assets && \
|
|
||||||
chmod -x res/gta5sync_*.qm res/*.desktop res/*gta5view*.png && \
|
|
||||||
cd build && \
|
|
||||||
mkdir -p qt5 && \
|
|
||||||
cd qt5 && \
|
|
||||||
echo "Grand Theft Auto V Snapmatic and Savegame viewer/editor" > ./description-pak && \
|
|
||||||
cd .. && \
|
|
||||||
|
|
||||||
# Set compiler
|
|
||||||
export CC=clang && \
|
|
||||||
export CXX=clang++ && \
|
|
||||||
|
|
||||||
# Prepare checkinstall step
|
|
||||||
mkdir -p /usr/share/gta5view && \
|
|
||||||
|
|
||||||
# Starting build
|
|
||||||
cd qt5 && \
|
|
||||||
cmake \
|
|
||||||
"-DCMAKE_INSTALL_PREFIX=/usr" \
|
|
||||||
"${CMAKE_BUILD_TYPE}" \
|
|
||||||
"-DFORCE_QT_VERSION=5" \
|
|
||||||
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
|
||||||
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
|
||||||
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
|
||||||
"-DWITH_DONATE=ON" \
|
|
||||||
"-DWITH_TELEMETRY=ON" \
|
|
||||||
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
|
|
||||||
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
|
||||||
"-DQCONF_BUILD=ON" \
|
|
||||||
../../ && \
|
|
||||||
make -j 4 && \
|
|
||||||
checkinstall -D --default --nodoc --install=no --pkgname=gta5view --pkgversion=${PACKAGE_VERSION} --pkgrelease=${PACKAGE_BUILD} --pkggroup=utility --maintainer="Syping \<dpkg@syping.de\>" --requires=libqt5core5a,libqt5gui5,libqt5network5,libqt5svg5,libqt5widgets5,qttranslations5-l10n --conflicts=gta5view-qt4,gta5view-qt5 --replaces=gta5view-qt4,gta5view-qt5 --pakdir=${PROJECT_DIR}/assets
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Install packages
|
|
||||||
.ci/debian_install.sh && \
|
|
||||||
|
|
||||||
# Build gta5view
|
|
||||||
.ci/debian_build.sh && \
|
|
||||||
cd ${PROJECT_DIR}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
if [ "${DOCKER_USER}" != "" ]; then
|
|
||||||
DOCKER_IMAGE=${DOCKER_USER}/debian:${DEBIAN_VERSION}
|
|
||||||
else
|
|
||||||
DOCKER_IMAGE=debian:${DEBIAN_VERSION}
|
|
||||||
fi
|
|
||||||
PROJECT_DIR_DOCKER=/gta5view
|
|
||||||
|
|
||||||
cd ${PROJECT_DIR} && \
|
|
||||||
docker pull ${DOCKER_IMAGE} && \
|
|
||||||
docker run --rm \
|
|
||||||
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
|
|
||||||
${DOCKER_IMAGE} \
|
|
||||||
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export APT_INSTALL=${APT_INSTALL} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/debian_install.sh && .ci/debian_build.sh"
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Source OS Release
|
|
||||||
source /etc/os-release
|
|
||||||
|
|
||||||
# When Debian add backports
|
|
||||||
if [ "${ID}" == "debian" ]; then
|
|
||||||
echo "deb http://deb.debian.org/debian ${VERSION_CODENAME}-backports main" >> /etc/apt/sources.list
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install packages
|
|
||||||
apt-get update -qq && \
|
|
||||||
apt-get install -qq ${APT_INSTALL} checkinstall cmake dpkg-dev fakeroot g++ gcc qtbase5-dev qt5-qmake qttranslations5-l10n libqt5svg5-dev
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
btc:187NSQSPzdMpQDGhxZAuw4AhZ7LgoAPV7D,eth:0x19d71DfCa86104d37a13D3c5d419936421CDC569,ltc:LKr6yvBoMMGmcxViS8Kc1A2sDjVSWTXn4m,xmr:43TB3ZMP5nk1pu5EQXRGPzdTKvmFEBGgccX3tNhRknLLiUYQ7z7dNedVHEA6WrWdByZv1isvFmjSGhCF7ddx3eRxFdm5Fzz
|
|
||||||
File diff suppressed because it is too large
Load diff
364
.ci/gta5view.nsi
364
.ci/gta5view.nsi
|
|
@ -1,364 +0,0 @@
|
||||||
######################################################################
|
|
||||||
|
|
||||||
!define APP_NAME "gta5view"
|
|
||||||
!define APP_EXT ".g5e"
|
|
||||||
!define COMP_NAME "Syping"
|
|
||||||
!define WEB_SITE "https://gta5view.syping.de/"
|
|
||||||
!define VERSION "1.10.2.0"
|
|
||||||
!define COPYRIGHT "Copyright © 2016-2022 Syping"
|
|
||||||
!define DESCRIPTION "Open Source Snapmatic and Savegame viewer/editor for GTA V"
|
|
||||||
!define INSTALLER_NAME "gta5view_setup.exe"
|
|
||||||
!define MAIN_APP_EXE "gta5view.exe"
|
|
||||||
!define INSTALL_TYPE "SetShellVarContext all"
|
|
||||||
!define REG_ROOT "HKLM"
|
|
||||||
!define REG_APP_PATH "Software\Microsoft\Windows\CurrentVersion\App Paths\${MAIN_APP_EXE}"
|
|
||||||
!define UNINSTALL_PATH "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
|
|
||||||
!define LICENSE_TXT "../LICENSE"
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
VIProductVersion "${VERSION}"
|
|
||||||
VIAddVersionKey "ProductName" "${APP_NAME}"
|
|
||||||
VIAddVersionKey "ProductVersion" "${VERSION}"
|
|
||||||
VIAddVersionKey "CompanyName" "${COMP_NAME}"
|
|
||||||
VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
|
|
||||||
VIAddVersionKey "FileDescription" "${DESCRIPTION}"
|
|
||||||
VIAddVersionKey "FileVersion" "${VERSION}"
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
!include "x64.nsh"
|
|
||||||
SetCompressor LZMA
|
|
||||||
Name "${APP_NAME}"
|
|
||||||
Caption "${APP_NAME}"
|
|
||||||
OutFile "${INSTALLER_NAME}"
|
|
||||||
#BrandingText "${APP_NAME}"
|
|
||||||
XPStyle on
|
|
||||||
Unicode true
|
|
||||||
InstallDirRegKey "${REG_ROOT}" "${REG_APP_PATH}" ""
|
|
||||||
InstallDir "$PROGRAMFILES64\Syping\gta5view"
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
!include "MUI2.nsh"
|
|
||||||
|
|
||||||
!define MUI_ABORTWARNING
|
|
||||||
!define MUI_UNABORTWARNING
|
|
||||||
|
|
||||||
!define MUI_LANGDLL_REGISTRY_ROOT "${REG_ROOT}"
|
|
||||||
!define MUI_LANGDLL_REGISTRY_KEY "${UNINSTALL_PATH}"
|
|
||||||
!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
|
|
||||||
|
|
||||||
!insertmacro MUI_PAGE_WELCOME
|
|
||||||
|
|
||||||
!ifdef LICENSE_TXT
|
|
||||||
!insertmacro MUI_PAGE_LICENSE "${LICENSE_TXT}"
|
|
||||||
!endif
|
|
||||||
|
|
||||||
!insertmacro MUI_PAGE_DIRECTORY
|
|
||||||
|
|
||||||
!ifdef REG_START_MENU
|
|
||||||
!define MUI_STARTMENUPAGE_NODISABLE
|
|
||||||
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "gta5view"
|
|
||||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${REG_ROOT}"
|
|
||||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${UNINSTALL_PATH}"
|
|
||||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${REG_START_MENU}"
|
|
||||||
!insertmacro MUI_PAGE_STARTMENU Application $SM_Folder
|
|
||||||
!endif
|
|
||||||
|
|
||||||
!insertmacro MUI_PAGE_INSTFILES
|
|
||||||
|
|
||||||
!define MUI_FINISHPAGE_RUN "$INSTDIR\${MAIN_APP_EXE}"
|
|
||||||
!insertmacro MUI_PAGE_FINISH
|
|
||||||
|
|
||||||
!insertmacro MUI_UNPAGE_CONFIRM
|
|
||||||
|
|
||||||
!insertmacro MUI_UNPAGE_INSTFILES
|
|
||||||
|
|
||||||
!insertmacro MUI_UNPAGE_FINISH
|
|
||||||
|
|
||||||
!insertmacro MUI_LANGUAGE "English"
|
|
||||||
!insertmacro MUI_LANGUAGE "French"
|
|
||||||
!insertmacro MUI_LANGUAGE "German"
|
|
||||||
!insertmacro MUI_LANGUAGE "Korean"
|
|
||||||
!insertmacro MUI_LANGUAGE "Russian"
|
|
||||||
!insertmacro MUI_LANGUAGE "Ukrainian"
|
|
||||||
!insertmacro MUI_LANGUAGE "TradChinese"
|
|
||||||
|
|
||||||
!insertmacro MUI_RESERVEFILE_LANGDLL
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
Function .onInit
|
|
||||||
!insertmacro MUI_LANGDLL_DISPLAY
|
|
||||||
!ifdef WIN32
|
|
||||||
MessageBox MB_OK|MB_ICONSTOP "Windows 32-Bit is not supported anymore!"
|
|
||||||
Quit
|
|
||||||
!endif
|
|
||||||
SetRegView 64
|
|
||||||
FunctionEnd
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
Section -MainProgram
|
|
||||||
${INSTALL_TYPE}
|
|
||||||
SetOverwrite ifnewer
|
|
||||||
SetOutPath "$INSTDIR"
|
|
||||||
File "../build/gta5view.exe"
|
|
||||||
File "/opt/llvm-mingw/x86_64-w64-mingw32/bin/libc++.dll"
|
|
||||||
File "/opt/llvm-mingw/x86_64-w64-mingw32/bin/libunwind.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/openssl/bin/libcrypto-1_1-x64.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/openssl/bin/libssl-1_1-x64.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Core.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Gui.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Network.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Svg.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Widgets.dll"
|
|
||||||
SetOutPath "$INSTDIR\lang"
|
|
||||||
File "../build/gta5sync_en_US.qm"
|
|
||||||
File "../build/gta5sync_de.qm"
|
|
||||||
File "../build/gta5sync_fr.qm"
|
|
||||||
File "../build/gta5sync_ko.qm"
|
|
||||||
File "../build/gta5sync_ru.qm"
|
|
||||||
File "../build/gta5sync_uk.qm"
|
|
||||||
File "../build/gta5sync_zh_TW.qm"
|
|
||||||
File "../build/qtbase_en_GB.qm"
|
|
||||||
File "../res/qt5/qtbase_de.qm"
|
|
||||||
File "../res/qt5/qtbase_fr.qm"
|
|
||||||
File "../res/qt5/qtbase_ko.qm"
|
|
||||||
File "../res/qt5/qtbase_ru.qm"
|
|
||||||
File "../res/qt5/qtbase_uk.qm"
|
|
||||||
File "../res/qt5/qtbase_zh_TW.qm"
|
|
||||||
SetOutPath "$INSTDIR\resources"
|
|
||||||
File "../res/add.svgz"
|
|
||||||
File "../res/avatararea.png"
|
|
||||||
File "../res/avatarareaimport.png"
|
|
||||||
File "../res/back.svgz"
|
|
||||||
File "../res/flag-de.png"
|
|
||||||
File "../res/flag-fr.png"
|
|
||||||
File "../res/flag-gb.png"
|
|
||||||
File "../res/flag-kr.png"
|
|
||||||
File "../res/flag-ru.png"
|
|
||||||
File "../res/flag-tw.png"
|
|
||||||
File "../res/flag-ua.png"
|
|
||||||
File "../res/flag-us.png"
|
|
||||||
File "../res/gta5view-16.png"
|
|
||||||
File "../res/gta5view-24.png"
|
|
||||||
File "../res/gta5view-32.png"
|
|
||||||
File "../res/gta5view-40.png"
|
|
||||||
File "../res/gta5view-48.png"
|
|
||||||
File "../res/gta5view-64.png"
|
|
||||||
File "../res/gta5view-96.png"
|
|
||||||
File "../res/gta5view-128.png"
|
|
||||||
File "../res/gta5view-256.png"
|
|
||||||
File "../res/mapcayoperico.jpg"
|
|
||||||
File "../res/mappreview.jpg"
|
|
||||||
File "../res/next.svgz"
|
|
||||||
File "../res/pointmaker-8.png"
|
|
||||||
File "../res/pointmaker-16.png"
|
|
||||||
File "../res/pointmaker-24.png"
|
|
||||||
File "../res/pointmaker-32.png"
|
|
||||||
File "../res/savegame.svgz"
|
|
||||||
File "../res/watermark_1b.png"
|
|
||||||
File "../res/watermark_2b.png"
|
|
||||||
File "../res/watermark_2r.png"
|
|
||||||
SetOutPath "$INSTDIR\imageformats"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qgif.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qicns.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qico.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qjpeg.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qsvg.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qtga.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qtiff.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qwbmp.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qwebp.dll"
|
|
||||||
SetOutPath "$INSTDIR\platforms"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/platforms/qwindows.dll"
|
|
||||||
SetOutPath "$INSTDIR\styles"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/styles/qcleanlooksstyle.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/styles/qplastiquestyle.dll"
|
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/styles/qwindowsvistastyle.dll"
|
|
||||||
SectionEnd
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
Section -Icons_Reg
|
|
||||||
SetOutPath "$INSTDIR"
|
|
||||||
WriteUninstaller "$INSTDIR\uninstall.exe"
|
|
||||||
|
|
||||||
!ifdef REG_START_MENU
|
|
||||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
|
||||||
CreateDirectory "$SMPROGRAMS\$SM_Folder"
|
|
||||||
CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}"
|
|
||||||
CreateShortCut "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
|
|
||||||
|
|
||||||
!ifdef WEB_SITE
|
|
||||||
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
|
|
||||||
CreateShortCut "$SMPROGRAMS\$SM_Folder\gta5view Website.lnk" "$INSTDIR\${APP_NAME} website.url"
|
|
||||||
!endif
|
|
||||||
!insertmacro MUI_STARTMENU_WRITE_END
|
|
||||||
!endif
|
|
||||||
|
|
||||||
!ifndef REG_START_MENU
|
|
||||||
CreateDirectory "$SMPROGRAMS\gta5view"
|
|
||||||
CreateShortCut "$SMPROGRAMS\gta5view\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}"
|
|
||||||
CreateShortCut "$SMPROGRAMS\gta5view\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
|
|
||||||
|
|
||||||
!ifdef WEB_SITE
|
|
||||||
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
|
|
||||||
CreateShortCut "$SMPROGRAMS\gta5view\gta5view Website.lnk" "$INSTDIR\${APP_NAME} website.url"
|
|
||||||
!endif
|
|
||||||
!endif
|
|
||||||
|
|
||||||
WriteRegStr ${REG_ROOT} "${REG_APP_PATH}" "" "$INSTDIR\${MAIN_APP_EXE}"
|
|
||||||
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayName" "${APP_NAME}"
|
|
||||||
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "UninstallString" "$INSTDIR\uninstall.exe"
|
|
||||||
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayIcon" "$INSTDIR\${MAIN_APP_EXE}"
|
|
||||||
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayVersion" "${VERSION}"
|
|
||||||
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "Publisher" "${COMP_NAME}"
|
|
||||||
|
|
||||||
!ifdef WEB_SITE
|
|
||||||
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "URLInfoAbout" "${WEB_SITE}"
|
|
||||||
!endif
|
|
||||||
SectionEnd
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
Section -ShellAssoc
|
|
||||||
WriteRegStr ${REG_ROOT} "Software\Classes\${APP_NAME}\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},0"
|
|
||||||
WriteRegStr ${REG_ROOT} "Software\Classes\${APP_NAME}\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"'
|
|
||||||
WriteRegStr ${REG_ROOT} "Software\Classes\${APP_EXT}" "" "${APP_NAME}"
|
|
||||||
WriteRegStr ${REG_ROOT} "Software\Classes\${APP_EXT}" "Content Type" "application/x-gta5view-export"
|
|
||||||
System::Call 'SHELL32::SHChangeNotify(i0x8000000,i0,p0,p0)'
|
|
||||||
SectionEnd
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
Section -un.ShellAssoc
|
|
||||||
ClearErrors
|
|
||||||
ReadRegStr $0 ${REG_ROOT} "Software\Classes\${APP_EXT}" ""
|
|
||||||
DeleteRegKey ${REG_ROOT} "Software\Classes\${APP_NAME}"
|
|
||||||
${IfNot} ${Errors}
|
|
||||||
${AndIf} $0 == "${APP_NAME}"
|
|
||||||
DeleteRegValue ${REG_ROOT} "Software\Classes\${APP_EXT}" ""
|
|
||||||
DeleteRegKey /IfEmpty ${REG_ROOT} "Software\Classes\${APP_EXT}"
|
|
||||||
${EndIf}
|
|
||||||
System::Call 'SHELL32::SHChangeNotify(i0x8000000,i0,p0,p0)'
|
|
||||||
SectionEnd
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
Section Uninstall
|
|
||||||
${INSTALL_TYPE}
|
|
||||||
Delete "$INSTDIR\gta5view.exe"
|
|
||||||
Delete "$INSTDIR\libc++.dll"
|
|
||||||
Delete "$INSTDIR\libunwind.dll"
|
|
||||||
Delete "$INSTDIR\libcrypto-1_1-x64.dll"
|
|
||||||
Delete "$INSTDIR\libssl-1_1-x64.dll"
|
|
||||||
Delete "$INSTDIR\Qt5Core.dll"
|
|
||||||
Delete "$INSTDIR\Qt5Gui.dll"
|
|
||||||
Delete "$INSTDIR\Qt5Network.dll"
|
|
||||||
Delete "$INSTDIR\Qt5Svg.dll"
|
|
||||||
Delete "$INSTDIR\Qt5Widgets.dll"
|
|
||||||
Delete "$INSTDIR\lang\gta5sync_en_US.qm"
|
|
||||||
Delete "$INSTDIR\lang\gta5sync_de.qm"
|
|
||||||
Delete "$INSTDIR\lang\gta5sync_fr.qm"
|
|
||||||
Delete "$INSTDIR\lang\gta5sync_ko.qm"
|
|
||||||
Delete "$INSTDIR\lang\gta5sync_ru.qm"
|
|
||||||
Delete "$INSTDIR\lang\gta5sync_uk.qm"
|
|
||||||
Delete "$INSTDIR\lang\gta5sync_zh_TW.qm"
|
|
||||||
Delete "$INSTDIR\lang\qtbase_en_GB.qm"
|
|
||||||
Delete "$INSTDIR\lang\qtbase_de.qm"
|
|
||||||
Delete "$INSTDIR\lang\qtbase_fr.qm"
|
|
||||||
Delete "$INSTDIR\lang\qtbase_ko.qm"
|
|
||||||
Delete "$INSTDIR\lang\qtbase_ru.qm"
|
|
||||||
Delete "$INSTDIR\lang\qtbase_uk.qm"
|
|
||||||
Delete "$INSTDIR\lang\qtbase_zh_TW.qm"
|
|
||||||
Delete "$INSTDIR\resources\add.svgz"
|
|
||||||
Delete "$INSTDIR\resources\avatararea.png"
|
|
||||||
Delete "$INSTDIR\resources\avatarareaimport.png"
|
|
||||||
Delete "$INSTDIR\resources\back.svgz"
|
|
||||||
Delete "$INSTDIR\resources\flag-de.png"
|
|
||||||
Delete "$INSTDIR\resources\flag-fr.png"
|
|
||||||
Delete "$INSTDIR\resources\flag-gb.png"
|
|
||||||
Delete "$INSTDIR\resources\flag-kr.png"
|
|
||||||
Delete "$INSTDIR\resources\flag-ru.png"
|
|
||||||
Delete "$INSTDIR\resources\flag-tw.png"
|
|
||||||
Delete "$INSTDIR\resources\flag-ua.png"
|
|
||||||
Delete "$INSTDIR\resources\flag-us.png"
|
|
||||||
Delete "$INSTDIR\resources\gta5view-16.png"
|
|
||||||
Delete "$INSTDIR\resources\gta5view-24.png"
|
|
||||||
Delete "$INSTDIR\resources\gta5view-32.png"
|
|
||||||
Delete "$INSTDIR\resources\gta5view-40.png"
|
|
||||||
Delete "$INSTDIR\resources\gta5view-48.png"
|
|
||||||
Delete "$INSTDIR\resources\gta5view-64.png"
|
|
||||||
Delete "$INSTDIR\resources\gta5view-96.png"
|
|
||||||
Delete "$INSTDIR\resources\gta5view-128.png"
|
|
||||||
Delete "$INSTDIR\resources\gta5view-256.png"
|
|
||||||
Delete "$INSTDIR\resources\mapcayoperico.jpg"
|
|
||||||
Delete "$INSTDIR\resources\mappreview.jpg"
|
|
||||||
Delete "$INSTDIR\resources\next.svgz"
|
|
||||||
Delete "$INSTDIR\resources\pointmaker-8.png"
|
|
||||||
Delete "$INSTDIR\resources\pointmaker-16.png"
|
|
||||||
Delete "$INSTDIR\resources\pointmaker-24.png"
|
|
||||||
Delete "$INSTDIR\resources\pointmaker-32.png"
|
|
||||||
Delete "$INSTDIR\resources\savegame.svgz"
|
|
||||||
Delete "$INSTDIR\resources\watermark_1b.png"
|
|
||||||
Delete "$INSTDIR\resources\watermark_2b.png"
|
|
||||||
Delete "$INSTDIR\resources\watermark_2r.png"
|
|
||||||
Delete "$INSTDIR\imageformats\qgif.dll"
|
|
||||||
Delete "$INSTDIR\imageformats\qicns.dll"
|
|
||||||
Delete "$INSTDIR\imageformats\qico.dll"
|
|
||||||
Delete "$INSTDIR\imageformats\qjpeg.dll"
|
|
||||||
Delete "$INSTDIR\imageformats\qsvg.dll"
|
|
||||||
Delete "$INSTDIR\imageformats\qtga.dll"
|
|
||||||
Delete "$INSTDIR\imageformats\qtiff.dll"
|
|
||||||
Delete "$INSTDIR\imageformats\qwbmp.dll"
|
|
||||||
Delete "$INSTDIR\imageformats\qwebp.dll"
|
|
||||||
Delete "$INSTDIR\platforms\qwindows.dll"
|
|
||||||
Delete "$INSTDIR\styles\qcleanlooksstyle.dll"
|
|
||||||
Delete "$INSTDIR\styles\qplastiquestyle.dll"
|
|
||||||
Delete "$INSTDIR\styles\qwindowsvistastyle.dll"
|
|
||||||
RmDir "$INSTDIR\lang"
|
|
||||||
RmDir "$INSTDIR\imageformats"
|
|
||||||
RmDir "$INSTDIR\platforms"
|
|
||||||
RmDir "$INSTDIR\styles"
|
|
||||||
|
|
||||||
Delete "$INSTDIR\uninstall.exe"
|
|
||||||
!ifdef WEB_SITE
|
|
||||||
Delete "$INSTDIR\${APP_NAME} website.url"
|
|
||||||
!endif
|
|
||||||
|
|
||||||
RmDir "$INSTDIR"
|
|
||||||
|
|
||||||
!ifdef REG_START_MENU
|
|
||||||
!insertmacro MUI_STARTMENU_GETFOLDER "Application" $SM_Folder
|
|
||||||
Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk"
|
|
||||||
Delete "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk"
|
|
||||||
!ifdef WEB_SITE
|
|
||||||
Delete "$SMPROGRAMS\$SM_Folder\gta5view Website.lnk"
|
|
||||||
!endif
|
|
||||||
RmDir "$SMPROGRAMS\$SM_Folder"
|
|
||||||
!endif
|
|
||||||
|
|
||||||
!ifndef REG_START_MENU
|
|
||||||
Delete "$SMPROGRAMS\gta5view\${APP_NAME}.lnk"
|
|
||||||
Delete "$SMPROGRAMS\gta5view\Uninstall ${APP_NAME}.lnk"
|
|
||||||
!ifdef WEB_SITE
|
|
||||||
Delete "$SMPROGRAMS\gta5view\gta5view Website.lnk"
|
|
||||||
!endif
|
|
||||||
RmDir "$SMPROGRAMS\gta5view"
|
|
||||||
!endif
|
|
||||||
|
|
||||||
DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}"
|
|
||||||
DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}"
|
|
||||||
SectionEnd
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
Function un.onInit
|
|
||||||
!insertmacro MUI_UNGETLANGUAGE
|
|
||||||
SetRegView 64
|
|
||||||
FunctionEnd
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Creating folders
|
|
||||||
cd ${PROJECT_DIR} && \
|
|
||||||
echo "gta5view build version is ${APPLICATION_VERSION}" && \
|
|
||||||
echo "gta5view image name is gta5view-osx_${APPLICATION_VERSION}.dmg" && \
|
|
||||||
mkdir -p build && \
|
|
||||||
mkdir -p assets && \
|
|
||||||
cd build && \
|
|
||||||
|
|
||||||
/usr/local/bin/cmake \
|
|
||||||
"-DCMAKE_PREFIX_PATH=/usr/local/opt/qt" \
|
|
||||||
"${CMAKE_BUILD_TYPE}" \
|
|
||||||
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
|
||||||
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
|
||||||
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
|
||||||
"-DWITH_DONATE=ON" \
|
|
||||||
"-DWITH_TELEMETRY=ON" \
|
|
||||||
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
|
|
||||||
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
|
||||||
../ && \
|
|
||||||
make -j 4 && \
|
|
||||||
/usr/local/opt/qt/bin/macdeployqt gta5view.app -dmg && \
|
|
||||||
cp -Rf gta5view.dmg ../assets/gta5view-osx_${APPLICATION_VERSION}.dmg
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Install packages
|
|
||||||
.ci/osx_install.sh && \
|
|
||||||
|
|
||||||
# Build gta5view
|
|
||||||
.ci/osx_build.sh && \
|
|
||||||
cd ${PROJECT_DIR}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Install packages
|
|
||||||
brew upgrade cmake qt
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Prepare environment variable
|
|
||||||
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
|
|
||||||
|
|
||||||
# Creating folders
|
|
||||||
cd ${PROJECT_DIR} && \
|
|
||||||
echo "gta5view build version is ${APPLICATION_VERSION}" && \
|
|
||||||
echo "gta5view executable is ${GTA5VIEW_EXECUTABLE}" && \
|
|
||||||
mkdir -p build && \
|
|
||||||
mkdir -p assets && \
|
|
||||||
|
|
||||||
# Starting build
|
|
||||||
cd build && \
|
|
||||||
mingw64-qt-cmake \
|
|
||||||
"${CMAKE_BUILD_TYPE}" \
|
|
||||||
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
|
||||||
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
|
||||||
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
|
||||||
"-DWITH_DONATE=ON" \
|
|
||||||
"-DWITH_TELEMETRY=ON" \
|
|
||||||
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
|
|
||||||
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
|
||||||
.. && \
|
|
||||||
make -j 4 && \
|
|
||||||
x86_64-w64-mingw32-strip -s gta5view.exe && \
|
|
||||||
cp -Rf *.exe ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} && \
|
|
||||||
cd ${PROJECT_DIR}/assets
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
DOCKER_IMAGE=sypingauto/gta5view-build:1.10-static
|
|
||||||
PROJECT_DIR_DOCKER=/gta5view
|
|
||||||
|
|
||||||
cd ${PROJECT_DIR} && \
|
|
||||||
docker pull ${DOCKER_IMAGE} && \
|
|
||||||
docker run --rm \
|
|
||||||
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
|
|
||||||
${DOCKER_IMAGE} \
|
|
||||||
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/windows_build.sh" && \
|
|
||||||
|
|
||||||
# Prepare environment variable
|
|
||||||
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
|
|
||||||
|
|
||||||
# Upload Assets to Dropbox
|
|
||||||
if [ "${PACKAGE_CODE}" == "gta5-mods" ]; then
|
|
||||||
${PROJECT_DIR}/.ci/dropbox_uploader.sh mkdir gta5-mods/${PACKAGE_VERSION}
|
|
||||||
${PROJECT_DIR}/.ci/dropbox_uploader.sh upload ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} gta5-mods/${PACKAGE_VERSION}/${GTA5VIEW_EXECUTABLE} && \
|
|
||||||
rm -rf ${GTA5VIEW_EXECUTABLE}
|
|
||||||
elif [ "${PACKAGE_CODE}" == "gtainside" ]; then
|
|
||||||
${PROJECT_DIR}/.ci/dropbox_uploader.sh mkdir gtainside/${PACKAGE_VERSION}
|
|
||||||
${PROJECT_DIR}/.ci/dropbox_uploader.sh upload ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} gtainside/${PACKAGE_VERSION}/${GTA5VIEW_EXECUTABLE} && \
|
|
||||||
rm -rf ${GTA5VIEW_EXECUTABLE}
|
|
||||||
fi
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Creating folders
|
|
||||||
cd ${PROJECT_DIR} && \
|
|
||||||
echo "gta5view build version is ${APPLICATION_VERSION}" && \
|
|
||||||
mkdir -p build && \
|
|
||||||
mkdir -p assets && \
|
|
||||||
|
|
||||||
# Starting build
|
|
||||||
cd build && \
|
|
||||||
mingw64-qt-cmake \
|
|
||||||
"${CMAKE_BUILD_TYPE}" \
|
|
||||||
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
|
||||||
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
|
||||||
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
|
||||||
"-DWITH_DONATE=ON" \
|
|
||||||
"-DWITH_TELEMETRY=ON" \
|
|
||||||
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
|
|
||||||
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
|
||||||
"-DQCONF_BUILD=ON" \
|
|
||||||
"-DGTA5VIEW_INLANG=RUNDIR:SEPARATOR:lang" \
|
|
||||||
"-DGTA5VIEW_LANG=RUNDIR:SEPARATOR:lang" \
|
|
||||||
"-DGTA5VIEW_PLUG=RUNDIR:SEPARATOR:plugins" \
|
|
||||||
.. && \
|
|
||||||
make -j 4 && \
|
|
||||||
x86_64-w64-mingw32-strip -s gta5view.exe && \
|
|
||||||
cd ${PROJECT_DIR}/assets && \
|
|
||||||
makensis "-XTarget amd64-unicode" -NOCD ${PROJECT_DIR}/.ci/gta5view.nsi && \
|
|
||||||
mv -f gta5view_setup.exe gta5view-${EXECUTABLE_VERSION}_setup.exe
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
DOCKER_IMAGE=sypingauto/gta5view-build:1.10-shared
|
|
||||||
PROJECT_DIR_DOCKER=/gta5view
|
|
||||||
|
|
||||||
cd ${PROJECT_DIR} && \
|
|
||||||
docker pull ${DOCKER_IMAGE} && \
|
|
||||||
docker run --rm \
|
|
||||||
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
|
|
||||||
${DOCKER_IMAGE} \
|
|
||||||
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/wininstall_build.sh"
|
|
||||||
36
.drone.yml
36
.drone.yml
|
|
@ -1,36 +0,0 @@
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
|
|
||||||
environment:
|
|
||||||
BUILD_TYPE: "REL"
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Windows Installer
|
|
||||||
image: sypingauto/gta5view-build:1.10-shared
|
|
||||||
environment:
|
|
||||||
BUILD_SCRIPT: "wininstall_build.sh"
|
|
||||||
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
|
||||||
TCA_PASS:
|
|
||||||
from_secret: tca_pass
|
|
||||||
commands:
|
|
||||||
- .drone/drone.sh
|
|
||||||
volumes:
|
|
||||||
- name: gta5view
|
|
||||||
path: /srv/gta5view
|
|
||||||
- name: Windows Portable
|
|
||||||
image: sypingauto/gta5view-build:1.10-static
|
|
||||||
environment:
|
|
||||||
BUILD_SCRIPT: "windows_build.sh"
|
|
||||||
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
|
||||||
TCA_PASS:
|
|
||||||
from_secret: tca_pass
|
|
||||||
commands:
|
|
||||||
- .drone/drone.sh
|
|
||||||
volumes:
|
|
||||||
- name: gta5view
|
|
||||||
path: /srv/gta5view
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- name: gta5view
|
|
||||||
host:
|
|
||||||
path: /srv/gta5view
|
|
||||||
Binary file not shown.
|
|
@ -1,33 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Cleanup previous Drone build
|
|
||||||
if [ -d "assets" ]; then
|
|
||||||
rm -rf assets
|
|
||||||
fi
|
|
||||||
if [ -d "build" ]; then
|
|
||||||
rm -rf build
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Decrypt Telemetry Authenticator
|
|
||||||
rm -rf tmext/TelemetryClassAuthenticator.cpp && \
|
|
||||||
openssl aes-256-cbc -k ${TCA_PASS} -in .drone/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d -pbkdf2
|
|
||||||
|
|
||||||
# Check if build is not tagged
|
|
||||||
if [ "${DRONE_TAG}" == "" ]; then
|
|
||||||
export EXECUTABLE_TAG=-$(git rev-parse --short HEAD)
|
|
||||||
else
|
|
||||||
export EXECUTABLE_TAG=
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if package code is not set
|
|
||||||
if [ "${PACKAGE_CODE}" == "" ]; then
|
|
||||||
export PACKAGE_CODE=Drone
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Init Application Commit Hash
|
|
||||||
export APPLICATION_COMMIT=$(git rev-parse --short HEAD)
|
|
||||||
|
|
||||||
# Start CI script and copying assets into gta5view directory
|
|
||||||
.ci/ci.sh && \
|
|
||||||
mkdir -p /srv/gta5view/${APPLICATION_COMMIT} && \
|
|
||||||
cp -Rf assets/* /srv/gta5view/${APPLICATION_COMMIT}/
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
app-id: de.syping.gta5view
|
|
||||||
runtime: org.kde.Platform
|
|
||||||
runtime-version: '5.15-21.08'
|
|
||||||
sdk: org.kde.Sdk
|
|
||||||
command: gta5view
|
|
||||||
finish-args:
|
|
||||||
- --share=network
|
|
||||||
- --share=ipc
|
|
||||||
- --socket=fallback-x11
|
|
||||||
- --socket=wayland
|
|
||||||
- --device=dri
|
|
||||||
modules:
|
|
||||||
- name: gta5view
|
|
||||||
buildsystem: cmake-ninja
|
|
||||||
config-opts:
|
|
||||||
- -DFLATPAK_BUILD=ON
|
|
||||||
- -DQCONF_BUILD=ON
|
|
||||||
- -DGTA5VIEW_BUILDCODE=Flatpak
|
|
||||||
- -DGTA5VIEW_BUILDTYPE=Release
|
|
||||||
sources:
|
|
||||||
- type: dir
|
|
||||||
path: ../
|
|
||||||
28
.gitattributes
vendored
28
.gitattributes
vendored
|
|
@ -1,28 +0,0 @@
|
||||||
# Auto detect text files and perform LF normalization
|
|
||||||
* text=auto eol=lf
|
|
||||||
|
|
||||||
# Development files
|
|
||||||
*.cpp text eol=lf
|
|
||||||
*.h text eol=lf
|
|
||||||
*.ui text eol=lf
|
|
||||||
*.qrc text eol=lf
|
|
||||||
|
|
||||||
# Development resources
|
|
||||||
*.ini text eol=lf
|
|
||||||
|
|
||||||
# Linux development files
|
|
||||||
*.desktop text eol=lf
|
|
||||||
|
|
||||||
# Windows development files
|
|
||||||
*.rc text eol=crlf
|
|
||||||
*.nsi text eol=crlf
|
|
||||||
*.exe.manifest text eol=crlf
|
|
||||||
|
|
||||||
# Binary files
|
|
||||||
*.png binary
|
|
||||||
*.jpg binary
|
|
||||||
*.qm binary
|
|
||||||
*.ico binary
|
|
||||||
*.icns binary
|
|
||||||
*.xcf binary
|
|
||||||
*.g5e binary
|
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -29,7 +29,3 @@
|
||||||
|
|
||||||
# Qt project user file
|
# Qt project user file
|
||||||
*.pro.user
|
*.pro.user
|
||||||
|
|
||||||
# Gettext translation files
|
|
||||||
*.po
|
|
||||||
*.pot
|
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
stages:
|
|
||||||
- build
|
|
||||||
|
|
||||||
variables:
|
|
||||||
BUILD_TYPE: "REL"
|
|
||||||
|
|
||||||
Windows Installer:
|
|
||||||
stage: build
|
|
||||||
image: sypingauto/gta5view-build:1.10-shared
|
|
||||||
variables:
|
|
||||||
BUILD_SCRIPT: "wininstall_build.sh"
|
|
||||||
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
|
||||||
script:
|
|
||||||
- .gitlab/gitlab.sh
|
|
||||||
artifacts:
|
|
||||||
name: "gta5view-$CI_COMMIT_REF_NAME-${CI_COMMIT_SHA:0:8}_setup"
|
|
||||||
paths:
|
|
||||||
- "gta5view-*.exe"
|
|
||||||
|
|
||||||
Windows Portable:
|
|
||||||
stage: build
|
|
||||||
image: sypingauto/gta5view-build:1.10-static
|
|
||||||
variables:
|
|
||||||
BUILD_SCRIPT: "windows_build.sh"
|
|
||||||
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
|
||||||
script:
|
|
||||||
- .gitlab/gitlab.sh
|
|
||||||
artifacts:
|
|
||||||
name: "gta5view-$CI_COMMIT_REF_NAME-${CI_COMMIT_SHA:0:8}_portable"
|
|
||||||
paths:
|
|
||||||
- "gta5view-*.exe"
|
|
||||||
Binary file not shown.
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Decrypt Telemetry Authenticator
|
|
||||||
rm -rf tmext/TelemetryClassAuthenticator.cpp && \
|
|
||||||
openssl aes-256-cbc -k ${tca_pass} -in .gitlab/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d
|
|
||||||
|
|
||||||
# Check if build is not tagged
|
|
||||||
if [ "${CI_COMMIT_TAG}" == "" ]; then
|
|
||||||
export EXECUTABLE_TAG=-$(git rev-parse --short HEAD)
|
|
||||||
else
|
|
||||||
export EXECUTABLE_TAG=
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if package code is not set
|
|
||||||
if [ "${PACKAGE_CODE}" == "" ]; then
|
|
||||||
export PACKAGE_CODE=GitLab
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Init Application Commit Hash
|
|
||||||
export APPLICATION_COMMIT=$(git rev-parse --short HEAD)
|
|
||||||
|
|
||||||
# Start CI script and copying assets into base directory
|
|
||||||
.ci/ci.sh && \
|
|
||||||
cp -Rf assets/* ./
|
|
||||||
50
.travis.yml
50
.travis.yml
|
|
@ -1,50 +0,0 @@
|
||||||
dist: bionic
|
|
||||||
sudo: required
|
|
||||||
|
|
||||||
language: cpp
|
|
||||||
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- BUILD_TYPE=REL
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- env:
|
|
||||||
- BUILD_SCRIPT=debian_docker.sh
|
|
||||||
- RELEASE_LABEL="Debian 64-Bit Package"
|
|
||||||
- DEBIAN_VERSION=buster
|
|
||||||
- DOCKER_USER=amd64
|
|
||||||
- APT_INSTALL=clang
|
|
||||||
- env:
|
|
||||||
- BUILD_SCRIPT=windows_docker.sh
|
|
||||||
- QT_SELECT=qt5-x86_64-w64-mingw32
|
|
||||||
- RELEASE_LABEL="Windows 64-Bit Portable"
|
|
||||||
- env:
|
|
||||||
- BUILD_SCRIPT=wininstall_docker.sh
|
|
||||||
- QT_SELECT=qt5-x86_64-w64-mingw32
|
|
||||||
- RELEASE_LABEL="Windows 64-Bit Installer"
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode14.2
|
|
||||||
env:
|
|
||||||
- BUILD_SCRIPT=osx_ci.sh
|
|
||||||
- RELEASE_LABEL="Mac OS X 64-Bit Disk Image"
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- ".travis/source.sh"
|
|
||||||
|
|
||||||
script:
|
|
||||||
- ".travis/travis.sh"
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
provider: releases
|
|
||||||
api_key:
|
|
||||||
secure: o7VneEz1aHfdVwZvOZLfopf6uJWNrFsZaBvunTmXFzpmNFhlNS1qwqgMUkIA2yBRbZ3wIzVs4vfwIHv7W9yE/PqK+AYL+R8+AwKGrwlgT4HqJNuk6VM/LNJ6GwT/qkQuaoOVw29bUjmzzgIRdHmw53SlJv6Hh1VE8HphlTT//aex6nCfcFhUZ0BETdZDWz5FSHwL3NalUoqfKfQrJeky5RXzCyCANQC2tKt0bV46GaWIgWrDo2KCTNqPtRWWf5GDmnkXE5IYRMQ3mXvO9iYh0v5Y2jo4PiXGUiFUU6Z3aAWFAiPdGclrBO697cf3lCTzDMhuCETR153qFYsLShUlFf61ITAmCeHAWETjZDri0lmPONo3GoNB6alGfYEA51qw14kXakrTpICtTJj7gw/gtUYOabW6hrzmieNzMBIy62RikDPjyakFnuwW2qNHRlD65e0jYv+6nCpb6E+OV16Ysh1zhV2vTfpfzVmSuyu2J+ELqXD3OZCXRSPpDIih9UQ8335p8FBji6jHORcgym/TRgdgRmENibh8tLzWp+UjpWHuWfcpvZgOskjfwU0iDMCayMJ7tDpOhXHcAhDRnd6XRIiOJ5YZCzflj2nEwmt3YUd7DwXS/AU+WHOmcNQBjXBxF/FJa35XXcy3HKJM5TTKqtph3medo30us5yXHeG6NNg=
|
|
||||||
label: ${RELEASE_LABEL}
|
|
||||||
file_glob: true
|
|
||||||
file: assets/*
|
|
||||||
skip_cleanup: true
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
||||||
Poァ鏖<EFBFBD>劾ラ<作1x」%几<>ャネw|RtZv<>kホ銓顴Z肄2チ廁湮ォ`<1A>ム,4vヨマ・@<>ヲeハ・~U$+<2B><><EFBFBD><1A><牾&蓬熙
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
rm -rf tmext/TelemetryClassAuthenticator.cpp && \
|
|
||||||
openssl aes-256-cbc -K $encrypted_db000a5d87d6_key -iv $encrypted_db000a5d87d6_iv -in .travis/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d && \
|
|
||||||
openssl aes-256-cbc -K $encrypted_d57e7d2f8877_key -iv $encrypted_d57e7d2f8877_iv -in .travis/dropbox_uploader.enc -out ~/.dropbox_uploader -d
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Install lua
|
|
||||||
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
|
|
||||||
brew install lua
|
|
||||||
else
|
|
||||||
sudo apt-get update -qq && \
|
|
||||||
sudo apt-get install -qq lua5.2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if build is not tagged
|
|
||||||
if [ "${TRAVIS_TAG}" == "" ]; then
|
|
||||||
export EXECUTABLE_TAG=-$(git rev-parse --short HEAD)
|
|
||||||
else
|
|
||||||
export EXECUTABLE_TAG=
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if package code is not set
|
|
||||||
if [ "${PACKAGE_CODE}" == "" ]; then
|
|
||||||
export PACKAGE_CODE=GitHub
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Init Application Commit Hash
|
|
||||||
export APPLICATION_COMMIT=$(git rev-parse --short HEAD)
|
|
||||||
|
|
||||||
# Start CI script
|
|
||||||
.ci/ci.sh
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Install packages
|
|
||||||
sudo .ci/debian_install.sh && \
|
|
||||||
|
|
||||||
# Build gta5view
|
|
||||||
sudo .ci/debian_build.sh && \
|
|
||||||
cd ${PROJECT_DIR}
|
|
||||||
100
AboutDialog.cpp
Normal file → Executable file
100
AboutDialog.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -16,111 +16,25 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
#include <QMessageBox>
|
|
||||||
#include "AboutDialog.h"
|
#include "AboutDialog.h"
|
||||||
#include "ui_AboutDialog.h"
|
#include "ui_AboutDialog.h"
|
||||||
#include "AppEnv.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
AboutDialog::AboutDialog(QWidget *parent) :
|
AboutDialog::AboutDialog(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::AboutDialog)
|
ui(new Ui::AboutDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Build Strings
|
|
||||||
QString appVersion = QApplication::applicationVersion();
|
|
||||||
const char* literalBuildType = GTA5SYNC_BUILDTYPE;
|
|
||||||
const QString buildType = tr(literalBuildType);
|
|
||||||
const QString projectBuild = AppEnv::getBuildDateTime();
|
|
||||||
const QString buildStr = GTA5SYNC_BUILDSTRING;
|
|
||||||
#ifdef GTA5SYNC_COMMIT
|
|
||||||
if ((strcmp(literalBuildType, REL_BUILDTYPE) != 0) && !appVersion.contains("-"))
|
|
||||||
appVersion = appVersion % "-" % GTA5SYNC_COMMIT;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Translator Comments
|
|
||||||
//: Translated by translator, example Translated by Syping
|
|
||||||
const QString translatedByStr = tr("Translated by %1");
|
|
||||||
//: Insert your name here and profile here in following scheme, First Translator,First Profile\\nSecond Translator\\nThird Translator,Second Profile
|
|
||||||
const QString translatorVal = tr("TRANSLATOR");
|
|
||||||
QStringList translatorContent;
|
|
||||||
if (translatorVal != "TRANSLATOR") {
|
|
||||||
const QStringList translatorList = translatorVal.split('\n');
|
|
||||||
for (const QString &translatorStr : translatorList) {
|
|
||||||
QStringList translatorStrList = translatorStr.split(',');
|
|
||||||
const QString translatorName = translatorStrList.at(0);
|
|
||||||
translatorStrList.removeFirst();
|
|
||||||
QString translatorProfile = translatorStrList.join(QString());
|
|
||||||
if (!translatorProfile.isEmpty()) {
|
|
||||||
translatorContent += QString("<a href=\"%1\">%2</a>").arg(translatorProfile, translatorName);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
translatorContent += translatorName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Project Description
|
|
||||||
const QString projectDes = tr("A project for viewing Grand Theft Auto V Snapmatic<br/>\nPictures and Savegames");
|
|
||||||
|
|
||||||
// Copyright Description
|
|
||||||
QString copyrightDes1 = tr("Copyright © <a href=\"%1\">%2</a> %3");
|
|
||||||
copyrightDes1 = copyrightDes1.arg(GTA5SYNC_APPVENDORLINK, GTA5SYNC_APPVENDOR, GTA5SYNC_COPYRIGHT);
|
|
||||||
QString copyrightDes2 = tr("%1 is licensed under <a href=\"https://www.gnu.org/licenses/gpl-3.0.html#content\">GNU GPLv3</a>");
|
|
||||||
copyrightDes2 = copyrightDes2.arg(GTA5SYNC_APPSTR);
|
|
||||||
QString copyrightDesA;
|
|
||||||
if (!translatorContent.isEmpty()) {
|
|
||||||
copyrightDesA = copyrightDes1 % "<br/>" % translatedByStr.arg(translatorContent.join(", ")) % "<br/>" % copyrightDes2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
copyrightDesA = copyrightDes1 % "<br/>" % copyrightDes2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup User Interface
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
aboutStr = ui->labAbout->text();
|
aboutStr = ui->labAbout->text();
|
||||||
titleStr = windowTitle();
|
QString appVersion = qApp->applicationVersion();
|
||||||
ui->labAbout->setText(aboutStr.arg(GTA5SYNC_APPSTR, projectDes, appVersion % " (" % buildType % ")", projectBuild, buildStr, qVersion(), copyrightDesA));
|
QString buildType = GTA5SYNC_BUILDTYPE;
|
||||||
setWindowTitle(titleStr.arg(GTA5SYNC_APPSTR));
|
buildType.replace("_", " ");
|
||||||
|
QString buildStr = QString("%1, %2").arg(QT_VERSION_STR, GTA5SYNC_COMPILER);
|
||||||
// Set Icon for Close Button
|
ui->labAbout->setText(aboutStr.arg(appVersion % " (" % buildType % ")", buildStr, qVersion(), __DATE__, __TIME__));
|
||||||
if (QIcon::hasThemeIcon("dialog-close")) {
|
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-close")) {
|
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// DPI calculation
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
if (!translatorContent.isEmpty()) {
|
|
||||||
resize(375 * screenRatio, 270 * screenRatio);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resize(375 * screenRatio, 260 * screenRatio);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AboutDialog::~AboutDialog()
|
AboutDialog::~AboutDialog()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutDialog::on_labAbout_linkActivated(const QString &link)
|
|
||||||
{
|
|
||||||
if (link.left(12) == "g5e://about?") {
|
|
||||||
QStringList aboutStrList = QString(link).remove(0, 12).split(":");
|
|
||||||
QMessageBox::information(this, QString::fromUtf8(QByteArray::fromBase64(aboutStrList.at(0).toUtf8())), QString::fromUtf8(QByteArray::fromBase64(aboutStrList.at(1).toUtf8())));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QDesktopServices::openUrl(QUrl(link));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
7
AboutDialog.h
Normal file → Executable file
7
AboutDialog.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -28,17 +28,16 @@ class AboutDialog;
|
||||||
class AboutDialog : public QDialog
|
class AboutDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AboutDialog(QWidget *parent = 0);
|
explicit AboutDialog(QWidget *parent = 0);
|
||||||
~AboutDialog();
|
~AboutDialog();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_labAbout_linkActivated(const QString &link);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::AboutDialog *ui;
|
Ui::AboutDialog *ui;
|
||||||
QString aboutStr;
|
QString aboutStr;
|
||||||
QString titleStr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ABOUTDIALOG_H
|
#endif // ABOUTDIALOG_H
|
||||||
|
|
|
||||||
24
AboutDialog.ui
Normal file → Executable file
24
AboutDialog.ui
Normal file → Executable file
|
|
@ -11,7 +11,7 @@
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>About %1</string>
|
<string>About gta5view</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|
@ -26,16 +26,17 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><span style="font-weight:600">%1</span><br/>
|
<string><span style=" font-weight:600;">gta5view</span><br/>
|
||||||
<br/>
|
<br/>
|
||||||
%2<br/>
|
A project for viewing Grand Theft Auto V Snapmatic<br/>
|
||||||
|
Pictures and Savegames<br/>
|
||||||
<br/>
|
<br/>
|
||||||
Version %3<br/>
|
Project version: %1<br/>
|
||||||
Created on %4<br/>
|
Project build: %4, %5<br/>
|
||||||
Built with Qt %5<br/>
|
Compiled with Qt %2<br/>
|
||||||
Running with Qt %6<br/>
|
Running with Qt %3<br/>
|
||||||
<br/>
|
<br/>
|
||||||
%7</string>
|
Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5view is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
|
@ -43,8 +44,8 @@ Running with Qt %6<br/>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="textInteractionFlags">
|
<property name="openExternalLinks">
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -74,6 +75,9 @@ Running with Qt %6<br/>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Close</string>
|
<string>&Close</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="dialog-close"/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
||||||
407
AppEnv.cpp
Normal file → Executable file
407
AppEnv.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -20,33 +20,16 @@
|
||||||
#include "AppEnv.h"
|
#include "AppEnv.h"
|
||||||
#include "StringParser.h"
|
#include "StringParser.h"
|
||||||
#include "StandardPaths.h"
|
#include "StandardPaths.h"
|
||||||
#include <QtGlobal>
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QScreen>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QRect>
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QDebug>
|
||||||
#if QT_VERSION < 0x050000
|
#include <QtGlobal>
|
||||||
#include <QDesktopWidget>
|
#include <QSettings>
|
||||||
#endif
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
AppEnv::AppEnv()
|
AppEnv::AppEnv()
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
// Build Stuff
|
|
||||||
|
|
||||||
QString AppEnv::getBuildDateTime()
|
|
||||||
{
|
|
||||||
return GTA5SYNC_BUILDDATETIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AppEnv::getBuildCode()
|
|
||||||
{
|
|
||||||
return GTA5SYNC_BUILDCODE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Folder Stuff
|
// Folder Stuff
|
||||||
|
|
@ -55,403 +38,95 @@ QString AppEnv::getGameFolder(bool *ok)
|
||||||
{
|
{
|
||||||
QDir dir;
|
QDir dir;
|
||||||
QString GTAV_FOLDER = QString::fromUtf8(qgetenv("GTAV_FOLDER"));
|
QString GTAV_FOLDER = QString::fromUtf8(qgetenv("GTAV_FOLDER"));
|
||||||
if (GTAV_FOLDER != "") {
|
if (GTAV_FOLDER != "")
|
||||||
|
{
|
||||||
dir.setPath(GTAV_FOLDER);
|
dir.setPath(GTAV_FOLDER);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
if (ok != NULL)
|
{
|
||||||
*ok = true;
|
if (ok != NULL) *ok = true;
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return dir.absolutePath();
|
return dir.absolutePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString GTAV_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/GTA V";
|
QString GTAV_defaultFolder = StandardPaths::documentsLocation() + QDir::separator() + "Rockstar Games" + QDir::separator() + "GTA V";
|
||||||
QString GTAV_returnFolder = GTAV_defaultFolder;
|
QString GTAV_returnFolder = GTAV_defaultFolder;
|
||||||
|
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings SyncSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
settings.beginGroup("dir");
|
SyncSettings.beginGroup("dir");
|
||||||
bool forceDir = settings.value("force", false).toBool();
|
bool forceDir = SyncSettings.value("force", false).toBool();
|
||||||
GTAV_returnFolder = settings.value("dir", GTAV_defaultFolder).toString();
|
GTAV_returnFolder = SyncSettings.value("dir", GTAV_defaultFolder).toString();
|
||||||
settings.endGroup();
|
SyncSettings.endGroup();
|
||||||
|
|
||||||
if (forceDir) {
|
if (forceDir)
|
||||||
|
{
|
||||||
dir.setPath(GTAV_returnFolder);
|
dir.setPath(GTAV_returnFolder);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
if (ok != 0)
|
{
|
||||||
*ok = true;
|
if (ok != 0) *ok = true;
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return dir.absolutePath();
|
return dir.absolutePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dir.setPath(GTAV_defaultFolder);
|
dir.setPath(GTAV_defaultFolder);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
if (ok != 0)
|
{
|
||||||
*ok = true;
|
if (ok != 0) *ok = true;
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return dir.absolutePath();
|
return dir.absolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!forceDir) {
|
if (!forceDir)
|
||||||
|
{
|
||||||
dir.setPath(GTAV_returnFolder);
|
dir.setPath(GTAV_returnFolder);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
if (ok != 0)
|
{
|
||||||
*ok = true;
|
if (ok != 0) *ok = true;
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return dir.absolutePath();
|
return dir.absolutePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok != 0)
|
if (ok != 0) *ok = false;
|
||||||
*ok = false;
|
return "";
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppEnv::setGameFolder(QString gameFolder)
|
bool AppEnv::setGameFolder(QString gameFolder)
|
||||||
{
|
{
|
||||||
QDir dir;
|
QDir dir;
|
||||||
dir.setPath(gameFolder);
|
dir.setPath(gameFolder);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
|
{
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AppEnv::getExLangFolder()
|
QString AppEnv::getLangFolder()
|
||||||
{
|
{
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_LANG);
|
return StringParser::convertBuildedString(QString::fromUtf8(GTA5SYNC_LANG));
|
||||||
}
|
|
||||||
|
|
||||||
QString AppEnv::getInLangFolder()
|
|
||||||
{
|
|
||||||
#ifdef GTA5SYNC_QCONF
|
|
||||||
#ifdef GTA5SYNC_INLANG
|
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_INLANG);
|
|
||||||
#else
|
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("/APPNAME:/translations"));
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef GTA5SYNC_INLANG
|
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_INLANG);
|
|
||||||
#else
|
|
||||||
return QLatin1String(":/tr");
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AppEnv::getPluginsFolder()
|
QString AppEnv::getPluginsFolder()
|
||||||
{
|
{
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_PLUG);
|
return StringParser::convertBuildedString(QString::fromUtf8(GTA5SYNC_PLUG));
|
||||||
}
|
|
||||||
|
|
||||||
QString AppEnv::getImagesFolder()
|
|
||||||
{
|
|
||||||
#if defined(GTA5SYNC_QCONF) && defined(GTA5SYNC_CMAKE)
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("/resources"));
|
|
||||||
#else
|
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("/APPNAME:/resources"));
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
return QLatin1String(":/img");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AppEnv::getShareFolder()
|
|
||||||
{
|
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_SHARE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Web Stuff
|
// Web Stuff
|
||||||
|
|
||||||
QByteArray AppEnv::getUserAgent()
|
QByteArray AppEnv::getUserAgent()
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x050400
|
return QString("Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 %1/%2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QString kernelVersion = QSysInfo::kernelVersion();
|
|
||||||
const QStringList &kernelVersionList = kernelVersion.split(".");
|
|
||||||
if (kernelVersionList.length() > 2) {
|
|
||||||
kernelVersion = kernelVersionList.at(0) % "." % kernelVersionList.at(1);
|
|
||||||
}
|
|
||||||
QString runArch = QSysInfo::buildCpuArchitecture();
|
|
||||||
if (runArch == "x86_64") {
|
|
||||||
runArch = "Win64; x64";
|
|
||||||
}
|
|
||||||
else if (runArch == "i686") {
|
|
||||||
const QString &curArch = QSysInfo::currentCpuArchitecture();
|
|
||||||
if (curArch == "x86_64") {
|
|
||||||
runArch = "WOW64";
|
|
||||||
}
|
|
||||||
else if (curArch == "i686") {
|
|
||||||
runArch = "Win32; x86";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QString("Mozilla/5.0 (Windows NT %1; %2) %3/%4").arg(kernelVersion, runArch, GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
|
|
||||||
#else
|
|
||||||
return QString("Mozilla/5.0 (%1; %2) %3/%4").arg(QSysInfo::kernelType(), QSysInfo::kernelVersion(), GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
return QString("Mozilla/5.0 %1/%2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl AppEnv::getCrewFetchingUrl(QString crewID)
|
QUrl AppEnv::getCrewFetchingUrl(QString crewID)
|
||||||
{
|
{
|
||||||
return QUrl(QString("https://socialclub.rockstargames.com/crew/%1/%1").arg(crewID));
|
return QUrl(QString("https://socialclub.rockstargames.com/reference/crewfeed/%1").arg(crewID));
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl AppEnv::getPlayerFetchingUrl(QString crewID, QString pageNumber)
|
QUrl AppEnv::getPlayerFetchingUrl(QString crewID, QString pageNumber)
|
||||||
{
|
{
|
||||||
return QUrl(QString("https://socialclub.rockstargames.com/crewsapi/GetMembersList?crewId=%1&pageNumber=%2&pageSize=5000").arg(crewID, pageNumber));
|
return QUrl(QString("https://socialclub.rockstargames.com/crewsapi/GetMembersList?crewId=%1&pageNumber=%2").arg(crewID, pageNumber));
|
||||||
}
|
|
||||||
|
|
||||||
QUrl AppEnv::getPlayerFetchingUrl(QString crewID, int pageNumber)
|
|
||||||
{
|
|
||||||
return getPlayerFetchingUrl(crewID, QString::number(pageNumber));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Game Stuff
|
|
||||||
|
|
||||||
GameVersion AppEnv::getGameVersion()
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QString argumentValue;
|
|
||||||
#ifdef _WIN64
|
|
||||||
argumentValue = "\\WOW6432Node";
|
|
||||||
#endif
|
|
||||||
QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat);
|
|
||||||
QString installFolderSc = registrySettingsSc.value("InstallFolder", "").toString();
|
|
||||||
QDir installFolderScDir(installFolderSc);
|
|
||||||
bool scVersionInstalled = false;
|
|
||||||
if (!installFolderSc.isEmpty() && installFolderScDir.exists()) {
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "gameVersionFoundSocialClubVersion";
|
|
||||||
#endif
|
|
||||||
scVersionInstalled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\GTAV").arg(argumentValue), QSettings::NativeFormat);
|
|
||||||
QString installFolderSteam = registrySettingsSteam.value("installfoldersteam", "").toString();
|
|
||||||
if (installFolderSteam.right(5) == "\\GTAV") {
|
|
||||||
installFolderSteam = installFolderSteam.remove(installFolderSteam.length() - 5, 5);
|
|
||||||
}
|
|
||||||
QDir installFolderSteamDir(installFolderSteam);
|
|
||||||
bool steamVersionInstalled = false;
|
|
||||||
if (!installFolderSteam.isEmpty() && installFolderSteamDir.exists()) {
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "gameVersionFoundSteamVersion";
|
|
||||||
#endif
|
|
||||||
steamVersionInstalled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scVersionInstalled && steamVersionInstalled) {
|
|
||||||
return GameVersion::BothVersions;
|
|
||||||
}
|
|
||||||
else if (scVersionInstalled) {
|
|
||||||
return GameVersion::SocialClubVersion;
|
|
||||||
}
|
|
||||||
else if (steamVersionInstalled) {
|
|
||||||
return GameVersion::SteamVersion;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return GameVersion::NoVersion;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return GameVersion::NoVersion;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
GameLanguage AppEnv::getGameLanguage(GameVersion gameVersion)
|
|
||||||
{
|
|
||||||
if (gameVersion == GameVersion::SocialClubVersion) {
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QString argumentValue;
|
|
||||||
#ifdef _WIN64
|
|
||||||
argumentValue = "\\WOW6432Node";
|
|
||||||
#endif
|
|
||||||
QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat);
|
|
||||||
QString languageSc = registrySettingsSc.value("Language", "").toString();
|
|
||||||
return gameLanguageFromString(languageSc);
|
|
||||||
#else
|
|
||||||
return GameLanguage::Undefined;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (gameVersion == GameVersion::SteamVersion) {
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QString argumentValue;
|
|
||||||
#ifdef _WIN64
|
|
||||||
argumentValue = "\\WOW6432Node";
|
|
||||||
#endif
|
|
||||||
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V Steam").arg(argumentValue), QSettings::NativeFormat);
|
|
||||||
QString languageSteam = registrySettingsSteam.value("Language", "").toString();
|
|
||||||
return gameLanguageFromString(languageSteam);
|
|
||||||
#else
|
|
||||||
return GameLanguage::Undefined;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return GameLanguage::Undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameLanguage AppEnv::gameLanguageFromString(QString gameLanguage)
|
|
||||||
{
|
|
||||||
if (gameLanguage == "en-US") {
|
|
||||||
return GameLanguage::English;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "fr-FR") {
|
|
||||||
return GameLanguage::French;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "it-IT") {
|
|
||||||
return GameLanguage::Italian;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "de-DE") {
|
|
||||||
return GameLanguage::German;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "es-ES") {
|
|
||||||
return GameLanguage::Spanish;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "es-MX") {
|
|
||||||
return GameLanguage::Mexican;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "pt-BR") {
|
|
||||||
return GameLanguage::Brasilian;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "ru-RU") {
|
|
||||||
return GameLanguage::Russian;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "pl-PL") {
|
|
||||||
return GameLanguage::Polish;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "ja-JP") {
|
|
||||||
return GameLanguage::Japanese;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "zh-CHS") {
|
|
||||||
return GameLanguage::SChinese;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "zh-CHT") {
|
|
||||||
return GameLanguage::TChinese;
|
|
||||||
}
|
|
||||||
else if (gameLanguage == "ko-KR") {
|
|
||||||
return GameLanguage::Korean;
|
|
||||||
}
|
|
||||||
return GameLanguage::Undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AppEnv::gameLanguageToString(GameLanguage gameLanguage)
|
|
||||||
{
|
|
||||||
switch (gameLanguage) {
|
|
||||||
case GameLanguage::English:
|
|
||||||
return "en-US";
|
|
||||||
case GameLanguage::French:
|
|
||||||
return "fr-FR";
|
|
||||||
case GameLanguage::Italian:
|
|
||||||
return "it-IT";
|
|
||||||
case GameLanguage::German:
|
|
||||||
return "de-DE";
|
|
||||||
case GameLanguage::Spanish:
|
|
||||||
return "es-ES";
|
|
||||||
case GameLanguage::Mexican:
|
|
||||||
return "es-MX";
|
|
||||||
case GameLanguage::Brasilian:
|
|
||||||
return "pt-BR";
|
|
||||||
case GameLanguage::Polish:
|
|
||||||
return "pl-PL";
|
|
||||||
case GameLanguage::Japanese:
|
|
||||||
return "ja-JP";
|
|
||||||
case GameLanguage::SChinese:
|
|
||||||
return "zh-CHS";
|
|
||||||
case GameLanguage::TChinese:
|
|
||||||
return "zh-CHT";
|
|
||||||
case GameLanguage::Korean:
|
|
||||||
return "ko-KR";
|
|
||||||
default:
|
|
||||||
return "Undefinied";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AppEnv::setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage)
|
|
||||||
{
|
|
||||||
bool socialClubVersion = false;
|
|
||||||
bool steamVersion = false;
|
|
||||||
if (gameVersion == GameVersion::SocialClubVersion) {
|
|
||||||
socialClubVersion = true;
|
|
||||||
}
|
|
||||||
else if (gameVersion == GameVersion::SteamVersion) {
|
|
||||||
steamVersion = true;
|
|
||||||
}
|
|
||||||
else if (gameVersion == GameVersion::BothVersions) {
|
|
||||||
socialClubVersion = true;
|
|
||||||
steamVersion = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (socialClubVersion) {
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QString argumentValue;
|
|
||||||
#ifdef _WIN64
|
|
||||||
argumentValue = "\\WOW6432Node";
|
|
||||||
#endif
|
|
||||||
QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat);
|
|
||||||
if (gameLanguage != GameLanguage::Undefined) {
|
|
||||||
registrySettingsSc.setValue("Language", gameLanguageToString(gameLanguage));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
registrySettingsSc.remove("Language");
|
|
||||||
}
|
|
||||||
registrySettingsSc.sync();
|
|
||||||
if (registrySettingsSc.status() != QSettings::NoError) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Q_UNUSED(gameLanguage)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (steamVersion) {
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QString argumentValue;
|
|
||||||
#ifdef _WIN64
|
|
||||||
argumentValue = "\\WOW6432Node";
|
|
||||||
#endif
|
|
||||||
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V Steam").arg(argumentValue), QSettings::NativeFormat);
|
|
||||||
if (gameLanguage != GameLanguage::Undefined) {
|
|
||||||
registrySettingsSteam.setValue("Language", gameLanguageToString(gameLanguage));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
registrySettingsSteam.remove("Language");
|
|
||||||
}
|
|
||||||
registrySettingsSteam.sync();
|
|
||||||
if (registrySettingsSteam.status() != QSettings::NoError) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Q_UNUSED(gameLanguage)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Screen Stuff
|
|
||||||
|
|
||||||
qreal AppEnv::screenRatio()
|
|
||||||
{
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
qreal dpi = QApplication::primaryScreen()->logicalDotsPerInch();
|
|
||||||
#else
|
|
||||||
qreal dpi = QApplication::desktop()->logicalDpiX();
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
return (dpi / 72);
|
|
||||||
#else
|
|
||||||
return (dpi / 96);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal AppEnv::screenRatioPR()
|
|
||||||
{
|
|
||||||
#if QT_VERSION >= 0x050600
|
|
||||||
return QApplication::primaryScreen()->devicePixelRatio();
|
|
||||||
#else
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
AppEnv.h
Normal file → Executable file
28
AppEnv.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -22,43 +22,21 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
enum class GameVersion : int { NoVersion = 0, SocialClubVersion = 1, SteamVersion = 2, BothVersions = 3 };
|
|
||||||
enum class GameLanguage : int { Undefined = 0, English = 1, French = 2, Italian = 3, German = 4, Spanish = 5, Mexican = 6, Brasilian = 7, Russian = 8, Polish = 9, Japanese = 10, SChinese = 11, TChinese = 12, Korean = 13 };
|
|
||||||
|
|
||||||
class AppEnv
|
class AppEnv
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AppEnv();
|
AppEnv();
|
||||||
|
|
||||||
// Build Stuff
|
|
||||||
static QString getBuildDateTime();
|
|
||||||
static QString getBuildCode();
|
|
||||||
|
|
||||||
// Folder Stuff
|
// Folder Stuff
|
||||||
static QString getGameFolder(bool *ok = 0);
|
static QString getGameFolder(bool *ok = 0);
|
||||||
static bool setGameFolder(QString gameFolder);
|
static bool setGameFolder(QString gameFolder);
|
||||||
static QString getExLangFolder();
|
static QString getLangFolder();
|
||||||
static QString getInLangFolder();
|
|
||||||
static QString getImagesFolder();
|
|
||||||
static QString getPluginsFolder();
|
static QString getPluginsFolder();
|
||||||
static QString getShareFolder();
|
|
||||||
|
|
||||||
// Web Stuff
|
// Web Stuff
|
||||||
static QByteArray getUserAgent();
|
static QByteArray getUserAgent();
|
||||||
static QUrl getCrewFetchingUrl(QString crewID);
|
static QUrl getCrewFetchingUrl(QString crewID);
|
||||||
static QUrl getPlayerFetchingUrl(QString crewID, QString pageNumber);
|
static QUrl getPlayerFetchingUrl(QString crewID, QString pageNumber);
|
||||||
static QUrl getPlayerFetchingUrl(QString crewID, int pageNumber);
|
|
||||||
|
|
||||||
// Game Stuff
|
|
||||||
static GameVersion getGameVersion();
|
|
||||||
static GameLanguage getGameLanguage(GameVersion gameVersion);
|
|
||||||
static GameLanguage gameLanguageFromString(QString gameLanguage);
|
|
||||||
static QString gameLanguageToString(GameLanguage gameLanguage);
|
|
||||||
static bool setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage);
|
|
||||||
|
|
||||||
// Screen Stuff
|
|
||||||
static qreal screenRatio();
|
|
||||||
static qreal screenRatioPR();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APPENV_H
|
#endif // APPENV_H
|
||||||
|
|
|
||||||
382
CMakeLists.txt
382
CMakeLists.txt
|
|
@ -1,382 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.7)
|
|
||||||
|
|
||||||
project(gta5view LANGUAGES C CXX)
|
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|
||||||
|
|
||||||
set(CMAKE_AUTOUIC ON)
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
|
||||||
set(CMAKE_AUTORCC ON)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
|
|
||||||
set(FORCE_QT_VERSION "" CACHE STRING "Force Qt Version")
|
|
||||||
if(FORCE_QT_VERSION)
|
|
||||||
set(QT_VERSION_MAJOR ${FORCE_QT_VERSION})
|
|
||||||
else()
|
|
||||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
|
||||||
endif()
|
|
||||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network Svg Widgets REQUIRED)
|
|
||||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET)
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
list(APPEND GTA5VIEW_LIBS
|
|
||||||
dwmapi
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
-DUNICODE
|
|
||||||
-D_UNICODE
|
|
||||||
-DWIN32
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_RESOURCES
|
|
||||||
res/app.rc
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(APPLE)
|
|
||||||
list(APPEND GTA5VIEW_RESOURCES
|
|
||||||
res/gta5view.icns
|
|
||||||
)
|
|
||||||
set(MACOSX_BUNDLE_BUNDLE_NAME gta5view)
|
|
||||||
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.10.2)
|
|
||||||
set(MACOSX_BUNDLE_ICON_FILE gta5view.icns)
|
|
||||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER de.syping.gta5view)
|
|
||||||
set_source_files_properties(res/gta5view.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
-DGTA5SYNC_CMAKE
|
|
||||||
-DGTA5SYNC_PROJECT
|
|
||||||
)
|
|
||||||
|
|
||||||
set(GTA5VIEW_SOURCES
|
|
||||||
main.cpp
|
|
||||||
AboutDialog.cpp
|
|
||||||
AppEnv.cpp
|
|
||||||
CrewDatabase.cpp
|
|
||||||
DatabaseThread.cpp
|
|
||||||
ExportDialog.cpp
|
|
||||||
ExportThread.cpp
|
|
||||||
GlobalString.cpp
|
|
||||||
IconLoader.cpp
|
|
||||||
ImportDialog.cpp
|
|
||||||
JsonEditorDialog.cpp
|
|
||||||
MapLocationDialog.cpp
|
|
||||||
OptionsDialog.cpp
|
|
||||||
PictureDialog.cpp
|
|
||||||
PictureExport.cpp
|
|
||||||
PictureWidget.cpp
|
|
||||||
PlayerListDialog.cpp
|
|
||||||
ProfileDatabase.cpp
|
|
||||||
ProfileInterface.cpp
|
|
||||||
ProfileLoader.cpp
|
|
||||||
ProfileWidget.cpp
|
|
||||||
RagePhoto.cpp
|
|
||||||
SavegameCopy.cpp
|
|
||||||
SavegameData.cpp
|
|
||||||
SavegameDialog.cpp
|
|
||||||
SavegameWidget.cpp
|
|
||||||
SidebarGenerator.cpp
|
|
||||||
SnapmaticEditor.cpp
|
|
||||||
SnapmaticPicture.cpp
|
|
||||||
SnapmaticWidget.cpp
|
|
||||||
StandardPaths.cpp
|
|
||||||
StringParser.cpp
|
|
||||||
TranslationClass.cpp
|
|
||||||
UserInterface.cpp
|
|
||||||
anpro/imagecropper.cpp
|
|
||||||
pcg/pcg_basic.c
|
|
||||||
uimod/JSHighlighter.cpp
|
|
||||||
uimod/UiModLabel.cpp
|
|
||||||
uimod/UiModWidget.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(GTA5VIEW_HEADERS
|
|
||||||
config.h
|
|
||||||
wrapper.h
|
|
||||||
AboutDialog.h
|
|
||||||
AppEnv.h
|
|
||||||
CrewDatabase.h
|
|
||||||
DatabaseThread.h
|
|
||||||
ExportDialog.h
|
|
||||||
ExportThread.h
|
|
||||||
GlobalString.h
|
|
||||||
IconLoader.h
|
|
||||||
ImportDialog.h
|
|
||||||
JsonEditorDialog.h
|
|
||||||
MapLocationDialog.h
|
|
||||||
OptionsDialog.h
|
|
||||||
PictureDialog.h
|
|
||||||
PictureExport.h
|
|
||||||
PictureWidget.h
|
|
||||||
PlayerListDialog.h
|
|
||||||
ProfileDatabase.h
|
|
||||||
ProfileInterface.h
|
|
||||||
ProfileLoader.h
|
|
||||||
ProfileWidget.h
|
|
||||||
RagePhoto.h
|
|
||||||
SavegameCopy.h
|
|
||||||
SavegameData.h
|
|
||||||
SavegameDialog.h
|
|
||||||
SavegameWidget.h
|
|
||||||
SidebarGenerator.h
|
|
||||||
SnapmaticEditor.h
|
|
||||||
SnapmaticPicture.h
|
|
||||||
SnapmaticWidget.h
|
|
||||||
StandardPaths.h
|
|
||||||
StringParser.h
|
|
||||||
TranslationClass.h
|
|
||||||
UserInterface.h
|
|
||||||
anpro/imagecropper.h
|
|
||||||
pcg/pcg_basic.h
|
|
||||||
uimod/JSHighlighter.h
|
|
||||||
uimod/UiModLabel.h
|
|
||||||
uimod/UiModWidget.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(GTA5VIEW_INCLUDEDIR
|
|
||||||
anpro
|
|
||||||
pcg
|
|
||||||
uimod
|
|
||||||
)
|
|
||||||
|
|
||||||
set(GTA5VIEW_FORMS
|
|
||||||
AboutDialog.ui
|
|
||||||
ExportDialog.ui
|
|
||||||
ImportDialog.ui
|
|
||||||
JsonEditorDialog.ui
|
|
||||||
MapLocationDialog.ui
|
|
||||||
OptionsDialog.ui
|
|
||||||
PictureDialog.ui
|
|
||||||
PlayerListDialog.ui
|
|
||||||
ProfileInterface.ui
|
|
||||||
SavegameDialog.ui
|
|
||||||
SavegameWidget.ui
|
|
||||||
SnapmaticEditor.ui
|
|
||||||
SnapmaticWidget.ui
|
|
||||||
UserInterface.ui
|
|
||||||
)
|
|
||||||
|
|
||||||
set(GTA5VIEW_TRANSLATIONS
|
|
||||||
res/gta5sync_de.ts
|
|
||||||
res/gta5sync_en_US.ts
|
|
||||||
res/gta5sync_fr.ts
|
|
||||||
res/gta5sync_ko.ts
|
|
||||||
res/gta5sync_ru.ts
|
|
||||||
res/gta5sync_uk.ts
|
|
||||||
res/gta5sync_zh_TW.ts
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND GTA5VIEW_RESOURCES
|
|
||||||
res/global.qrc
|
|
||||||
res/template.qrc
|
|
||||||
)
|
|
||||||
set_property(SOURCE res/global.qrc PROPERTY AUTORCC_OPTIONS "-threshold;0;-compress;9")
|
|
||||||
|
|
||||||
if(Qt5LinguistTools_FOUND)
|
|
||||||
qt5_add_translation(GTA5VIEW_QMFILES
|
|
||||||
${GTA5VIEW_TRANSLATIONS}
|
|
||||||
res/qt5/qtbase_en_GB.ts
|
|
||||||
)
|
|
||||||
set(LINGUIST_FOUND TRUE)
|
|
||||||
elseif(Qt6LinguistTools_FOUND)
|
|
||||||
qt6_add_translation(GTA5VIEW_QMFILES
|
|
||||||
${GTA5VIEW_TRANSLATIONS}
|
|
||||||
res/qt6/qtbase_en_GB.ts
|
|
||||||
)
|
|
||||||
set(LINGUIST_FOUND TRUE)
|
|
||||||
else()
|
|
||||||
set(GTA5VIEW_QMFILES
|
|
||||||
res/gta5sync_de.qm
|
|
||||||
res/gta5sync_en_US.qm
|
|
||||||
res/gta5sync_fr.qm
|
|
||||||
res/gta5sync_ko.qm
|
|
||||||
res/gta5sync_ru.qm
|
|
||||||
res/gta5sync_uk.qm
|
|
||||||
res/gta5sync_zh_TW.qm
|
|
||||||
res/qt${QT_VERSION_MAJOR}/qtbase_en_GB.qm
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(QCONF_BUILD "System installation intended Qconf build" OFF)
|
|
||||||
if(QCONF_BUILD)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
-DGTA5SYNC_QCONF
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
list(APPEND GTA5VIEW_RESOURCES
|
|
||||||
res/img.qrc
|
|
||||||
res/tr_g5p.qrc
|
|
||||||
res/qt${QT_VERSION_MAJOR}/tr_qt.qrc
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(FLATPAK_BUILD "Flatpak modifications and optimisations" OFF)
|
|
||||||
if(FLATPAK_BUILD)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
-DGTA5SYNC_FLATPAK
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(WITH_DONATE "Donate menu option and donation dialog" OFF)
|
|
||||||
if(WITH_DONATE)
|
|
||||||
set(DONATE_ADDRESSES "" CACHE STRING "Donation addresses")
|
|
||||||
list(APPEND GTA5VIEW_HEADERS
|
|
||||||
anpro/QrCode.h
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_SOURCES
|
|
||||||
anpro/QrCode.cpp
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
-DGTA5SYNC_DONATE
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_RESOURCES
|
|
||||||
res/donate.qrc
|
|
||||||
)
|
|
||||||
if(DONATE_ADDRESSES)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_DONATE_ADDRESSES=\"${DONATE_ADDRESSES}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(WITH_MOTD "Developer message system directed to users" OFF)
|
|
||||||
if(WITH_MOTD)
|
|
||||||
set(MOTD_WEBURL "" CACHE STRING "Messages WebURL")
|
|
||||||
list(APPEND GTA5VIEW_HEADERS
|
|
||||||
MessageThread.h
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_SOURCES
|
|
||||||
MessageThread.cpp
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
-DGTA5SYNC_MOTD
|
|
||||||
)
|
|
||||||
if(MOTD_WEBURL)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_MOTD_WEBURL=\"${MOTD_WEBURL}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(WITH_TELEMETRY "Hardware survey and basic telemetry system" OFF)
|
|
||||||
if(WITH_TELEMETRY)
|
|
||||||
set(TELEMETRY_AUTHID "" CACHE STRING "Telemetry AuthID")
|
|
||||||
set(TELEMETRY_AUTHPW "" CACHE STRING "Telemetry AuthPW")
|
|
||||||
set(TELEMETRY_PUSHURL "" CACHE STRING "Telemetry PushURL")
|
|
||||||
set(TELEMETRY_REGURL "" CACHE STRING "Telemetry RegURL")
|
|
||||||
set(TELEMETRY_WEBURL "" CACHE STRING "Telemetry WebURL")
|
|
||||||
list(APPEND GTA5VIEW_HEADERS
|
|
||||||
TelemetryClass.h
|
|
||||||
tmext/TelemetryClassAuthenticator.h
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_SOURCES
|
|
||||||
TelemetryClass.cpp
|
|
||||||
tmext/TelemetryClassAuthenticator.cpp
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_INCLUDEDIR
|
|
||||||
tmext
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
-DGTA5SYNC_TELEMETRY
|
|
||||||
)
|
|
||||||
if(TELEMETRY_AUTHID AND TELEMETRY_AUTHPW AND TELEMETRY_PUSHURL AND TELEMETRY_REGURL)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_TELEMETRY_AUTHID=\"${TELEMETRY_AUTHID}\""
|
|
||||||
"-DGTA5SYNC_TELEMETRY_AUTHPW=\"${TELEMETRY_AUTHPW}\""
|
|
||||||
"-DGTA5SYNC_TELEMETRY_PUSHURL=\"${TELEMETRY_PUSHURL}\""
|
|
||||||
"-DGTA5SYNC_TELEMETRY_REGURL=\"${TELEMETRY_REGURL}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(TELEMETRY_WEBURL)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_TELEMETRY_WEBURL=\"${TELEMETRY_WEBURL}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(WIN32)
|
|
||||||
list(APPEND GTA5VIEW_LIBS
|
|
||||||
d3d9
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(GTA5VIEW_APPVER)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_APPVER=\"${GTA5VIEW_APPVER}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(GTA5VIEW_BUILDCODE)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_BUILDCODE=\"${GTA5VIEW_BUILDCODE}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(GTA5VIEW_BUILDTYPE)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_BUILDTYPE=\"${GTA5VIEW_BUILDTYPE}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(GTA5VIEW_COMMIT)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_COMMIT=\"${GTA5VIEW_COMMIT}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(GTA5VIEW_INLANG)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_INLANG=\"${GTA5VIEW_INLANG}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(GTA5VIEW_LANG)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_LANG=\"${GTA5VIEW_LANG}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(GTA5VIEW_PLUG)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_PLUG=\"${GTA5VIEW_PLUG}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(gta5view
|
|
||||||
WIN32 MACOSX_BUNDLE
|
|
||||||
${GTA5VIEW_HEADERS}
|
|
||||||
${GTA5VIEW_SOURCES}
|
|
||||||
${GTA5VIEW_FORMS}
|
|
||||||
${GTA5VIEW_RESOURCES}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(LINGUIST_FOUND AND QCONF_BUILD)
|
|
||||||
add_custom_target(translations DEPENDS ${GTA5VIEW_QMFILES})
|
|
||||||
add_dependencies(gta5view translations)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.16.0")
|
|
||||||
target_precompile_headers(gta5view PRIVATE config.h)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.14.0")
|
|
||||||
qt5_import_plugins(gta5view INCLUDE Qt5::QSvgPlugin)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_compile_definitions(gta5view PRIVATE ${GTA5VIEW_DEFINES})
|
|
||||||
target_include_directories(gta5view PRIVATE ${GTA5VIEW_INCLUDEDIR})
|
|
||||||
target_link_libraries(gta5view PRIVATE Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::Widgets ${GTA5VIEW_LIBS})
|
|
||||||
|
|
||||||
install(TARGETS gta5view DESTINATION bin)
|
|
||||||
install(FILES res/de.syping.gta5view.desktop DESTINATION share/applications)
|
|
||||||
install(FILES res/de.syping.gta5view.metainfo.xml DESTINATION share/metainfo)
|
|
||||||
install(FILES res/de.syping.gta5view.xml DESTINATION share/mime/packages)
|
|
||||||
install(FILES res/gta5view-16.png DESTINATION share/icons/hicolor/16x16/apps RENAME de.syping.gta5view.png)
|
|
||||||
install(FILES res/gta5view-24.png DESTINATION share/icons/hicolor/24x24/apps RENAME de.syping.gta5view.png)
|
|
||||||
install(FILES res/gta5view-32.png DESTINATION share/icons/hicolor/32x32/apps RENAME de.syping.gta5view.png)
|
|
||||||
install(FILES res/gta5view-48.png DESTINATION share/icons/hicolor/48x48/apps RENAME de.syping.gta5view.png)
|
|
||||||
install(FILES res/gta5view-64.png DESTINATION share/icons/hicolor/64x64/apps RENAME de.syping.gta5view.png)
|
|
||||||
install(FILES res/gta5view-96.png DESTINATION share/icons/hicolor/96x96/apps RENAME de.syping.gta5view.png)
|
|
||||||
install(FILES res/gta5view-128.png DESTINATION share/icons/hicolor/128x128/apps RENAME de.syping.gta5view.png)
|
|
||||||
install(FILES res/gta5view-256.png DESTINATION share/icons/hicolor/256x256/apps RENAME de.syping.gta5view.png)
|
|
||||||
install(FILES res/gta5view-512.png DESTINATION share/icons/hicolor/512x512/apps RENAME de.syping.gta5view.png)
|
|
||||||
if(QCONF_BUILD)
|
|
||||||
include(res/img.cmake)
|
|
||||||
install(FILES ${GTA5VIEW_IMGFILES} DESTINATION share/gta5view/resources)
|
|
||||||
install(FILES ${GTA5VIEW_QMFILES} DESTINATION share/gta5view/translations)
|
|
||||||
endif()
|
|
||||||
111
CrewDatabase.cpp
Normal file → Executable file
111
CrewDatabase.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -19,9 +19,6 @@
|
||||||
#include "StandardPaths.h"
|
#include "StandardPaths.h"
|
||||||
#include "CrewDatabase.h"
|
#include "CrewDatabase.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QMutexLocker>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
|
|
@ -31,7 +28,7 @@ CrewDatabase::CrewDatabase(QObject *parent) : QObject(parent)
|
||||||
dir.mkpath(StandardPaths::dataLocation());
|
dir.mkpath(StandardPaths::dataLocation());
|
||||||
dir.setPath(StandardPaths::dataLocation());
|
dir.setPath(StandardPaths::dataLocation());
|
||||||
QString dirPath = dir.absolutePath();
|
QString dirPath = dir.absolutePath();
|
||||||
QString defaultConfPath = dirPath % "/crews.ini";
|
QString defaultConfPath = dirPath + QDir::separator() + "crews.ini";
|
||||||
|
|
||||||
QSettings confPathSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings confPathSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
confPathSettings.beginGroup("Database");
|
confPathSettings.beginGroup("Database");
|
||||||
|
|
@ -40,8 +37,6 @@ CrewDatabase::CrewDatabase(QObject *parent) : QObject(parent)
|
||||||
|
|
||||||
crewDB = new QSettings(confPathFile, QSettings::IniFormat);
|
crewDB = new QSettings(confPathFile, QSettings::IniFormat);
|
||||||
crewDB->beginGroup("Crews");
|
crewDB->beginGroup("Crews");
|
||||||
|
|
||||||
addProcess = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CrewDatabase::~CrewDatabase()
|
CrewDatabase::~CrewDatabase()
|
||||||
|
|
@ -52,85 +47,31 @@ CrewDatabase::~CrewDatabase()
|
||||||
|
|
||||||
QStringList CrewDatabase::getCrews()
|
QStringList CrewDatabase::getCrews()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QStringList compatibleCrewList = crewDB->childKeys();
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "getCrews";
|
|
||||||
#endif
|
|
||||||
return getCrews_p();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList CrewDatabase::getCrews_p()
|
|
||||||
{
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "getCrews_p";
|
|
||||||
#endif
|
|
||||||
QStringList compatibleCrewList = getCompatibleCrews_p();
|
|
||||||
crewDB->endGroup();
|
crewDB->endGroup();
|
||||||
crewDB->beginGroup("CrewList");
|
crewDB->beginGroup("CrewList");
|
||||||
QStringList crewIDs = crewDB->value("IDs", QStringList()).toStringList();
|
QStringList crewIDs = crewDB->value("IDs", QStringList()).toStringList();
|
||||||
crewIDs += compatibleCrewList;
|
crewIDs.append(compatibleCrewList);
|
||||||
crewIDs.removeDuplicates();
|
crewIDs.removeDuplicates();
|
||||||
crewDB->endGroup();
|
crewDB->endGroup();
|
||||||
crewDB->beginGroup("Crews");
|
crewDB->beginGroup("Crews");
|
||||||
return crewIDs;
|
return crewIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList CrewDatabase::getCompatibleCrews()
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "getCompatibleCrews";
|
|
||||||
#endif
|
|
||||||
return getCompatibleCrews_p();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList CrewDatabase::getCompatibleCrews_p()
|
|
||||||
{
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "getCompatibleCrews_p";
|
|
||||||
#endif
|
|
||||||
return crewDB->childKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CrewDatabase::getCrewName(QString crewID)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "getCrewName" << crewID;
|
|
||||||
#endif
|
|
||||||
QString crewStr = crewDB->value(crewID, crewID).toString();
|
|
||||||
if (crewID == "0") crewStr = tr("No Crew", "");
|
|
||||||
return crewStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CrewDatabase::getCrewName(int crewID)
|
QString CrewDatabase::getCrewName(int crewID)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
return crewDB->value(QString::number(crewID), crewID).toString();
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "getCrewName" << crewID;
|
|
||||||
#endif
|
|
||||||
QString crewStr = crewDB->value(QString::number(crewID), crewID).toString();
|
|
||||||
if (crewID == 0) crewStr = tr("No Crew", "");
|
|
||||||
return crewStr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrewDatabase::setCrewName(int crewID, QString crewName)
|
void CrewDatabase::setCrewName(int crewID, QString crewName)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "setCrewName" << crewID << crewName;
|
|
||||||
#endif
|
|
||||||
crewDB->setValue(QString::number(crewID), crewName);
|
crewDB->setValue(QString::number(crewID), crewName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrewDatabase::addCrew(int crewID)
|
void CrewDatabase::addCrew(int crewID)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QStringList crews = getCrews();
|
||||||
#ifdef GTA5SYNC_DEBUG
|
crews.append(QString::number(crewID));
|
||||||
qDebug() << "addCrew" << crewID;
|
|
||||||
#endif
|
|
||||||
QStringList crews = getCrews_p();
|
|
||||||
crews += QString::number(crewID);
|
|
||||||
crews.removeDuplicates();
|
crews.removeDuplicates();
|
||||||
crewDB->endGroup();
|
crewDB->endGroup();
|
||||||
crewDB->beginGroup("CrewList");
|
crewDB->beginGroup("CrewList");
|
||||||
|
|
@ -138,39 +79,3 @@ void CrewDatabase::addCrew(int crewID)
|
||||||
crewDB->endGroup();
|
crewDB->endGroup();
|
||||||
crewDB->beginGroup("Crews");
|
crewDB->beginGroup("Crews");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CrewDatabase::isCompatibleCrew(QString crewNID)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "isCompatibleCrew" << crewNID;
|
|
||||||
#endif
|
|
||||||
return crewDB->contains(crewNID);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CrewDatabase::isCompatibleCrew(int crewID)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "isCompatibleCrew" << crewID;
|
|
||||||
#endif
|
|
||||||
return crewDB->contains(QString::number(crewID));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrewDatabase::setAddingCrews(bool addingCrews)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "setAddingCrews" << addingCrews;
|
|
||||||
#endif
|
|
||||||
addProcess = addingCrews;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CrewDatabase::isAddingCrews()
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "isAddingCrews";
|
|
||||||
#endif
|
|
||||||
return addProcess;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
17
CrewDatabase.h
Normal file → Executable file
17
CrewDatabase.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QMutex>
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
||||||
class CrewDatabase : public QObject
|
class CrewDatabase : public QObject
|
||||||
|
|
@ -29,25 +28,15 @@ class CrewDatabase : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CrewDatabase(QObject *parent = 0);
|
explicit CrewDatabase(QObject *parent = 0);
|
||||||
QString getCrewName(QString crewID);
|
void setCrewName(int crewID, QString crewName);
|
||||||
QString getCrewName(int crewID);
|
QString getCrewName(int crewID);
|
||||||
QStringList getCompatibleCrews();
|
|
||||||
QStringList getCrews();
|
QStringList getCrews();
|
||||||
void setAddingCrews(bool addingCrews);
|
|
||||||
bool isCompatibleCrew(QString crewNID);
|
|
||||||
bool isCompatibleCrew(int crewID);
|
|
||||||
bool isAddingCrews();
|
|
||||||
~CrewDatabase();
|
~CrewDatabase();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QMutex mutex;
|
|
||||||
bool addProcess;
|
|
||||||
QSettings *crewDB;
|
QSettings *crewDB;
|
||||||
QStringList getCrews_p();
|
|
||||||
QStringList getCompatibleCrews_p();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCrewName(int crewID, QString crewName);
|
|
||||||
void addCrew(int crewID);
|
void addCrew(int crewID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
204
DatabaseThread.cpp
Normal file → Executable file
204
DatabaseThread.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -31,124 +31,154 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#define crewMaxPages 83
|
|
||||||
#define maxLoadFails 3
|
|
||||||
|
|
||||||
DatabaseThread::DatabaseThread(CrewDatabase *crewDB, QObject *parent) : QThread(parent), crewDB(crewDB)
|
DatabaseThread::DatabaseThread(CrewDatabase *crewDB, QObject *parent) : QThread(parent), crewDB(crewDB)
|
||||||
{
|
{
|
||||||
continueLastCrew = true;
|
crewMaxPages = 83;
|
||||||
threadRunning = true;
|
threadRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseThread::run()
|
void DatabaseThread::run()
|
||||||
{
|
{
|
||||||
QEventLoop threadLoop;
|
QEventLoop threadLoop;
|
||||||
|
QStringList crewList;
|
||||||
|
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit()));
|
// Quick time scan
|
||||||
|
if (crewList.length() <= 3)
|
||||||
|
{
|
||||||
|
scanCrewReference(crewList, 2500);
|
||||||
|
scanCrewMembersList(crewList, 3, 2500);
|
||||||
|
emit playerNameUpdated();
|
||||||
|
}
|
||||||
|
else if (crewList.length() <= 5)
|
||||||
|
{
|
||||||
|
scanCrewReference(crewList, 2500);
|
||||||
|
scanCrewMembersList(crewList, 2, 2500);
|
||||||
|
emit playerNameUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
QEventLoop *waitingLoop = new QEventLoop();
|
||||||
|
QTimer::singleShot(10000, waitingLoop, SLOT(quit()));
|
||||||
|
waitingLoop->exec();
|
||||||
|
delete waitingLoop;
|
||||||
|
|
||||||
|
while (threadRunning)
|
||||||
|
{
|
||||||
|
crewList = crewDB->getCrews();
|
||||||
|
|
||||||
|
// Long time scan
|
||||||
|
scanCrewReference(crewList, 10000);
|
||||||
|
scanCrewMembersList(crewList, crewMaxPages, 10000);
|
||||||
|
emit playerNameUpdated();
|
||||||
|
|
||||||
while (threadRunning) {
|
|
||||||
QTimer::singleShot(300000, &threadLoop, SLOT(quit()));
|
QTimer::singleShot(300000, &threadLoop, SLOT(quit()));
|
||||||
threadLoop.exec();
|
threadLoop.exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseThread::scanCrewReference(const QStringList &crewList, const int &requestDelay)
|
void DatabaseThread::scanCrewReference(QStringList crewList, int requestDelay)
|
||||||
|
{
|
||||||
|
foreach (const QString &crewID, crewList)
|
||||||
|
{
|
||||||
|
if (crewID != "0")
|
||||||
{
|
{
|
||||||
for (const QString &crewID : crewList) {
|
|
||||||
if (threadRunning && crewID != QLatin1String("0")) {
|
|
||||||
QNetworkAccessManager *netManager = new QNetworkAccessManager();
|
QNetworkAccessManager *netManager = new QNetworkAccessManager();
|
||||||
|
|
||||||
QNetworkRequest netRequest(AppEnv::getCrewFetchingUrl(crewID));
|
QNetworkRequest netRequest(AppEnv::getCrewFetchingUrl(crewID));
|
||||||
#if QT_VERSION >= 0x050600
|
|
||||||
#if QT_VERSION < 0x060000
|
|
||||||
netRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent());
|
netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent());
|
||||||
netRequest.setRawHeader("Accept", "text/html");
|
netRequest.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||||
netRequest.setRawHeader("Accept-Charset", "utf-8");
|
netRequest.setRawHeader("Accept-Language", "en-US;q=0.5,en;q=0.3");
|
||||||
netRequest.setRawHeader("Accept-Language", "en-US,en;q=0.9");
|
|
||||||
netRequest.setRawHeader("Connection", "keep-alive");
|
netRequest.setRawHeader("Connection", "keep-alive");
|
||||||
|
|
||||||
QNetworkReply *netReply = netManager->get(netRequest);
|
QNetworkReply *netReply = netManager->get(netRequest);
|
||||||
|
|
||||||
QEventLoop *downloadLoop = new QEventLoop();
|
QEventLoop *downloadLoop = new QEventLoop();
|
||||||
QObject::connect(netReply, SIGNAL(finished()), downloadLoop, SLOT(quit()));
|
QObject::connect(netReply, SIGNAL(finished()), downloadLoop, SLOT(quit()));
|
||||||
if (!continueLastCrew)
|
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), downloadLoop, SLOT(quit()));
|
|
||||||
QTimer::singleShot(30000, downloadLoop, SLOT(quit()));
|
QTimer::singleShot(30000, downloadLoop, SLOT(quit()));
|
||||||
downloadLoop->exec();
|
downloadLoop->exec();
|
||||||
downloadLoop->disconnect();
|
|
||||||
delete downloadLoop;
|
delete downloadLoop;
|
||||||
|
|
||||||
if (netReply->isFinished()) {
|
if (netReply->isFinished())
|
||||||
|
{
|
||||||
|
QByteArray crewJson = netReply->readAll();
|
||||||
|
QJsonDocument crewDocument = QJsonDocument::fromJson(crewJson);
|
||||||
|
QJsonObject crewObject = crewDocument.object();
|
||||||
|
QVariantMap crewMap = crewObject.toVariantMap();
|
||||||
QString crewName;
|
QString crewName;
|
||||||
QByteArray crewHtml = netReply->readAll();
|
bool isFound = false;
|
||||||
QStringList crewHtmlSplit1 = QString::fromUtf8(crewHtml).split("<title>Rockstar Games Social Club - Crew : ");
|
|
||||||
if (crewHtmlSplit1.length() >= 2) {
|
if (crewMap.contains("activities"))
|
||||||
QStringList crewHtmlSplit2 = QString(crewHtmlSplit1.at(1)).split("</title>");
|
{
|
||||||
if (crewHtmlSplit2.length() >= 1) {
|
QList<QVariant> activitiesList = crewMap["activities"].toList();
|
||||||
crewName = crewHtmlSplit2.at(0);
|
foreach (const QVariant &activitiesVariant, activitiesList)
|
||||||
|
{
|
||||||
|
QMap<QString, QVariant> activityRootMap = activitiesVariant.toMap();
|
||||||
|
foreach(const QVariant &activityRootVariant, activityRootMap)
|
||||||
|
{
|
||||||
|
QMap<QString, QVariant> activityMap = activityRootVariant.toMap();
|
||||||
|
foreach(const QVariant &activityVariant, activityMap)
|
||||||
|
{
|
||||||
|
QMap<QString, QVariant> activityFinalMap = activityVariant.toMap();
|
||||||
|
if (activityFinalMap.contains("id") && activityFinalMap["id"] == crewID)
|
||||||
|
{
|
||||||
|
if (activityFinalMap.contains("name") && isFound == false)
|
||||||
|
{
|
||||||
|
isFound = true;
|
||||||
|
crewName = activityFinalMap["name"].toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!crewName.isEmpty()) {
|
|
||||||
emit crewNameFound(crewID.toInt(), crewName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
netReply->abort();
|
}
|
||||||
|
if (!crewName.isNull())
|
||||||
|
{
|
||||||
|
crewDB->setCrewName(crewID.toInt(), crewName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threadRunning) {
|
|
||||||
QEventLoop *waitingLoop = new QEventLoop();
|
QEventLoop *waitingLoop = new QEventLoop();
|
||||||
QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit()));
|
QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit()));
|
||||||
if (!continueLastCrew)
|
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), waitingLoop, SLOT(quit()));
|
|
||||||
waitingLoop->exec();
|
waitingLoop->exec();
|
||||||
waitingLoop->disconnect();
|
|
||||||
delete waitingLoop;
|
delete waitingLoop;
|
||||||
}
|
|
||||||
|
|
||||||
|
netReply->deleteLater();
|
||||||
delete netReply;
|
delete netReply;
|
||||||
|
netManager->deleteLater();
|
||||||
delete netManager;
|
delete netManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int &maxPages, const int &requestDelay)
|
void DatabaseThread::scanCrewMembersList(QStringList crewList, int maxPages, int requestDelay)
|
||||||
|
{
|
||||||
|
foreach (const QString &crewID, crewList)
|
||||||
|
{
|
||||||
|
if (crewID != "0")
|
||||||
{
|
{
|
||||||
for (const QString &crewID : crewList) {
|
|
||||||
if (threadRunning && crewID != QLatin1String("0")) {
|
|
||||||
int currentFail = 0;
|
|
||||||
int currentPage = 0;
|
int currentPage = 0;
|
||||||
int foundPlayers = 0;
|
int foundPlayers = 0;
|
||||||
int totalPlayers = 1000;
|
int totalPlayers = 1000;
|
||||||
|
|
||||||
while(foundPlayers < totalPlayers && currentPage < maxPages && (continueLastCrew ? true : threadRunning)) {
|
while(foundPlayers < totalPlayers && currentPage < maxPages)
|
||||||
|
{
|
||||||
QNetworkAccessManager *netManager = new QNetworkAccessManager();
|
QNetworkAccessManager *netManager = new QNetworkAccessManager();
|
||||||
QNetworkRequest netRequest(AppEnv::getPlayerFetchingUrl(crewID, currentPage));
|
|
||||||
#if QT_VERSION >= 0x050600
|
QNetworkRequest netRequest(AppEnv::getPlayerFetchingUrl(crewID, QString::number(currentPage)));
|
||||||
#if QT_VERSION < 0x060000
|
|
||||||
netRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent());
|
netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent());
|
||||||
netRequest.setRawHeader("Accept", "application/json");
|
netRequest.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||||
netRequest.setRawHeader("Accept-Charset", "utf-8");
|
netRequest.setRawHeader("Accept-Language", "en-US;q=0.5,en;q=0.3");
|
||||||
netRequest.setRawHeader("Accept-Language", "en-US,en;q=0.9");
|
|
||||||
netRequest.setRawHeader("Connection", "keep-alive");
|
netRequest.setRawHeader("Connection", "keep-alive");
|
||||||
|
|
||||||
QNetworkReply *netReply = netManager->get(netRequest);
|
QNetworkReply *netReply = netManager->get(netRequest);
|
||||||
|
|
||||||
QEventLoop *downloadLoop = new QEventLoop();
|
QEventLoop *downloadLoop = new QEventLoop();
|
||||||
QObject::connect(netReply, SIGNAL(finished()), downloadLoop, SLOT(quit()));
|
QObject::connect(netReply, SIGNAL(finished()), downloadLoop, SLOT(quit()));
|
||||||
if (!continueLastCrew)
|
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), downloadLoop, SLOT(quit()));
|
|
||||||
QTimer::singleShot(30000, downloadLoop, SLOT(quit()));
|
QTimer::singleShot(30000, downloadLoop, SLOT(quit()));
|
||||||
downloadLoop->exec();
|
downloadLoop->exec();
|
||||||
downloadLoop->disconnect();
|
|
||||||
delete downloadLoop;
|
delete downloadLoop;
|
||||||
|
|
||||||
if (netReply->isFinished()) {
|
if (netReply->isFinished())
|
||||||
|
{
|
||||||
QByteArray crewJson = netReply->readAll();
|
QByteArray crewJson = netReply->readAll();
|
||||||
QJsonDocument crewDocument = QJsonDocument::fromJson(crewJson);
|
QJsonDocument crewDocument = QJsonDocument::fromJson(crewJson);
|
||||||
QJsonObject crewObject = crewDocument.object();
|
QJsonObject crewObject = crewDocument.object();
|
||||||
|
|
@ -156,68 +186,38 @@ void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int
|
||||||
|
|
||||||
if (crewMap.contains("Total")) { totalPlayers = crewMap["Total"].toInt(); }
|
if (crewMap.contains("Total")) { totalPlayers = crewMap["Total"].toInt(); }
|
||||||
|
|
||||||
if (crewMap.contains("Members")) {
|
if (crewMap.contains("Members"))
|
||||||
const QList<QVariant> memberList = crewMap["Members"].toList();
|
{
|
||||||
for (const QVariant &memberVariant : memberList) {
|
QList<QVariant> memberList = crewMap["Members"].toList();
|
||||||
|
foreach (const QVariant &memberVariant, memberList)
|
||||||
|
{
|
||||||
QMap<QString, QVariant> memberMap = memberVariant.toMap();
|
QMap<QString, QVariant> memberMap = memberVariant.toMap();
|
||||||
if (memberMap.contains("RockstarId") && memberMap.contains("Name")) {
|
foundPlayers++;
|
||||||
|
if (memberMap.contains("RockstarId") && memberMap.contains("Name"))
|
||||||
|
{
|
||||||
int RockstarId = memberMap["RockstarId"].toInt();
|
int RockstarId = memberMap["RockstarId"].toInt();
|
||||||
QString memberName = memberMap["Name"].toString();
|
QString memberName = memberMap["Name"].toString();
|
||||||
if (!memberName.isEmpty() && RockstarId != 0) {
|
if (memberName != "" && RockstarId != 0)
|
||||||
foundPlayers++;
|
{
|
||||||
emit playerNameFound(RockstarId, memberName);
|
emit playerNameFound(RockstarId, memberName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentPage++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
currentFail++;
|
|
||||||
if (currentFail == maxLoadFails) {
|
|
||||||
currentFail = 0;
|
|
||||||
currentPage++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete netReply;
|
|
||||||
delete netManager;
|
|
||||||
|
|
||||||
if (foundPlayers < totalPlayers && currentPage < maxPages && (continueLastCrew ? true : threadRunning)) {
|
|
||||||
QEventLoop *waitingLoop = new QEventLoop();
|
QEventLoop *waitingLoop = new QEventLoop();
|
||||||
QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit()));
|
QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit()));
|
||||||
if (!continueLastCrew) { QObject::connect(this, SIGNAL(threadTerminated()), waitingLoop, SLOT(quit())); }
|
|
||||||
waitingLoop->exec();
|
waitingLoop->exec();
|
||||||
waitingLoop->disconnect();
|
|
||||||
delete waitingLoop;
|
delete waitingLoop;
|
||||||
}
|
|
||||||
}
|
currentPage++;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseThread::deleteCompatibleCrews(QStringList *crewList)
|
netReply->deleteLater();
|
||||||
{
|
delete netReply;
|
||||||
for (const QString &crewNID : *crewList) {
|
netManager->deleteLater();
|
||||||
if (crewDB->isCompatibleCrew(crewNID)) {
|
delete netManager;
|
||||||
crewList->removeAll(crewNID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList DatabaseThread::deleteCompatibleCrews(const QStringList &crewList)
|
|
||||||
{
|
|
||||||
QStringList crewListR = crewList;
|
|
||||||
for (const QString &crewNID : crewListR) {
|
|
||||||
if (crewDB->isCompatibleCrew(crewNID)) {
|
|
||||||
crewListR.removeAll(crewNID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return crewListR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseThread::terminateThread()
|
|
||||||
{
|
|
||||||
threadRunning = false;
|
|
||||||
emit threadTerminated();
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
DatabaseThread.h
Normal file → Executable file
19
DatabaseThread.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -29,28 +29,21 @@ class DatabaseThread : public QThread
|
||||||
public:
|
public:
|
||||||
explicit DatabaseThread(CrewDatabase *crewDB, QObject *parent = 0);
|
explicit DatabaseThread(CrewDatabase *crewDB, QObject *parent = 0);
|
||||||
|
|
||||||
public slots:
|
|
||||||
void terminateThread();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CrewDatabase *crewDB;
|
CrewDatabase *crewDB;
|
||||||
void scanCrewMembersList(const QStringList &crewList, const int &maxPages, const int &requestDelay);
|
void scanCrewMembersList(QStringList crewList, int maxPages, int requestDelay);
|
||||||
void scanCrewReference(const QStringList &crewList, const int &requestDelay);
|
void scanCrewReference(QStringList crewList, int requestDelay);
|
||||||
void deleteCompatibleCrews(QStringList *crewList);
|
|
||||||
QStringList deleteCompatibleCrews(const QStringList &crewList);
|
|
||||||
bool continueLastCrew;
|
|
||||||
bool threadRunning;
|
bool threadRunning;
|
||||||
|
int crewMaxPages;
|
||||||
int plyrPerReq;
|
int plyrPerReq;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void crewNameFound(int crewID, QString crewName);
|
|
||||||
void crewNameUpdated();
|
|
||||||
void playerNameFound(int playerID, QString playerName);
|
void playerNameFound(int playerID, QString playerName);
|
||||||
void playerNameUpdated();
|
void playerNameUpdated();
|
||||||
void threadTerminated();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DATABASETHREAD_H
|
#endif // DATABASETHREAD_H
|
||||||
|
|
|
||||||
4
ExportDialog.cpp
Normal file → Executable file
4
ExportDialog.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
||||||
4
ExportDialog.h
Normal file → Executable file
4
ExportDialog.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
||||||
6
ExportDialog.ui
Normal file → Executable file
6
ExportDialog.ui
Normal file → Executable file
|
|
@ -13,9 +13,6 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Dialog</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="modal">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlExport">
|
<layout class="QVBoxLayout" name="vlExport">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
|
|
@ -210,6 +207,9 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Close</string>
|
<string>&Close</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="dialog-close"/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
||||||
64
ExportThread.cpp
Normal file → Executable file
64
ExportThread.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2020 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -17,24 +17,16 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "SnapmaticPicture.h"
|
#include "SnapmaticPicture.h"
|
||||||
#include "ProfileInterface.h"
|
|
||||||
#include "PictureExport.h"
|
#include "PictureExport.h"
|
||||||
#include "ProfileWidget.h"
|
#include "ProfileWidget.h"
|
||||||
#include "ExportThread.h"
|
#include "ExportThread.h"
|
||||||
#include "SavegameData.h"
|
#include "SavegameData.h"
|
||||||
#include "AppEnv.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
#include <QDesktopWidget>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
#include <QScreen>
|
|
||||||
#else
|
|
||||||
#include <QDesktopWidget>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ExportThread::ExportThread(QMap<ProfileWidget*,QString> profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent) : QThread(parent),
|
ExportThread::ExportThread(QMap<ProfileWidget*,QString> profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent) : QThread(parent),
|
||||||
profileMap(profileMap), exportDirectory(exportDirectory), pictureCopyEnabled(pictureCopyEnabled), pictureExportEnabled(pictureExportEnabled), exportCount(exportCount)
|
profileMap(profileMap), exportDirectory(exportDirectory), pictureCopyEnabled(pictureCopyEnabled), pictureExportEnabled(pictureExportEnabled), exportCount(exportCount)
|
||||||
{
|
{
|
||||||
|
|
@ -49,7 +41,7 @@ void ExportThread::run()
|
||||||
// Quality Settings
|
// Quality Settings
|
||||||
settings.beginGroup("Pictures");
|
settings.beginGroup("Pictures");
|
||||||
int defaultQuality = 100;
|
int defaultQuality = 100;
|
||||||
QSize defExportSize = SnapmaticPicture::getSnapmaticResolution();
|
QSize defExportSize = QSize(960, 536);
|
||||||
int customQuality = settings.value("CustomQuality", defaultQuality).toInt();
|
int customQuality = settings.value("CustomQuality", defaultQuality).toInt();
|
||||||
if (customQuality < 1 || customQuality > 100)
|
if (customQuality < 1 || customQuality > 100)
|
||||||
{
|
{
|
||||||
|
|
@ -81,42 +73,29 @@ void ExportThread::run()
|
||||||
// End Picture Settings
|
// End Picture Settings
|
||||||
|
|
||||||
int intExportProgress = 0;
|
int intExportProgress = 0;
|
||||||
for (ProfileWidget *widget : profileMap.keys())
|
foreach(ProfileWidget *widget, profileMap.keys())
|
||||||
{
|
{
|
||||||
if (widget->isSelected())
|
if (widget->isSelected())
|
||||||
{
|
{
|
||||||
if (widget->getWidgetType() == "SnapmaticWidget")
|
if (widget->getWidgetType() == "SnapmaticWidget")
|
||||||
{
|
{
|
||||||
SnapmaticWidget *picWidget = qobject_cast<SnapmaticWidget*>(widget);
|
SnapmaticWidget *picWidget = (SnapmaticWidget*)widget;
|
||||||
SnapmaticPicture *picture = picWidget->getPicture();
|
SnapmaticPicture *picture = picWidget->getPicture();
|
||||||
|
|
||||||
if (pictureExportEnabled)
|
if (pictureExportEnabled)
|
||||||
{
|
{
|
||||||
QString exportFileName = PictureExport::getPictureFileName(picture);
|
QString exportFileName = PictureExport::getPictureFileName(picture);
|
||||||
if (exportFileName.right(4) != ".jpg" && exportFileName.right(4) != ".png")
|
|
||||||
{
|
|
||||||
exportFileName += ".jpg";
|
|
||||||
}
|
|
||||||
|
|
||||||
intExportProgress++;
|
intExportProgress++;
|
||||||
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
|
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
|
||||||
emit exportProgressUpdate(intExportProgress);
|
emit exportProgressUpdate(intExportProgress);
|
||||||
|
|
||||||
// Scale Picture
|
// Scale Picture
|
||||||
QImage exportPicture = picture->getImage();
|
QImage exportPicture = picture->getPicture();
|
||||||
if (sizeMode == "Desktop")
|
if (sizeMode == "Desktop")
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
QRect desktopResolution = QApplication::primaryScreen()->geometry();
|
|
||||||
int desktopSizeWidth = qRound((double)desktopResolution.width() * screenRatioPR);
|
|
||||||
int desktopSizeHeight = qRound((double)desktopResolution.height() * screenRatioPR);
|
|
||||||
#else
|
|
||||||
QRect desktopResolution = QApplication::desktop()->screenGeometry();
|
QRect desktopResolution = QApplication::desktop()->screenGeometry();
|
||||||
int desktopSizeWidth = desktopResolution.width();
|
exportPicture = exportPicture.scaled(desktopResolution.width(), desktopResolution.height(), aspectRatio, Qt::SmoothTransformation);
|
||||||
int desktopSizeHeight = desktopResolution.height();
|
|
||||||
#endif
|
|
||||||
exportPicture = exportPicture.scaled(desktopSizeWidth, desktopSizeHeight, aspectRatio, Qt::SmoothTransformation);
|
|
||||||
}
|
}
|
||||||
else if (sizeMode == "Custom")
|
else if (sizeMode == "Custom")
|
||||||
{
|
{
|
||||||
|
|
@ -126,41 +105,44 @@ void ExportThread::run()
|
||||||
bool isSaved;
|
bool isSaved;
|
||||||
if (useCustomQuality)
|
if (useCustomQuality)
|
||||||
{
|
{
|
||||||
isSaved = exportPicture.save(exportDirectory % "/" % exportFileName, "JPEG", customQuality);
|
isSaved = exportPicture.save(exportDirectory + "/" + exportFileName, "JPEG", customQuality);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
isSaved = exportPicture.save(exportDirectory % "/" % exportFileName, "JPEG", 100);
|
isSaved = exportPicture.save(exportDirectory + "/" + exportFileName, "JPEG", 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSaved)
|
if (!isSaved)
|
||||||
{
|
{
|
||||||
failedExportPictures += exportFileName;
|
failedExportPictures.append(exportFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pictureCopyEnabled)
|
if (pictureCopyEnabled)
|
||||||
{
|
{
|
||||||
QString exportFileName = PictureExport::getPictureFileName(picture);
|
QString originalFileName = picWidget->getPicturePath();
|
||||||
if (exportFileName.right(4) != ".g5e")
|
QString adjustedFileName = originalFileName;
|
||||||
|
if (adjustedFileName.right(7) == ".hidden") // for the hidden file system
|
||||||
{
|
{
|
||||||
exportFileName += ".g5e";
|
adjustedFileName.remove(adjustedFileName.length() - 7, 7);
|
||||||
}
|
}
|
||||||
|
QFileInfo adjustedFileInfo(adjustedFileName);
|
||||||
|
QString exportFileName = adjustedFileInfo.fileName();
|
||||||
|
|
||||||
intExportProgress++;
|
intExportProgress++;
|
||||||
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
|
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
|
||||||
emit exportProgressUpdate(intExportProgress);
|
emit exportProgressUpdate(intExportProgress);
|
||||||
|
|
||||||
QString exportFilePath = exportDirectory % "/" % exportFileName;
|
QString exportFilePath = exportDirectory + "/" + exportFileName;
|
||||||
if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);}
|
if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);}
|
||||||
if (!picture->exportPicture(exportDirectory % "/" % exportFileName, SnapmaticFormat::G5E_Format))
|
if (!QFile::copy(originalFileName, exportFilePath))
|
||||||
{
|
{
|
||||||
failedCopyPictures += exportFileName;
|
failedCopyPictures.append(exportFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (widget->getWidgetType() == "SavegameWidget")
|
else if (widget->getWidgetType() == "SavegameWidget")
|
||||||
{
|
{
|
||||||
SavegameWidget *sgdWidget = qobject_cast<SavegameWidget*>(widget);
|
SavegameWidget *sgdWidget = (SavegameWidget*)widget;
|
||||||
SavegameData *savegame = sgdWidget->getSavegame();
|
SavegameData *savegame = sgdWidget->getSavegame();
|
||||||
|
|
||||||
QString originalFileName = savegame->getSavegameFileName();
|
QString originalFileName = savegame->getSavegameFileName();
|
||||||
|
|
@ -171,11 +153,11 @@ void ExportThread::run()
|
||||||
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
|
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
|
||||||
emit exportProgressUpdate(intExportProgress);
|
emit exportProgressUpdate(intExportProgress);
|
||||||
|
|
||||||
QString exportFilePath = exportDirectory % "/" % exportFileName;
|
QString exportFilePath = exportDirectory + "/" + exportFileName;
|
||||||
if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);}
|
if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);}
|
||||||
if (!QFile::copy(originalFileName, exportFilePath))
|
if (!QFile::copy(originalFileName, exportFilePath))
|
||||||
{
|
{
|
||||||
failedSavegames += exportFileName;
|
failedSavegames.append(exportFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
ExportThread.h
Normal file → Executable file
4
ExportThread.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
||||||
55
GlobalString.cpp
Normal file → Executable file
55
GlobalString.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -16,29 +16,27 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "TranslationClass.h"
|
#include <QLocale>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QStringList>
|
||||||
#include "GlobalString.h"
|
#include "GlobalString.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QLocale>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
GlobalString::GlobalString()
|
GlobalString::GlobalString()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, QString> GlobalString::getGlobalMap()
|
QMap<QString, QString> GlobalString::getGlobalMap()
|
||||||
{
|
{
|
||||||
QMap<QString, QString> globalMap;
|
QMap<QString, QString> globalMap;
|
||||||
QSettings globalFile(getLanguageFile(), QSettings::IniFormat);
|
QSettings globalFile(getLanguageFile(), QSettings::IniFormat);
|
||||||
#if QT_VERSION < 0x060000
|
|
||||||
globalFile.setIniCodec("UTF-8");
|
globalFile.setIniCodec("UTF-8");
|
||||||
#endif
|
|
||||||
globalFile.beginGroup("Global");
|
globalFile.beginGroup("Global");
|
||||||
for (const QString &globalStr : globalFile.childKeys()) {
|
QStringList globalStrList = globalFile.childKeys();
|
||||||
|
foreach(const QString &globalStr, globalStrList)
|
||||||
|
{
|
||||||
globalMap[globalStr] = globalFile.value(globalStr, globalStr).toString();
|
globalMap[globalStr] = globalFile.value(globalStr, globalStr).toString();
|
||||||
}
|
}
|
||||||
globalFile.endGroup();
|
globalFile.endGroup();
|
||||||
|
|
@ -49,14 +47,12 @@ QString GlobalString::getString(QString valueStr, bool *ok)
|
||||||
{
|
{
|
||||||
QString globalString = valueStr;
|
QString globalString = valueStr;
|
||||||
QSettings globalFile(getLanguageFile(), QSettings::IniFormat);
|
QSettings globalFile(getLanguageFile(), QSettings::IniFormat);
|
||||||
#if QT_VERSION < 0x060000
|
|
||||||
globalFile.setIniCodec("UTF-8");
|
globalFile.setIniCodec("UTF-8");
|
||||||
#endif
|
|
||||||
globalFile.beginGroup("Global");
|
globalFile.beginGroup("Global");
|
||||||
QStringList globalStrList = globalFile.childKeys();
|
QStringList globalStrList = globalFile.childKeys();
|
||||||
if (globalStrList.contains(valueStr)) {
|
if (globalStrList.contains(valueStr))
|
||||||
if (ok != nullptr)
|
{
|
||||||
*ok = true;
|
if (ok != 0) *ok = true;
|
||||||
globalString = globalFile.value(valueStr, valueStr).toString();
|
globalString = globalFile.value(valueStr, valueStr).toString();
|
||||||
}
|
}
|
||||||
globalFile.endGroup();
|
globalFile.endGroup();
|
||||||
|
|
@ -66,19 +62,28 @@ QString GlobalString::getString(QString valueStr, bool *ok)
|
||||||
QString GlobalString::getLanguageFile()
|
QString GlobalString::getLanguageFile()
|
||||||
{
|
{
|
||||||
QString language = getLanguage();
|
QString language = getLanguage();
|
||||||
QString languageFile = ":/global/global." % language % ".ini";
|
QString languageFile = ":/global/global." + language + ".ini";
|
||||||
#if QT_VERSION >= 0x050200
|
|
||||||
if (!QFileInfo::exists(languageFile))
|
|
||||||
languageFile = ":/global/global.en.ini";
|
|
||||||
#else
|
|
||||||
if (!QFileInfo(languageFile).exists())
|
if (!QFileInfo(languageFile).exists())
|
||||||
|
{
|
||||||
languageFile = ":/global/global.en.ini";
|
languageFile = ":/global/global.en.ini";
|
||||||
#endif
|
}
|
||||||
|
|
||||||
return languageFile;
|
return languageFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GlobalString::getLanguage()
|
QString GlobalString::getLanguage()
|
||||||
{
|
{
|
||||||
return Translator->getCurrentAreaLanguage();
|
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
|
settings.beginGroup("Interface");
|
||||||
|
QString language = settings.value("Language","System").toString();
|
||||||
|
settings.endGroup();
|
||||||
|
if (language == "System" || language.trimmed() == "")
|
||||||
|
{
|
||||||
|
QString languageName = QLocale::system().name();
|
||||||
|
QStringList langList = languageName.split("_");
|
||||||
|
if (langList.length() >= 1)
|
||||||
|
{
|
||||||
|
language = langList.at(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return language;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
GlobalString.h
Normal file → Executable file
6
GlobalString.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -26,7 +26,7 @@ class GlobalString
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GlobalString();
|
GlobalString();
|
||||||
static QString getString(QString valueStr, bool *ok = nullptr);
|
static QString getString(QString valueStr, bool *ok = 0);
|
||||||
static QString getLanguageFile();
|
static QString getLanguageFile();
|
||||||
static QString getLanguage();
|
static QString getLanguage();
|
||||||
static QMap<QString, QString> getGlobalMap();
|
static QMap<QString, QString> getGlobalMap();
|
||||||
|
|
|
||||||
45
IconLoader.cpp
Normal file → Executable file
45
IconLoader.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -17,45 +17,24 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "IconLoader.h"
|
#include "IconLoader.h"
|
||||||
#include "AppEnv.h"
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
IconLoader::IconLoader()
|
IconLoader::IconLoader()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon IconLoader::loadingAppIcon()
|
QIcon IconLoader::loadingAppIcon()
|
||||||
{
|
{
|
||||||
QIcon appIcon;
|
QIcon appIcon;
|
||||||
#if defined(GTA5SYNC_QCONF) && defined(GTA5SYNC_CMAKE)
|
appIcon.addFile(":/img/5sync-16.png", QSize(16, 16));
|
||||||
#ifdef Q_OS_WIN
|
appIcon.addFile(":/img/5sync-24.png", QSize(24, 24));
|
||||||
const QString pattern = AppEnv::getImagesFolder() % QLatin1String("/gta5view-%1.png");
|
appIcon.addFile(":/img/5sync-32.png", QSize(32, 32));
|
||||||
#else
|
appIcon.addFile(":/img/5sync-40.png", QSize(40, 40));
|
||||||
const QString pattern = AppEnv::getShareFolder() % QLatin1String("/icons/hicolor/%1x%1/apps/de.syping.gta5view.png");
|
appIcon.addFile(":/img/5sync-48.png", QSize(48, 48));
|
||||||
#endif
|
appIcon.addFile(":/img/5sync-64.png", QSize(64, 64));
|
||||||
#else
|
appIcon.addFile(":/img/5sync-96.png", QSize(96, 96));
|
||||||
const QString pattern = AppEnv::getImagesFolder() % QLatin1String("/gta5view-%1.png");
|
appIcon.addFile(":/img/5sync-128.png", QSize(128, 128));
|
||||||
#endif
|
appIcon.addFile(":/img/5sync-256.png", QSize(256, 256));
|
||||||
appIcon.addFile(pattern.arg("16"), QSize(16, 16));
|
|
||||||
appIcon.addFile(pattern.arg("24"), QSize(24, 24));
|
|
||||||
appIcon.addFile(pattern.arg("32"), QSize(32, 32));
|
|
||||||
appIcon.addFile(pattern.arg("40"), QSize(40, 40));
|
|
||||||
appIcon.addFile(pattern.arg("48"), QSize(48, 48));
|
|
||||||
appIcon.addFile(pattern.arg("64"), QSize(64, 64));
|
|
||||||
appIcon.addFile(pattern.arg("96"), QSize(96, 96));
|
|
||||||
appIcon.addFile(pattern.arg("128"), QSize(128, 128));
|
|
||||||
appIcon.addFile(pattern.arg("256"), QSize(256, 256));
|
|
||||||
return appIcon;
|
return appIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon IconLoader::loadingPointmakerIcon()
|
|
||||||
{
|
|
||||||
QIcon pointmakerIcon;
|
|
||||||
const QString pattern = AppEnv::getImagesFolder() % QLatin1String("/pointmaker-%1.png");
|
|
||||||
pointmakerIcon.addFile(pattern.arg("8"), QSize(8, 8));
|
|
||||||
pointmakerIcon.addFile(pattern.arg("16"), QSize(16, 16));
|
|
||||||
pointmakerIcon.addFile(pattern.arg("24"), QSize(24, 24));
|
|
||||||
pointmakerIcon.addFile(pattern.arg("32"), QSize(32, 32));
|
|
||||||
return pointmakerIcon;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
5
IconLoader.h
Normal file → Executable file
5
IconLoader.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -26,7 +26,6 @@ class IconLoader
|
||||||
public:
|
public:
|
||||||
IconLoader();
|
IconLoader();
|
||||||
static QIcon loadingAppIcon();
|
static QIcon loadingAppIcon();
|
||||||
static QIcon loadingPointmakerIcon();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ICONLOADER_H
|
#endif // ICONLOADER_H
|
||||||
|
|
|
||||||
974
ImportDialog.cpp
974
ImportDialog.cpp
|
|
@ -1,974 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2017-2022 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "ui_ImportDialog.h"
|
|
||||||
#include "SnapmaticPicture.h"
|
|
||||||
#include "SidebarGenerator.h"
|
|
||||||
#include "StandardPaths.h"
|
|
||||||
#include "ImportDialog.h"
|
|
||||||
#include "imagecropper.h"
|
|
||||||
#include "AppEnv.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QImageReader>
|
|
||||||
#include <QColorDialog>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QPixmap>
|
|
||||||
#include <QImage>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QStyle>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QRgb>
|
|
||||||
|
|
||||||
// IMAGES VALUES
|
|
||||||
#define snapmaticAvatarResolution 470
|
|
||||||
#define snapmaticAvatarPlacementW 145
|
|
||||||
#define snapmaticAvatarPlacementH 66
|
|
||||||
|
|
||||||
ImportDialog::ImportDialog(QString profileName, QWidget *parent) :
|
|
||||||
QDialog(parent), profileName(profileName),
|
|
||||||
ui(new Ui::ImportDialog)
|
|
||||||
{
|
|
||||||
// Set Window Flags
|
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
|
||||||
ui->cmdOK->setDefault(true);
|
|
||||||
ui->cmdOK->setFocus();
|
|
||||||
importAgreed = false;
|
|
||||||
settingsLocked = false;
|
|
||||||
watermarkAvatar = true;
|
|
||||||
watermarkPicture = false;
|
|
||||||
insideAvatarZone = false;
|
|
||||||
avatarAreaImage = QImage(AppEnv::getImagesFolder() % "/avatarareaimport.png");
|
|
||||||
selectedColour = QColor::fromRgb(0, 0, 0, 255);
|
|
||||||
|
|
||||||
// Set Icon for OK Button
|
|
||||||
if (QIcon::hasThemeIcon("dialog-ok")) {
|
|
||||||
ui->cmdOK->setIcon(QIcon::fromTheme("dialog-ok"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-ok")) {
|
|
||||||
ui->cmdOK->setIcon(QIcon::fromTheme("gtk-ok"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Icon for Cancel Button
|
|
||||||
if (QIcon::hasThemeIcon("dialog-cancel")) {
|
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-cancel")) {
|
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->cbIgnore->setChecked(false);
|
|
||||||
ui->labColour->setText(tr("Background Colour: <span style=\"color: %1\">%1</span>").arg(selectedColour.name()));
|
|
||||||
ui->labBackgroundImage->setText(tr("Background Image:"));
|
|
||||||
ui->cmdBackgroundWipe->setVisible(false);
|
|
||||||
|
|
||||||
// Snapmatic Resolution
|
|
||||||
snapmaticResolution = SnapmaticPicture::getSnapmaticResolution();
|
|
||||||
ui->cbResolution->addItem("GTA V", snapmaticResolution);
|
|
||||||
ui->cbResolution->addItem("FiveM", QSize(1920, 1072));
|
|
||||||
ui->cbResolution->addItem("1280x720", QSize(1280, 720));
|
|
||||||
ui->cbResolution->addItem("1920x1080", QSize(1920, 1080));
|
|
||||||
ui->cbResolution->addItem("2560x1440", QSize(2560, 1440));
|
|
||||||
|
|
||||||
// Set Import Settings
|
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
|
||||||
settings.beginGroup("Import");
|
|
||||||
QString currentProfile = settings.value("Profile", "Default").toString();
|
|
||||||
settings.endGroup();
|
|
||||||
processSettings(currentProfile);
|
|
||||||
|
|
||||||
// DPI calculation
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
snapmaticResolutionLW = 516 * screenRatio; // 430
|
|
||||||
snapmaticResolutionLH = 288 * screenRatio; // 240
|
|
||||||
ui->labPicture->setMinimumSize(snapmaticResolutionLW, snapmaticResolutionLH);
|
|
||||||
|
|
||||||
ui->vlButtom->setSpacing(6 * screenRatio);
|
|
||||||
#ifndef Q_OS_MAC
|
|
||||||
ui->vlButtom->setContentsMargins(9 * screenRatio, 6 * screenRatio, 9 * screenRatio, 9 * screenRatio);
|
|
||||||
#else
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
if (QApplication::style()->objectName() == "macos") {
|
|
||||||
#else
|
|
||||||
if (QApplication::style()->objectName() == "macintosh") {
|
|
||||||
#endif
|
|
||||||
ui->vlButtom->setContentsMargins(9 * screenRatio, 9 * screenRatio, 9 * screenRatio, 9 * screenRatio);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->vlButtom->setContentsMargins(9 * screenRatio, 6 * screenRatio, 9 * screenRatio, 9 * screenRatio);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Options menu
|
|
||||||
optionsMenu.addAction(tr("&Import new Picture..."), this, SLOT(importNewPicture()));
|
|
||||||
optionsMenu.addAction(tr("&Crop Picture..."), this, SLOT(cropPicture()));
|
|
||||||
optionsMenu.addSeparator();
|
|
||||||
optionsMenu.addAction(tr("&Load Settings..."), this, SLOT(loadImportSettings()));
|
|
||||||
optionsMenu.addAction(tr("&Save Settings..."), this, SLOT(saveImportSettings()));
|
|
||||||
ui->cmdOptions->setMenu(&optionsMenu);
|
|
||||||
|
|
||||||
const QSize windowSize = sizeHint();
|
|
||||||
setMinimumSize(windowSize);
|
|
||||||
setMaximumSize(windowSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImportDialog::~ImportDialog()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::processImage()
|
|
||||||
{
|
|
||||||
if (workImage.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QImage snapmaticImage = workImage;
|
|
||||||
QPixmap snapmaticPixmap(snapmaticResolution);
|
|
||||||
snapmaticPixmap.fill(selectedColour);
|
|
||||||
QPainter snapmaticPainter(&snapmaticPixmap);
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
if (!backImage.isNull()) {
|
|
||||||
if (!ui->cbStretch->isChecked()) {
|
|
||||||
int diffWidth = 0;
|
|
||||||
int diffHeight = 0;
|
|
||||||
if (backImage.width() != snapmaticResolution.width()) {
|
|
||||||
diffWidth = snapmaticResolution.width() - backImage.width();
|
|
||||||
diffWidth = diffWidth / 2;
|
|
||||||
}
|
|
||||||
else if (backImage.height() != snapmaticResolution.height()) {
|
|
||||||
diffHeight = snapmaticResolution.height() - backImage.height();
|
|
||||||
diffHeight = diffHeight / 2;
|
|
||||||
}
|
|
||||||
snapmaticPainter.drawImage(0 + diffWidth, 0 + diffHeight, backImage);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
snapmaticPainter.drawImage(0, 0, QImage(backImage).scaled(snapmaticResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
|
||||||
}
|
|
||||||
if (ui->cbAvatar->isChecked() && ui->cbForceAvatarColour->isChecked()) {
|
|
||||||
snapmaticPainter.fillRect(snapmaticAvatarPlacementW, snapmaticAvatarPlacementH, snapmaticAvatarResolution, snapmaticAvatarResolution, selectedColour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (insideAvatarZone) {
|
|
||||||
// Avatar mode
|
|
||||||
int diffWidth = 0;
|
|
||||||
int diffHeight = 0;
|
|
||||||
if (ui->cbIgnore->isChecked()) {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
}
|
|
||||||
else if (ui->cbBorderless->isChecked()) {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
|
||||||
if (snapmaticImage.width() > snapmaticAvatarResolution) {
|
|
||||||
int diffWidth = snapmaticImage.width() - snapmaticAvatarResolution;
|
|
||||||
diffWidth = diffWidth / 2;
|
|
||||||
QImage croppedImage(snapmaticAvatarResolution, snapmaticAvatarResolution, QImage::Format_ARGB32);
|
|
||||||
croppedImage.fill(Qt::transparent);
|
|
||||||
QPainter croppedPainter(&croppedImage);
|
|
||||||
croppedPainter.drawImage(0 - diffWidth, 0, snapmaticImage);
|
|
||||||
croppedPainter.end();
|
|
||||||
snapmaticImage = croppedImage;
|
|
||||||
}
|
|
||||||
else if (snapmaticImage.height() > snapmaticAvatarResolution) {
|
|
||||||
int diffHeight = snapmaticImage.height() - snapmaticAvatarResolution;
|
|
||||||
diffHeight = diffHeight / 2;
|
|
||||||
QImage croppedImage(snapmaticAvatarResolution, snapmaticAvatarResolution, QImage::Format_ARGB32);
|
|
||||||
croppedImage.fill(Qt::transparent);
|
|
||||||
QPainter croppedPainter(&croppedImage);
|
|
||||||
croppedPainter.drawImage(0, 0 - diffHeight, snapmaticImage);
|
|
||||||
croppedPainter.end();
|
|
||||||
snapmaticImage = croppedImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
||||||
if (snapmaticImage.width() > snapmaticImage.height()) {
|
|
||||||
diffHeight = snapmaticAvatarResolution - snapmaticImage.height();
|
|
||||||
diffHeight = diffHeight / 2;
|
|
||||||
}
|
|
||||||
else if (snapmaticImage.width() < snapmaticImage.height()) {
|
|
||||||
diffWidth = snapmaticAvatarResolution - snapmaticImage.width();
|
|
||||||
diffWidth = diffWidth / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snapmaticPainter.drawImage(snapmaticAvatarPlacementW + diffWidth, snapmaticAvatarPlacementH + diffHeight, snapmaticImage);
|
|
||||||
if (ui->cbWatermark->isChecked())
|
|
||||||
processWatermark(&snapmaticPainter);
|
|
||||||
imageTitle = tr("Custom Avatar", "Custom Avatar Description in SC, don't use Special Character!");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Picture mode
|
|
||||||
int diffWidth = 0;
|
|
||||||
int diffHeight = 0;
|
|
||||||
if (ui->cbIgnore->isChecked()) {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
}
|
|
||||||
else if (ui->cbBorderless->isChecked()) {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
|
||||||
if (snapmaticImage.width() > snapmaticResolution.width()) {
|
|
||||||
int diffWidth = snapmaticImage.width() - snapmaticResolution.width();
|
|
||||||
diffWidth = diffWidth / 2;
|
|
||||||
QImage croppedImage(snapmaticResolution, QImage::Format_ARGB32);
|
|
||||||
croppedImage.fill(Qt::transparent);
|
|
||||||
QPainter croppedPainter(&croppedImage);
|
|
||||||
croppedPainter.drawImage(0 - diffWidth, 0, snapmaticImage);
|
|
||||||
croppedPainter.end();
|
|
||||||
snapmaticImage = croppedImage;
|
|
||||||
}
|
|
||||||
else if (snapmaticImage.height() > snapmaticResolution.height()) {
|
|
||||||
int diffHeight = snapmaticImage.height() - snapmaticResolution.height();
|
|
||||||
diffHeight = diffHeight / 2;
|
|
||||||
QImage croppedImage(snapmaticResolution, QImage::Format_ARGB32);
|
|
||||||
croppedImage.fill(Qt::transparent);
|
|
||||||
QPainter croppedPainter(&croppedImage);
|
|
||||||
croppedPainter.drawImage(0, 0 - diffHeight, snapmaticImage);
|
|
||||||
croppedPainter.end();
|
|
||||||
snapmaticImage = croppedImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
||||||
if (snapmaticImage.width() != snapmaticResolution.width()) {
|
|
||||||
diffWidth = snapmaticResolution.width() - snapmaticImage.width();
|
|
||||||
diffWidth = diffWidth / 2;
|
|
||||||
}
|
|
||||||
else if (snapmaticImage.height() != snapmaticResolution.height()) {
|
|
||||||
diffHeight = snapmaticResolution.height() - snapmaticImage.height();
|
|
||||||
diffHeight = diffHeight / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snapmaticPainter.drawImage(0 + diffWidth, 0 + diffHeight, snapmaticImage);
|
|
||||||
if (ui->cbWatermark->isChecked())
|
|
||||||
processWatermark(&snapmaticPainter);
|
|
||||||
imageTitle = tr("Custom Picture", "Custom Picture Description in SC, don't use Special Character!");
|
|
||||||
}
|
|
||||||
snapmaticPainter.end();
|
|
||||||
newImage = snapmaticPixmap.toImage();
|
|
||||||
#if QT_VERSION >= 0x050600
|
|
||||||
snapmaticPixmap.setDevicePixelRatio(screenRatioPR);
|
|
||||||
#endif
|
|
||||||
ui->labPicture->setPixmap(snapmaticPixmap.scaled(snapmaticResolutionLW * screenRatioPR, snapmaticResolutionLH * screenRatioPR, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::reworkImage()
|
|
||||||
{
|
|
||||||
workImage = QImage();
|
|
||||||
if (origImage.width() == origImage.height()) {
|
|
||||||
if (ui->cbResolution->currentIndex() == 0) {
|
|
||||||
insideAvatarZone = true;
|
|
||||||
ui->cbAvatar->setChecked(true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
insideAvatarZone = false;
|
|
||||||
ui->cbAvatar->setChecked(false);
|
|
||||||
}
|
|
||||||
if (origImage.height() > snapmaticResolution.height()) {
|
|
||||||
workImage = origImage.scaled(snapmaticResolution.height(), snapmaticResolution.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
workImage = origImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (origImage.width() > snapmaticResolution.width() && origImage.width() > origImage.height()) {
|
|
||||||
insideAvatarZone = false;
|
|
||||||
ui->cbAvatar->setChecked(false);
|
|
||||||
workImage = origImage.scaledToWidth(snapmaticResolution.width(), Qt::SmoothTransformation);
|
|
||||||
}
|
|
||||||
else if (origImage.height() > snapmaticResolution.height() && origImage.height() > origImage.width()) {
|
|
||||||
insideAvatarZone = false;
|
|
||||||
ui->cbAvatar->setChecked(false);
|
|
||||||
workImage = origImage.scaledToHeight(snapmaticResolution.height(), Qt::SmoothTransformation);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
insideAvatarZone = false;
|
|
||||||
ui->cbAvatar->setChecked(false);
|
|
||||||
workImage = origImage;
|
|
||||||
}
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::processWatermark(QPainter *snapmaticPainter)
|
|
||||||
{
|
|
||||||
bool blackWatermark = false;
|
|
||||||
bool redWatermark = false;
|
|
||||||
if (selectedColour.red() > 127) {
|
|
||||||
if (selectedColour.green() > 127 || selectedColour.blue() > 127) {
|
|
||||||
redWatermark = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
redWatermark = true;
|
|
||||||
}
|
|
||||||
if (selectedColour.lightness() > 127) {
|
|
||||||
blackWatermark = true;
|
|
||||||
}
|
|
||||||
// draw watermark
|
|
||||||
if (redWatermark) {
|
|
||||||
const QImage viewWatermark = QImage(AppEnv::getImagesFolder() % "/watermark_2r.png");
|
|
||||||
snapmaticPainter->drawImage(snapmaticResolution.width() - viewWatermark.width(), 0, viewWatermark);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QImage viewWatermark = QImage(AppEnv::getImagesFolder() % "/watermark_2b.png");
|
|
||||||
if (!blackWatermark) {
|
|
||||||
viewWatermark.invertPixels(QImage::InvertRgb);
|
|
||||||
}
|
|
||||||
snapmaticPainter->drawImage(snapmaticResolution.width() - viewWatermark.width(), 0, viewWatermark);
|
|
||||||
}
|
|
||||||
QImage textWatermark = QImage(AppEnv::getImagesFolder() % "/watermark_1b.png");
|
|
||||||
if (!blackWatermark) {
|
|
||||||
textWatermark.invertPixels(QImage::InvertRgb);
|
|
||||||
}
|
|
||||||
snapmaticPainter->drawImage(snapmaticResolution.width() - textWatermark.width(), 0, textWatermark);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::processSettings(QString settingsProfile, bool setDefault)
|
|
||||||
{
|
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
|
||||||
settings.beginGroup("Import");
|
|
||||||
if (setDefault) {
|
|
||||||
settings.setValue("Profile", settingsProfile);
|
|
||||||
}
|
|
||||||
if (settingsProfile == "Default") {
|
|
||||||
watermarkAvatar = true;
|
|
||||||
watermarkPicture = false;
|
|
||||||
selectedColour = QColor::fromRgb(0, 0, 0, 255);
|
|
||||||
backImage = QImage();
|
|
||||||
ui->cbBorderless->setChecked(false);
|
|
||||||
ui->cbStretch->setChecked(false);
|
|
||||||
ui->cbForceAvatarColour->setChecked(false);
|
|
||||||
ui->cbUnlimited->setChecked(false);
|
|
||||||
ui->cbImportAsIs->setChecked(false);
|
|
||||||
ui->cbResolution->setCurrentIndex(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
settings.beginGroup(settingsProfile);
|
|
||||||
watermarkAvatar = settings.value("WatermarkAvatar", true).toBool();
|
|
||||||
watermarkPicture = settings.value("WatermarkPicture", false).toBool();
|
|
||||||
backImage = qvariant_cast<QImage>(settings.value("BackgroundImage", QImage()));
|
|
||||||
selectedColour = qvariant_cast<QColor>(settings.value("SelectedColour", QColor::fromRgb(0, 0, 0, 255)));
|
|
||||||
ui->cbBorderless->setChecked(settings.value("BorderlessImage", false).toBool());
|
|
||||||
ui->cbStretch->setChecked(settings.value("BackgroundStretch", false).toBool());
|
|
||||||
ui->cbForceAvatarColour->setChecked(settings.value("ForceAvatarColour", false).toBool());
|
|
||||||
ui->cbUnlimited->setChecked(settings.value("UnlimitedBuffer", false).toBool());
|
|
||||||
ui->cbImportAsIs->setChecked(settings.value("ImportAsIs", false).toBool());
|
|
||||||
const QVariant data = settings.value("Resolution", SnapmaticPicture::getSnapmaticResolution());
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
if (data.typeId() == QMetaType::QSize)
|
|
||||||
#else
|
|
||||||
if (data.type() == QVariant::Size)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
int index = ui->cbResolution->findData(data);
|
|
||||||
if (index != -1) {
|
|
||||||
ui->cbResolution->setCurrentIndex(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
settings.endGroup();
|
|
||||||
}
|
|
||||||
if (!workImage.isNull()) {
|
|
||||||
if (ui->cbAvatar->isChecked()) {
|
|
||||||
ui->cbWatermark->setChecked(watermarkAvatar);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->cbWatermark->setChecked(watermarkPicture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->labColour->setText(tr("Background Colour: <span style=\"color: %1\">%1</span>").arg(selectedColour.name()));
|
|
||||||
if (!backImage.isNull()) {
|
|
||||||
ui->labBackgroundImage->setText(tr("Background Image: %1").arg(tr("Storage", "Background Image: Storage")));
|
|
||||||
ui->cmdBackgroundWipe->setVisible(true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->labBackgroundImage->setText(tr("Background Image:"));
|
|
||||||
ui->cmdBackgroundWipe->setVisible(false);
|
|
||||||
}
|
|
||||||
settings.endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::saveSettings(QString settingsProfile)
|
|
||||||
{
|
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
|
||||||
settings.beginGroup("Import");
|
|
||||||
settings.beginGroup(settingsProfile);
|
|
||||||
settings.setValue("WatermarkAvatar", watermarkAvatar);
|
|
||||||
settings.setValue("WatermarkPicture", watermarkPicture);
|
|
||||||
settings.setValue("BackgroundImage", backImage);
|
|
||||||
settings.setValue("SelectedColour", selectedColour);
|
|
||||||
settings.setValue("BorderlessImage", ui->cbBorderless->isChecked());
|
|
||||||
settings.setValue("BackgroundStretch", ui->cbStretch->isChecked());
|
|
||||||
settings.setValue("ForceAvatarColour", ui->cbForceAvatarColour->isChecked());
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
const QVariant data = ui->cbResolution->currentData();
|
|
||||||
#else
|
|
||||||
const QVariant data = ui->cbResolution->itemData(ui->cbResolution->currentIndex());
|
|
||||||
#endif
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
if (data.typeId() == QMetaType::QSize)
|
|
||||||
#else
|
|
||||||
if (data.type() == QVariant::Size)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
settings.setValue("Resolution", data);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
settings.setValue("Resolution", SnapmaticPicture::getSnapmaticResolution());
|
|
||||||
}
|
|
||||||
settings.setValue("UnlimitedBuffer", ui->cbUnlimited->isChecked());
|
|
||||||
settings.setValue("ImportAsIs", ui->cbImportAsIs->isChecked());
|
|
||||||
settings.endGroup();
|
|
||||||
settings.setValue("Profile", settingsProfile);
|
|
||||||
settings.endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::cropPicture()
|
|
||||||
{
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
|
|
||||||
QDialog cropDialog(this);
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
cropDialog.setObjectName(QStringLiteral("CropDialog"));
|
|
||||||
#else
|
|
||||||
cropDialog.setObjectName(QString::fromUtf8("CropDialog"));
|
|
||||||
#endif
|
|
||||||
cropDialog.setWindowTitle(tr("Crop Picture..."));
|
|
||||||
cropDialog.setWindowFlags(cropDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
cropDialog.setModal(true);
|
|
||||||
|
|
||||||
QVBoxLayout cropLayout;
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
cropLayout.setObjectName(QStringLiteral("CropLayout"));
|
|
||||||
#else
|
|
||||||
cropLayout.setObjectName(QString::fromUtf8("CropLayout"));
|
|
||||||
#endif
|
|
||||||
cropLayout.setContentsMargins(0, 0, 0, 0);
|
|
||||||
cropLayout.setSpacing(0);
|
|
||||||
cropDialog.setLayout(&cropLayout);
|
|
||||||
|
|
||||||
ImageCropper imageCropper(&cropDialog);
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
imageCropper.setObjectName(QStringLiteral("ImageCropper"));
|
|
||||||
#else
|
|
||||||
imageCropper.setObjectName(QString::fromUtf8("ImageCropper"));
|
|
||||||
#endif
|
|
||||||
imageCropper.setBackgroundColor(Qt::black);
|
|
||||||
imageCropper.setCroppingRectBorderColor(QColor(255, 255, 255, 127));
|
|
||||||
imageCropper.setImage(QPixmap::fromImage(origImage, Qt::AutoColor));
|
|
||||||
imageCropper.setProportion(QSize(1, 1));
|
|
||||||
imageCropper.setFixedSize(workImage.size());
|
|
||||||
cropLayout.addWidget(&imageCropper);
|
|
||||||
|
|
||||||
QHBoxLayout buttonLayout;
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
cropLayout.setObjectName(QStringLiteral("ButtonLayout"));
|
|
||||||
#else
|
|
||||||
cropLayout.setObjectName(QString::fromUtf8("ButtonLayout"));
|
|
||||||
#endif
|
|
||||||
cropLayout.addLayout(&buttonLayout);
|
|
||||||
|
|
||||||
QPushButton cropButton(&cropDialog);
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
cropButton.setObjectName(QStringLiteral("CropButton"));
|
|
||||||
#else
|
|
||||||
cropButton.setObjectName(QString::fromUtf8("CropButton"));
|
|
||||||
#endif
|
|
||||||
cropButton.setMinimumSize(0, 40 * screenRatio);
|
|
||||||
cropButton.setText(tr("&Crop"));
|
|
||||||
cropButton.setToolTip(tr("Crop Picture"));
|
|
||||||
QObject::connect(&cropButton, SIGNAL(clicked(bool)), &cropDialog, SLOT(accept()));
|
|
||||||
|
|
||||||
buttonLayout.addWidget(&cropButton);
|
|
||||||
|
|
||||||
cropDialog.show();
|
|
||||||
cropDialog.setFixedSize(cropDialog.sizeHint());
|
|
||||||
if (cropDialog.exec() == QDialog::Accepted) {
|
|
||||||
QImage *croppedImage = new QImage(imageCropper.cropImage().toImage());
|
|
||||||
setImage(croppedImage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::importNewPicture()
|
|
||||||
{
|
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
|
||||||
settings.beginGroup("FileDialogs");
|
|
||||||
bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool();
|
|
||||||
settings.beginGroup("ImportCopy");
|
|
||||||
|
|
||||||
fileDialogPreOpen: //Work?
|
|
||||||
QFileDialog fileDialog(this);
|
|
||||||
fileDialog.setFileMode(QFileDialog::ExistingFile);
|
|
||||||
fileDialog.setViewMode(QFileDialog::Detail);
|
|
||||||
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
|
|
||||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
|
|
||||||
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
fileDialog.setWindowTitle(QApplication::translate("ProfileInterface", "Import..."));
|
|
||||||
fileDialog.setLabelText(QFileDialog::Accept, QApplication::translate("ProfileInterface", "Import"));
|
|
||||||
|
|
||||||
// Getting readable Image formats
|
|
||||||
QString imageFormatsStr = " ";
|
|
||||||
for (const QByteArray &imageFormat : QImageReader::supportedImageFormats()) {
|
|
||||||
imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList filters;
|
|
||||||
filters << QApplication::translate("ProfileInterface", "All image files (%1)").arg(imageFormatsStr.trimmed());
|
|
||||||
filters << QApplication::translate("ProfileInterface", "All files (**)");
|
|
||||||
fileDialog.setNameFilters(filters);
|
|
||||||
|
|
||||||
QList<QUrl> sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls());
|
|
||||||
|
|
||||||
fileDialog.setSidebarUrls(sidebarUrls);
|
|
||||||
fileDialog.setDirectory(settings.value(profileName % "+Directory", StandardPaths::documentsLocation()).toString());
|
|
||||||
fileDialog.restoreGeometry(settings.value(profileName % "+Geometry", "").toByteArray());
|
|
||||||
|
|
||||||
if (fileDialog.exec()) {
|
|
||||||
QStringList selectedFiles = fileDialog.selectedFiles();
|
|
||||||
if (selectedFiles.length() == 1) {
|
|
||||||
QString selectedFile = selectedFiles.at(0);
|
|
||||||
QString selectedFileName = QFileInfo(selectedFile).fileName();
|
|
||||||
|
|
||||||
QFile snapmaticFile(selectedFile);
|
|
||||||
if (!snapmaticFile.open(QFile::ReadOnly)) {
|
|
||||||
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be open").arg("\""+selectedFileName+"\""));
|
|
||||||
goto fileDialogPreOpen;
|
|
||||||
}
|
|
||||||
QImage *importImage = new QImage();
|
|
||||||
QImageReader snapmaticImageReader;
|
|
||||||
snapmaticImageReader.setDecideFormatFromContent(true);
|
|
||||||
snapmaticImageReader.setDevice(&snapmaticFile);
|
|
||||||
if (!snapmaticImageReader.read(importImage)) {
|
|
||||||
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\""));
|
|
||||||
delete importImage;
|
|
||||||
goto fileDialogPreOpen;
|
|
||||||
}
|
|
||||||
setImage(importImage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.setValue(profileName % "+Geometry", fileDialog.saveGeometry());
|
|
||||||
settings.setValue(profileName % "+Directory", fileDialog.directory().absolutePath());
|
|
||||||
settings.endGroup();
|
|
||||||
settings.endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::loadImportSettings()
|
|
||||||
{
|
|
||||||
if (settingsLocked) {
|
|
||||||
QMessageBox::information(this, tr("Load Settings..."), tr("Please import a new picture first"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool ok;
|
|
||||||
QStringList profileList;
|
|
||||||
profileList << tr("Default", "Default as Default Profile")
|
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("1")
|
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("2")
|
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("3")
|
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("4")
|
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("5");
|
|
||||||
QString sProfile = QInputDialog::getItem(this, tr("Load Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags());
|
|
||||||
if (ok) {
|
|
||||||
QString pProfile;
|
|
||||||
if (sProfile == tr("Default", "Default as Default Profile")) {
|
|
||||||
pProfile = "Default";
|
|
||||||
}
|
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1")) {
|
|
||||||
pProfile = "Profile 1";
|
|
||||||
}
|
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2")) {
|
|
||||||
pProfile = "Profile 2";
|
|
||||||
}
|
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3")) {
|
|
||||||
pProfile = "Profile 3";
|
|
||||||
}
|
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4"))
|
|
||||||
{
|
|
||||||
pProfile = "Profile 4";
|
|
||||||
}
|
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5")) {
|
|
||||||
pProfile = "Profile 5";
|
|
||||||
}
|
|
||||||
processSettings(pProfile, true);
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::saveImportSettings()
|
|
||||||
{
|
|
||||||
if (settingsLocked) {
|
|
||||||
QMessageBox::information(this, tr("Save Settings..."), tr("Please import a new picture first"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool ok;
|
|
||||||
QStringList profileList;
|
|
||||||
profileList << tr("Profile %1", "Profile %1 as Profile 1").arg("1")
|
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("2")
|
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("3")
|
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("4")
|
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("5");
|
|
||||||
QString sProfile = QInputDialog::getItem(this, tr("Save Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags());
|
|
||||||
if (ok) {
|
|
||||||
QString pProfile;
|
|
||||||
if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1")) {
|
|
||||||
pProfile = "Profile 1";
|
|
||||||
}
|
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2")) {
|
|
||||||
pProfile = "Profile 2";
|
|
||||||
}
|
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3")) {
|
|
||||||
pProfile = "Profile 3";
|
|
||||||
}
|
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4")) {
|
|
||||||
pProfile = "Profile 4";
|
|
||||||
}
|
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5")) {
|
|
||||||
pProfile = "Profile 5";
|
|
||||||
}
|
|
||||||
saveSettings(pProfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage ImportDialog::image()
|
|
||||||
{
|
|
||||||
if (ui->cbImportAsIs->isChecked()) {
|
|
||||||
return origImage;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return newImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::setImage(QImage *image_)
|
|
||||||
{
|
|
||||||
origImage = *image_;
|
|
||||||
workImage = QImage();
|
|
||||||
if (image_->width() == image_->height()) {
|
|
||||||
if (ui->cbResolution->currentIndex() == 0) {
|
|
||||||
insideAvatarZone = true;
|
|
||||||
ui->cbAvatar->setChecked(true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
insideAvatarZone = false;
|
|
||||||
ui->cbAvatar->setChecked(false);
|
|
||||||
}
|
|
||||||
if (image_->height() > snapmaticResolution.height()) {
|
|
||||||
workImage = image_->scaled(snapmaticResolution.height(), snapmaticResolution.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
delete image_;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
workImage = *image_;
|
|
||||||
delete image_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (image_->width() > snapmaticResolution.width() && image_->width() > image_->height()) {
|
|
||||||
insideAvatarZone = false;
|
|
||||||
ui->cbAvatar->setChecked(false);
|
|
||||||
workImage = image_->scaledToWidth(snapmaticResolution.width(), Qt::SmoothTransformation);
|
|
||||||
delete image_;
|
|
||||||
}
|
|
||||||
else if (image_->height() > snapmaticResolution.height() && image_->height() > image_->width()) {
|
|
||||||
insideAvatarZone = false;
|
|
||||||
ui->cbAvatar->setChecked(false);
|
|
||||||
workImage = image_->scaledToHeight(snapmaticResolution.height(), Qt::SmoothTransformation);
|
|
||||||
delete image_;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
insideAvatarZone = false;
|
|
||||||
ui->cbAvatar->setChecked(false);
|
|
||||||
workImage = *image_;
|
|
||||||
delete image_;
|
|
||||||
}
|
|
||||||
processImage();
|
|
||||||
lockSettings(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::lockSettings(bool lock)
|
|
||||||
{
|
|
||||||
ui->gbAdvanced->setDisabled(lock);
|
|
||||||
if (ui->cbImportAsIs->isChecked()) {
|
|
||||||
ui->gbBackground->setDisabled(true);
|
|
||||||
ui->gbSettings->setDisabled(true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->gbBackground->setDisabled(lock);
|
|
||||||
ui->gbSettings->setDisabled(lock);
|
|
||||||
}
|
|
||||||
ui->cmdOK->setDisabled(lock);
|
|
||||||
settingsLocked = lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::enableOverwriteMode()
|
|
||||||
{
|
|
||||||
setWindowTitle(QApplication::translate("ImageEditorDialog", "Overwrite Image..."));
|
|
||||||
ui->cmdOK->setText(QApplication::translate("ImageEditorDialog", "&Overwrite"));
|
|
||||||
ui->cmdOK->setToolTip(QApplication::translate("ImageEditorDialog", "Apply changes"));
|
|
||||||
ui->cmdCancel->setText(QApplication::translate("ImageEditorDialog", "&Close"));
|
|
||||||
ui->cmdCancel->setToolTip(QApplication::translate("ImageEditorDialog", "Discard changes"));
|
|
||||||
ui->cmdCancel->setDefault(true);
|
|
||||||
ui->cmdCancel->setFocus();
|
|
||||||
lockSettings(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImportDialog::isImportAgreed()
|
|
||||||
{
|
|
||||||
return importAgreed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImportDialog::isUnlimitedBuffer()
|
|
||||||
{
|
|
||||||
return ui->cbUnlimited->isChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImportDialog::areSettingsLocked()
|
|
||||||
{
|
|
||||||
return settingsLocked;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ImportDialog::getImageTitle()
|
|
||||||
{
|
|
||||||
if (ui->cbImportAsIs->isChecked()) {
|
|
||||||
return tr("Custom Picture", "Custom Picture Description in SC, don't use Special Character!");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return imageTitle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cbIgnore_toggled(bool checked)
|
|
||||||
{
|
|
||||||
ui->cbBorderless->setDisabled(checked);
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cbAvatar_toggled(bool checked)
|
|
||||||
{
|
|
||||||
if (ui->cbResolution->currentIndex() != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!workImage.isNull() && workImage.width() == workImage.height() && !checked) {
|
|
||||||
if (QMessageBox::No == QMessageBox::warning(this, tr("Snapmatic Avatar Zone"), tr("Are you sure to use a square image outside of the Avatar Zone?\nWhen you want to use it as Avatar the image will be detached!"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) {
|
|
||||||
ui->cbAvatar->setChecked(true);
|
|
||||||
insideAvatarZone = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
insideAvatarZone = ui->cbAvatar->isChecked();
|
|
||||||
watermarkBlock = true;
|
|
||||||
if (insideAvatarZone) {
|
|
||||||
ui->cbWatermark->setChecked(watermarkAvatar);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->cbWatermark->setChecked(watermarkPicture);
|
|
||||||
}
|
|
||||||
watermarkBlock = false;
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cmdCancel_clicked()
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cmdOK_clicked()
|
|
||||||
{
|
|
||||||
importAgreed = true;
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_labPicture_labelPainted()
|
|
||||||
{
|
|
||||||
if (insideAvatarZone) {
|
|
||||||
QImage avatarAreaFinalImage(avatarAreaImage);
|
|
||||||
if (selectedColour.lightness() > 127) {
|
|
||||||
avatarAreaFinalImage.setColor(1, qRgb(0, 0, 0));
|
|
||||||
}
|
|
||||||
QPainter labelPainter(ui->labPicture);
|
|
||||||
labelPainter.drawImage(0, 0, avatarAreaFinalImage.scaled(snapmaticResolutionLW, snapmaticResolutionLH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
|
||||||
labelPainter.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cmdColourChange_clicked()
|
|
||||||
{
|
|
||||||
QColor newSelectedColour = QColorDialog::getColor(selectedColour, this, tr("Select Colour..."));
|
|
||||||
if (newSelectedColour.isValid()) {
|
|
||||||
selectedColour = newSelectedColour;
|
|
||||||
ui->labColour->setText(tr("Background Colour: <span style=\"color: %1\">%1</span>").arg(selectedColour.name()));
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cmdBackgroundChange_clicked()
|
|
||||||
{
|
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
|
||||||
settings.beginGroup("FileDialogs");
|
|
||||||
bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool();
|
|
||||||
settings.beginGroup("ImportBackground");
|
|
||||||
|
|
||||||
fileDialogPreOpen:
|
|
||||||
QFileDialog fileDialog(this);
|
|
||||||
fileDialog.setFileMode(QFileDialog::ExistingFiles);
|
|
||||||
fileDialog.setViewMode(QFileDialog::Detail);
|
|
||||||
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
|
|
||||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
|
|
||||||
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
fileDialog.setWindowTitle(QApplication::translate("ProfileInterface", "Import..."));
|
|
||||||
fileDialog.setLabelText(QFileDialog::Accept, QApplication::translate("ProfileInterface", "Import"));
|
|
||||||
|
|
||||||
// Getting readable Image formats
|
|
||||||
QString imageFormatsStr = " ";
|
|
||||||
for (const QByteArray &imageFormat : QImageReader::supportedImageFormats()) {
|
|
||||||
imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList filters;
|
|
||||||
filters << QApplication::translate("ProfileInterface", "All image files (%1)").arg(imageFormatsStr.trimmed());
|
|
||||||
filters << QApplication::translate("ProfileInterface", "All files (**)");
|
|
||||||
fileDialog.setNameFilters(filters);
|
|
||||||
|
|
||||||
QList<QUrl> sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls());
|
|
||||||
|
|
||||||
fileDialog.setSidebarUrls(sidebarUrls);
|
|
||||||
fileDialog.setDirectory(settings.value("Directory", StandardPaths::documentsLocation()).toString());
|
|
||||||
fileDialog.restoreGeometry(settings.value("Geometry", "").toByteArray());
|
|
||||||
|
|
||||||
if (fileDialog.exec()) {
|
|
||||||
QStringList selectedFiles = fileDialog.selectedFiles();
|
|
||||||
if (selectedFiles.length() == 1) {
|
|
||||||
QString selectedFile = selectedFiles.at(0);
|
|
||||||
QString selectedFileName = QFileInfo(selectedFile).fileName();
|
|
||||||
|
|
||||||
QFile snapmaticFile(selectedFile);
|
|
||||||
if (!snapmaticFile.open(QFile::ReadOnly)) {
|
|
||||||
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be open").arg("\""+selectedFileName+"\""));
|
|
||||||
goto fileDialogPreOpen;
|
|
||||||
}
|
|
||||||
QImage importImage;
|
|
||||||
QImageReader snapmaticImageReader;
|
|
||||||
snapmaticImageReader.setDecideFormatFromContent(true);
|
|
||||||
snapmaticImageReader.setDevice(&snapmaticFile);
|
|
||||||
if (!snapmaticImageReader.read(&importImage)) {
|
|
||||||
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\""));
|
|
||||||
goto fileDialogPreOpen;
|
|
||||||
}
|
|
||||||
backImage = importImage.scaled(snapmaticResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
||||||
backgroundPath = selectedFile;
|
|
||||||
ui->labBackgroundImage->setText(tr("Background Image: %1").arg(tr("File", "Background Image: File")));
|
|
||||||
ui->cmdBackgroundWipe->setVisible(true);
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.setValue("Geometry", fileDialog.saveGeometry());
|
|
||||||
settings.setValue("Directory", fileDialog.directory().absolutePath());
|
|
||||||
settings.endGroup();
|
|
||||||
settings.endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cmdBackgroundWipe_clicked()
|
|
||||||
{
|
|
||||||
backImage = QImage();
|
|
||||||
ui->labBackgroundImage->setText(tr("Background Image:"));
|
|
||||||
ui->cmdBackgroundWipe->setVisible(false);
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cbStretch_toggled(bool checked)
|
|
||||||
{
|
|
||||||
Q_UNUSED(checked)
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cbForceAvatarColour_toggled(bool checked)
|
|
||||||
{
|
|
||||||
Q_UNUSED(checked)
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cbWatermark_toggled(bool checked)
|
|
||||||
{
|
|
||||||
if (!watermarkBlock) {
|
|
||||||
if (insideAvatarZone) {
|
|
||||||
watermarkAvatar = checked;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
watermarkPicture = checked;
|
|
||||||
}
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cbBorderless_toggled(bool checked)
|
|
||||||
{
|
|
||||||
ui->cbIgnore->setDisabled(checked);
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cbImportAsIs_toggled(bool checked)
|
|
||||||
{
|
|
||||||
ui->cbResolution->setDisabled(checked);
|
|
||||||
ui->labResolution->setDisabled(checked);
|
|
||||||
ui->gbBackground->setDisabled(checked);
|
|
||||||
ui->gbSettings->setDisabled(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cbResolution_currentIndexChanged(int index)
|
|
||||||
{
|
|
||||||
Q_UNUSED(index)
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
const QVariant data = ui->cbResolution->currentData();
|
|
||||||
#else
|
|
||||||
const QVariant data = ui->cbResolution->itemData(ui->cbResolution->currentIndex());
|
|
||||||
#endif
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
if (data.typeId() == QMetaType::QSize)
|
|
||||||
#else
|
|
||||||
if (data.type() == QVariant::Size)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
const QSize dataSize = data.toSize();
|
|
||||||
if (dataSize == SnapmaticPicture::getSnapmaticResolution()) {
|
|
||||||
ui->cbAvatar->setEnabled(true);
|
|
||||||
snapmaticResolution = dataSize;
|
|
||||||
reworkImage();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!workImage.isNull() && workImage.width() == workImage.height() && ui->cbAvatar->isChecked()) {
|
|
||||||
if (QMessageBox::No == QMessageBox::warning(this, tr("Snapmatic Avatar Zone"), tr("Are you sure to use a square image outside of the Avatar Zone?\nWhen you want to use it as Avatar the image will be detached!"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) {
|
|
||||||
ui->cbResolution->setCurrentIndex(0);
|
|
||||||
ui->cbAvatar->setChecked(true);
|
|
||||||
insideAvatarZone = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->cbAvatar->setChecked(false);
|
|
||||||
ui->cbAvatar->setDisabled(true);
|
|
||||||
insideAvatarZone = false;
|
|
||||||
ui->cbWatermark->setChecked(watermarkPicture);
|
|
||||||
snapmaticResolution = dataSize;
|
|
||||||
reworkImage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2017-2021 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef IMPORTDIALOG_H
|
|
||||||
#define IMPORTDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QMenu>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class ImportDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ImportDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ImportDialog(QString profileName, QWidget *parent = 0);
|
|
||||||
~ImportDialog();
|
|
||||||
QImage image();
|
|
||||||
QString getImageTitle();
|
|
||||||
void setImage(QImage *image);
|
|
||||||
void lockSettings(bool lock);
|
|
||||||
void enableOverwriteMode();
|
|
||||||
bool isImportAgreed();
|
|
||||||
bool isUnlimitedBuffer();
|
|
||||||
bool areSettingsLocked();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void processImage();
|
|
||||||
void reworkImage();
|
|
||||||
void cropPicture();
|
|
||||||
void importNewPicture();
|
|
||||||
void loadImportSettings();
|
|
||||||
void saveImportSettings();
|
|
||||||
void on_cbIgnore_toggled(bool checked);
|
|
||||||
void on_cbAvatar_toggled(bool checked);
|
|
||||||
void on_cmdCancel_clicked();
|
|
||||||
void on_cmdOK_clicked();
|
|
||||||
void on_labPicture_labelPainted();
|
|
||||||
void on_cmdColourChange_clicked();
|
|
||||||
void on_cmdBackgroundChange_clicked();
|
|
||||||
void on_cmdBackgroundWipe_clicked();
|
|
||||||
void on_cbStretch_toggled(bool checked);
|
|
||||||
void on_cbForceAvatarColour_toggled(bool checked);
|
|
||||||
void on_cbWatermark_toggled(bool checked);
|
|
||||||
void on_cbBorderless_toggled(bool checked);
|
|
||||||
void on_cbImportAsIs_toggled(bool checked);
|
|
||||||
void on_cbResolution_currentIndexChanged(int index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString profileName;
|
|
||||||
Ui::ImportDialog *ui;
|
|
||||||
QImage avatarAreaImage;
|
|
||||||
QString backgroundPath;
|
|
||||||
QString imageTitle;
|
|
||||||
QImage backImage;
|
|
||||||
QImage workImage;
|
|
||||||
QImage origImage;
|
|
||||||
QImage newImage;
|
|
||||||
QColor selectedColour;
|
|
||||||
QMenu optionsMenu;
|
|
||||||
QSize snapmaticResolution;
|
|
||||||
bool insideAvatarZone;
|
|
||||||
bool watermarkPicture;
|
|
||||||
bool watermarkAvatar;
|
|
||||||
bool watermarkBlock;
|
|
||||||
bool settingsLocked;
|
|
||||||
bool importAgreed;
|
|
||||||
int snapmaticResolutionLW;
|
|
||||||
int snapmaticResolutionLH;
|
|
||||||
void processWatermark(QPainter *snapmaticPainter);
|
|
||||||
void processSettings(QString settingsProfile, bool setDefault = false);
|
|
||||||
void saveSettings(QString settingsProfile);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // IMPORTDIALOG_H
|
|
||||||
420
ImportDialog.ui
420
ImportDialog.ui
|
|
@ -1,420 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>ImportDialog</class>
|
|
||||||
<widget class="QDialog" name="ImportDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>516</width>
|
|
||||||
<height>673</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>516</width>
|
|
||||||
<height>512</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Import...</string>
|
|
||||||
</property>
|
|
||||||
<property name="modal">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlImport">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="UiModLabel" name="labPicture">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>516</width>
|
|
||||||
<height>288</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QFrame" name="buttomFrame">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlButtom">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbSettings">
|
|
||||||
<property name="title">
|
|
||||||
<string>Picture</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlSettings">
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="glPicture">
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QCheckBox" name="cbIgnore">
|
|
||||||
<property name="text">
|
|
||||||
<string>Ignore Aspect Ratio</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QCheckBox" name="cbAvatar">
|
|
||||||
<property name="text">
|
|
||||||
<string>Avatar</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="cbWatermark">
|
|
||||||
<property name="text">
|
|
||||||
<string>Watermark</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QCheckBox" name="cbBorderless">
|
|
||||||
<property name="text">
|
|
||||||
<string>Crop to Aspect Ratio</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbBackground">
|
|
||||||
<property name="title">
|
|
||||||
<string>Background</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlBackground">
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="glBackground">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<layout class="QHBoxLayout" name="hlColourManage">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labColour">
|
|
||||||
<property name="text">
|
|
||||||
<string>Background Colour: <span style="color: %1">%1</span></string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlColourButton">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="cmdColourChange">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Select background colour</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="hsColour">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QCheckBox" name="cbStretch">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Ignore Aspect Ratio</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QCheckBox" name="cbForceAvatarColour">
|
|
||||||
<property name="text">
|
|
||||||
<string>Force Colour in Avatar Zone</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="hlBackgroundManage">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labBackgroundImage">
|
|
||||||
<property name="text">
|
|
||||||
<string>Background Image:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlBackgroundButton">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="cmdBackgroundChange">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Select background image</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="cmdBackgroundWipe">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Remove background image</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">X</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="hsBackgroundImage">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbAdvanced">
|
|
||||||
<property name="title">
|
|
||||||
<string>Advanced</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlAdvanced">
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="glAdvanced">
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="cbUnlimited">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Unlimited Buffer</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QCheckBox" name="cbImportAsIs">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Import as-is</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0" colspan="2">
|
|
||||||
<layout class="QHBoxLayout" name="hlResolution">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labResolution">
|
|
||||||
<property name="text">
|
|
||||||
<string>Resolution:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="cbResolution">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Snapmatic resolution</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="vsInterface">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlButtons">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdOptions">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Import options</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Options</string>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="hsButtons">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdOK">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Import picture</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&OK</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdCancel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Discard picture</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Cancel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>UiModLabel</class>
|
|
||||||
<extends>QLabel</extends>
|
|
||||||
<header>uimod/UiModLabel.h</header>
|
|
||||||
<slots>
|
|
||||||
<signal>mouseMoved()</signal>
|
|
||||||
<signal>mouseReleased()</signal>
|
|
||||||
<signal>mousePressed()</signal>
|
|
||||||
<signal>mouseDoubleClicked()</signal>
|
|
||||||
</slots>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
|
|
@ -1,226 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2017-2021 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "JsonEditorDialog.h"
|
|
||||||
#include "ui_JsonEditorDialog.h"
|
|
||||||
#include "SnapmaticEditor.h"
|
|
||||||
#include "AppEnv.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050200
|
|
||||||
#include <QFontDatabase>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
|
||||||
#include "TelemetryClass.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) :
|
|
||||||
QDialog(parent), smpic(picture),
|
|
||||||
ui(new Ui::JsonEditorDialog)
|
|
||||||
{
|
|
||||||
// Set Window Flags
|
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
setWindowFlag(Qt::WindowMinMaxButtonsHint, true);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowMinMaxButtonsHint);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
|
||||||
ui->cmdClose->setDefault(true);
|
|
||||||
ui->cmdClose->setFocus();
|
|
||||||
|
|
||||||
// Set Icon for Close Button
|
|
||||||
if (QIcon::hasThemeIcon("dialog-close")) {
|
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-close")) {
|
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Icon for Save Button
|
|
||||||
if (QIcon::hasThemeIcon("document-save")) {
|
|
||||||
ui->cmdSave->setIcon(QIcon::fromTheme("document-save"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-save")) {
|
|
||||||
ui->cmdSave->setIcon(QIcon::fromTheme("gtk-save"));
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonCode = picture->getJsonStr();
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050200
|
|
||||||
ui->txtJSON->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
|
||||||
#else
|
|
||||||
QFont jsonFont = ui->txtJSON->font();
|
|
||||||
jsonFont.setStyleHint(QFont::Monospace);
|
|
||||||
jsonFont.setFixedPitch(true);
|
|
||||||
ui->txtJSON->setFont(jsonFont);
|
|
||||||
#endif
|
|
||||||
QFontMetrics fontMetrics(ui->txtJSON->font());
|
|
||||||
#if QT_VERSION >= 0x050B00
|
|
||||||
ui->txtJSON->setTabStopDistance(fontMetrics.horizontalAdvance(" "));
|
|
||||||
#else
|
|
||||||
ui->txtJSON->setTabStopWidth(fontMetrics.width(" "));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonCode.toUtf8());
|
|
||||||
ui->txtJSON->setStyleSheet("QPlainTextEdit{background-color: rgb(46, 47, 48); color: rgb(238, 231, 172);}");
|
|
||||||
ui->txtJSON->setPlainText(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Indented)).trimmed());
|
|
||||||
jsonHl = new JSHighlighter(ui->txtJSON->document());
|
|
||||||
|
|
||||||
// DPI calculation
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
#ifndef Q_OS_MAC
|
|
||||||
ui->hlButtons->setSpacing(6 * screenRatio);
|
|
||||||
ui->hlButtons->setContentsMargins(9 * screenRatio, 0, 9 * screenRatio, 0);
|
|
||||||
ui->vlInterface->setContentsMargins(0, 0, 0, 9 * screenRatio);
|
|
||||||
#else
|
|
||||||
ui->hlButtons->setSpacing(6 * screenRatio);
|
|
||||||
ui->hlButtons->setContentsMargins(9 * screenRatio, 0, 9 * screenRatio, 0);
|
|
||||||
ui->vlInterface->setContentsMargins(0, 0, 0, 9 * screenRatio);
|
|
||||||
#endif
|
|
||||||
if (screenRatio > 1) {
|
|
||||||
ui->lineJSON->setMinimumHeight(qRound(1 * screenRatio));
|
|
||||||
ui->lineJSON->setMaximumHeight(qRound(1 * screenRatio));
|
|
||||||
ui->lineJSON->setLineWidth(qRound(1 * screenRatio));
|
|
||||||
}
|
|
||||||
resize(450 * screenRatio, 550 * screenRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonEditorDialog::~JsonEditorDialog()
|
|
||||||
{
|
|
||||||
delete jsonHl;
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JsonEditorDialog::closeEvent(QCloseEvent *ev)
|
|
||||||
{
|
|
||||||
QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " ");
|
|
||||||
QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8());
|
|
||||||
QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8());
|
|
||||||
QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact));
|
|
||||||
QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact));
|
|
||||||
if (newCode != originalCode) {
|
|
||||||
QMessageBox::StandardButton button = QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("<h4>Unsaved changes detected</h4>You want to save the JSON content before you quit?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel);
|
|
||||||
if (button == QMessageBox::Yes) {
|
|
||||||
if (saveJsonContent()) {
|
|
||||||
ev->accept();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ev->ignore();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (button == QMessageBox::No) {
|
|
||||||
ev->accept();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ev->ignore();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JsonEditorDialog::saveJsonContent()
|
|
||||||
{
|
|
||||||
QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " ");
|
|
||||||
QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8());
|
|
||||||
if (!jsonNew.isEmpty()) {
|
|
||||||
QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8());
|
|
||||||
QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact));
|
|
||||||
QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact));
|
|
||||||
if (newCode != originalCode) {
|
|
||||||
QString currentFilePath = smpic->getPictureFilePath();
|
|
||||||
QString originalFilePath = smpic->getOriginalPictureFilePath();
|
|
||||||
QString backupFileName = originalFilePath % ".bak";
|
|
||||||
if (!QFile::exists(backupFileName)) {
|
|
||||||
QFile::copy(currentFilePath, backupFileName);
|
|
||||||
}
|
|
||||||
smpic->setJsonStr(newCode, true);
|
|
||||||
if (!smpic->isJsonOk()) {
|
|
||||||
QString lastStep = smpic->getLastStep(false);
|
|
||||||
QString readableError;
|
|
||||||
if (lastStep.contains("JSONINCOMPLETE") && lastStep.contains("JSONERROR")) {
|
|
||||||
readableError = SnapmaticPicture::tr("JSON is incomplete and malformed");
|
|
||||||
}
|
|
||||||
else if (lastStep.contains("JSONINCOMPLETE")) {
|
|
||||||
readableError = SnapmaticPicture::tr("JSON is incomplete");
|
|
||||||
}
|
|
||||||
else if (lastStep.contains("JSONERROR")) {
|
|
||||||
readableError = SnapmaticPicture::tr("JSON is malformed");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
readableError = tr("JSON Error");
|
|
||||||
}
|
|
||||||
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of %1").arg(readableError));
|
|
||||||
smpic->setJsonStr(originalCode, true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!smpic->exportPicture(currentFilePath)) {
|
|
||||||
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error"));
|
|
||||||
smpic->setJsonStr(originalCode, true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
jsonCode = newCode;
|
|
||||||
smpic->updateStrings();
|
|
||||||
smpic->emitUpdate();
|
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
|
||||||
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
|
||||||
telemetrySettings.endGroup();
|
|
||||||
if (pushUsageData && Telemetry->canPush()) {
|
|
||||||
QJsonDocument jsonDocument;
|
|
||||||
QJsonObject jsonObject;
|
|
||||||
jsonObject["Type"] = "JSONEdited";
|
|
||||||
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of JSON Error"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JsonEditorDialog::on_cmdClose_clicked()
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void JsonEditorDialog::on_cmdSave_clicked()
|
|
||||||
{
|
|
||||||
if (saveJsonContent())
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2017 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef JSONEDITORDIALOG_H
|
|
||||||
#define JSONEDITORDIALOG_H
|
|
||||||
|
|
||||||
#include "SnapmaticPicture.h"
|
|
||||||
#include "JSHighlighter.h"
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class JsonEditorDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class JsonEditorDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent = 0);
|
|
||||||
bool saveJsonContent();
|
|
||||||
~JsonEditorDialog();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void closeEvent(QCloseEvent *ev);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void on_cmdClose_clicked();
|
|
||||||
void on_cmdSave_clicked();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void codeUpdated(QString jsonCode);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString jsonCode;
|
|
||||||
JSHighlighter *jsonHl;
|
|
||||||
SnapmaticPicture *smpic;
|
|
||||||
Ui::JsonEditorDialog *ui;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // JSONEDITORDIALOG_H
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>JsonEditorDialog</class>
|
|
||||||
<widget class="QDialog" name="JsonEditorDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>550</width>
|
|
||||||
<height>450</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Snapmatic JSON Editor</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlInterface">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="vlJSON">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QPlainTextEdit" name="txtJSON">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="Line" name="lineJSON">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>1</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>16777215</width>
|
|
||||||
<height>1</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">QFrame[frameShape="4"]
|
|
||||||
{
|
|
||||||
color: black;
|
|
||||||
}</string>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlButtons">
|
|
||||||
<item>
|
|
||||||
<spacer name="hsButtons">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdSave">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Apply changes</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Save</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdClose">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Discard changes</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Close</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
675
LICENSE
675
LICENSE
|
|
@ -1,674 +1 @@
|
||||||
GNU GENERAL PUBLIC LICENSE
|
The license for GRAND THEFT AUTO V SYNC is GNU GPLv3
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains free
|
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
|
||||||
any other work released this way by its authors. You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
||||||
|
|
|
||||||
54
LICENSE.GPL
Normal file → Executable file
54
LICENSE.GPL
Normal file → Executable file
|
|
@ -1,7 +1,7 @@
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 3, 29 June 2007
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
@ -620,55 +620,3 @@ copy of the Program in return for a fee.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
||||||
|
|
|
||||||
566
LICENSE.LGPL
Normal file → Executable file
566
LICENSE.LGPL
Normal file → Executable file
|
|
@ -1,165 +1,459 @@
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
Version 3, 29 June 2007
|
Version 2.1, February 1999
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
This version of the GNU Lesser General Public License incorporates
|
Preamble
|
||||||
the terms and conditions of version 3 of the GNU General Public
|
|
||||||
License, supplemented by the additional permissions listed below.
|
|
||||||
|
|
||||||
0. Additional Definitions.
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
This license, the Lesser General Public License, applies to some
|
||||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
specially designated software packages--typically libraries--of the
|
||||||
General Public License.
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
"The Library" refers to a covered work governed by this License,
|
When we speak of free software, we are referring to freedom of use,
|
||||||
other than an Application or a Combined Work as defined below.
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
An "Application" is any work that makes use of an interface provided
|
To protect your rights, we need to make restrictions that forbid
|
||||||
by the Library, but which is not otherwise based on the Library.
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
Defining a subclass of a class defined by the Library is deemed a mode
|
rights. These restrictions translate to certain responsibilities for
|
||||||
of using an interface provided by the Library.
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
A "Combined Work" is a work produced by combining or linking an
|
For example, if you distribute copies of the library, whether gratis
|
||||||
Application with the Library. The particular version of the Library
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
with which the Combined Work was made is also called the "Linked
|
you. You must make sure that they, too, receive or can get the source
|
||||||
Version".
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
The "Minimal Corresponding Source" for a Combined Work means the
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
Corresponding Source for the Combined Work, excluding any source code
|
library, and (2) we offer you this license, which gives you legal
|
||||||
for portions of the Combined Work that, considered in isolation, are
|
permission to copy, distribute and/or modify the library.
|
||||||
based on the Application, and not on the Linked Version.
|
|
||||||
|
|
||||||
The "Corresponding Application Code" for a Combined Work means the
|
To protect each distributor, we want to make it very clear that
|
||||||
object code and/or source code for the Application, including any data
|
there is no warranty for the free library. Also, if the library is
|
||||||
and utility programs needed for reproducing the Combined Work from the
|
modified by someone else and passed on, the recipients should know
|
||||||
Application, but excluding the System Libraries of the Combined Work.
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
1. Exception to Section 3 of the GNU GPL.
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
You may convey a covered work under sections 3 and 4 of this License
|
Most GNU software, including some libraries, is covered by the
|
||||||
without being bound by section 3 of the GNU GPL.
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
2. Conveying Modified Versions.
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
If you modify a copy of the Library, and, in your modifications, a
|
We call this license the "Lesser" General Public License because it
|
||||||
facility refers to a function or data to be supplied by an Application
|
does Less to protect the user's freedom than the ordinary General
|
||||||
that uses the facility (other than as an argument passed when the
|
Public License. It also provides other free software developers Less
|
||||||
facility is invoked), then you may convey a copy of the modified
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
version:
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
a) under this License, provided that you make a good faith effort to
|
For example, on rare occasions, there may be a special need to
|
||||||
ensure that, in the event an Application does not supply the
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
function or data, the facility still operates, and performs
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
whatever part of its purpose remains meaningful, or
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
b) under the GNU GPL, with none of the additional permissions of
|
In other cases, permission to use a particular library in non-free
|
||||||
this License applicable to that copy.
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
3. Object Code Incorporating Material from Library Header Files.
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
The object code form of an Application may incorporate material from
|
The precise terms and conditions for copying, distribution and
|
||||||
a header file that is part of the Library. You may convey such object
|
modification follow. Pay close attention to the difference between a
|
||||||
code under terms of your choice, provided that, if the incorporated
|
"work based on the library" and a "work that uses the library". The
|
||||||
material is not limited to numerical parameters, data structure
|
former contains code derived from the library, whereas the latter must
|
||||||
layouts and accessors, or small macros, inline functions and templates
|
be combined with the library in order to run.
|
||||||
(ten or fewer lines in length), you do both of the following:
|
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the object code that the
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
Library is used in it and that the Library and its use are
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
0. This License Agreement applies to any software library or other
|
||||||
document.
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
4. Combined Works.
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
You may convey a Combined Work under terms of your choice that,
|
The "Library", below, refers to any such software library or work
|
||||||
taken together, effectively do not restrict modification of the
|
which has been distributed under these terms. A "work based on the
|
||||||
portions of the Library contained in the Combined Work and reverse
|
Library" means either the Library or any derivative work under
|
||||||
engineering for debugging such modifications, if you also do each of
|
copyright law: that is to say, a work containing the Library or a
|
||||||
the following:
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the Combined Work that
|
"Source code" for a work means the preferred form of the work for
|
||||||
the Library is used in it and that the Library and its use are
|
making modifications to it. For a library, complete source code means
|
||||||
covered by this License.
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
Activities other than copying, distribution and modification are not
|
||||||
document.
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
c) For a Combined Work that displays copyright notices during
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
execution, include the copyright notice for the Library among
|
complete source code as you receive it, in any medium, provided that
|
||||||
these notices, as well as a reference directing the user to the
|
you conspicuously and appropriately publish on each copy an
|
||||||
copies of the GNU GPL and this license document.
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
d) Do one of the following:
|
warranty; and distribute a copy of this License along with the
|
||||||
|
|
||||||
0) Convey the Minimal Corresponding Source under the terms of this
|
|
||||||
License, and the Corresponding Application Code in a form
|
|
||||||
suitable for, and under terms that permit, the user to
|
|
||||||
recombine or relink the Application with a modified version of
|
|
||||||
the Linked Version to produce a modified Combined Work, in the
|
|
||||||
manner specified by section 6 of the GNU GPL for conveying
|
|
||||||
Corresponding Source.
|
|
||||||
|
|
||||||
1) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (a) uses at run time
|
|
||||||
a copy of the Library already present on the user's computer
|
|
||||||
system, and (b) will operate properly with a modified version
|
|
||||||
of the Library that is interface-compatible with the Linked
|
|
||||||
Version.
|
|
||||||
|
|
||||||
e) Provide Installation Information, but only if you would otherwise
|
|
||||||
be required to provide such information under section 6 of the
|
|
||||||
GNU GPL, and only to the extent that such information is
|
|
||||||
necessary to install and execute a modified version of the
|
|
||||||
Combined Work produced by recombining or relinking the
|
|
||||||
Application with a modified version of the Linked Version. (If
|
|
||||||
you use option 4d0, the Installation Information must accompany
|
|
||||||
the Minimal Corresponding Source and Corresponding Application
|
|
||||||
Code. If you use option 4d1, you must provide the Installation
|
|
||||||
Information in the manner specified by section 6 of the GNU GPL
|
|
||||||
for conveying Corresponding Source.)
|
|
||||||
|
|
||||||
5. Combined Libraries.
|
|
||||||
|
|
||||||
You may place library facilities that are a work based on the
|
|
||||||
Library side by side in a single library together with other library
|
|
||||||
facilities that are not Applications and are not covered by this
|
|
||||||
License, and convey such a combined library under terms of your
|
|
||||||
choice, if you do both of the following:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work based
|
|
||||||
on the Library, uncombined with any other library facilities,
|
|
||||||
conveyed under the terms of this License.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library that part of it
|
|
||||||
is a work based on the Library, and explaining where to find the
|
|
||||||
accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
6. Revised Versions of the GNU Lesser General Public License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the GNU Lesser General Public License from time to time. Such new
|
|
||||||
versions will be similar in spirit to the present version, but may
|
|
||||||
differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Library as you received it specifies that a certain numbered version
|
|
||||||
of the GNU Lesser General Public License "or any later version"
|
|
||||||
applies to it, you have the option of following the terms and
|
|
||||||
conditions either of that published version or of any later version
|
|
||||||
published by the Free Software Foundation. If the Library as you
|
|
||||||
received it does not specify a version number of the GNU Lesser
|
|
||||||
General Public License, you may choose any version of the GNU Lesser
|
|
||||||
General Public License ever published by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Library as you received it specifies that a proxy can decide
|
|
||||||
whether future versions of the GNU Lesser General Public License shall
|
|
||||||
apply, that proxy's public statement of acceptance of any version is
|
|
||||||
permanent authorization for you to choose that version for the
|
|
||||||
Library.
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,346 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2017-2021 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "MapLocationDialog.h"
|
|
||||||
#include "ui_MapLocationDialog.h"
|
|
||||||
#include "IconLoader.h"
|
|
||||||
#include "AppEnv.h"
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QStyle>
|
|
||||||
|
|
||||||
MapLocationDialog::MapLocationDialog(double x, double y, QWidget *parent) :
|
|
||||||
QDialog(parent), xpos_old(x), ypos_old(y),
|
|
||||||
ui(new Ui::MapLocationDialog)
|
|
||||||
{
|
|
||||||
// Set Window Flags
|
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
|
||||||
ui->cmdDone->setVisible(false);
|
|
||||||
ui->cmdApply->setVisible(false);
|
|
||||||
ui->cmdRevert->setVisible(false);
|
|
||||||
ui->cmdDone->setCursor(Qt::ArrowCursor);
|
|
||||||
ui->cmdClose->setCursor(Qt::ArrowCursor);
|
|
||||||
|
|
||||||
// DPI calculation
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
int widgetMargin = qRound(3 * screenRatio);
|
|
||||||
ui->hlMapDialog->setContentsMargins(widgetMargin, widgetMargin, widgetMargin, widgetMargin);
|
|
||||||
ui->vlMapDialog->setSpacing(widgetMargin);
|
|
||||||
setMinimumSize(500 * screenRatio, 600 * screenRatio);
|
|
||||||
setMaximumSize(500 * screenRatio, 600 * screenRatio);
|
|
||||||
|
|
||||||
zoomPercent = 100;
|
|
||||||
changeMode = false;
|
|
||||||
propUpdate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MapLocationDialog::~MapLocationDialog()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::drawPointOnMap(double xpos_d, double ypos_d)
|
|
||||||
{
|
|
||||||
ui->labPos->setText(tr("X: %1\nY: %2", "X and Y position").arg(QString::number(xpos_d), QString::number(ypos_d)));
|
|
||||||
xpos_new = xpos_d;
|
|
||||||
ypos_new = ypos_d;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::setCayoPerico(bool isCayoPerico)
|
|
||||||
{
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
p_isCayoPerico = isCayoPerico;
|
|
||||||
if (isCayoPerico) {
|
|
||||||
setMinimumSize(500 * screenRatio, 500 * screenRatio);
|
|
||||||
setMaximumSize(500 * screenRatio, 500 * screenRatio);
|
|
||||||
ui->hlMapDialog->removeItem(ui->vlMapDialog);
|
|
||||||
ui->hlMapDialog->insertLayout(0, ui->vlMapDialog);
|
|
||||||
ui->hlMapDialog->removeItem(ui->vlPosLayout);
|
|
||||||
ui->hlMapDialog->addLayout(ui->vlPosLayout);
|
|
||||||
ui->labPos->setAlignment(Qt::AlignRight);
|
|
||||||
mapImage = QImage(AppEnv::getImagesFolder() % "/mapcayoperico.jpg");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mapImage = QImage(AppEnv::getImagesFolder() % "/mappreview.jpg");
|
|
||||||
}
|
|
||||||
drawPointOnMap(xpos_old, ypos_old);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::updatePosFromEvent(double x, double y)
|
|
||||||
{
|
|
||||||
QSize mapPixelSize = size();
|
|
||||||
double x_per = x / mapPixelSize.width(); // get X %
|
|
||||||
double y_per = y / mapPixelSize.height(); // get Y %
|
|
||||||
double x_pos, y_pos;
|
|
||||||
if (p_isCayoPerico) {
|
|
||||||
x_pos = x_per * 2340; // 2340 is 100% for X (Cayo Perico)
|
|
||||||
y_pos = y_per * -2340; // -2340 is 100% for Y (Cayo Perico)
|
|
||||||
x_pos = x_pos + 3560; // +3560 gets corrected for X (Cayo Perico)
|
|
||||||
y_pos = y_pos - 3980; // -3980 gets corrected for Y (Cayo Perico)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x_pos = x_per * 10000; // 10000 is 100% for X (Los Santos)
|
|
||||||
y_pos = y_per * -12000; // -12000 is 100% for Y (Los Santos)
|
|
||||||
x_pos = x_pos - 4000; // -4000 gets corrected for X (Los Santos)
|
|
||||||
y_pos = y_pos + 8000; // +8000 gets corrected for Y (Los Santos)
|
|
||||||
}
|
|
||||||
drawPointOnMap(x_pos, y_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::paintEvent(QPaintEvent *ev)
|
|
||||||
{
|
|
||||||
QPainter painter(this);
|
|
||||||
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
|
||||||
|
|
||||||
// Screen Ratio
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
|
|
||||||
// Paint Map
|
|
||||||
const double zoomLevel = static_cast<double>(zoomPercent) / 100;
|
|
||||||
const QSize mapImageSize = mapImage.size();
|
|
||||||
const QPointF mapImageMid(static_cast<double>(mapImageSize.width()) / 2, static_cast<double>(mapImageSize.height()) / 2);
|
|
||||||
const QSizeF srcImageSize(static_cast<double>(mapImageSize.width()) / zoomLevel , static_cast<double>(mapImageSize.height()) / zoomLevel);
|
|
||||||
const QPointF mapImageTopLeft(mapImageMid.x() - (srcImageSize.width() / 2), mapImageMid.y() - (srcImageSize.height() / 2));
|
|
||||||
const QPointF mapImageBottomRight(mapImageMid.x() + (srcImageSize.width() / 2), mapImageMid.y() + (srcImageSize.height() / 2));
|
|
||||||
painter.drawImage(QRect(QPoint(0, 0), size()), mapImage, QRectF(mapImageTopLeft, mapImageBottomRight));
|
|
||||||
|
|
||||||
// Paint Marker
|
|
||||||
QSize mapPixelSize = size();
|
|
||||||
int pointMarkerSize = 8 * screenRatio;
|
|
||||||
int pointMarkerHalfSize = pointMarkerSize / 2;
|
|
||||||
double xpos_mp, ypos_mp;
|
|
||||||
if (p_isCayoPerico) {
|
|
||||||
double xpos_per = xpos_new - 3560; // correct X in reserve
|
|
||||||
double ypos_per = ypos_new + 3980; // correct y in reserve
|
|
||||||
xpos_per = xpos_per / 2340; // divide 100% for X
|
|
||||||
ypos_per = ypos_per / -2340; // divide 100% for Y
|
|
||||||
xpos_mp = xpos_per * mapPixelSize.width(); // locate window width pos
|
|
||||||
ypos_mp = ypos_per * mapPixelSize.height(); // locate window height pos
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
double xpos_per = xpos_new + 4000; // correct X in reserve
|
|
||||||
double ypos_per = ypos_new - 8000; // correct y in reserve
|
|
||||||
xpos_per = xpos_per / 10000; // divide 100% for X
|
|
||||||
ypos_per = ypos_per / -12000; // divide 100% for Y
|
|
||||||
xpos_mp = xpos_per * mapPixelSize.width(); // locate window width pos
|
|
||||||
ypos_mp = ypos_per * mapPixelSize.height(); // locate window height pos
|
|
||||||
}
|
|
||||||
QPointF pointMarkerPos(xpos_mp, ypos_mp);
|
|
||||||
if (screenRatioPR != 1) {
|
|
||||||
pointMarkerPos.setX(pointMarkerPos.x() - pointMarkerHalfSize + screenRatioPR);
|
|
||||||
pointMarkerPos.setY(pointMarkerPos.y() - pointMarkerHalfSize + screenRatioPR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pointMarkerPos.setX(pointMarkerPos.x() - pointMarkerHalfSize);
|
|
||||||
pointMarkerPos.setY(pointMarkerPos.y() - pointMarkerHalfSize);
|
|
||||||
}
|
|
||||||
QPixmap mapMarkerPixmap = IconLoader::loadingPointmakerIcon().pixmap(QSize(pointMarkerSize, pointMarkerSize));
|
|
||||||
painter.drawPixmap(pointMarkerPos, mapMarkerPixmap);
|
|
||||||
|
|
||||||
QDialog::paintEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::mouseMoveEvent(QMouseEvent *ev)
|
|
||||||
{
|
|
||||||
if (changeMode && ev->buttons() & Qt::LeftButton) {
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
const QPointF localPos = ev->position();
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
const QPointF localPos = ev->localPos();
|
|
||||||
#else
|
|
||||||
const QPointF localPos = ev->posF();
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
if (screenRatioPR != 1) {
|
|
||||||
updatePosFromEvent(localPos.x() - screenRatioPR, localPos.y() - screenRatioPR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updatePosFromEvent(localPos.x(), localPos.y());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
updatePosFromEvent(localPos.x(), localPos.y());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (dragStart && ev->buttons() & Qt::LeftButton) {
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
const QPointF dragNewPosition = ev->position();
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
const QPointF dragNewPosition = ev->localPos();
|
|
||||||
#else
|
|
||||||
const QPointF dragNewPosition = ev->posF();
|
|
||||||
#endif
|
|
||||||
mapDiffPosition = dragNewPosition - dragPosition + mapDiffPosition;
|
|
||||||
dragPosition = dragNewPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::mousePressEvent(QMouseEvent *ev)
|
|
||||||
{
|
|
||||||
if (!changeMode && ev->button() == Qt::LeftButton) {
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
dragPosition = ev->position();
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
dragPosition = ev->localPos();
|
|
||||||
#else
|
|
||||||
dragPosition = ev->posF();
|
|
||||||
#endif
|
|
||||||
dragStart = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::mouseReleaseEvent(QMouseEvent *ev)
|
|
||||||
{
|
|
||||||
if (changeMode && ev->button() == Qt::LeftButton) {
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
const QPointF localPos = ev->position();
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
const QPointF localPos = ev->localPos();
|
|
||||||
#else
|
|
||||||
const QPointF localPos = ev->posF();
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
if (screenRatioPR != 1) {
|
|
||||||
updatePosFromEvent(localPos.x() - screenRatioPR, localPos.y() - screenRatioPR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updatePosFromEvent(localPos.x(), localPos.y());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
updatePosFromEvent(localPos.x(), localPos.y());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (dragStart && ev->button() == Qt::LeftButton) {
|
|
||||||
dragStart = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::wheelEvent(QWheelEvent *ev)
|
|
||||||
{
|
|
||||||
#ifdef GTA5SYNC_EXPERIMENTAL
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
const QPoint numPixels = ev->pixelDelta();
|
|
||||||
const QPoint numDegrees = ev->angleDelta();
|
|
||||||
#else
|
|
||||||
QPoint numDegrees;
|
|
||||||
if (ev->orientation() == Qt::Horizontal) {
|
|
||||||
numDegrees.setX(ev->delta());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
numDegrees.setY(ev->delta());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
if (!numPixels.isNull()) {
|
|
||||||
if (numPixels.y() < 0 && zoomPercent != 100) {
|
|
||||||
zoomPercent = zoomPercent - 10;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
else if (numPixels.y() > 0 && zoomPercent != 400) {
|
|
||||||
zoomPercent = zoomPercent + 10;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!numDegrees.isNull()) {
|
|
||||||
if (numDegrees.y() < 0 && zoomPercent != 100) {
|
|
||||||
zoomPercent = zoomPercent - 10;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
else if (numDegrees.y() > 0 && zoomPercent != 400) {
|
|
||||||
zoomPercent = zoomPercent + 10;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Q_UNUSED(ev)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::on_cmdChange_clicked()
|
|
||||||
{
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
int pointMakerSize = 8 * screenRatio;
|
|
||||||
QPixmap pointMakerPixmap = IconLoader::loadingPointmakerIcon().pixmap(QSize(pointMakerSize, pointMakerSize));
|
|
||||||
QCursor pointMakerCursor(pointMakerPixmap);
|
|
||||||
ui->cmdDone->setVisible(true);
|
|
||||||
ui->cmdApply->setVisible(false);
|
|
||||||
ui->cmdChange->setVisible(false);
|
|
||||||
ui->cmdRevert->setVisible(false);
|
|
||||||
|
|
||||||
setCursor(pointMakerCursor);
|
|
||||||
changeMode = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::on_cmdDone_clicked()
|
|
||||||
{
|
|
||||||
ui->cmdDone->setVisible(false);
|
|
||||||
ui->cmdChange->setVisible(true);
|
|
||||||
if (xpos_new != xpos_old || ypos_new != ypos_old) {
|
|
||||||
ui->cmdApply->setVisible(true);
|
|
||||||
ui->cmdRevert->setVisible(true);
|
|
||||||
}
|
|
||||||
setCursor(Qt::ArrowCursor);
|
|
||||||
changeMode = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::on_cmdApply_clicked()
|
|
||||||
{
|
|
||||||
propUpdate = true;
|
|
||||||
xpos_old = xpos_new;
|
|
||||||
ypos_old = ypos_new;
|
|
||||||
ui->cmdApply->setVisible(false);
|
|
||||||
ui->cmdRevert->setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::on_cmdRevert_clicked()
|
|
||||||
{
|
|
||||||
drawPointOnMap(xpos_old, ypos_old);
|
|
||||||
ui->cmdApply->setVisible(false);
|
|
||||||
ui->cmdRevert->setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MapLocationDialog::propUpdated()
|
|
||||||
{
|
|
||||||
return propUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
double MapLocationDialog::getXpos()
|
|
||||||
{
|
|
||||||
return xpos_old;
|
|
||||||
}
|
|
||||||
|
|
||||||
double MapLocationDialog::getYpos()
|
|
||||||
{
|
|
||||||
return ypos_old;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::on_cmdClose_clicked()
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2017-2021 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef MAPLOCATIONDIALOG_H
|
|
||||||
#define MAPLOCATIONDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class MapLocationDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MapLocationDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit MapLocationDialog(double x, double y, QWidget *parent = 0);
|
|
||||||
void drawPointOnMap(double x, double y);
|
|
||||||
void setCayoPerico(bool isCayoPerico);
|
|
||||||
bool propUpdated();
|
|
||||||
double getXpos();
|
|
||||||
double getYpos();
|
|
||||||
~MapLocationDialog();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *ev);
|
|
||||||
void mouseMoveEvent(QMouseEvent *ev);
|
|
||||||
void mousePressEvent(QMouseEvent *ev);
|
|
||||||
void mouseReleaseEvent(QMouseEvent *ev);
|
|
||||||
void wheelEvent(QWheelEvent *ev);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void on_cmdApply_clicked();
|
|
||||||
void on_cmdDone_clicked();
|
|
||||||
void on_cmdClose_clicked();
|
|
||||||
void on_cmdChange_clicked();
|
|
||||||
void on_cmdRevert_clicked();
|
|
||||||
void updatePosFromEvent(double x, double y);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int zoomPercent;
|
|
||||||
double xpos_old;
|
|
||||||
double ypos_old;
|
|
||||||
double xpos_new;
|
|
||||||
double ypos_new;
|
|
||||||
bool dragStart;
|
|
||||||
bool propUpdate;
|
|
||||||
bool changeMode;
|
|
||||||
bool p_isCayoPerico;
|
|
||||||
QImage mapImage;
|
|
||||||
QPointF dragPosition;
|
|
||||||
QPointF mapDiffPosition;
|
|
||||||
Ui::MapLocationDialog *ui;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MAPLOCATIONDIALOG_H
|
|
||||||
|
|
@ -1,238 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>MapLocationDialog</class>
|
|
||||||
<widget class="QDialog" name="MapLocationDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>500</width>
|
|
||||||
<height>600</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>500</width>
|
|
||||||
<height>600</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>500</width>
|
|
||||||
<height>600</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Snapmatic Map Viewer</string>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">QDialog#MapLocationDialog {
|
|
||||||
background-color: transparent;
|
|
||||||
}</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlMapPreview">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlMapDialog">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="vlPosLayout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labPos">
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">QLabel{
|
|
||||||
color: rgb(255, 255, 255);
|
|
||||||
}</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="vsPosSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="hsMapDialog">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="vlMapDialog">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdClose">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Close viewer</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Close</string>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="vsMapDialog">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdApply">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Apply new position</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Apply</string>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdRevert">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Revert old position</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Revert</string>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdChange">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Select new position</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Select</string>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdDone">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Quit select position</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Done</string>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2020 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "TranslationClass.h"
|
|
||||||
#include "MessageThread.h"
|
|
||||||
#include "AppEnv.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QUrlQuery>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
MessageThread::MessageThread(uint cacheId, QObject *parent) : QThread(parent), cacheId(cacheId)
|
|
||||||
{
|
|
||||||
threadRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageThread::run()
|
|
||||||
{
|
|
||||||
QEventLoop threadLoop;
|
|
||||||
|
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit()));
|
|
||||||
|
|
||||||
while (threadRunning) {
|
|
||||||
{
|
|
||||||
#ifdef GTA5SYNC_MOTD_WEBURL
|
|
||||||
QUrl motdWebUrl = QUrl(GTA5SYNC_MOTD_WEBURL);
|
|
||||||
#else
|
|
||||||
QUrl motdWebUrl = QUrl("https://motd.syping.de/gta5view-dev/");
|
|
||||||
#endif
|
|
||||||
QUrlQuery urlQuery(motdWebUrl);
|
|
||||||
urlQuery.addQueryItem("code", GTA5SYNC_BUILDCODE);
|
|
||||||
urlQuery.addQueryItem("cacheid", QString::number(cacheId));
|
|
||||||
urlQuery.addQueryItem("lang", Translator->getCurrentLanguage());
|
|
||||||
urlQuery.addQueryItem("version", GTA5SYNC_APPVER);
|
|
||||||
motdWebUrl.setQuery(urlQuery);
|
|
||||||
|
|
||||||
QNetworkAccessManager *netManager = new QNetworkAccessManager();
|
|
||||||
QNetworkRequest netRequest(motdWebUrl);
|
|
||||||
netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent());
|
|
||||||
QNetworkReply *netReply = netManager->get(netRequest);
|
|
||||||
|
|
||||||
QEventLoop downloadLoop;
|
|
||||||
QObject::connect(netManager, SIGNAL(finished(QNetworkReply*)), &downloadLoop, SLOT(quit()));
|
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit()));
|
|
||||||
QTimer::singleShot(60000, &downloadLoop, SLOT(quit()));
|
|
||||||
downloadLoop.exec();
|
|
||||||
|
|
||||||
if (netReply->isFinished()) {
|
|
||||||
QByteArray jsonContent = netReply->readAll();
|
|
||||||
QString headerData = QString::fromUtf8(netReply->rawHeader("gta5view"));
|
|
||||||
if (!headerData.isEmpty()) {
|
|
||||||
QMap<QString,QString> headerMap;
|
|
||||||
const QStringList headerVarList = headerData.split(';');
|
|
||||||
for (QString headerVar : headerVarList) {
|
|
||||||
QStringList varValueList = headerVar.split('=');
|
|
||||||
if (varValueList.length() >= 2) {
|
|
||||||
const QString variable = varValueList.at(0).trimmed();
|
|
||||||
varValueList.removeFirst();
|
|
||||||
const QString value = varValueList.join('=');
|
|
||||||
headerMap.insert(variable, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (headerMap.value("update", "false") == "true") {
|
|
||||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonContent);
|
|
||||||
emit messagesArrived(jsonDocument.object());
|
|
||||||
}
|
|
||||||
if (headerMap.contains("cache")) {
|
|
||||||
bool uintOk;
|
|
||||||
uint cacheVal = headerMap.value("cache").toUInt(&uintOk);
|
|
||||||
if (uintOk) {
|
|
||||||
cacheId = cacheVal;
|
|
||||||
emit updateCacheId(cacheId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete netReply;
|
|
||||||
delete netManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimer::singleShot(300000, &threadLoop, SLOT(quit()));
|
|
||||||
threadLoop.exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageThread::terminateThread()
|
|
||||||
{
|
|
||||||
threadRunning = false;
|
|
||||||
emit threadTerminated();
|
|
||||||
}
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2020 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef MESSAGETHREAD_H
|
|
||||||
#define MESSAGETHREAD_H
|
|
||||||
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
class MessageThread : public QThread
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit MessageThread(uint cacheId, QObject *parent = 0);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void terminateThread();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool threadRunning;
|
|
||||||
uint cacheId;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void run();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void messagesArrived(const QJsonObject &messageObject);
|
|
||||||
void updateCacheId(uint cacheId);
|
|
||||||
void threadTerminated();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MESSAGETHREAD_H
|
|
||||||
573
OptionsDialog.cpp
Normal file → Executable file
573
OptionsDialog.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -18,69 +18,34 @@
|
||||||
|
|
||||||
#include "OptionsDialog.h"
|
#include "OptionsDialog.h"
|
||||||
#include "ui_OptionsDialog.h"
|
#include "ui_OptionsDialog.h"
|
||||||
#include "TranslationClass.h"
|
|
||||||
#include "StandardPaths.h"
|
#include "StandardPaths.h"
|
||||||
#include "UserInterface.h"
|
#include "UserInterface.h"
|
||||||
#include "wrapper.h"
|
|
||||||
#include "AppEnv.h"
|
#include "AppEnv.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
#include <QDesktopWidget>
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QStyleFactory>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QFontDialog>
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QClipboard>
|
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTimer>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
#include <QScreen>
|
|
||||||
#else
|
|
||||||
#include <QDesktopWidget>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
|
||||||
#include "TelemetryClass.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) :
|
OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) :
|
||||||
QDialog(parent), profileDB(profileDB),
|
QDialog(parent), profileDB(profileDB),
|
||||||
ui(new Ui::OptionsDialog)
|
ui(new Ui::OptionsDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup User Interface
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->tabWidget->setCurrentIndex(0);
|
ui->tabWidget->setCurrentIndex(0);
|
||||||
ui->labPicCustomRes->setVisible(false);
|
ui->labPicCustomRes->setVisible(false);
|
||||||
ui->cmdCancel->setDefault(true);
|
|
||||||
ui->cmdCancel->setFocus();
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
QRect desktopResolution = QApplication::desktop()->screenGeometry(parent);
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
QRect desktopResolution = QApplication::primaryScreen()->geometry();
|
|
||||||
int desktopSizeWidth = qRound((double)desktopResolution.width() * screenRatioPR);
|
|
||||||
int desktopSizeHeight = qRound((double)desktopResolution.height() * screenRatioPR);
|
|
||||||
#else
|
|
||||||
QRect desktopResolution = QApplication::desktop()->screenGeometry(this);
|
|
||||||
int desktopSizeWidth = desktopResolution.width();
|
int desktopSizeWidth = desktopResolution.width();
|
||||||
int desktopSizeHeight = desktopResolution.height();
|
int desktopSizeHeight = desktopResolution.height();
|
||||||
#endif
|
|
||||||
aspectRatio = Qt::KeepAspectRatio;
|
aspectRatio = Qt::KeepAspectRatio;
|
||||||
defExportSize = SnapmaticPicture::getSnapmaticResolution();
|
defExportSize = QSize(960, 536);
|
||||||
cusExportSize = defExportSize;
|
cusExportSize = defExportSize;
|
||||||
defaultQuality = 100;
|
defaultQuality = 100;
|
||||||
customQuality = 100;
|
customQuality = 100;
|
||||||
|
|
@ -92,127 +57,100 @@ OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) :
|
||||||
ui->rbPicDesktopRes->setText(ui->rbPicDesktopRes->text().arg(QString::number(desktopSizeWidth), QString::number(desktopSizeHeight)));
|
ui->rbPicDesktopRes->setText(ui->rbPicDesktopRes->text().arg(QString::number(desktopSizeWidth), QString::number(desktopSizeHeight)));
|
||||||
ui->rbPicDefaultRes->setText(ui->rbPicDefaultRes->text().arg(QString::number(defExportSize.width()), QString::number(defExportSize.height())));
|
ui->rbPicDefaultRes->setText(ui->rbPicDefaultRes->text().arg(QString::number(defExportSize.width()), QString::number(defExportSize.height())));
|
||||||
|
|
||||||
// Set Icon for OK Button
|
|
||||||
if (QIcon::hasThemeIcon("dialog-ok")) {
|
|
||||||
ui->cmdOK->setIcon(QIcon::fromTheme("dialog-ok"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-ok")) {
|
|
||||||
ui->cmdOK->setIcon(QIcon::fromTheme("gtk-ok"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Icon for Cancel Button
|
|
||||||
if (QIcon::hasThemeIcon("dialog-cancel")) {
|
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-cancel")) {
|
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Icon for Copy Button
|
|
||||||
if (QIcon::hasThemeIcon("edit-copy")) {
|
|
||||||
ui->cmdCopyStatsID->setIcon(QIcon::fromTheme("edit-copy"));
|
|
||||||
}
|
|
||||||
|
|
||||||
setupTreeWidget();
|
setupTreeWidget();
|
||||||
setupLanguageBox();
|
setupLanguageBox();
|
||||||
setupRadioButtons();
|
setupRadioButtons();
|
||||||
setupDefaultProfile();
|
setupDefaultProfile();
|
||||||
setupPictureSettings();
|
setupPictureSettings();
|
||||||
setupCustomGTAFolder();
|
setupCustomGTAFolder();
|
||||||
setupInterfaceSettings();
|
|
||||||
setupStatisticsSettings();
|
|
||||||
setupSnapmaticPictureViewer();
|
setupSnapmaticPictureViewer();
|
||||||
setupWindowsGameSettings();
|
|
||||||
|
|
||||||
#ifndef Q_QS_ANDROID
|
this->setWindowTitle(windowTitle().arg(GTA5SYNC_APPSTR));
|
||||||
// DPI calculation
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
resize(435 * screenRatio, 405 * screenRatio);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ui->rbModern->setText(ui->rbModern->text().arg(GTA5SYNC_APPSTR));
|
|
||||||
ui->rbClassic->setText(ui->rbClassic->text().arg(GTA5SYNC_APPSTR));
|
|
||||||
setWindowTitle(windowTitle().arg(GTA5SYNC_APPSTR));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionsDialog::~OptionsDialog()
|
OptionsDialog::~OptionsDialog()
|
||||||
{
|
{
|
||||||
delete settings;
|
delete settings;
|
||||||
qDeleteAll(playerItems.begin(), playerItems.end());
|
foreach(QTreeWidgetItem *playerItem, playerItems)
|
||||||
playerItems.clear();
|
{
|
||||||
|
delete playerItem;
|
||||||
|
}
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::setupTreeWidget()
|
void OptionsDialog::setupTreeWidget()
|
||||||
{
|
{
|
||||||
const QStringList players = profileDB->getPlayers();
|
foreach(const QString &playerIDStr, profileDB->getPlayers())
|
||||||
if (players.length() != 0) {
|
{
|
||||||
for (auto it = players.constBegin(); it != players.constEnd(); it++) {
|
|
||||||
bool ok;
|
bool ok;
|
||||||
int playerID = it->toInt(&ok);
|
int playerID = playerIDStr.toInt(&ok);
|
||||||
if (ok) {
|
if (ok)
|
||||||
const QString playerName = profileDB->getPlayerName(playerID);
|
{
|
||||||
|
QString playerName = profileDB->getPlayerName(playerID);
|
||||||
|
|
||||||
QStringList playerTreeViewList;
|
QStringList playerTreeViewList;
|
||||||
playerTreeViewList += *it;
|
playerTreeViewList << playerIDStr;
|
||||||
playerTreeViewList += playerName;
|
playerTreeViewList << playerName;
|
||||||
|
|
||||||
QTreeWidgetItem *playerItem = new QTreeWidgetItem(playerTreeViewList);
|
QTreeWidgetItem *playerItem = new QTreeWidgetItem(playerTreeViewList);
|
||||||
ui->twPlayers->addTopLevelItem(playerItem);
|
ui->twPlayers->addTopLevelItem(playerItem);
|
||||||
playerItems += playerItem;
|
playerItems.append(playerItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ui->twPlayers->sortItems(1, Qt::AscendingOrder);
|
ui->twPlayers->sortItems(1, Qt::AscendingOrder);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabPlayers));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::setupLanguageBox()
|
void OptionsDialog::setupLanguageBox()
|
||||||
{
|
{
|
||||||
settings->beginGroup("Interface");
|
settings->beginGroup("Interface");
|
||||||
currentLanguage = settings->value("Language","System").toString();
|
currentLanguage = settings->value("Language","System").toString();
|
||||||
currentAreaLanguage = settings->value("AreaLanguage", "Auto").toString();
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
const QString cbSysStr = tr("%1 (Language priority)", "First language a person can talk with a different person/application. \"Native\" or \"Not Native\".").arg(tr("System",
|
QStringList langList = QLocale::system().name().split("_");
|
||||||
"System in context of System default"));
|
if (langList.length() > 0)
|
||||||
#ifdef Q_OS_WIN
|
{
|
||||||
QString cbAutoStr;
|
QString cbSysStr = tr("%1 (%2 if available)", "System like PC System = %1, System Language like Deutsch = %2").arg(tr("System",
|
||||||
if (AppEnv::getGameLanguage(AppEnv::getGameVersion()) != GameLanguage::Undefined) {
|
"System like PC System"), QLocale::languageToString(QLocale(langList.at(0)).language()));
|
||||||
cbAutoStr = tr("%1 (Game language)", "Next closest language compared to the Game settings").arg(tr("Auto", "Automatic language choice."));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cbAutoStr = tr("%1 (Closest to Interface)", "Next closest language compared to the Interface").arg(tr("Auto", "Automatic language choice."));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const QString cbAutoStr = tr("%1 (Closest to Interface)", "Next closest language compared to the Interface").arg(tr("Auto", "Automatic language choice."));
|
|
||||||
#endif
|
|
||||||
ui->cbLanguage->addItem(cbSysStr, "System");
|
ui->cbLanguage->addItem(cbSysStr, "System");
|
||||||
ui->cbAreaLanguage->addItem(cbAutoStr, "Auto");
|
}
|
||||||
|
|
||||||
QStringList availableLanguages;
|
QString cbEngStr = "English (English) [en]";
|
||||||
availableLanguages << QString("en_GB");
|
ui->cbLanguage->addItem(QIcon::fromTheme("flag-us"), cbEngStr, "en");
|
||||||
#ifndef GTA5SYNC_QCONF
|
if (currentLanguage == "en")
|
||||||
availableLanguages << TranslationClass::listTranslations(AppEnv::getExLangFolder());
|
{
|
||||||
|
#if QT_VERSION >= 0x050000
|
||||||
|
ui->cbLanguage->setCurrentText(cbEngStr);
|
||||||
|
#else
|
||||||
|
int indexOfEnglish = ui->cbLanguage->findText(cbEngStr);
|
||||||
|
ui->cbLanguage->setCurrentIndex(indexOfEnglish);
|
||||||
#endif
|
#endif
|
||||||
availableLanguages << TranslationClass::listTranslations(AppEnv::getInLangFolder());
|
}
|
||||||
availableLanguages.removeDuplicates();
|
|
||||||
availableLanguages.sort();
|
QDir langDir;
|
||||||
|
langDir.setNameFilters(QStringList("gta5sync_*.qm"));
|
||||||
|
langDir.setPath(AppEnv::getLangFolder());
|
||||||
|
QStringList langFiles;
|
||||||
|
langFiles << langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort);
|
||||||
|
langDir.setPath(":/tr");
|
||||||
|
langFiles << langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort);
|
||||||
|
langFiles.removeDuplicates();
|
||||||
|
|
||||||
|
foreach(const QString &langFile, langFiles)
|
||||||
|
{
|
||||||
|
QString lang = langFile;
|
||||||
|
lang.remove("gta5sync_");
|
||||||
|
lang.remove(".qm");
|
||||||
|
|
||||||
for (const QString &lang : qAsConst(availableLanguages)) {
|
|
||||||
QLocale langLocale(lang);
|
QLocale langLocale(lang);
|
||||||
const QString cbLangStr = langLocale.nativeLanguageName() % " (" % langLocale.nativeCountryName() % ") [" % lang % "]";
|
QString languageNameInternational = QLocale::languageToString(langLocale.language());
|
||||||
const QString langIconPath = AppEnv::getImagesFolder() % "/flag-" % TranslationClass::getCountryCode(langLocale) % ".png";
|
QString languageNameNative = langLocale.nativeLanguageName();
|
||||||
|
|
||||||
if (QFile::exists(langIconPath)) {
|
QString cbLangStr = languageNameNative + " (" + languageNameInternational + ") [" + lang + "]";
|
||||||
ui->cbLanguage->addItem(QIcon(langIconPath), cbLangStr, lang);
|
QString langIconStr = "flag-" + lang;
|
||||||
}
|
|
||||||
else {
|
ui->cbLanguage->addItem(QIcon::fromTheme(langIconStr), cbLangStr, lang);
|
||||||
ui->cbLanguage->addItem(cbLangStr, lang);
|
if (currentLanguage == lang)
|
||||||
}
|
{
|
||||||
if (currentLanguage == lang) {
|
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
ui->cbLanguage->setCurrentText(cbLangStr);
|
ui->cbLanguage->setCurrentText(cbLangStr);
|
||||||
#else
|
#else
|
||||||
|
|
@ -221,53 +159,6 @@ void OptionsDialog::setupLanguageBox()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString aCurrentLanguage = QString("en_GB");
|
|
||||||
if (Translator->isLanguageLoaded())
|
|
||||||
aCurrentLanguage = Translator->getCurrentLanguage();
|
|
||||||
QLocale currentLocale = QLocale(aCurrentLanguage);
|
|
||||||
ui->labCurrentLanguage->setText(tr("Current: %1").arg(currentLocale.nativeLanguageName() % " (" % currentLocale.nativeCountryName() % ") [" % aCurrentLanguage % "]"));
|
|
||||||
|
|
||||||
availableLanguages.clear();
|
|
||||||
availableLanguages << TranslationClass::listAreaTranslations();
|
|
||||||
availableLanguages.removeDuplicates();
|
|
||||||
availableLanguages.sort();
|
|
||||||
|
|
||||||
for (const QString &lang : qAsConst(availableLanguages)) {
|
|
||||||
// correcting Language Location if possible
|
|
||||||
QString aLang = lang;
|
|
||||||
if (QFile::exists(":/global/global." % lang % ".loc")) {
|
|
||||||
QFile locFile(":/global/global." % lang % ".loc");
|
|
||||||
if (locFile.open(QFile::ReadOnly)) {
|
|
||||||
aLang = QString::fromUtf8(locFile.readLine()).trimmed();
|
|
||||||
locFile.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QLocale langLocale(aLang);
|
|
||||||
const QString cbLangStr = langLocale.nativeLanguageName() % " (" % langLocale.nativeCountryName() % ") [" % aLang % "]";
|
|
||||||
ui->cbAreaLanguage->addItem(cbLangStr, lang);
|
|
||||||
if (currentAreaLanguage == lang) {
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
ui->cbAreaLanguage->setCurrentText(cbLangStr);
|
|
||||||
#else
|
|
||||||
int indexOfLang = ui->cbAreaLanguage->findText(cbLangStr);
|
|
||||||
ui->cbAreaLanguage->setCurrentIndex(indexOfLang);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString aCurrentAreaLanguage = Translator->getCurrentAreaLanguage();
|
|
||||||
if (QFile::exists(":/global/global." % aCurrentAreaLanguage % ".loc")) {
|
|
||||||
qDebug() << "locFile found";
|
|
||||||
QFile locFile(":/global/global." % aCurrentAreaLanguage % ".loc");
|
|
||||||
if (locFile.open(QFile::ReadOnly)) {
|
|
||||||
aCurrentAreaLanguage = QString::fromUtf8(locFile.readLine()).trimmed();
|
|
||||||
locFile.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentLocale = QLocale(aCurrentAreaLanguage);
|
|
||||||
ui->labCurrentAreaLanguage->setText(tr("Current: %1").arg(currentLocale.nativeLanguageName() % " (" % currentLocale.nativeCountryName() % ") [" % aCurrentAreaLanguage % "]"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::setupRadioButtons()
|
void OptionsDialog::setupRadioButtons()
|
||||||
|
|
@ -277,69 +168,21 @@ void OptionsDialog::setupRadioButtons()
|
||||||
contentMode = settings->value("ContentMode", 0).toInt(&contentModeOk);
|
contentMode = settings->value("ContentMode", 0).toInt(&contentModeOk);
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
if (contentModeOk) {
|
if (contentModeOk)
|
||||||
switch (contentMode) {
|
|
||||||
case 0:
|
|
||||||
case 20:
|
|
||||||
ui->rbModern->setChecked(true);
|
|
||||||
ui->cbDoubleclick->setChecked(false);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
case 21:
|
|
||||||
ui->rbModern->setChecked(true);
|
|
||||||
ui->cbDoubleclick->setChecked(true);
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
ui->rbClassic->setChecked(true);
|
|
||||||
ui->cbDoubleclick->setChecked(false);
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
ui->rbClassic->setChecked(true);
|
|
||||||
ui->cbDoubleclick->setChecked(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::setupInterfaceSettings()
|
|
||||||
{
|
{
|
||||||
settings->beginGroup("Startup");
|
if (contentMode == 0)
|
||||||
const QString currentStyle = QApplication::style()->objectName();
|
{
|
||||||
const QString appStyle = settings->value("AppStyle", currentStyle).toString();
|
ui->rbOpenWithSC->setChecked(true);
|
||||||
bool customStyle = settings->value("CustomStyle", false).toBool();
|
|
||||||
const QStringList availableStyles = QStyleFactory::keys();
|
|
||||||
ui->cbStyleList->addItems(availableStyles);
|
|
||||||
if (availableStyles.contains(appStyle, Qt::CaseInsensitive)) {
|
|
||||||
// use 'for' for select to be sure it's case insensitive
|
|
||||||
int currentIndex = 0;
|
|
||||||
for (const QString ¤tStyleFF : availableStyles) {
|
|
||||||
if (currentStyleFF.toLower() == appStyle.toLower()) {
|
|
||||||
ui->cbStyleList->setCurrentIndex(currentIndex);
|
|
||||||
}
|
}
|
||||||
currentIndex++;
|
else if (contentMode == 1)
|
||||||
|
{
|
||||||
|
ui->rbOpenWithDC->setChecked(true);
|
||||||
|
}
|
||||||
|
else if (contentMode == 2)
|
||||||
|
{
|
||||||
|
ui->rbSelectWithSC->setChecked(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (availableStyles.contains(currentStyle, Qt::CaseInsensitive)) {
|
|
||||||
int currentIndex = 0;
|
|
||||||
for (const QString ¤tStyleFF : availableStyles) {
|
|
||||||
if (currentStyleFF.toLower() == currentStyle.toLower()) {
|
|
||||||
ui->cbStyleList->setCurrentIndex(currentIndex);
|
|
||||||
}
|
|
||||||
currentIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->cbDefaultStyle->setChecked(!customStyle);
|
|
||||||
ui->cbStyleList->setEnabled(customStyle);
|
|
||||||
const QFont currentFont = QApplication::font();
|
|
||||||
const QFont appFont = qvariant_cast<QFont>(settings->value("AppFont", currentFont));
|
|
||||||
bool customFont = settings->value("CustomFont", false).toBool();
|
|
||||||
ui->cbDefaultFont->setChecked(!customFont);
|
|
||||||
ui->cbFont->setEnabled(customFont);
|
|
||||||
ui->cbFont->setCurrentFont(appFont);
|
|
||||||
settings->endGroup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::on_cmdOK_clicked()
|
void OptionsDialog::on_cmdOK_clicked()
|
||||||
|
|
@ -353,30 +196,29 @@ void OptionsDialog::applySettings()
|
||||||
settings->beginGroup("Interface");
|
settings->beginGroup("Interface");
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
settings->setValue("Language", ui->cbLanguage->currentData());
|
settings->setValue("Language", ui->cbLanguage->currentData());
|
||||||
settings->setValue("AreaLanguage", ui->cbAreaLanguage->currentData());
|
|
||||||
#else
|
#else
|
||||||
settings->setValue("Language", ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()));
|
settings->setValue("Language", ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()));
|
||||||
settings->setValue("AreaLanguage", ui->cbAreaLanguage->itemData(ui->cbAreaLanguage->currentIndex()));
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef Q_OS_WIN
|
#ifdef GTA5SYNC_WIN
|
||||||
#if QT_VERSION >= 0x050200
|
#if QT_VERSION >= 0x050200
|
||||||
settings->setValue("NavigationBar", ui->cbSnapmaticNavigationBar->isChecked());
|
settings->setValue("NavigationBar", ui->cbSnapmaticNavigationBar->isChecked());
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
settings->setValue("NavigationBar", ui->cbSnapmaticNavigationBar->isChecked());
|
|
||||||
#endif
|
#endif
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
settings->beginGroup("Profile");
|
settings->beginGroup("Profile");
|
||||||
int newContentMode = 20;
|
int newContentMode = 0;
|
||||||
if (ui->rbModern->isChecked()) {
|
if (ui->rbOpenWithSC->isChecked())
|
||||||
newContentMode = 20;
|
{
|
||||||
|
newContentMode = 0;
|
||||||
}
|
}
|
||||||
else if (ui->rbClassic->isChecked()) {
|
else if (ui->rbOpenWithDC->isChecked())
|
||||||
newContentMode = 10;
|
{
|
||||||
|
newContentMode = 1;
|
||||||
}
|
}
|
||||||
if (ui->cbDoubleclick->isChecked()) {
|
else if (ui->rbSelectWithSC->isChecked())
|
||||||
newContentMode++;
|
{
|
||||||
|
newContentMode = 2;
|
||||||
}
|
}
|
||||||
settings->setValue("ContentMode", newContentMode);
|
settings->setValue("ContentMode", newContentMode);
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
|
|
@ -387,15 +229,18 @@ void OptionsDialog::applySettings()
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
settings->beginGroup("Pictures");
|
settings->beginGroup("Pictures");
|
||||||
if (ui->cbPicCustomQuality->isChecked()) {
|
if (ui->cbPicCustomQuality->isChecked())
|
||||||
|
{
|
||||||
settings->setValue("CustomQuality", ui->hsPicQuality->value());
|
settings->setValue("CustomQuality", ui->hsPicQuality->value());
|
||||||
}
|
}
|
||||||
settings->setValue("CustomQualityEnabled", ui->cbPicCustomQuality->isChecked());
|
settings->setValue("CustomQualityEnabled", ui->cbPicCustomQuality->isChecked());
|
||||||
QString sizeMode = "Default";
|
QString sizeMode = "Default";
|
||||||
if (ui->rbPicDesktopRes->isChecked()) {
|
if (ui->rbPicDesktopRes->isChecked())
|
||||||
|
{
|
||||||
sizeMode = "Desktop";
|
sizeMode = "Desktop";
|
||||||
}
|
}
|
||||||
else if (ui->rbPicCustomRes->isChecked()) {
|
else if (ui->rbPicCustomRes->isChecked())
|
||||||
|
{
|
||||||
sizeMode = "Custom";
|
sizeMode = "Custom";
|
||||||
settings->setValue("CustomSize", QSize(ui->sbPicExportWidth->value(), ui->sbPicExportHeight->value()));
|
settings->setValue("CustomSize", QSize(ui->sbPicExportWidth->value(), ui->sbPicExportHeight->value()));
|
||||||
}
|
}
|
||||||
|
|
@ -409,72 +254,25 @@ void OptionsDialog::applySettings()
|
||||||
settings->setValue("force", forceCustomFolder);
|
settings->setValue("force", forceCustomFolder);
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
bool defaultStyle = ui->cbDefaultStyle->isChecked();
|
#if QT_VERSION >= 0x050000
|
||||||
settings->beginGroup("Startup");
|
emit settingsApplied(newContentMode, ui->cbLanguage->currentData().toString());
|
||||||
if (!defaultStyle) {
|
|
||||||
QString newStyle = ui->cbStyleList->currentText();
|
|
||||||
settings->setValue("CustomStyle", true);
|
|
||||||
settings->setValue("AppStyle", newStyle);
|
|
||||||
QApplication::setStyle(QStyleFactory::create(newStyle));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
settings->setValue("CustomStyle", false);
|
|
||||||
}
|
|
||||||
bool defaultFont = ui->cbDefaultFont->isChecked();
|
|
||||||
if (!defaultFont) {
|
|
||||||
QFont newFont = ui->cbFont->currentFont();
|
|
||||||
settings->setValue("CustomFont", true);
|
|
||||||
settings->setValue("AppFont", newFont);
|
|
||||||
QApplication::setFont(newFont);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
settings->setValue("CustomFont", false);
|
|
||||||
}
|
|
||||||
settings->endGroup();
|
|
||||||
|
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
|
||||||
settings->beginGroup("Telemetry");
|
|
||||||
settings->setValue("PushAppConf", ui->cbAppConfigStats->isChecked());
|
|
||||||
settings->setValue("PushUsageData", ui->cbUsageData->isChecked());
|
|
||||||
if (!Telemetry->isStateForced()) { settings->setValue("IsEnabled", ui->cbParticipateStats->isChecked()); }
|
|
||||||
settings->endGroup();
|
|
||||||
Telemetry->refresh();
|
|
||||||
Telemetry->work();
|
|
||||||
if (ui->cbUsageData->isChecked() && Telemetry->canPush()) {
|
|
||||||
QJsonDocument jsonDocument;
|
|
||||||
QJsonObject jsonObject;
|
|
||||||
jsonObject["Type"] = "SettingsUpdated";
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["UpdateTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
#else
|
||||||
jsonObject["UpdateTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
emit settingsApplied(newContentMode, ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()).toString());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
bool languageChanged = ui->cbLanguage->currentData().toString() != currentLanguage;
|
bool languageChanged = ui->cbLanguage->currentData().toString() != currentLanguage;
|
||||||
bool languageAreaChanged = ui->cbAreaLanguage->currentData().toString() != currentAreaLanguage;
|
|
||||||
#else
|
#else
|
||||||
bool languageChanged = ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentLanguage;
|
bool languageChanged = ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentLanguage;
|
||||||
bool languageAreaChanged = ui->cbAreaLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentAreaLanguage;
|
|
||||||
#endif
|
#endif
|
||||||
if (languageChanged) {
|
|
||||||
Translator->unloadTranslation(qApp);
|
|
||||||
Translator->initUserLanguage();
|
|
||||||
Translator->loadTranslation(qApp);
|
|
||||||
}
|
|
||||||
else if (languageAreaChanged) {
|
|
||||||
Translator->initUserLanguage();
|
|
||||||
}
|
|
||||||
|
|
||||||
settings->sync();
|
if ((forceCustomFolder && ui->txtFolder->text() != currentCFolder) || (forceCustomFolder != currentFFolder && forceCustomFolder))
|
||||||
emit settingsApplied(newContentMode, languageChanged);
|
{
|
||||||
|
QMessageBox::information(this, tr("%1", "%1").arg(GTA5SYNC_APPSTR), tr("The new Custom Folder will initialize after you restart %1.").arg(GTA5SYNC_APPSTR));
|
||||||
if ((forceCustomFolder && ui->txtFolder->text() != currentCFolder) || (forceCustomFolder != currentFFolder && forceCustomFolder)) {
|
}
|
||||||
QMessageBox::information(this, tr("%1", "%1").arg(GTA5SYNC_APPSTR), tr("The new Custom Folder will initialise after you restart %1.").arg(GTA5SYNC_APPSTR));
|
if (languageChanged)
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("%1", "%1").arg(GTA5SYNC_APPSTR), tr("The language change will take effect after you restart %1.").arg(GTA5SYNC_APPSTR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -488,11 +286,13 @@ void OptionsDialog::setupDefaultProfile()
|
||||||
ui->cbProfiles->addItem(cbNoneStr, "");
|
ui->cbProfiles->addItem(cbNoneStr, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::commitProfiles(const QStringList &profiles)
|
void OptionsDialog::commitProfiles(QStringList profiles)
|
||||||
|
{
|
||||||
|
foreach(const QString &profile, profiles)
|
||||||
{
|
{
|
||||||
for (const QString &profile : profiles) {
|
|
||||||
ui->cbProfiles->addItem(tr("Profile: %1").arg(profile), profile);
|
ui->cbProfiles->addItem(tr("Profile: %1").arg(profile), profile);
|
||||||
if (defaultProfile == profile) {
|
if (defaultProfile == profile)
|
||||||
|
{
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
ui->cbProfiles->setCurrentText(tr("Profile: %1").arg(profile));
|
ui->cbProfiles->setCurrentText(tr("Profile: %1").arg(profile));
|
||||||
#else
|
#else
|
||||||
|
|
@ -530,7 +330,8 @@ void OptionsDialog::setupPictureSettings()
|
||||||
|
|
||||||
// Quality Settings
|
// Quality Settings
|
||||||
customQuality = settings->value("CustomQuality", defaultQuality).toInt();
|
customQuality = settings->value("CustomQuality", defaultQuality).toInt();
|
||||||
if (customQuality < 1 || customQuality > 100) {
|
if (customQuality < 1 || customQuality > 100)
|
||||||
|
{
|
||||||
customQuality = 100;
|
customQuality = 100;
|
||||||
}
|
}
|
||||||
ui->hsPicQuality->setValue(customQuality);
|
ui->hsPicQuality->setValue(customQuality);
|
||||||
|
|
@ -538,132 +339,56 @@ void OptionsDialog::setupPictureSettings()
|
||||||
|
|
||||||
// Size Settings
|
// Size Settings
|
||||||
cusExportSize = settings->value("CustomSize", defExportSize).toSize();
|
cusExportSize = settings->value("CustomSize", defExportSize).toSize();
|
||||||
if (cusExportSize.width() > 3840) {
|
if (cusExportSize.width() > 3840)
|
||||||
|
{
|
||||||
cusExportSize.setWidth(3840);
|
cusExportSize.setWidth(3840);
|
||||||
}
|
}
|
||||||
else if (cusExportSize.height() > 2160) {
|
else if (cusExportSize.height() > 2160)
|
||||||
|
{
|
||||||
cusExportSize.setHeight(2160);
|
cusExportSize.setHeight(2160);
|
||||||
}
|
}
|
||||||
if (cusExportSize.width() < 1) {
|
if (cusExportSize.width() < 1)
|
||||||
|
{
|
||||||
cusExportSize.setWidth(1);
|
cusExportSize.setWidth(1);
|
||||||
}
|
}
|
||||||
else if (cusExportSize.height() < 1) {
|
else if (cusExportSize.height() < 1)
|
||||||
|
{
|
||||||
cusExportSize.setHeight(1);
|
cusExportSize.setHeight(1);
|
||||||
}
|
}
|
||||||
ui->sbPicExportWidth->setValue(cusExportSize.width());
|
ui->sbPicExportWidth->setValue(cusExportSize.width());
|
||||||
ui->sbPicExportHeight->setValue(cusExportSize.height());
|
ui->sbPicExportHeight->setValue(cusExportSize.height());
|
||||||
|
|
||||||
QString sizeMode = settings->value("ExportSizeMode", "Default").toString();
|
QString sizeMode = settings->value("ExportSizeMode", "Default").toString();
|
||||||
if (sizeMode == "Desktop") {
|
if (sizeMode == "Desktop")
|
||||||
|
{
|
||||||
ui->rbPicDesktopRes->setChecked(true);
|
ui->rbPicDesktopRes->setChecked(true);
|
||||||
}
|
}
|
||||||
else if (sizeMode == "Custom") {
|
else if (sizeMode == "Custom")
|
||||||
|
{
|
||||||
ui->rbPicCustomRes->setChecked(true);
|
ui->rbPicCustomRes->setChecked(true);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->rbPicDefaultRes->setChecked(true);
|
ui->rbPicDefaultRes->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
aspectRatio = (Qt::AspectRatioMode)settings->value("AspectRatio", Qt::KeepAspectRatio).toInt();
|
aspectRatio = (Qt::AspectRatioMode)settings->value("AspectRatio", Qt::KeepAspectRatio).toInt();
|
||||||
if (aspectRatio == Qt::IgnoreAspectRatio) {
|
if (aspectRatio == Qt::IgnoreAspectRatio)
|
||||||
|
{
|
||||||
ui->cbIgnoreAspectRatio->setChecked(true);
|
ui->cbIgnoreAspectRatio->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::setupStatisticsSettings()
|
|
||||||
{
|
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
|
||||||
ui->cbParticipateStats->setText(tr("Participate in %1 User Statistics").arg(GTA5SYNC_APPSTR));
|
|
||||||
ui->labUserStats->setText(QString("<a href=\"%2\">%1</a>").arg(tr("View %1 User Statistics Online").arg(GTA5SYNC_APPSTR), TelemetryClass::getWebURL().toString()));
|
|
||||||
|
|
||||||
settings->beginGroup("Telemetry");
|
|
||||||
ui->cbParticipateStats->setChecked(Telemetry->isEnabled());
|
|
||||||
ui->cbAppConfigStats->setChecked(settings->value("PushAppConf", false).toBool());
|
|
||||||
ui->cbUsageData->setChecked(settings->value("PushUsageData", false).toBool());
|
|
||||||
settings->endGroup();
|
|
||||||
|
|
||||||
if (Telemetry->isStateForced()) {
|
|
||||||
ui->cbParticipateStats->setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Telemetry->isRegistered()) {
|
|
||||||
ui->labParticipationID->setText(tr("Participation ID: %1").arg(Telemetry->getRegisteredID()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->labParticipationID->setText(tr("Participation ID: %1").arg(tr("Not registered")));
|
|
||||||
ui->cmdCopyStatsID->setVisible(false);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabStats));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::setupWindowsGameSettings()
|
|
||||||
{
|
|
||||||
#ifdef GTA5SYNC_GAME
|
|
||||||
GameVersion gameVersion = AppEnv::getGameVersion();
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if (gameVersion != GameVersion::NoVersion) {
|
|
||||||
if (gameVersion == GameVersion::SocialClubVersion) {
|
|
||||||
ui->gbSteam->setDisabled(true);
|
|
||||||
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
|
||||||
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No"))));
|
|
||||||
if (AppEnv::getGameLanguage(GameVersion::SocialClubVersion) != GameLanguage::Undefined) {
|
|
||||||
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SocialClubVersion))).nativeLanguageName()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(tr("OS defined")));
|
|
||||||
}
|
|
||||||
ui->labSteamLanguage->setVisible(false);
|
|
||||||
}
|
|
||||||
else if (gameVersion == GameVersion::SteamVersion) {
|
|
||||||
ui->gbSocialClub->setDisabled(true);
|
|
||||||
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No"))));
|
|
||||||
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
|
||||||
ui->labSocialClubLanguage->setVisible(false);
|
|
||||||
if (AppEnv::getGameLanguage(GameVersion::SteamVersion) != GameLanguage::Undefined) {
|
|
||||||
ui->labSteamLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SteamVersion))).nativeLanguageName()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->labSteamLanguage->setText(tr("Language: %1").arg(tr("Steam defined")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
|
||||||
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
|
||||||
if (AppEnv::getGameLanguage(GameVersion::SocialClubVersion) != GameLanguage::Undefined) {
|
|
||||||
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SocialClubVersion))).nativeLanguageName()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(tr("OS defined")));
|
|
||||||
}
|
|
||||||
if (AppEnv::getGameLanguage(GameVersion::SteamVersion) != GameLanguage::Undefined) {
|
|
||||||
ui->labSteamLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SteamVersion))).nativeLanguageName()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->labSteamLanguage->setText(tr("Language: %1").arg(tr("Steam defined")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabGame));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabGame));
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabGame));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::on_cbIgnoreAspectRatio_toggled(bool checked)
|
void OptionsDialog::on_cbIgnoreAspectRatio_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked)
|
||||||
|
{
|
||||||
aspectRatio = Qt::IgnoreAspectRatio;
|
aspectRatio = Qt::IgnoreAspectRatio;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
aspectRatio = Qt::KeepAspectRatio;
|
aspectRatio = Qt::KeepAspectRatio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -675,7 +400,8 @@ void OptionsDialog::setupCustomGTAFolder()
|
||||||
settings->beginGroup("dir");
|
settings->beginGroup("dir");
|
||||||
currentCFolder = settings->value("dir", "").toString();
|
currentCFolder = settings->value("dir", "").toString();
|
||||||
currentFFolder = settings->value("force", false).toBool();
|
currentFFolder = settings->value("force", false).toBool();
|
||||||
if (currentCFolder == "" && ok) {
|
if (currentCFolder == "" && ok)
|
||||||
|
{
|
||||||
currentCFolder = defaultGameFolder;
|
currentCFolder = defaultGameFolder;
|
||||||
}
|
}
|
||||||
ui->txtFolder->setText(currentCFolder);
|
ui->txtFolder->setText(currentCFolder);
|
||||||
|
|
@ -685,61 +411,26 @@ void OptionsDialog::setupCustomGTAFolder()
|
||||||
|
|
||||||
void OptionsDialog::setupSnapmaticPictureViewer()
|
void OptionsDialog::setupSnapmaticPictureViewer()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef GTA5SYNC_WIN
|
||||||
#if QT_VERSION >= 0x050200
|
#if QT_VERSION >= 0x050200
|
||||||
settings->beginGroup("Interface");
|
settings->beginGroup("Interface");
|
||||||
ui->cbSnapmaticNavigationBar->setChecked(settings->value("NavigationBar", true).toBool());
|
ui->cbSnapmaticNavigationBar->setChecked(settings->value("NavigationBar", false).toBool());
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
#else
|
#else
|
||||||
ui->cbSnapmaticNavigationBar->setVisible(false);
|
ui->cbSnapmaticNavigationBar->setVisible(false);
|
||||||
ui->gbSnapmaticPictureViewer->setVisible(false);
|
ui->gbSnapmaticPictureViewer->setVisible(false);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
settings->beginGroup("Interface");
|
ui->cbSnapmaticNavigationBar->setVisible(false);
|
||||||
ui->cbSnapmaticNavigationBar->setChecked(settings->value("NavigationBar", true).toBool());
|
ui->gbSnapmaticPictureViewer->setVisible(false);
|
||||||
settings->endGroup();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::on_cmdExploreFolder_clicked()
|
void OptionsDialog::on_cmdExploreFolder_clicked()
|
||||||
{
|
{
|
||||||
const QString GTAV_Folder = QFileDialog::getExistingDirectory(this, UserInterface::tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly);
|
QString GTAV_Folder = QFileDialog::getExistingDirectory(this, UserInterface::tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly);
|
||||||
if (QDir(GTAV_Folder).exists()) {
|
if (QFileInfo(GTAV_Folder).exists())
|
||||||
|
{
|
||||||
ui->txtFolder->setText(GTAV_Folder);
|
ui->txtFolder->setText(GTAV_Folder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::on_cbDefaultStyle_toggled(bool checked)
|
|
||||||
{
|
|
||||||
ui->cbStyleList->setDisabled(checked);
|
|
||||||
ui->labStyle->setDisabled(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::on_cbDefaultFont_toggled(bool checked)
|
|
||||||
{
|
|
||||||
ui->cbFont->setDisabled(checked);
|
|
||||||
ui->cmdFont->setDisabled(checked);
|
|
||||||
ui->labFont->setDisabled(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::on_cmdCopyStatsID_clicked()
|
|
||||||
{
|
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
|
||||||
QApplication::clipboard()->setText(Telemetry->getRegisteredID());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::on_cbFont_currentFontChanged(const QFont &font)
|
|
||||||
{
|
|
||||||
ui->cbFont->setFont(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::on_cmdFont_clicked()
|
|
||||||
{
|
|
||||||
bool ok;
|
|
||||||
const QFont font = QFontDialog::getFont(&ok, ui->cbFont->currentFont(), this);
|
|
||||||
if (ok) {
|
|
||||||
ui->cbFont->setCurrentFont(font);
|
|
||||||
ui->cbFont->setFont(font);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
18
OptionsDialog.h
Normal file → Executable file
18
OptionsDialog.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -36,7 +36,7 @@ class OptionsDialog : public QDialog
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit OptionsDialog(ProfileDatabase *profileDB, QWidget *parent = 0);
|
explicit OptionsDialog(ProfileDatabase *profileDB, QWidget *parent = 0);
|
||||||
void commitProfiles(const QStringList &profiles);
|
void commitProfiles(QStringList profiles);
|
||||||
~OptionsDialog();
|
~OptionsDialog();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
@ -46,27 +46,20 @@ private slots:
|
||||||
void on_hsPicQuality_valueChanged(int value);
|
void on_hsPicQuality_valueChanged(int value);
|
||||||
void on_cbIgnoreAspectRatio_toggled(bool checked);
|
void on_cbIgnoreAspectRatio_toggled(bool checked);
|
||||||
void on_cmdExploreFolder_clicked();
|
void on_cmdExploreFolder_clicked();
|
||||||
void on_cbDefaultStyle_toggled(bool checked);
|
|
||||||
void on_cbDefaultFont_toggled(bool checked);
|
|
||||||
void on_cmdCopyStatsID_clicked();
|
|
||||||
void on_cbFont_currentFontChanged(const QFont &font);
|
|
||||||
void on_cmdFont_clicked();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void settingsApplied(int contentMode, bool languageChanged);
|
void settingsApplied(int contentMode, QString language);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProfileDatabase *profileDB;
|
ProfileDatabase *profileDB;
|
||||||
Ui::OptionsDialog *ui;
|
Ui::OptionsDialog *ui;
|
||||||
QList<QTreeWidgetItem*> playerItems;
|
QList<QTreeWidgetItem*> playerItems;
|
||||||
Qt::AspectRatioMode aspectRatio;
|
Qt::AspectRatioMode aspectRatio;
|
||||||
QString currentAreaLanguage;
|
|
||||||
QString currentLanguage;
|
QString currentLanguage;
|
||||||
QString currentCFolder;
|
QString currentCFolder;
|
||||||
QString defaultProfile;
|
QString defaultProfile;
|
||||||
QString percentString;
|
QString percentString;
|
||||||
QSettings *settings;
|
QSettings *settings;
|
||||||
bool withoutPlayers;
|
|
||||||
bool currentFFolder;
|
bool currentFFolder;
|
||||||
int contentMode;
|
int contentMode;
|
||||||
int customQuality;
|
int customQuality;
|
||||||
|
|
@ -79,10 +72,7 @@ private:
|
||||||
void setupDefaultProfile();
|
void setupDefaultProfile();
|
||||||
void setupPictureSettings();
|
void setupPictureSettings();
|
||||||
void setupCustomGTAFolder();
|
void setupCustomGTAFolder();
|
||||||
void setupInterfaceSettings();
|
|
||||||
void setupStatisticsSettings();
|
|
||||||
void setupSnapmaticPictureViewer();
|
void setupSnapmaticPictureViewer();
|
||||||
void setupWindowsGameSettings();
|
|
||||||
void applySettings();
|
void applySettings();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
383
OptionsDialog.ui
Normal file → Executable file
383
OptionsDialog.ui
Normal file → Executable file
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>435</width>
|
<width>435</width>
|
||||||
<height>524</height>
|
<height>405</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|
@ -34,9 +34,9 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="vlProfileContentMode">
|
<layout class="QVBoxLayout" name="vlProfileContentMode">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="rbModern">
|
<widget class="QRadioButton" name="rbOpenWithSC">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">%1 1.9+</string>
|
<string>Open with Singleclick</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|
@ -44,16 +44,16 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="rbClassic">
|
<widget class="QRadioButton" name="rbOpenWithDC">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">%1 1.0-1.8</string>
|
<string>Open with Doubleclick</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cbDoubleclick">
|
<widget class="QRadioButton" name="rbSelectWithSC">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Open with Doubleclick</string>
|
<string>Select with Singleclick</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -314,7 +314,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="vsPictures">
|
<spacer name="vsTabPictures">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -382,363 +382,20 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="tabGame">
|
<widget class="QWidget" name="tabLocalization">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Game</string>
|
<string>Language</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QVBoxLayout" name="vlGame">
|
<layout class="QVBoxLayout" name="vlLocalization">
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbSocialClub">
|
|
||||||
<property name="title">
|
|
||||||
<string>Social Club Version</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlGameSocialClub">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labSocialClubFound">
|
|
||||||
<property name="text">
|
|
||||||
<string>Found: %1</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labSocialClubLanguage">
|
|
||||||
<property name="text">
|
|
||||||
<string>Language: %1</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbSteam">
|
|
||||||
<property name="title">
|
|
||||||
<string>Steam Version</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlGameSteam">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labSteamFound">
|
|
||||||
<property name="text">
|
|
||||||
<string>Found: %1</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labSteamLanguage">
|
|
||||||
<property name="text">
|
|
||||||
<string>Language: %1</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="vsGame">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="tabStats">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Feedback</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="vlStats">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbUserStats">
|
|
||||||
<property name="title">
|
|
||||||
<string>Participation</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlUserStats">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cbParticipateStats">
|
|
||||||
<property name="text">
|
|
||||||
<string>Participate in %1 User Statistics</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labUserStats">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"><a href="%2">%1</a></string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="openExternalLinks">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbCategories">
|
|
||||||
<property name="title">
|
|
||||||
<string>Categories</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlCategories">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cbGeneralStats">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Hardware, Application and OS Specification</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cbOSLangStats">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>System Language Configuration</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cbAppConfigStats">
|
|
||||||
<property name="text">
|
|
||||||
<string>Application Configuration</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cbUsageData">
|
|
||||||
<property name="text">
|
|
||||||
<string>Personal Usage Data</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbOther">
|
|
||||||
<property name="title">
|
|
||||||
<string>Other</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlFeedbackOther">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlParticipation">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labParticipationID">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Participation ID: %1</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdCopyStatsID">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Copy</string>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="vsUserStats">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="tabInterface">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Interface</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="vlInterface">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="gbLanguage">
|
<widget class="QGroupBox" name="gbLanguage">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Language for Interface</string>
|
<string>Language</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="vlLanguage">
|
<layout class="QVBoxLayout" name="vlLanguage">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="cbLanguage"/>
|
<widget class="QComboBox" name="cbLanguage"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labCurrentLanguage">
|
|
||||||
<property name="text">
|
|
||||||
<string>Current: %1</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbAreas">
|
|
||||||
<property name="title">
|
|
||||||
<string>Language for Areas</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlAreas">
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="cbAreaLanguage"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labCurrentAreaLanguage">
|
|
||||||
<property name="text">
|
|
||||||
<string>Current: %1</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbStyle">
|
|
||||||
<property name="title">
|
|
||||||
<string>Style</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlStyle">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cbDefaultStyle">
|
|
||||||
<property name="text">
|
|
||||||
<string>Use Default Style (Restart)</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlStyle">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labStyle">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Style:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="cbStyleList">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbFont">
|
|
||||||
<property name="title">
|
|
||||||
<string>Font</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlFont">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cbDefaultFont">
|
|
||||||
<property name="text">
|
|
||||||
<string>Use Default Font (Restart)</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlFont">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labFont">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Font:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QFontComboBox" name="cbFont">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="cmdFont">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -782,28 +439,28 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
|
||||||
<string>Apply changes</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string extracomment="OK, Cancel, Apply">&OK</string>
|
<string extracomment="OK, Cancel, Apply">&OK</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="dialog-ok"/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="cmdCancel">
|
<widget class="QPushButton" name="cmdClose">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
|
||||||
<string>Discard changes</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string extracomment="OK, Cancel, Apply">&Cancel</string>
|
<string extracomment="OK, Cancel, Apply">&Cancel</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="dialog-cancel"/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
@ -813,7 +470,7 @@
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>cmdCancel</sender>
|
<sender>cmdClose</sender>
|
||||||
<signal>clicked()</signal>
|
<signal>clicked()</signal>
|
||||||
<receiver>OptionsDialog</receiver>
|
<receiver>OptionsDialog</receiver>
|
||||||
<slot>close()</slot>
|
<slot>close()</slot>
|
||||||
|
|
|
||||||
109
PictureCopy.cpp
Executable file
109
PictureCopy.cpp
Executable file
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
|
* Copyright (C) 2016 Syping
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "PictureCopy.h"
|
||||||
|
#include "PictureDialog.h"
|
||||||
|
#include "StandardPaths.h"
|
||||||
|
#include "SidebarGenerator.h"
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
PictureCopy::PictureCopy()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PictureCopy::copyPicture(QWidget *parent, QString picPath)
|
||||||
|
{
|
||||||
|
QSettings settings("Syping", "gta5sync");
|
||||||
|
settings.beginGroup("FileDialogs");
|
||||||
|
settings.beginGroup("PictureCopy");
|
||||||
|
|
||||||
|
QString adjustedPicPath = picPath;
|
||||||
|
if (adjustedPicPath.right(7) == ".hidden") // for the hidden file system
|
||||||
|
{
|
||||||
|
adjustedPicPath.remove(adjustedPicPath.length() - 7, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileDialogPreSave:
|
||||||
|
QFileInfo sgdFileInfo(adjustedPicPath);
|
||||||
|
QFileDialog fileDialog(parent);
|
||||||
|
fileDialog.setFileMode(QFileDialog::AnyFile);
|
||||||
|
fileDialog.setViewMode(QFileDialog::Detail);
|
||||||
|
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||||
|
fileDialog.setOption(QFileDialog::DontUseNativeDialog, false);
|
||||||
|
fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true);
|
||||||
|
fileDialog.setDefaultSuffix("");
|
||||||
|
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
|
fileDialog.setWindowTitle(PictureDialog::tr("Export as GTA Snapmatic..."));
|
||||||
|
fileDialog.setLabelText(QFileDialog::Accept, PictureDialog::tr("&Export"));
|
||||||
|
|
||||||
|
QStringList filters;
|
||||||
|
filters << PictureDialog::tr("Snapmatic pictures (PGTA*)");
|
||||||
|
filters << PictureDialog::tr("All files (**)");
|
||||||
|
fileDialog.setNameFilters(filters);
|
||||||
|
|
||||||
|
QList<QUrl> sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls());
|
||||||
|
|
||||||
|
fileDialog.setSidebarUrls(sidebarUrls);
|
||||||
|
fileDialog.setDirectory(settings.value("Directory", StandardPaths::documentsLocation()).toString());
|
||||||
|
fileDialog.selectFile(sgdFileInfo.fileName());
|
||||||
|
fileDialog.restoreGeometry(settings.value(parent->objectName() + "+Geomtery", "").toByteArray());
|
||||||
|
|
||||||
|
if (fileDialog.exec())
|
||||||
|
{
|
||||||
|
QStringList selectedFiles = fileDialog.selectedFiles();
|
||||||
|
if (selectedFiles.length() == 1)
|
||||||
|
{
|
||||||
|
QString selectedFile = selectedFiles.at(0);
|
||||||
|
|
||||||
|
if (QFile::exists(selectedFile))
|
||||||
|
{
|
||||||
|
if (QMessageBox::Yes == QMessageBox::warning(parent, PictureDialog::tr("Export as GTA Snapmatic"), PictureDialog::tr("Overwrite %1 with current Snapmatic picture?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes))
|
||||||
|
{
|
||||||
|
if (!QFile::remove(selectedFile))
|
||||||
|
{
|
||||||
|
QMessageBox::warning(parent, PictureDialog::tr("Export as GTA Snapmatic"), PictureDialog::tr("Failed to overwrite %1 with current Snapmatic picture").arg("\""+selectedFile+"\""));
|
||||||
|
goto fileDialogPreSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto fileDialogPreSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isCopied = QFile::copy(picPath, selectedFile);
|
||||||
|
if (!isCopied)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(parent, PictureDialog::tr("Export as GTA Snapmatic"), PictureDialog::tr("Failed to copy current Snapmatic picture"));
|
||||||
|
goto fileDialogPreSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::warning(parent, PictureDialog::tr("Export as GTA Snapmatic"), PictureDialog::tr("No valid file is selected"));
|
||||||
|
goto fileDialogPreSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.setValue(parent->objectName() + "+Geometry", fileDialog.saveGeometry());
|
||||||
|
settings.setValue("Directory", fileDialog.directory().absolutePath());
|
||||||
|
settings.endGroup();
|
||||||
|
}
|
||||||
26
wrapper.h → PictureCopy.h
Normal file → Executable file
26
wrapper.h → PictureCopy.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -16,15 +16,17 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef WRAPPER_H
|
#ifndef PICTURECOPY_H
|
||||||
#define WRAPPER_H
|
#define PICTURECOPY_H
|
||||||
|
|
||||||
#if QT_VERSION < 0x050700
|
#include <QWidget>
|
||||||
#if __cplusplus > 201703L
|
#include <QString>
|
||||||
#define qAsConst(x) std::as_const(x)
|
|
||||||
#else
|
|
||||||
#define qAsConst
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // WRAPPER_H
|
class PictureCopy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PictureCopy();
|
||||||
|
static void copyPicture(QWidget *parent, QString picPath);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PICTURECOPY_H
|
||||||
882
PictureDialog.cpp
Normal file → Executable file
882
PictureDialog.cpp
Normal file → Executable file
File diff suppressed because it is too large
Load diff
72
PictureDialog.h
Normal file → Executable file
72
PictureDialog.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -22,9 +22,7 @@
|
||||||
#include "SnapmaticPicture.h"
|
#include "SnapmaticPicture.h"
|
||||||
#include "ProfileDatabase.h"
|
#include "ProfileDatabase.h"
|
||||||
#include "CrewDatabase.h"
|
#include "CrewDatabase.h"
|
||||||
#include <QResizeEvent>
|
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QToolBar>
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
@ -38,27 +36,24 @@ class PictureDialog : public QDialog
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit PictureDialog(ProfileDatabase *profileDB, CrewDatabase *crewDB, QWidget *parent = 0);
|
explicit PictureDialog(ProfileDatabase *profileDB, CrewDatabase *crewDB, QWidget *parent = 0);
|
||||||
explicit PictureDialog(ProfileDatabase *profileDB, CrewDatabase *crewDB, QString profileName, QWidget *parent = 0);
|
void setSnapmaticPicture(SnapmaticPicture *picture, QString picPath, bool readOk, bool indexed, int index);
|
||||||
explicit PictureDialog(bool primaryWindow, ProfileDatabase *profileDB, CrewDatabase *crewDB, QWidget *parent = 0);
|
void setSnapmaticPicture(SnapmaticPicture *picture, QString picPath, bool readOk);
|
||||||
explicit PictureDialog(bool primaryWindow, ProfileDatabase *profileDB, CrewDatabase *crewDB, QString profileName, QWidget *parent = 0);
|
void setSnapmaticPicture(SnapmaticPicture *picture, QString picPath);
|
||||||
void setupPictureDialog();
|
|
||||||
void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk, bool indexed, int index);
|
|
||||||
void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk, int index);
|
void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk, int index);
|
||||||
void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk);
|
void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk);
|
||||||
void setSnapmaticPicture(SnapmaticPicture *picture, int index);
|
void setSnapmaticPicture(SnapmaticPicture *picture, int index);
|
||||||
void setSnapmaticPicture(SnapmaticPicture *picture);
|
void setSnapmaticPicture(SnapmaticPicture *picture);
|
||||||
void addPreviousNextButtons();
|
void addPreviousNextButtons();
|
||||||
void styliseDialog();
|
void stylizeDialog();
|
||||||
bool isIndexed();
|
bool isIndexed();
|
||||||
int getIndex();
|
int getIndex();
|
||||||
~PictureDialog();
|
~PictureDialog();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void adaptDialogSize();
|
|
||||||
void crewNameUpdated();
|
|
||||||
void playerNameUpdated();
|
void playerNameUpdated();
|
||||||
void dialogNextPictureRequested();
|
void dialogNextPictureRequested();
|
||||||
void dialogPreviousPictureRequested();
|
void dialogPreviousPictureRequested();
|
||||||
|
void adaptNewDialogSize(QSize newLabelSize);
|
||||||
void exportCustomContextMenuRequested(const QPoint &pos);
|
void exportCustomContextMenuRequested(const QPoint &pos);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
@ -70,67 +65,44 @@ private slots:
|
||||||
void exportCustomContextMenuRequestedPrivate(const QPoint &pos, bool fullscreen);
|
void exportCustomContextMenuRequestedPrivate(const QPoint &pos, bool fullscreen);
|
||||||
void nextPictureRequestedSlot();
|
void nextPictureRequestedSlot();
|
||||||
void previousPictureRequestedSlot();
|
void previousPictureRequestedSlot();
|
||||||
void editSnapmaticProperties();
|
|
||||||
void editSnapmaticRawJson();
|
|
||||||
void editSnapmaticImage();
|
|
||||||
void renderOverlayPicture();
|
|
||||||
void renderPicture();
|
|
||||||
void openPreviewMap();
|
|
||||||
void updated();
|
|
||||||
void customSignal(QString signal);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void nextPictureRequested();
|
void nextPictureRequested();
|
||||||
void previousPictureRequested();
|
void previousPictureRequested();
|
||||||
void newPictureCommited(QImage picture);
|
void newPictureCommited(QImage picture);
|
||||||
void endDatabaseThread();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *ev);
|
|
||||||
bool eventFilter(QObject *obj, QEvent *ev);
|
bool eventFilter(QObject *obj, QEvent *ev);
|
||||||
void mousePressEvent(QMouseEvent *ev);
|
void mousePressEvent(QMouseEvent *ev);
|
||||||
#ifdef Q_OS_WIN
|
bool event(QEvent *event);
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result);
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString generateCrewString();
|
|
||||||
QString generatePlayersString();
|
|
||||||
bool primaryWindow;
|
|
||||||
ProfileDatabase *profileDB;
|
ProfileDatabase *profileDB;
|
||||||
CrewDatabase *crewDB;
|
CrewDatabase *crewDB;
|
||||||
QString profileName;
|
|
||||||
Ui::PictureDialog *ui;
|
Ui::PictureDialog *ui;
|
||||||
QMap<QString, QString> globalMap;
|
QMap<QString, QString> globalMap;
|
||||||
SnapmaticPicture *smpic;
|
SnapmaticPicture *smpic;
|
||||||
QWidget *fullscreenWidget;
|
QWidget *fullscreenWidget;
|
||||||
QImage avatarAreaPicture;
|
QAction *jpegExportAction;
|
||||||
|
QAction *pgtaExportAction;
|
||||||
QImage snapmaticPicture;
|
QImage snapmaticPicture;
|
||||||
QImage overlayTempImage;
|
|
||||||
QString jsonDrawString;
|
QString jsonDrawString;
|
||||||
QString windowTitleStr;
|
QString windowTitleStr;
|
||||||
|
QStringList plyrsList;
|
||||||
QString picAreaStr;
|
QString picAreaStr;
|
||||||
QString crewStr;
|
QString picArea;
|
||||||
bool overlayEnabled;
|
QString picTitl;
|
||||||
bool rqFullscreen;
|
QString picPath;
|
||||||
bool naviEnabled;
|
QString created;
|
||||||
bool previewMode;
|
QString crewID;
|
||||||
|
QString locX;
|
||||||
|
QString locY;
|
||||||
|
QString locZ;
|
||||||
|
bool rqfullscreen;
|
||||||
|
bool navienabled;
|
||||||
bool indexed;
|
bool indexed;
|
||||||
int index;
|
int index;
|
||||||
int avatarLocX;
|
QMenu *exportMenu;
|
||||||
int avatarLocY;
|
|
||||||
int avatarSize;
|
|
||||||
QMenu *manageMenu;
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
QPoint dragPosition;
|
|
||||||
bool dragStart;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PICTUREDIALOG_H
|
#endif // PICTUREDIALOG_H
|
||||||
|
|
|
||||||
30
PictureDialog.ui
Normal file → Executable file
30
PictureDialog.ui
Normal file → Executable file
|
|
@ -7,11 +7,11 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>960</width>
|
<width>960</width>
|
||||||
<height>618</height>
|
<height>602</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Snapmatic Picture Viewer - %1</string>
|
<string>%1 - Snapmatic Picture Viewer</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="vlPictureLayout">
|
<layout class="QVBoxLayout" name="vlPictureLayout">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
|
|
@ -43,6 +43,9 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="res/app.qrc">:/img/960x536.png</pixmap>
|
||||||
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -98,10 +101,10 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><span style="font-weight:600">Title: </span>%6<br/>
|
<string><span style=" font-weight:600;">Title: </span>%6<br/>
|
||||||
<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/>
|
<span style=" font-weight:600;">Location: </span>%7 (%1, %2, %3)<br/>
|
||||||
<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/>
|
<span style=" font-weight:600;">Players: </span>%4 (Crew %5)<br/>
|
||||||
<span style="font-weight:600">Created: </span>%8</string>
|
<span style=" font-weight:600;">Created: </span>%8</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|
@ -147,7 +150,7 @@
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="cmdManage">
|
<widget class="QPushButton" name="cmdExport">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
|
|
@ -158,10 +161,10 @@
|
||||||
<enum>Qt::NoFocus</enum>
|
<enum>Qt::NoFocus</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Manage picture</string>
|
<string>Export picture</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Manage</string>
|
<string>&Export</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoDefault">
|
<property name="autoDefault">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
|
|
@ -180,11 +183,14 @@
|
||||||
<enum>Qt::NoFocus</enum>
|
<enum>Qt::NoFocus</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Close viewer</string>
|
<string>Close</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Close</string>
|
<string>&Close</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="dialog-close"/>
|
||||||
|
</property>
|
||||||
<property name="autoDefault">
|
<property name="autoDefault">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -214,7 +220,9 @@
|
||||||
</slots>
|
</slots>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources>
|
||||||
|
<include location="res/app.qrc"/>
|
||||||
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>cmdClose</sender>
|
<sender>cmdClose</sender>
|
||||||
|
|
|
||||||
264
PictureExport.cpp
Normal file → Executable file
264
PictureExport.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2020 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -17,32 +17,23 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "AppEnv.h"
|
|
||||||
#include "PictureExport.h"
|
#include "PictureExport.h"
|
||||||
#include "PictureDialog.h"
|
#include "PictureDialog.h"
|
||||||
#include "StandardPaths.h"
|
#include "StandardPaths.h"
|
||||||
#include "SidebarGenerator.h"
|
#include "SidebarGenerator.h"
|
||||||
#include <QStringBuilder>
|
#include <QDesktopWidget>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#if QT_VERSION < 0x050000
|
|
||||||
#include <QDesktopWidget>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
#include <QSaveFile>
|
|
||||||
#include <QScreen>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PictureExport::PictureExport()
|
PictureExport::PictureExport()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PictureExport::exportAsPicture(QWidget *parent, SnapmaticPicture *picture)
|
void PictureExport::exportPicture(QWidget *parent, SnapmaticPicture *picture)
|
||||||
{
|
{
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
|
|
||||||
|
|
@ -50,51 +41,54 @@ void PictureExport::exportAsPicture(QWidget *parent, SnapmaticPicture *picture)
|
||||||
// Quality Settings
|
// Quality Settings
|
||||||
settings.beginGroup("Pictures");
|
settings.beginGroup("Pictures");
|
||||||
int defaultQuality = 100;
|
int defaultQuality = 100;
|
||||||
QSize defExportSize = SnapmaticPicture::getSnapmaticResolution();
|
QSize defExportSize = QSize(960, 536);
|
||||||
int customQuality = settings.value("CustomQuality", defaultQuality).toInt();
|
int customQuality = settings.value("CustomQuality", defaultQuality).toInt();
|
||||||
if (customQuality < 1 || customQuality > 100) {
|
if (customQuality < 1 || customQuality > 100)
|
||||||
|
{
|
||||||
customQuality = 100;
|
customQuality = 100;
|
||||||
}
|
}
|
||||||
bool useCustomQuality = settings.value("CustomQualityEnabled", false).toBool();
|
bool useCustomQuality = settings.value("CustomQualityEnabled", false).toBool();
|
||||||
|
|
||||||
// Size Settings
|
// Size Settings
|
||||||
QSize cusExportSize = settings.value("CustomSize", defExportSize).toSize();
|
QSize cusExportSize = settings.value("CustomSize", defExportSize).toSize();
|
||||||
if (cusExportSize.width() > 3840) {
|
if (cusExportSize.width() > 3840)
|
||||||
|
{
|
||||||
cusExportSize.setWidth(3840);
|
cusExportSize.setWidth(3840);
|
||||||
}
|
}
|
||||||
else if (cusExportSize.height() > 2160) {
|
else if (cusExportSize.height() > 2160)
|
||||||
|
{
|
||||||
cusExportSize.setHeight(2160);
|
cusExportSize.setHeight(2160);
|
||||||
}
|
}
|
||||||
if (cusExportSize.width() < 1) {
|
if (cusExportSize.width() < 1)
|
||||||
|
{
|
||||||
cusExportSize.setWidth(1);
|
cusExportSize.setWidth(1);
|
||||||
}
|
}
|
||||||
else if (cusExportSize.height() < 1) {
|
else if (cusExportSize.height() < 1)
|
||||||
|
{
|
||||||
cusExportSize.setHeight(1);
|
cusExportSize.setHeight(1);
|
||||||
}
|
}
|
||||||
QString sizeMode = settings.value("ExportSizeMode", "Default").toString();
|
QString sizeMode = settings.value("ExportSizeMode", "Default").toString();
|
||||||
Qt::AspectRatioMode aspectRatio = (Qt::AspectRatioMode)settings.value("AspectRatio", Qt::KeepAspectRatio).toInt();
|
Qt::AspectRatioMode aspectRatio = (Qt::AspectRatioMode)settings.value("AspectRatio", Qt::KeepAspectRatio).toInt();
|
||||||
QString defaultExportFormat = settings.value("DefaultExportFormat", ".jpg").toString();
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
// End Picture Settings
|
// End Picture Settings
|
||||||
|
|
||||||
settings.beginGroup("FileDialogs");
|
settings.beginGroup("FileDialogs");
|
||||||
bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool();
|
settings.beginGroup("ExportPicture");
|
||||||
settings.beginGroup("ExportAsPicture");
|
|
||||||
|
|
||||||
fileDialogPreSave: //Work?
|
fileDialogPreSave:
|
||||||
QFileDialog fileDialog(parent);
|
QFileDialog fileDialog(parent);
|
||||||
fileDialog.setFileMode(QFileDialog::AnyFile);
|
fileDialog.setFileMode(QFileDialog::AnyFile);
|
||||||
fileDialog.setViewMode(QFileDialog::Detail);
|
fileDialog.setViewMode(QFileDialog::Detail);
|
||||||
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
|
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
|
fileDialog.setOption(QFileDialog::DontUseNativeDialog, false);
|
||||||
fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true);
|
fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true);
|
||||||
fileDialog.setDefaultSuffix("suffix");
|
fileDialog.setDefaultSuffix("suffix");
|
||||||
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
fileDialog.setWindowTitle(PictureDialog::tr("Export as Picture..."));
|
fileDialog.setWindowTitle(PictureDialog::tr("Export as JPG picture..."));
|
||||||
fileDialog.setLabelText(QFileDialog::Accept, PictureDialog::tr("Export"));
|
fileDialog.setLabelText(QFileDialog::Accept, PictureDialog::tr("Export"));
|
||||||
|
|
||||||
QStringList filters;
|
QStringList filters;
|
||||||
filters << PictureDialog::tr("JPEG Graphics (*.jpg *.jpeg)");
|
filters << PictureDialog::tr("JPEG picture (*.jpg)");
|
||||||
filters << PictureDialog::tr("Portable Network Graphics (*.png)");
|
filters << PictureDialog::tr("Portable Network Graphics (*.png)");
|
||||||
fileDialog.setNameFilters(filters);
|
fileDialog.setNameFilters(filters);
|
||||||
|
|
||||||
|
|
@ -102,204 +96,102 @@ fileDialogPreSave: //Work?
|
||||||
|
|
||||||
fileDialog.setSidebarUrls(sidebarUrls);
|
fileDialog.setSidebarUrls(sidebarUrls);
|
||||||
fileDialog.setDirectory(settings.value("Directory", StandardPaths::picturesLocation()).toString());
|
fileDialog.setDirectory(settings.value("Directory", StandardPaths::picturesLocation()).toString());
|
||||||
fileDialog.restoreGeometry(settings.value(parent->objectName() % "+Geometry", "").toByteArray());
|
fileDialog.restoreGeometry(settings.value(parent->objectName() + "+Geomtery", "").toByteArray());
|
||||||
|
|
||||||
QString newPictureFileName = getPictureFileName(picture) % defaultExportFormat;
|
QString newPictureFileName = getPictureFileName(picture);
|
||||||
fileDialog.selectFile(newPictureFileName);
|
fileDialog.selectFile(newPictureFileName);
|
||||||
|
|
||||||
if (fileDialog.exec()) {
|
if (fileDialog.exec())
|
||||||
|
{
|
||||||
QStringList selectedFiles = fileDialog.selectedFiles();
|
QStringList selectedFiles = fileDialog.selectedFiles();
|
||||||
if (selectedFiles.length() == 1) {
|
if (selectedFiles.length() == 1)
|
||||||
|
{
|
||||||
QString saveFileFormat;
|
QString saveFileFormat;
|
||||||
QString selectedFile = selectedFiles.at(0);
|
QString selectedFile = selectedFiles.at(0);
|
||||||
|
|
||||||
if (selectedFile.right(4) == ".jpg") {
|
if (selectedFile.right(4) == ".jpg")
|
||||||
|
{
|
||||||
saveFileFormat = "JPEG";
|
saveFileFormat = "JPEG";
|
||||||
}
|
}
|
||||||
else if (selectedFile.right(4) == ".jpeg") {
|
else if (selectedFile.right(4) == ".jpeg")
|
||||||
|
{
|
||||||
saveFileFormat = "JPEG";
|
saveFileFormat = "JPEG";
|
||||||
}
|
}
|
||||||
else if (selectedFile.right(4) == ".png") {
|
else if (selectedFile.right(4) == ".png")
|
||||||
|
{
|
||||||
saveFileFormat = "PNG";
|
saveFileFormat = "PNG";
|
||||||
}
|
}
|
||||||
else if (selectedFile.right(7) == ".suffix") {
|
else if (selectedFile.right(7) == ".suffix")
|
||||||
if (fileDialog.selectedNameFilter() == "JPEG picture (*.jpg)") {
|
{
|
||||||
|
if (fileDialog.selectedNameFilter() == "JPEG picture (*.jpg)")
|
||||||
|
{
|
||||||
selectedFile.replace(".suffix", ".jpg");
|
selectedFile.replace(".suffix", ".jpg");
|
||||||
}
|
}
|
||||||
else if (fileDialog.selectedNameFilter() == "Portable Network Graphics (*.png)") {
|
else if (fileDialog.selectedNameFilter() == "Portable Network Graphics (*.png)")
|
||||||
|
{
|
||||||
selectedFile.replace(".suffix", ".png");
|
selectedFile.replace(".suffix", ".png");
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
selectedFile.replace(".suffix", ".jpg");
|
selectedFile.replace(".suffix", ".jpg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QFile::exists(selectedFile)) {
|
if (QFile::exists(selectedFile))
|
||||||
if (QMessageBox::No == QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Overwrite %1 with current Snapmatic picture?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) {
|
{
|
||||||
goto fileDialogPreSave; //Work?
|
if (QMessageBox::Yes == QMessageBox::warning(parent, PictureDialog::tr("Export as JPG picture"), PictureDialog::tr("Overwrite %1 with current Snapmatic picture?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes))
|
||||||
|
{
|
||||||
|
if (!QFile::remove(selectedFile))
|
||||||
|
{
|
||||||
|
QMessageBox::warning(parent, PictureDialog::tr("Export as JPG picture"), PictureDialog::tr("Failed to overwrite %1 with current Snapmatic picture").arg("\""+selectedFile+"\""));
|
||||||
|
goto fileDialogPreSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto fileDialogPreSave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale Picture
|
// Scale Picture
|
||||||
QImage exportPicture = picture->getImage();
|
QImage exportPicture = picture->getPicture();
|
||||||
if (sizeMode == "Desktop") {
|
if (sizeMode == "Desktop")
|
||||||
#if QT_VERSION >= 0x050000
|
{
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
QRect desktopResolution = QApplication::primaryScreen()->geometry();
|
|
||||||
int desktopSizeWidth = qRound((double)desktopResolution.width() * screenRatioPR);
|
|
||||||
int desktopSizeHeight = qRound((double)desktopResolution.height() * screenRatioPR);
|
|
||||||
#else
|
|
||||||
QRect desktopResolution = QApplication::desktop()->screenGeometry();
|
QRect desktopResolution = QApplication::desktop()->screenGeometry();
|
||||||
int desktopSizeWidth = desktopResolution.width();
|
exportPicture = exportPicture.scaled(desktopResolution.width(), desktopResolution.height(), aspectRatio, Qt::SmoothTransformation);
|
||||||
int desktopSizeHeight = desktopResolution.height();
|
|
||||||
#endif
|
|
||||||
exportPicture = exportPicture.scaled(desktopSizeWidth, desktopSizeHeight, aspectRatio, Qt::SmoothTransformation);
|
|
||||||
}
|
}
|
||||||
else if (sizeMode == "Custom") {
|
else if (sizeMode == "Custom")
|
||||||
|
{
|
||||||
exportPicture = exportPicture.scaled(cusExportSize, aspectRatio, Qt::SmoothTransformation);
|
exportPicture = exportPicture.scaled(cusExportSize, aspectRatio, Qt::SmoothTransformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
int errorId = 0;
|
bool isSaved;
|
||||||
bool isSaved = false;
|
if (useCustomQuality)
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
QSaveFile *picFile = new QSaveFile(selectedFile);
|
|
||||||
#else
|
|
||||||
QFile *picFile = new QFile(selectedFile);
|
|
||||||
#endif
|
|
||||||
if (picFile->open(QIODevice::WriteOnly)) {
|
|
||||||
isSaved = exportPicture.save(picFile, saveFileFormat.toStdString().c_str(), useCustomQuality ? customQuality : defaultQuality);
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
if (isSaved) {
|
|
||||||
isSaved = picFile->commit();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
errorId = 1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
picFile->close();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
errorId = 2;
|
|
||||||
}
|
|
||||||
delete picFile;
|
|
||||||
|
|
||||||
if (!isSaved) {
|
|
||||||
switch (errorId) {
|
|
||||||
case 0:
|
|
||||||
QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Failed to export the picture because the system occurred a write failure"));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Failed to export the picture because the format detection failures"));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Failed to export the picture because the file can't be written"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Failed to export the picture because of an unknown reason"));
|
|
||||||
}
|
|
||||||
goto fileDialogPreSave; //Work?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("No valid file is selected"));
|
|
||||||
goto fileDialogPreSave; //Work?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.setValue(parent->objectName() % "+Geometry", fileDialog.saveGeometry());
|
|
||||||
settings.setValue("Directory", fileDialog.directory().absolutePath());
|
|
||||||
settings.endGroup();
|
|
||||||
settings.endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PictureExport::exportAsSnapmatic(QWidget *parent, SnapmaticPicture *picture)
|
|
||||||
{
|
{
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
isSaved = exportPicture.save(selectedFile, saveFileFormat.toStdString().c_str(), customQuality);
|
||||||
settings.beginGroup("FileDialogs");
|
|
||||||
bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool();
|
|
||||||
settings.beginGroup("ExportAsSnapmatic");
|
|
||||||
|
|
||||||
QString adjustedPicPath = picture->getOriginalPictureFileName();
|
|
||||||
|
|
||||||
fileDialogPreSave: //Work?
|
|
||||||
QFileInfo sgdFileInfo(adjustedPicPath);
|
|
||||||
QFileDialog fileDialog(parent);
|
|
||||||
fileDialog.setFileMode(QFileDialog::AnyFile);
|
|
||||||
fileDialog.setViewMode(QFileDialog::Detail);
|
|
||||||
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
|
|
||||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
|
|
||||||
fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true);
|
|
||||||
fileDialog.setDefaultSuffix(".rem");
|
|
||||||
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
fileDialog.setWindowTitle(PictureDialog::tr("Export as Snapmatic..."));
|
|
||||||
fileDialog.setLabelText(QFileDialog::Accept, PictureDialog::tr("Export"));
|
|
||||||
|
|
||||||
QStringList filters;
|
|
||||||
filters << PictureDialog::tr("GTA V Export (*.g5e)");
|
|
||||||
#ifndef GTA5SYNC_FLATPAK
|
|
||||||
filters << PictureDialog::tr("GTA V Raw Export (*.auto)");
|
|
||||||
#endif
|
|
||||||
filters << PictureDialog::tr("Snapmatic pictures (PGTA*)");
|
|
||||||
fileDialog.setNameFilters(filters);
|
|
||||||
|
|
||||||
QList<QUrl> sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls());
|
|
||||||
|
|
||||||
fileDialog.setSidebarUrls(sidebarUrls);
|
|
||||||
fileDialog.setDirectory(settings.value("Directory", StandardPaths::documentsLocation()).toString());
|
|
||||||
fileDialog.restoreGeometry(settings.value(parent->objectName() % "+Geometry", "").toByteArray());
|
|
||||||
fileDialog.selectFile(QString(picture->getExportPictureFileName() % ".g5e"));
|
|
||||||
|
|
||||||
if (fileDialog.exec()) {
|
|
||||||
QStringList selectedFiles = fileDialog.selectedFiles();
|
|
||||||
if (selectedFiles.length() == 1) {
|
|
||||||
QString selectedFile = selectedFiles.at(0);
|
|
||||||
bool isAutoExt = false;
|
|
||||||
#ifndef GTA5SYNC_FLATPAK
|
|
||||||
if (selectedFile.right(5) == ".auto") {
|
|
||||||
isAutoExt = true;
|
|
||||||
QString dirPath = QFileInfo(selectedFile).dir().path();
|
|
||||||
QString stockFileName = sgdFileInfo.fileName();
|
|
||||||
selectedFile = dirPath % "/" % stockFileName;
|
|
||||||
}
|
}
|
||||||
#endif
|
else
|
||||||
if (selectedFile.right(4) == ".rem") {
|
{
|
||||||
selectedFile.remove(selectedFile.length() - 4, 4);
|
isSaved = exportPicture.save(selectedFile, saveFileFormat.toStdString().c_str(), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QFile::exists(selectedFile)) {
|
if (!isSaved)
|
||||||
if (QMessageBox::No == QMessageBox::warning(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("Overwrite %1 with current Snapmatic picture?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) {
|
{
|
||||||
goto fileDialogPreSave; //Work?
|
QMessageBox::warning(parent, PictureDialog::tr("Export as JPG picture"), PictureDialog::tr("Failed to export current Snapmatic picture"));
|
||||||
|
goto fileDialogPreSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::warning(parent, PictureDialog::tr("Export as JPG picture"), PictureDialog::tr("No valid file is selected"));
|
||||||
|
goto fileDialogPreSave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedFile.right(4) == ".g5e") {
|
settings.setValue(parent->objectName() + "+Geometry", fileDialog.saveGeometry());
|
||||||
bool isExported = picture->exportPicture(selectedFile, SnapmaticFormat::G5E_Format);
|
|
||||||
if (!isExported) {
|
|
||||||
QMessageBox::warning(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("Failed to export current Snapmatic picture"));
|
|
||||||
goto fileDialogPreSave; //Work?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bool isCopied = picture->exportPicture(selectedFile, SnapmaticFormat::PGTA_Format);
|
|
||||||
if (!isCopied) {
|
|
||||||
QMessageBox::warning(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("Failed to export current Snapmatic picture"));
|
|
||||||
goto fileDialogPreSave; //Work?
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isAutoExt) QMessageBox::information(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("Exported Snapmatic to \"%1\" because of using the .auto extension.").arg(selectedFile));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QMessageBox::warning(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("No valid file is selected"));
|
|
||||||
goto fileDialogPreSave; //Work?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.setValue(parent->objectName() % "+Geometry", fileDialog.saveGeometry());
|
|
||||||
settings.setValue("Directory", fileDialog.directory().absolutePath());
|
settings.setValue("Directory", fileDialog.directory().absolutePath());
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PictureExport::getPictureFileName(SnapmaticPicture *picture)
|
QString PictureExport::getPictureFileName(SnapmaticPicture *picture)
|
||||||
|
|
|
||||||
7
PictureExport.h
Normal file → Executable file
7
PictureExport.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -27,8 +27,7 @@ class PictureExport
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PictureExport();
|
PictureExport();
|
||||||
static void exportAsPicture(QWidget *parent, SnapmaticPicture *picture);
|
static void exportPicture(QWidget *parent, SnapmaticPicture *picture);
|
||||||
static void exportAsSnapmatic(QWidget *parent, SnapmaticPicture *picture);
|
|
||||||
static QString getPictureFileName(SnapmaticPicture *picture);
|
static QString getPictureFileName(SnapmaticPicture *picture);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2020 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -19,12 +19,13 @@
|
||||||
#include "PictureDialog.h"
|
#include "PictureDialog.h"
|
||||||
#include "PictureWidget.h"
|
#include "PictureWidget.h"
|
||||||
#include "UiModLabel.h"
|
#include "UiModLabel.h"
|
||||||
#include "AppEnv.h"
|
#include <QDesktopWidget>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
PictureWidget::PictureWidget(QWidget *parent) : QDialog(parent)
|
PictureWidget::PictureWidget(QWidget *parent) : QDialog(parent)
|
||||||
{
|
{
|
||||||
|
|
@ -43,6 +44,7 @@ PictureWidget::PictureWidget(QWidget *parent) : QDialog(parent)
|
||||||
|
|
||||||
QObject::connect(pictureLabel, SIGNAL(mouseDoubleClicked(Qt::MouseButton)), this, SLOT(pictureDoubleClicked(Qt::MouseButton)));
|
QObject::connect(pictureLabel, SIGNAL(mouseDoubleClicked(Qt::MouseButton)), this, SLOT(pictureDoubleClicked(Qt::MouseButton)));
|
||||||
QObject::connect(pictureLabel, SIGNAL(customContextMenuRequested(QPoint)), parent, SLOT(exportCustomContextMenuRequested(QPoint)));
|
QObject::connect(pictureLabel, SIGNAL(customContextMenuRequested(QPoint)), parent, SLOT(exportCustomContextMenuRequested(QPoint)));
|
||||||
|
QObject::connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(updateWindowSize(int)));
|
||||||
|
|
||||||
setLayout(widgetLayout);
|
setLayout(widgetLayout);
|
||||||
}
|
}
|
||||||
|
|
@ -56,8 +58,10 @@ PictureWidget::~PictureWidget()
|
||||||
|
|
||||||
bool PictureWidget::eventFilter(QObject *obj, QEvent *ev)
|
bool PictureWidget::eventFilter(QObject *obj, QEvent *ev)
|
||||||
{
|
{
|
||||||
if (obj == this) {
|
if (obj == this)
|
||||||
if (ev->type() == QEvent::KeyPress) {
|
{
|
||||||
|
if (ev->type() == QEvent::KeyPress)
|
||||||
|
{
|
||||||
QKeyEvent *keyEvent = (QKeyEvent*)ev;
|
QKeyEvent *keyEvent = (QKeyEvent*)ev;
|
||||||
switch (keyEvent->key()){
|
switch (keyEvent->key()){
|
||||||
case Qt::Key_Left:
|
case Qt::Key_Left:
|
||||||
|
|
@ -74,29 +78,32 @@ bool PictureWidget::eventFilter(QObject *obj, QEvent *ev)
|
||||||
|
|
||||||
void PictureWidget::pictureDoubleClicked(Qt::MouseButton button)
|
void PictureWidget::pictureDoubleClicked(Qt::MouseButton button)
|
||||||
{
|
{
|
||||||
if (button == Qt::LeftButton) {
|
if (button == Qt::LeftButton)
|
||||||
|
{
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PictureWidget::setImage(QImage image_, QRect rec)
|
void PictureWidget::setImage(QImage image_, QRect rec)
|
||||||
{
|
{
|
||||||
const qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
image = image_;
|
image = image_;
|
||||||
QPixmap pixmap = QPixmap::fromImage(image.scaled(rec.width() * screenRatioPR, rec.height() * screenRatioPR, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
pictureLabel->setPixmap(QPixmap::fromImage(image.scaled(rec.width(), rec.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation)));
|
||||||
#if QT_VERSION >= 0x050600
|
|
||||||
pixmap.setDevicePixelRatio(AppEnv::screenRatioPR());
|
|
||||||
#endif
|
|
||||||
pictureLabel->setPixmap(pixmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PictureWidget::setImage(QImage image_)
|
void PictureWidget::setImage(QImage image_)
|
||||||
{
|
{
|
||||||
const qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
image = image_;
|
image = image_;
|
||||||
QPixmap pixmap = QPixmap::fromImage(image.scaled(geometry().width() * screenRatioPR, geometry().height() * screenRatioPR, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
pictureLabel->setPixmap(QPixmap::fromImage(image.scaled(geometry().width(), geometry().height(), Qt::KeepAspectRatio, Qt::SmoothTransformation)));
|
||||||
#if QT_VERSION >= 0x050600
|
}
|
||||||
pixmap.setDevicePixelRatio(screenRatioPR);
|
|
||||||
#endif
|
void PictureWidget::updateWindowSize(int screenID)
|
||||||
pictureLabel->setPixmap(pixmap);
|
{
|
||||||
|
if (screenID == QApplication::desktop()->screenNumber(this))
|
||||||
|
{
|
||||||
|
QRect desktopRect = QApplication::desktop()->screenGeometry(this);
|
||||||
|
this->move(desktopRect.x(), desktopRect.y());
|
||||||
|
this->resize(desktopRect.width(), desktopRect.height());
|
||||||
|
this->showFullScreen();
|
||||||
|
pictureLabel->setPixmap(QPixmap::fromImage(image.scaled(desktopRect.width(), desktopRect.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -46,6 +46,7 @@ private:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void pictureDoubleClicked(Qt::MouseButton button);
|
void pictureDoubleClicked(Qt::MouseButton button);
|
||||||
|
void updateWindowSize(int screenID);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void nextPictureRequested();
|
void nextPictureRequested();
|
||||||
|
|
|
||||||
|
|
@ -1,225 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2016-2021 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "PlayerListDialog.h"
|
|
||||||
#include "ui_PlayerListDialog.h"
|
|
||||||
#include "wrapper.h"
|
|
||||||
#include "AppEnv.h"
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QFontMetrics>
|
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QPixmap>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
PlayerListDialog::PlayerListDialog(QStringList players, ProfileDatabase *profileDB, QWidget *parent) :
|
|
||||||
QDialog(parent), players(players), profileDB(profileDB),
|
|
||||||
ui(new Ui::PlayerListDialog)
|
|
||||||
{
|
|
||||||
// Set Window Flags
|
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
listUpdated = false;
|
|
||||||
ui->setupUi(this);
|
|
||||||
ui->cmdCancel->setDefault(true);
|
|
||||||
ui->cmdCancel->setFocus();
|
|
||||||
|
|
||||||
// Set Icon for Apply Button
|
|
||||||
if (QIcon::hasThemeIcon("dialog-ok-apply")) {
|
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok-apply"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("dialog-apply")) {
|
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-apply"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-apply")) {
|
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("gtk-apply"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("dialog-ok")) {
|
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-ok")) {
|
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Icon for Cancel Button
|
|
||||||
if (QIcon::hasThemeIcon("dialog-cancel")) {
|
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-cancel")) {
|
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Icon for Manage Buttons
|
|
||||||
if (QIcon::hasThemeIcon("go-previous") && QIcon::hasThemeIcon("go-next") && QIcon::hasThemeIcon("list-add")) {
|
|
||||||
#if QT_VERSION < 0x050600
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
if (screenRatio != 1) {
|
|
||||||
QSize iconSize = ui->cmdMakeAv->iconSize();
|
|
||||||
iconSize = QSize(iconSize.width() * screenRatio, iconSize.height() * screenRatio);
|
|
||||||
ui->cmdMakeAv->setIconSize(iconSize);
|
|
||||||
ui->cmdMakeSe->setIconSize(iconSize);
|
|
||||||
ui->cmdMakeAd->setIconSize(iconSize);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ui->cmdMakeAv->setIcon(QIcon::fromTheme("go-previous"));
|
|
||||||
ui->cmdMakeSe->setIcon(QIcon::fromTheme("go-next"));
|
|
||||||
ui->cmdMakeAd->setIcon(QIcon::fromTheme("list-add"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#if QT_VERSION < 0x050600
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
if (screenRatio != 1) {
|
|
||||||
QSize iconSize = ui->cmdMakeAv->iconSize();
|
|
||||||
iconSize = QSize(iconSize.width() * screenRatio, iconSize.height() * screenRatio);
|
|
||||||
ui->cmdMakeAv->setIconSize(iconSize);
|
|
||||||
ui->cmdMakeSe->setIconSize(iconSize);
|
|
||||||
ui->cmdMakeAd->setIconSize(iconSize);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ui->cmdMakeAv->setIcon(QIcon(AppEnv::getImagesFolder() % "/back.svgz"));
|
|
||||||
ui->cmdMakeSe->setIcon(QIcon(AppEnv::getImagesFolder() % "/next.svgz"));
|
|
||||||
ui->cmdMakeAd->setIcon(QIcon(AppEnv::getImagesFolder() % "/add.svgz"));
|
|
||||||
}
|
|
||||||
buildInterface();
|
|
||||||
|
|
||||||
// DPI calculation
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
resize(500 * screenRatio, 350 * screenRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerListDialog::~PlayerListDialog()
|
|
||||||
{
|
|
||||||
for (QObject *object : ui->listAvPlayers->children()) {
|
|
||||||
delete object;
|
|
||||||
}
|
|
||||||
for (QObject *object : ui->listSePlayers->children()) {
|
|
||||||
delete object;
|
|
||||||
}
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerListDialog::on_cmdCancel_clicked()
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerListDialog::buildInterface()
|
|
||||||
{
|
|
||||||
const QStringList dbPlayers = profileDB->getPlayers();
|
|
||||||
for (const QString &sePlayer : qAsConst(players)) {
|
|
||||||
QListWidgetItem *playerItem = new QListWidgetItem(profileDB->getPlayerName(sePlayer));
|
|
||||||
playerItem->setData(Qt::UserRole, sePlayer);
|
|
||||||
ui->listSePlayers->addItem(playerItem);
|
|
||||||
}
|
|
||||||
for (const QString &dbPlayer : dbPlayers) {
|
|
||||||
if (!players.contains(dbPlayer)) {
|
|
||||||
QListWidgetItem *playerItem = new QListWidgetItem(profileDB->getPlayerName(dbPlayer));
|
|
||||||
playerItem->setData(Qt::UserRole, dbPlayer);
|
|
||||||
ui->listAvPlayers->addItem(playerItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->listAvPlayers->sortItems(Qt::AscendingOrder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerListDialog::on_cmdMakeAv_clicked()
|
|
||||||
{
|
|
||||||
for (QListWidgetItem *item : ui->listSePlayers->selectedItems()) {
|
|
||||||
QString playerName = item->text();
|
|
||||||
int playerID = item->data(Qt::UserRole).toInt();
|
|
||||||
delete item;
|
|
||||||
QListWidgetItem *playerItem = new QListWidgetItem(playerName);
|
|
||||||
playerItem->setData(Qt::UserRole, playerID);
|
|
||||||
ui->listAvPlayers->addItem(playerItem);
|
|
||||||
ui->listAvPlayers->sortItems(Qt::AscendingOrder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerListDialog::on_cmdMakeSe_clicked()
|
|
||||||
{
|
|
||||||
int maxPlayers = 30;
|
|
||||||
if (maxPlayers < ui->listSePlayers->count() + ui->listAvPlayers->selectedItems().count()) {
|
|
||||||
QMessageBox::warning(this, tr("Add Players..."), tr("Failed to add more Players because the limit of Players are %1!").arg(QString::number(maxPlayers)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (QListWidgetItem *item : ui->listAvPlayers->selectedItems()) {
|
|
||||||
QString playerName = item->text();
|
|
||||||
int playerID = item->data(Qt::UserRole).toInt();
|
|
||||||
delete item;
|
|
||||||
QListWidgetItem *playerItem = new QListWidgetItem(playerName);
|
|
||||||
playerItem->setData(Qt::UserRole, playerID);
|
|
||||||
ui->listSePlayers->addItem(playerItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerListDialog::on_cmdMakeAd_clicked()
|
|
||||||
{
|
|
||||||
bool playerOk;
|
|
||||||
int playerID = QInputDialog::getInt(this, tr("Add Player..."), tr("Enter Social Club Player ID"), 1, 1, 214783647, 1, &playerOk, windowFlags());
|
|
||||||
if (playerOk) {
|
|
||||||
for (int i = 0; i < ui->listAvPlayers->count(); ++i) {
|
|
||||||
QListWidgetItem *item = ui->listAvPlayers->item(i);
|
|
||||||
QString itemPlayerName = item->text();
|
|
||||||
int itemPlayerID = item->data(Qt::UserRole).toInt();
|
|
||||||
if (itemPlayerID == playerID) {
|
|
||||||
delete item;
|
|
||||||
QListWidgetItem *playerItem = new QListWidgetItem(itemPlayerName);
|
|
||||||
playerItem->setData(Qt::UserRole, playerID);
|
|
||||||
ui->listSePlayers->addItem(playerItem);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < ui->listSePlayers->count(); ++i) {
|
|
||||||
QListWidgetItem *item = ui->listSePlayers->item(i);
|
|
||||||
int itemPlayerID = item->data(Qt::UserRole).toInt();
|
|
||||||
if (itemPlayerID == playerID)
|
|
||||||
{
|
|
||||||
QMessageBox::warning(this, tr("Add Player..."), tr("Failed to add Player %1 because Player %1 is already added!").arg(QString::number(playerID)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QListWidgetItem *playerItem = new QListWidgetItem(QString::number(playerID));
|
|
||||||
playerItem->setData(Qt::UserRole, playerID);
|
|
||||||
ui->listSePlayers->addItem(playerItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerListDialog::on_cmdApply_clicked()
|
|
||||||
{
|
|
||||||
players.clear();
|
|
||||||
for (int i = 0; i < ui->listSePlayers->count(); ++i) {
|
|
||||||
players += ui->listSePlayers->item(i)->data(Qt::UserRole).toString();
|
|
||||||
}
|
|
||||||
emit playerListUpdated(players);
|
|
||||||
listUpdated = true;
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList PlayerListDialog::getPlayerList() const
|
|
||||||
{
|
|
||||||
return players;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PlayerListDialog::isListUpdated()
|
|
||||||
{
|
|
||||||
return listUpdated;
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2016-2017 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef PLAYERLISTDIALOG_H
|
|
||||||
#define PLAYERLISTDIALOG_H
|
|
||||||
|
|
||||||
#include "ProfileDatabase.h"
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class PlayerListDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class PlayerListDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit PlayerListDialog(QStringList players, ProfileDatabase *profileDB, QWidget *parent = 0);
|
|
||||||
QStringList getPlayerList() const;
|
|
||||||
bool isListUpdated();
|
|
||||||
~PlayerListDialog();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void on_cmdCancel_clicked();
|
|
||||||
void on_cmdMakeAv_clicked();
|
|
||||||
void on_cmdMakeSe_clicked();
|
|
||||||
void on_cmdMakeAd_clicked();
|
|
||||||
void on_cmdApply_clicked();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QStringList players;
|
|
||||||
ProfileDatabase *profileDB;
|
|
||||||
Ui::PlayerListDialog *ui;
|
|
||||||
bool listUpdated;
|
|
||||||
void buildInterface();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void playerListUpdated(QStringList playerList);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PLAYERLISTDIALOG_H
|
|
||||||
|
|
@ -1,173 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>PlayerListDialog</class>
|
|
||||||
<widget class="QDialog" name="PlayerListDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>500</width>
|
|
||||||
<height>350</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Edit Players...</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlInterface">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlPlayers">
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="vlAvPlayers">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labAvPlayers">
|
|
||||||
<property name="text">
|
|
||||||
<string>Available Players:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QListWidget" name="listAvPlayers">
|
|
||||||
<property name="selectionMode">
|
|
||||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="vlButtons">
|
|
||||||
<item>
|
|
||||||
<spacer name="vsButtons1">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdMakeSe">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdMakeAv">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdMakeAd">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="vsButtons2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="vlSePlayers">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labSePlayers">
|
|
||||||
<property name="text">
|
|
||||||
<string>Selected Players:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QListWidget" name="listSePlayers">
|
|
||||||
<property name="dragDropMode">
|
|
||||||
<enum>QAbstractItemView::InternalMove</enum>
|
|
||||||
</property>
|
|
||||||
<property name="selectionMode">
|
|
||||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="hlButtons">
|
|
||||||
<item>
|
|
||||||
<spacer name="hsButtons">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdApply">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Apply</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cmdCancel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Cancel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
30
ProfileDatabase.cpp
Normal file → Executable file
30
ProfileDatabase.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -19,9 +19,6 @@
|
||||||
#include "ProfileDatabase.h"
|
#include "ProfileDatabase.h"
|
||||||
#include "StandardPaths.h"
|
#include "StandardPaths.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QMutexLocker>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
|
|
@ -31,7 +28,7 @@ ProfileDatabase::ProfileDatabase(QObject *parent) : QObject(parent)
|
||||||
dir.mkpath(StandardPaths::dataLocation());
|
dir.mkpath(StandardPaths::dataLocation());
|
||||||
dir.setPath(StandardPaths::dataLocation());
|
dir.setPath(StandardPaths::dataLocation());
|
||||||
QString dirPath = dir.absolutePath();
|
QString dirPath = dir.absolutePath();
|
||||||
QString defaultConfPath = dirPath % "/players.ini";
|
QString defaultConfPath = dirPath + QDir::separator() + "players.ini";
|
||||||
|
|
||||||
QSettings confPathSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings confPathSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
confPathSettings.beginGroup("Database");
|
confPathSettings.beginGroup("Database");
|
||||||
|
|
@ -50,36 +47,15 @@ ProfileDatabase::~ProfileDatabase()
|
||||||
|
|
||||||
QStringList ProfileDatabase::getPlayers()
|
QStringList ProfileDatabase::getPlayers()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "getPlayers";
|
|
||||||
#endif
|
|
||||||
return profileDB->childKeys();
|
return profileDB->childKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProfileDatabase::getPlayerName(QString playerID)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "getPlayerName" << playerID;
|
|
||||||
#endif
|
|
||||||
return profileDB->value(playerID, playerID).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ProfileDatabase::getPlayerName(int playerID)
|
QString ProfileDatabase::getPlayerName(int playerID)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "getPlayerName" << playerID;
|
|
||||||
#endif
|
|
||||||
return profileDB->value(QString::number(playerID), playerID).toString();
|
return profileDB->value(QString::number(playerID), playerID).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileDatabase::setPlayerName(int playerID, QString playerName)
|
void ProfileDatabase::setPlayerName(int playerID, QString playerName)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
|
||||||
qDebug() << "setPlayerName" << playerID << playerName;
|
|
||||||
#endif
|
|
||||||
profileDB->setValue(QString::number(playerID), playerName);
|
profileDB->setValue(QString::number(playerID), playerName);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
ProfileDatabase.h
Normal file → Executable file
7
ProfileDatabase.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QMutex>
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
||||||
class ProfileDatabase : public QObject
|
class ProfileDatabase : public QObject
|
||||||
|
|
@ -29,13 +28,11 @@ class ProfileDatabase : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ProfileDatabase(QObject *parent = 0);
|
explicit ProfileDatabase(QObject *parent = 0);
|
||||||
QString getPlayerName(QString playerID);
|
|
||||||
QString getPlayerName(int playerID);
|
QString getPlayerName(int playerID);
|
||||||
QStringList getPlayers();
|
QStringList getPlayers();
|
||||||
~ProfileDatabase();
|
~ProfileDatabase();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QMutex mutex;
|
|
||||||
QSettings *profileDB;
|
QSettings *profileDB;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
||||||
2252
ProfileInterface.cpp
Normal file → Executable file
2252
ProfileInterface.cpp
Normal file → Executable file
File diff suppressed because it is too large
Load diff
73
ProfileInterface.h
Normal file → Executable file
73
ProfileInterface.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -29,11 +29,8 @@
|
||||||
#include "ExportThread.h"
|
#include "ExportThread.h"
|
||||||
#include "SavegameData.h"
|
#include "SavegameData.h"
|
||||||
#include "CrewDatabase.h"
|
#include "CrewDatabase.h"
|
||||||
#include "pcg_basic.h"
|
|
||||||
#include <QFileSystemWatcher>
|
|
||||||
#include <QProgressDialog>
|
#include <QProgressDialog>
|
||||||
#include <QSpacerItem>
|
#include <QSpacerItem>
|
||||||
#include <QDateTime>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
@ -42,61 +39,39 @@ namespace Ui {
|
||||||
class ProfileInterface;
|
class ProfileInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class MassTool : int { Qualify = 0, Players = 1, Crew = 2, Title = 3 };
|
|
||||||
|
|
||||||
class ProfileInterface : public QWidget
|
class ProfileInterface : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ProfileInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent = 0);
|
explicit ProfileInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent = 0);
|
||||||
void setProfileFolder(QString folder, QString profile);
|
void setProfileFolder(QString folder, QString profile);
|
||||||
void settingsApplied(int contentMode, bool languageChanged);
|
void settingsApplied(int contentMode, QString language);
|
||||||
void setupProfileInterface();
|
void setupProfileInterface();
|
||||||
void massTool(MassTool tool);
|
void disableSelected();
|
||||||
|
void enableSelected();
|
||||||
int selectedWidgets();
|
int selectedWidgets();
|
||||||
void retranslateUi();
|
|
||||||
~ProfileInterface();
|
~ProfileInterface();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void contextMenuTriggeredPIC(QContextMenuEvent* ev);
|
|
||||||
void contextMenuTriggeredSGD(QContextMenuEvent* ev);
|
|
||||||
void hoverProfileWidgetCheck();
|
|
||||||
void selectAllWidgets();
|
void selectAllWidgets();
|
||||||
void deselectAllWidgets();
|
void deselectAllWidgets();
|
||||||
void disableSelected();
|
|
||||||
void enableSelected();
|
|
||||||
void exportSelected();
|
void exportSelected();
|
||||||
void deleteSelected();
|
void deleteSelected();
|
||||||
void deleteSelectedR();
|
|
||||||
void updatePalette();
|
|
||||||
void importFiles();
|
void importFiles();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_cmdCloseProfile_clicked();
|
void on_cmdCloseProfile_clicked();
|
||||||
void on_cmdImport_clicked();
|
void on_cmdImport_clicked();
|
||||||
void pictureLoaded_event(SnapmaticPicture *picture);
|
void pictureLoaded(SnapmaticPicture *picture, QString picturePath);
|
||||||
void pictureFixed_event(SnapmaticPicture *picture);
|
void savegameLoaded(SavegameData *savegame, QString savegamePath);
|
||||||
void savegameLoaded_event(SavegameData *savegame, QString savegamePath);
|
|
||||||
void loadingProgress(int value, int maximum);
|
void loadingProgress(int value, int maximum);
|
||||||
void pictureDeleted_event();
|
void pictureDeleted();
|
||||||
void savegameDeleted_event();
|
void savegameDeleted();
|
||||||
void profileLoaded_p();
|
void profileLoaded_p();
|
||||||
void profileWidgetSelected();
|
void profileWidgetSelected();
|
||||||
void profileWidgetDeselected();
|
void profileWidgetDeselected();
|
||||||
void massToolQualify();
|
|
||||||
void massToolPlayers();
|
|
||||||
void massToolCrew();
|
|
||||||
void massToolTitle();
|
|
||||||
void dialogNextPictureRequested(QWidget *dialog);
|
void dialogNextPictureRequested(QWidget *dialog);
|
||||||
void dialogPreviousPictureRequested(QWidget *dialog);
|
void dialogPreviousPictureRequested(QWidget *dialog);
|
||||||
void on_saProfileContent_dropped(const QMimeData *mimeData);
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
void directoryChanged(const QString &path);
|
|
||||||
void directoryScanned(QVector<QString> savegameFiles, QVector<QString> snapmaticPics);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool eventFilter(QObject *watched, QEvent *event);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProfileDatabase *profileDB;
|
ProfileDatabase *profileDB;
|
||||||
|
|
@ -105,45 +80,27 @@ private:
|
||||||
Ui::ProfileInterface *ui;
|
Ui::ProfileInterface *ui;
|
||||||
|
|
||||||
ProfileLoader *profileLoader;
|
ProfileLoader *profileLoader;
|
||||||
ProfileWidget *previousWidget;
|
|
||||||
QList<SavegameData*> savegames;
|
QList<SavegameData*> savegames;
|
||||||
QList<SnapmaticPicture*> pictures;
|
QList<SnapmaticPicture*> pictures;
|
||||||
QMap<ProfileWidget*,QString> widgets;
|
QMap<ProfileWidget*,QString> widgets;
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
QFileSystemWatcher fileSystemWatcher;
|
|
||||||
QVector<QString> savegameFiles;
|
|
||||||
QVector<QString> snapmaticPics;
|
|
||||||
#endif
|
|
||||||
QSpacerItem *saSpacerItem;
|
QSpacerItem *saSpacerItem;
|
||||||
QStringList fixedPictures;
|
|
||||||
QString enabledPicStr;
|
QString enabledPicStr;
|
||||||
QString profileFolder;
|
QString profileFolder;
|
||||||
QString profileName;
|
QString profileName;
|
||||||
QString loadingStr;
|
QString loadingStr;
|
||||||
QString language;
|
|
||||||
pcg32_random_t rng;
|
|
||||||
bool contextMenuOpened;
|
|
||||||
bool isProfileLoaded;
|
|
||||||
int selectedWidgts;
|
int selectedWidgts;
|
||||||
int contentMode;
|
int contentMode;
|
||||||
|
|
||||||
bool isSupportedImageFile(QString selectedFileName);
|
bool importFile(QString selectedFile, bool warn);
|
||||||
bool importFile(QString selectedFile, QDateTime importDateTime, bool notMultiple);
|
bool importSnapmaticPicture(SnapmaticPicture *picture, QString picPath, bool warn = true);
|
||||||
bool importUrls(const QMimeData *mimeData);
|
|
||||||
bool importRemote(QUrl remoteUrl);
|
|
||||||
bool importImage(QImage *snapmaticImage, QDateTime importDateTime);
|
|
||||||
bool importFilesProgress(QStringList selectedFiles);
|
|
||||||
bool importSnapmaticPicture(SnapmaticPicture *picture, bool warn = true);
|
|
||||||
bool importSavegameData(SavegameData *savegame, QString sgdPath, bool warn = true);
|
bool importSavegameData(SavegameData *savegame, QString sgdPath, bool warn = true);
|
||||||
void pictureLoaded(SnapmaticPicture *picture, bool inserted);
|
void pictureLoaded_f(SnapmaticPicture *picture, QString picturePath, bool inserted);
|
||||||
void savegameLoaded(SavegameData *savegame, QString savegamePath, bool inserted);
|
void savegameLoaded_f(SavegameData *savegame, QString savegamePath, bool inserted);
|
||||||
void savegameDeleted(SavegameWidget *sgdWidget, bool isRemoteEmited = false);
|
void savegameDeleted_f(QWidget *sgdWidget);
|
||||||
void pictureDeleted(SnapmaticWidget *picWidget, bool isRemoteEmited = false);
|
void pictureDeleted_f(QWidget *picWidget);
|
||||||
void deleteSelectedL(bool isRemoteEmited = false);
|
|
||||||
void insertSnapmaticIPI(QWidget *widget);
|
void insertSnapmaticIPI(QWidget *widget);
|
||||||
void insertSavegameIPI(QWidget *widget);
|
void insertSavegameIPI(QWidget *widget);
|
||||||
void sortingProfileInterface();
|
void sortingProfileInterface();
|
||||||
int getRandomUid();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void profileLoaded();
|
void profileLoaded();
|
||||||
|
|
|
||||||
25
ProfileInterface.ui
Normal file → Executable file
25
ProfileInterface.ui
Normal file → Executable file
|
|
@ -103,18 +103,15 @@
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<widget class="UiModWidget" name="saProfileContent">
|
<widget class="QWidget" name="saProfileContent">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>398</width>
|
<width>98</width>
|
||||||
<height>257</height>
|
<height>28</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="acceptDrops">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlProfile">
|
<layout class="QVBoxLayout" name="vlProfile">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
|
|
@ -195,7 +192,7 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Import file</string>
|
<string>Import exported file</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Import...</string>
|
<string>&Import...</string>
|
||||||
|
|
@ -219,6 +216,9 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Close</string>
|
<string>&Close</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="dialog-close"/>
|
||||||
|
</property>
|
||||||
<property name="autoDefault">
|
<property name="autoDefault">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -228,17 +228,6 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>UiModWidget</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>UiModWidget.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
<slots>
|
|
||||||
<signal>dropped(QMimeData*)</signal>
|
|
||||||
</slots>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
||||||
120
ProfileLoader.cpp
Normal file → Executable file
120
ProfileLoader.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -16,118 +16,78 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "SnapmaticPicture.h"
|
|
||||||
#include "ProfileLoader.h"
|
#include "ProfileLoader.h"
|
||||||
|
#include "SnapmaticPicture.h"
|
||||||
#include "SavegameData.h"
|
#include "SavegameData.h"
|
||||||
#include "CrewDatabase.h"
|
#include "CrewDatabase.h"
|
||||||
#include "wrapper.h"
|
#include <QStringList>
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QVector>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QList>
|
|
||||||
#else
|
|
||||||
#include "sys/types.h"
|
|
||||||
#include "sys/stat.h"
|
|
||||||
#include "dirent.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ProfileLoader::ProfileLoader(QString profileFolder, CrewDatabase *crewDB, QObject *parent) : QThread(parent), profileFolder(profileFolder), crewDB(crewDB)
|
ProfileLoader::ProfileLoader(QString profileFolder, CrewDatabase *crewDB, QObject *parent) : QThread(parent), profileFolder(profileFolder), crewDB(crewDB)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileLoader::run()
|
void ProfileLoader::run()
|
||||||
{
|
{
|
||||||
int curFile = 1;
|
int curFile = 1;
|
||||||
int maximumV = 0;
|
QDir profileDir;
|
||||||
QVector<int> crewList;
|
QList<int> crewList;
|
||||||
QVector<QString> savegameFiles;
|
profileDir.setPath(profileFolder);
|
||||||
QVector<QString> snapmaticPics;
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
// Seek pictures and savegames
|
||||||
QDir dir(profileFolder);
|
profileDir.setNameFilters(QStringList("SGTA*"));
|
||||||
const QStringList files = dir.entryList(QDir::Files);
|
QStringList SavegameFiles = profileDir.entryList(QDir::Files | QDir::NoDot, QDir::NoSort);
|
||||||
for (const QString &fileName : files) {
|
QStringList BackupFiles = SavegameFiles.filter(".bak", Qt::CaseInsensitive);
|
||||||
if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) {
|
profileDir.setNameFilters(QStringList("PGTA*"));
|
||||||
savegameFiles << fileName;
|
QStringList SnapmaticPics = profileDir.entryList(QDir::Files | QDir::NoDot, QDir::NoSort);
|
||||||
maximumV++;
|
BackupFiles.append(SnapmaticPics.filter(".bak", Qt::CaseInsensitive));
|
||||||
}
|
|
||||||
if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) {
|
|
||||||
snapmaticPics << fileName;
|
|
||||||
maximumV++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
DIR *dirp = opendir(profileFolder.toUtf8().constData());
|
|
||||||
struct dirent *dp;
|
|
||||||
while ((dp = readdir(dirp)) != 0) {
|
|
||||||
const QString fileName = QString::fromUtf8(dp->d_name);
|
|
||||||
const QString filePath = profileFolder % "/" % fileName;
|
|
||||||
struct stat fileStat;
|
|
||||||
stat(filePath.toUtf8().constData(), &fileStat);
|
|
||||||
if (S_ISREG(fileStat.st_mode) != 0) {
|
|
||||||
if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) {
|
|
||||||
savegameFiles << fileName;
|
|
||||||
maximumV++;
|
|
||||||
}
|
|
||||||
if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) {
|
|
||||||
snapmaticPics << fileName;
|
|
||||||
maximumV++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir(dirp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Directory successfully scanned
|
SavegameFiles.removeDuplicates();
|
||||||
emit directoryScanned(savegameFiles, snapmaticPics);
|
SnapmaticPics.removeDuplicates();
|
||||||
|
foreach(const QString &BackupFile, BackupFiles)
|
||||||
|
{
|
||||||
|
SavegameFiles.removeAll(BackupFile);
|
||||||
|
SnapmaticPics.removeAll(BackupFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
int maximumV = SavegameFiles.length() + SnapmaticPics.length();
|
||||||
|
|
||||||
// Loading pictures and savegames
|
// Loading pictures and savegames
|
||||||
emit loadingProgress(curFile, maximumV);
|
emit loadingProgress(curFile, maximumV);
|
||||||
for (const QString &SavegameFile : qAsConst(savegameFiles)) {
|
foreach(const QString &SavegameFile, SavegameFiles)
|
||||||
|
{
|
||||||
emit loadingProgress(curFile, maximumV);
|
emit loadingProgress(curFile, maximumV);
|
||||||
const QString sgdPath = profileFolder % "/" % SavegameFile;
|
QString sgdPath = profileFolder + QDir::separator() + SavegameFile;
|
||||||
SavegameData *savegame = new SavegameData(sgdPath);
|
SavegameData *savegame = new SavegameData(sgdPath);
|
||||||
if (savegame->readingSavegame()) {
|
if (savegame->readingSavegame())
|
||||||
|
{
|
||||||
emit savegameLoaded(savegame, sgdPath);
|
emit savegameLoaded(savegame, sgdPath);
|
||||||
}
|
}
|
||||||
curFile++;
|
curFile++;
|
||||||
}
|
}
|
||||||
for (const QString &SnapmaticPic : qAsConst(snapmaticPics)) {
|
foreach(const QString &SnapmaticPic, SnapmaticPics)
|
||||||
|
{
|
||||||
emit loadingProgress(curFile, maximumV);
|
emit loadingProgress(curFile, maximumV);
|
||||||
const QString picturePath = profileFolder % "/" % SnapmaticPic;
|
QString picturePath = profileFolder + QDir::separator() + SnapmaticPic;
|
||||||
SnapmaticPicture *picture = new SnapmaticPicture(picturePath);
|
SnapmaticPicture *picture = new SnapmaticPicture(picturePath);
|
||||||
if (picture->readingPicture(true)) {
|
if (picture->readingPicture())
|
||||||
if (picture->isFormatSwitched()) {
|
{
|
||||||
picture->setSnapmaticFormat(SnapmaticFormat::PGTA_Format);
|
emit pictureLoaded(picture, picturePath);
|
||||||
if (picture->exportPicture(picturePath, SnapmaticFormat::PGTA_Format)) {
|
|
||||||
emit pictureFixed(picture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit pictureLoaded(picture);
|
|
||||||
int crewNumber = picture->getSnapmaticProperties().crewID;
|
int crewNumber = picture->getSnapmaticProperties().crewID;
|
||||||
if (!crewList.contains(crewNumber)) {
|
if (!crewList.contains(crewNumber))
|
||||||
crewList += crewNumber;
|
{
|
||||||
|
crewList.append(crewNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curFile++;
|
curFile++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adding found crews
|
// adding found crews
|
||||||
crewDB->setAddingCrews(true);
|
foreach(int crewID, crewList)
|
||||||
for (int crewID : qAsConst(crewList)) {
|
{
|
||||||
crewDB->addCrew(crewID);
|
crewDB->addCrew(crewID);
|
||||||
}
|
}
|
||||||
crewDB->setAddingCrews(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileLoader::preloaded()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProfileLoader::loaded()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
12
ProfileLoader.h
Normal file → Executable file
12
ProfileLoader.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -39,16 +39,10 @@ private:
|
||||||
CrewDatabase *crewDB;
|
CrewDatabase *crewDB;
|
||||||
ProfileLoader *profileLoader;
|
ProfileLoader *profileLoader;
|
||||||
|
|
||||||
private slots:
|
|
||||||
void preloaded();
|
|
||||||
void loaded();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void pictureLoaded(SnapmaticPicture *picture);
|
void pictureLoaded(SnapmaticPicture *picture, QString picturePath);
|
||||||
void pictureFixed(SnapmaticPicture *picture);
|
|
||||||
void savegameLoaded(SavegameData *savegame, QString savegamePath);
|
void savegameLoaded(SavegameData *savegame, QString savegamePath);
|
||||||
void loadingProgress(int value, int maximum);
|
void loadingProgress(int value, int maximum);
|
||||||
void directoryScanned(QVector<QString> savegameFiles, QVector<QString> snapmaticPics);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PROFILELOADER_H
|
#endif // PROFILELOADER_H
|
||||||
|
|
|
||||||
9
ProfileWidget.cpp
Normal file → Executable file
9
ProfileWidget.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -28,11 +28,6 @@ ProfileWidget::~ProfileWidget()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileWidget::retranslate()
|
|
||||||
{
|
|
||||||
qDebug() << "ProfileWidget::retranslate got used without overwrite";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProfileWidget::isSelected()
|
bool ProfileWidget::isSelected()
|
||||||
{
|
{
|
||||||
qDebug() << "ProfileWidget::isSelected got used without overwrite";
|
qDebug() << "ProfileWidget::isSelected got used without overwrite";
|
||||||
|
|
|
||||||
5
ProfileWidget.h
Normal file → Executable file
5
ProfileWidget.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -32,7 +32,6 @@ public:
|
||||||
virtual bool isSelected();
|
virtual bool isSelected();
|
||||||
virtual QString getWidgetType();
|
virtual QString getWidgetType();
|
||||||
virtual int getContentMode();
|
virtual int getContentMode();
|
||||||
virtual void retranslate();
|
|
||||||
~ProfileWidget();
|
~ProfileWidget();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
55
README.md
55
README.md
|
|
@ -1,45 +1,30 @@
|
||||||
## gta5view
|
## gta5view
|
||||||
Open Source Snapmatic and Savegame viewer/editor for GTA V
|
Grand Theft Auto V Savegame and Snapmatic viewer
|
||||||
|
|
||||||
- View Snapmatics with the ability to disable them in-game
|
- Viewing Snapmatics and giving the ability to disable them in-game
|
||||||
- Edit Snapmatic pictures and properties in multiple ways
|
- Import/Export Snapmatics and Savegames
|
||||||
- Import/Export Snapmatics, Savegames and pictures
|
- Choosing between multiple Social Club accounts as GTA V profiles IDs
|
||||||
- Choose between multiple Social Club accounts as GTA V profiles IDs
|
|
||||||
|
|
||||||
#### Screenshots
|
#### Screenshots
|
||||||

|
<img src="https://i.imgur.com/Mi3n6IL.png"/>
|
||||||

|
<img src="https://i.imgur.com/Sg75ksS.png"/>
|
||||||

|
|
||||||
|
|
||||||
#### Build gta5view for Windows
|
#### Build gta5view Debian/Ubuntu
|
||||||
|
|
||||||
# Note: Install Docker Community Edition and Git before continuing
|
apt-get install git gcc g++ qtbase5-dev qt5-qmake make checkinstall
|
||||||
docker pull sypingauto/gta5view-build:1.10-static
|
git clone https://github.com/SyDevTeam/gta5view
|
||||||
git clone https://gitlab.com/Syping/gta5view
|
mkdir build && cd build
|
||||||
docker run --rm -v "$PWD/gta5view:/gta5view" -it sypingauto/gta5view-build:1.10-static
|
qmake -qt=5 ../gta5view.pro # or just qmake ../gta5view.pro
|
||||||
mingw64-qt-cmake -B /gta5view/build /gta5view
|
make
|
||||||
cmake --build /gta5view/build
|
INSTALL_ROOT=/usr checkinstall --pkgname=gta5view --pkggroup=utility --requires=libqt5core5a,libqt5gui5,libqt5network5,libqt5widgets5
|
||||||
|
|
||||||
#### Build gta5view for Debian/Ubuntu
|
#### Build gta5view Windows
|
||||||
|
|
||||||
sudo apt-get install cmake git gcc g++ libqt5svg5-dev make qtbase5-dev qttranslations5-l10n
|
Downloading <a href="https://www.qt.io/">Qt Framework</a> and install it.<br>
|
||||||
git clone https://gitlab.com/Syping/gta5view
|
Take the Online Installer and choose the MinGW version or install Microsoft Visual Studio 2013/2015 Community<br>
|
||||||
cmake -B gta5view-build gta5view
|
Downloading Source Code over GitHub or with your Git client.<br>
|
||||||
cmake --build gta5view-build
|
Open the gta5view.pro file with Qt Creator and build it over Qt Creator.<br>
|
||||||
sudo cmake --install gta5view-build
|
|
||||||
|
|
||||||
#### Build gta5view for Arch/Manjaro
|
#### Download Binary Releases
|
||||||
|
|
||||||
sudo pacman -S cmake gcc git make qt5-base qt5-svg qt5-tools qt5-translations
|
Go to <a href="https://github.com/SyDevTeam/gta5view/releases">gta5view release</a> and download the .exe file for Windows, .deb file for Debian/Ubuntu and .rpm file for Red Hat/openSuSE/Fedora.
|
||||||
git clone https://gitlab.com/Syping/gta5view
|
|
||||||
cmake -B gta5view-build gta5view
|
|
||||||
cmake --build gta5view-build
|
|
||||||
sudo cmake --install gta5view-build
|
|
||||||
|
|
||||||
#### Build gta5view for Fedora/RHEL
|
|
||||||
|
|
||||||
sudo dnf install cmake git gcc gcc-c++ make qt5-qtbase-devel qt5-qtsvg-devel qt5-qttranslations
|
|
||||||
git clone https://gitlab.com/Syping/gta5view
|
|
||||||
cmake -B gta5view-build gta5view
|
|
||||||
cmake --build gta5view-build
|
|
||||||
sudo cmake --install gta5view-build
|
|
||||||
|
|
|
||||||
893
RagePhoto.cpp
893
RagePhoto.cpp
|
|
@ -1,893 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2020-2022 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "RagePhoto.h"
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QBuffer>
|
|
||||||
#include <QFile>
|
|
||||||
#if QT_VERSION < 0x060000
|
|
||||||
#include <QTextCodec>
|
|
||||||
#else
|
|
||||||
#include <QStringEncoder>
|
|
||||||
#include <QStringDecoder>
|
|
||||||
#endif
|
|
||||||
#ifdef RAGEPHOTO_BENCHMARK
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <chrono>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline quint32 joaatFromSI(const char *data, size_t size)
|
|
||||||
{
|
|
||||||
quint32 val = 0xE47AB81CUL;
|
|
||||||
for (size_t i = 0; i != size; i++) {
|
|
||||||
val += data[i];
|
|
||||||
val += (val << 10);
|
|
||||||
val ^= (val >> 6);
|
|
||||||
}
|
|
||||||
val += (val << 3);
|
|
||||||
val ^= (val >> 11);
|
|
||||||
val += (val << 15);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
RagePhoto::RagePhoto()
|
|
||||||
{
|
|
||||||
p_photoFormat = PhotoFormat::Undefined;
|
|
||||||
p_isLoaded = false;
|
|
||||||
p_inputMode = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
RagePhoto::RagePhoto(const QByteArray &data) : p_fileData(data)
|
|
||||||
{
|
|
||||||
p_photoFormat = PhotoFormat::Undefined;
|
|
||||||
p_isLoaded = false;
|
|
||||||
p_inputMode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
RagePhoto::RagePhoto(const QString &filePath) : p_filePath(filePath)
|
|
||||||
{
|
|
||||||
p_photoFormat = PhotoFormat::Undefined;
|
|
||||||
p_isLoaded = false;
|
|
||||||
p_inputMode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
RagePhoto::RagePhoto(QIODevice *ioDevice) : p_ioDevice(ioDevice)
|
|
||||||
{
|
|
||||||
p_photoFormat = PhotoFormat::Undefined;
|
|
||||||
p_isLoaded = false;
|
|
||||||
p_inputMode = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RagePhoto::isLoaded()
|
|
||||||
{
|
|
||||||
return p_isLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RagePhoto::load()
|
|
||||||
{
|
|
||||||
if (p_inputMode == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (p_isLoaded)
|
|
||||||
clear();
|
|
||||||
|
|
||||||
if (p_inputMode == 1) {
|
|
||||||
QFile pictureFile(p_filePath);
|
|
||||||
if (pictureFile.open(QIODevice::ReadOnly)) {
|
|
||||||
p_fileData = pictureFile.readAll();
|
|
||||||
}
|
|
||||||
pictureFile.close();
|
|
||||||
}
|
|
||||||
else if (p_inputMode == 2) {
|
|
||||||
if (!p_ioDevice->isOpen()) {
|
|
||||||
if (!p_ioDevice->open(QIODevice::ReadOnly))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
p_fileData = p_ioDevice->readAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
QBuffer dataBuffer(&p_fileData);
|
|
||||||
dataBuffer.open(QIODevice::ReadOnly);
|
|
||||||
|
|
||||||
#ifdef RAGEPHOTO_BENCHMARK
|
|
||||||
auto benchmark_parse_start = std::chrono::high_resolution_clock::now();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char uInt32Buffer[4];
|
|
||||||
qint64 size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
quint32 format = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
if (format == static_cast<quint32>(PhotoFormat::GTA5)) {
|
|
||||||
char photoHeader[256];
|
|
||||||
size = dataBuffer.read(photoHeader, 256);
|
|
||||||
if (size != 256) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (const QChar &photoChar : utf16LEToString(photoHeader, 256)) {
|
|
||||||
if (photoChar.isNull())
|
|
||||||
break;
|
|
||||||
p_photoString += photoChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_headerSum = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_endOfFile = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_jsonOffset = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_titlOffset = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_descOffset = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char markerBuffer[4];
|
|
||||||
size = dataBuffer.read(markerBuffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
if (strncmp(markerBuffer, "JPEG", 4) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_photoBuffer = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
quint32 t_photoSize = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char *photoData = static_cast<char*>(malloc(t_photoSize));
|
|
||||||
if (!photoData)
|
|
||||||
return false;
|
|
||||||
size = dataBuffer.read(photoData, t_photoSize);
|
|
||||||
if (size != t_photoSize) {
|
|
||||||
free(photoData);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
p_photoData = QByteArray(photoData, t_photoSize);
|
|
||||||
free(photoData);
|
|
||||||
|
|
||||||
dataBuffer.seek(p_jsonOffset + 264);
|
|
||||||
size = dataBuffer.read(markerBuffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
if (strncmp(markerBuffer, "JSON", 4) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_jsonBuffer = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char *jsonBytes = static_cast<char*>(malloc(p_jsonBuffer));
|
|
||||||
if (!jsonBytes)
|
|
||||||
return false;
|
|
||||||
size = dataBuffer.read(jsonBytes, p_jsonBuffer);
|
|
||||||
if (size != p_jsonBuffer) {
|
|
||||||
free(jsonBytes);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
quint32 i;
|
|
||||||
for (i = 0; i != p_jsonBuffer; i++) {
|
|
||||||
if (jsonBytes[i] == '\x00')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p_jsonData = QByteArray(jsonBytes, i);
|
|
||||||
free(jsonBytes);
|
|
||||||
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData);
|
|
||||||
if (t_jsonDocument.isNull())
|
|
||||||
return false;
|
|
||||||
p_jsonObject = t_jsonDocument.object();
|
|
||||||
|
|
||||||
dataBuffer.seek(p_titlOffset + 264);
|
|
||||||
size = dataBuffer.read(markerBuffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
if (strncmp(markerBuffer, "TITL", 4) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_titlBuffer = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char *titlBytes = static_cast<char*>(malloc(p_titlBuffer));
|
|
||||||
if (!titlBytes)
|
|
||||||
return false;
|
|
||||||
size = dataBuffer.read(titlBytes, p_titlBuffer);
|
|
||||||
if (size != p_titlBuffer){
|
|
||||||
free(titlBytes);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (i = 0; i != p_titlBuffer; i++) {
|
|
||||||
if (titlBytes[i] == '\x00')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p_titleString = QString::fromUtf8(titlBytes, i);
|
|
||||||
free(titlBytes);
|
|
||||||
|
|
||||||
dataBuffer.seek(p_descOffset + 264);
|
|
||||||
size = dataBuffer.read(markerBuffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
if (strncmp(markerBuffer, "DESC", 4) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_descBuffer = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char *descBytes = static_cast<char*>(malloc(p_descBuffer));
|
|
||||||
if (!descBytes)
|
|
||||||
return false;
|
|
||||||
size = dataBuffer.read(descBytes, p_descBuffer);
|
|
||||||
if (size != p_descBuffer) {
|
|
||||||
free(descBytes);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (i = 0; i != p_descBuffer; i++) {
|
|
||||||
if (descBytes[i] == '\x00')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p_descriptionString = QString::fromUtf8(descBytes, i);
|
|
||||||
free(descBytes);
|
|
||||||
|
|
||||||
dataBuffer.seek(p_endOfFile + 260);
|
|
||||||
size = dataBuffer.read(markerBuffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
if (strncmp(markerBuffer, "JEND", 4) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef RAGEPHOTO_BENCHMARK
|
|
||||||
auto benchmark_parse_end = std::chrono::high_resolution_clock::now();
|
|
||||||
auto benchmark_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(benchmark_parse_end - benchmark_parse_start);
|
|
||||||
if (p_inputMode == 1) {
|
|
||||||
QTextStream(stdout) << QFileInfo(p_filePath).fileName() << ": " << benchmark_ns.count() << "ns" << Qt::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QTextStream(stdout) << "PGTA5" << p_jsonObject.value("uid").toInt() << ": " << benchmark_ns.count() << "ns" << Qt::endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (p_photoFormat != PhotoFormat::G5EX)
|
|
||||||
p_photoFormat = PhotoFormat::GTA5;
|
|
||||||
|
|
||||||
p_fileData.clear();
|
|
||||||
p_isLoaded = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (format == static_cast<quint32>(PhotoFormat::G5EX)) {
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
format = charToUInt32LE(uInt32Buffer);
|
|
||||||
if (format == static_cast<quint32>(ExportFormat::G5E3P)) {
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
quint32 compressedSize = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char *compressedPhotoHeader = static_cast<char*>(malloc(compressedSize));
|
|
||||||
if (!compressedPhotoHeader)
|
|
||||||
return false;
|
|
||||||
size = dataBuffer.read(compressedPhotoHeader, compressedSize);
|
|
||||||
if (size != compressedSize) {
|
|
||||||
free(compressedPhotoHeader);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QByteArray t_photoHeader = QByteArray::fromRawData(compressedPhotoHeader, compressedSize);
|
|
||||||
t_photoHeader = qUncompress(t_photoHeader);
|
|
||||||
free(compressedPhotoHeader);
|
|
||||||
if (t_photoHeader.isEmpty())
|
|
||||||
return false;
|
|
||||||
p_photoString = QString::fromUtf8(t_photoHeader);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_headerSum = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_photoBuffer = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
compressedSize = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char *compressedPhoto = static_cast<char*>(malloc(compressedSize));
|
|
||||||
if (!compressedPhoto)
|
|
||||||
return false;
|
|
||||||
size = dataBuffer.read(compressedPhoto, compressedSize);
|
|
||||||
if (size != compressedSize) {
|
|
||||||
free(compressedPhoto);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QByteArray t_photoData = QByteArray::fromRawData(compressedPhoto, compressedSize);
|
|
||||||
p_photoData = qUncompress(t_photoData);
|
|
||||||
free(compressedPhoto);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_jsonOffset = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_jsonBuffer = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
compressedSize = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char *compressedJson = static_cast<char*>(malloc(compressedSize));
|
|
||||||
if (!compressedJson)
|
|
||||||
return false;
|
|
||||||
size = dataBuffer.read(compressedJson, compressedSize);
|
|
||||||
if (size != compressedSize) {
|
|
||||||
free(compressedJson);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QByteArray t_jsonBytes = QByteArray::fromRawData(compressedJson, compressedSize);
|
|
||||||
p_jsonData = qUncompress(t_jsonBytes);
|
|
||||||
free(compressedJson);
|
|
||||||
if (p_jsonData.isEmpty())
|
|
||||||
return false;
|
|
||||||
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData);
|
|
||||||
if (t_jsonDocument.isNull())
|
|
||||||
return false;
|
|
||||||
p_jsonObject = t_jsonDocument.object();
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_titlOffset = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_titlBuffer = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
compressedSize = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char *compressedTitl = static_cast<char*>(malloc(compressedSize));
|
|
||||||
if (!compressedTitl)
|
|
||||||
return false;
|
|
||||||
size = dataBuffer.read(compressedTitl, compressedSize);
|
|
||||||
if (size != compressedSize) {
|
|
||||||
free(compressedTitl);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QByteArray t_titlBytes = QByteArray::fromRawData(compressedTitl, compressedSize);
|
|
||||||
t_titlBytes = qUncompress(t_titlBytes);
|
|
||||||
free(compressedTitl);
|
|
||||||
p_titleString = QString::fromUtf8(t_titlBytes);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_descOffset = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_descBuffer = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
compressedSize = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
char *compressedDesc = static_cast<char*>(malloc(compressedSize));
|
|
||||||
if (!compressedDesc)
|
|
||||||
return false;
|
|
||||||
size = dataBuffer.read(compressedDesc, compressedSize);
|
|
||||||
if (size != compressedSize) {
|
|
||||||
free(compressedDesc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QByteArray t_descBytes = QByteArray::fromRawData(compressedDesc, compressedSize);
|
|
||||||
t_descBytes = qUncompress(t_descBytes);
|
|
||||||
free(compressedDesc);
|
|
||||||
p_descriptionString = QString::fromUtf8(t_descBytes);
|
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
|
||||||
if (size != 4)
|
|
||||||
return false;
|
|
||||||
p_endOfFile = charToUInt32LE(uInt32Buffer);
|
|
||||||
|
|
||||||
#ifdef RAGEPHOTO_BENCHMARK
|
|
||||||
auto benchmark_parse_end = std::chrono::high_resolution_clock::now();
|
|
||||||
auto benchmark_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(benchmark_parse_end - benchmark_parse_start);
|
|
||||||
if (p_inputMode == 1) {
|
|
||||||
QTextStream(stdout) << QFileInfo(p_filePath).fileName() << ": " << benchmark_ns.count() << "ns" << Qt::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QTextStream(stdout) << "PGTA5" << p_jsonObject.value("uid").toInt() << ": " << benchmark_ns.count() << "ns" << Qt::endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
p_photoFormat = PhotoFormat::G5EX;
|
|
||||||
|
|
||||||
p_fileData.clear();
|
|
||||||
p_isLoaded = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (format == static_cast<quint32>(ExportFormat::G5E2P)) {
|
|
||||||
p_photoFormat = PhotoFormat::G5EX;
|
|
||||||
p_fileData = qUncompress(dataBuffer.readAll());
|
|
||||||
if (p_fileData.isEmpty())
|
|
||||||
return false;
|
|
||||||
p_inputMode = 0;
|
|
||||||
return load();
|
|
||||||
}
|
|
||||||
else if (format == static_cast<quint32>(ExportFormat::G5E1P)) {
|
|
||||||
#if QT_VERSION >= 0x050A00
|
|
||||||
size = dataBuffer.skip(1);
|
|
||||||
if (size != 1)
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
if (!dataBuffer.seek(dataBuffer.pos() + 1))
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char length[1];
|
|
||||||
size = dataBuffer.read(length, 1);
|
|
||||||
if (size != 1)
|
|
||||||
return false;
|
|
||||||
int i_length = QByteArray::number(static_cast<int>(length[0]), 16).toInt() + 6;
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050A00
|
|
||||||
size = dataBuffer.skip(i_length);
|
|
||||||
if (size != i_length)
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
if (!dataBuffer.seek(dataBuffer.pos() + i_length))
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
p_photoFormat = PhotoFormat::G5EX;
|
|
||||||
p_fileData = qUncompress(dataBuffer.readAll());
|
|
||||||
if (p_fileData.isEmpty())
|
|
||||||
return false;
|
|
||||||
p_inputMode = 0;
|
|
||||||
return load();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::clear()
|
|
||||||
{
|
|
||||||
p_photoFormat = PhotoFormat::Undefined;
|
|
||||||
p_jsonObject = QJsonObject();
|
|
||||||
p_descriptionString.clear();
|
|
||||||
p_jsonData.clear();
|
|
||||||
p_photoData.clear();
|
|
||||||
p_photoString.clear();
|
|
||||||
p_titleString.clear();
|
|
||||||
p_headerSum = 0;
|
|
||||||
p_isLoaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::setDescription(const QString &description)
|
|
||||||
{
|
|
||||||
p_descriptionString = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::setFileData(const QByteArray &data)
|
|
||||||
{
|
|
||||||
p_fileData = data;
|
|
||||||
p_inputMode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::setFilePath(const QString &filePath)
|
|
||||||
{
|
|
||||||
p_filePath = filePath;
|
|
||||||
p_inputMode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::setIODevice(QIODevice *ioDevice)
|
|
||||||
{
|
|
||||||
p_ioDevice = ioDevice;
|
|
||||||
p_inputMode = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RagePhoto::setJsonData(const QByteArray &data)
|
|
||||||
{
|
|
||||||
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(data);
|
|
||||||
if (t_jsonDocument.isNull())
|
|
||||||
return false;
|
|
||||||
p_jsonObject = t_jsonDocument.object();
|
|
||||||
// serializer band-aid
|
|
||||||
QJsonObject t_jsonObject = p_jsonObject;
|
|
||||||
t_jsonObject["sign"] = "__gta5view.sign";
|
|
||||||
t_jsonDocument.setObject(t_jsonObject);
|
|
||||||
p_jsonData = t_jsonDocument.toJson(QJsonDocument::Compact);
|
|
||||||
char sign_char[24];
|
|
||||||
sprintf(sign_char, "%llu", (0x100000000000000ULL | joaatFromSI(p_photoData.constData(), p_photoData.size())));
|
|
||||||
p_jsonData.replace("\"__gta5view.sign\"", sign_char);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RagePhoto::setPhotoBuffer(quint32 size, bool moveOffsets)
|
|
||||||
{
|
|
||||||
if (size < static_cast<quint32>(p_photoData.size()))
|
|
||||||
return false;
|
|
||||||
p_photoBuffer = size;
|
|
||||||
if (moveOffsets) {
|
|
||||||
p_jsonOffset = size + 28;
|
|
||||||
p_titlOffset = p_jsonOffset + p_jsonBuffer + 8;
|
|
||||||
p_descOffset = p_titlOffset + p_titlBuffer + 8;
|
|
||||||
p_endOfFile = p_descOffset + p_descBuffer + 12;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RagePhoto::setPhotoData(const QByteArray &data)
|
|
||||||
{
|
|
||||||
quint32 size = data.size();
|
|
||||||
if (size > p_photoBuffer)
|
|
||||||
return false;
|
|
||||||
p_photoData = data;
|
|
||||||
// serializer band-aid
|
|
||||||
setJsonData(p_jsonData);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RagePhoto::setPhotoData(const char *data, int size)
|
|
||||||
{
|
|
||||||
if (static_cast<quint32>(size) > p_photoBuffer)
|
|
||||||
return false;
|
|
||||||
p_photoData = QByteArray(data, size);
|
|
||||||
// serializer band-aid
|
|
||||||
setJsonData(p_jsonData);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::setPhotoFormat(PhotoFormat photoFormat)
|
|
||||||
{
|
|
||||||
p_photoFormat = photoFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::setTitle(const QString &title)
|
|
||||||
{
|
|
||||||
p_titleString = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QByteArray RagePhoto::jsonData(JsonFormat jsonFormat)
|
|
||||||
{
|
|
||||||
if (jsonFormat == JsonFormat::Compact) {
|
|
||||||
return QJsonDocument(p_jsonObject).toJson(QJsonDocument::Compact);
|
|
||||||
}
|
|
||||||
else if (jsonFormat == JsonFormat::Indented) {
|
|
||||||
return QJsonDocument(p_jsonObject).toJson(QJsonDocument::Indented);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return p_jsonData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const QJsonObject RagePhoto::jsonObject()
|
|
||||||
{
|
|
||||||
return p_jsonObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QByteArray RagePhoto::photoData()
|
|
||||||
{
|
|
||||||
return p_photoData;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString RagePhoto::description()
|
|
||||||
{
|
|
||||||
return p_descriptionString;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString RagePhoto::photoString()
|
|
||||||
{
|
|
||||||
return p_photoString;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString RagePhoto::title()
|
|
||||||
{
|
|
||||||
return p_titleString;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint32 RagePhoto::photoBuffer()
|
|
||||||
{
|
|
||||||
return p_photoBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint32 RagePhoto::photoSize()
|
|
||||||
{
|
|
||||||
return p_photoData.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
RagePhoto::PhotoFormat RagePhoto::photoFormat()
|
|
||||||
{
|
|
||||||
return p_photoFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray RagePhoto::save(PhotoFormat photoFormat)
|
|
||||||
{
|
|
||||||
QByteArray data;
|
|
||||||
QBuffer dataBuffer(&data);
|
|
||||||
dataBuffer.open(QIODevice::WriteOnly);
|
|
||||||
save(&dataBuffer, photoFormat);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
|
|
||||||
{
|
|
||||||
// serializer band-aid
|
|
||||||
setJsonData(p_jsonData);
|
|
||||||
|
|
||||||
if (photoFormat == PhotoFormat::G5EX) {
|
|
||||||
char uInt32Buffer[4];
|
|
||||||
quint32 format = static_cast<quint32>(PhotoFormat::G5EX);
|
|
||||||
uInt32ToCharLE(format, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
format = static_cast<quint32>(ExportFormat::G5E3P);
|
|
||||||
uInt32ToCharLE(format, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
QByteArray compressedData = qCompress(p_photoString.toUtf8(), 9);
|
|
||||||
quint32 compressedSize = compressedData.size();
|
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
ioDevice->write(compressedData);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_headerSum, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_photoBuffer, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
compressedData = qCompress(p_photoData, 9);
|
|
||||||
compressedSize = compressedData.size();
|
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
ioDevice->write(compressedData);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_jsonOffset, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_jsonBuffer, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
compressedData = qCompress(p_jsonData, 9);
|
|
||||||
compressedSize = compressedData.size();
|
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
ioDevice->write(compressedData);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_titlOffset, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_titlBuffer, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
compressedData = qCompress(p_titleString.toUtf8(), 9);
|
|
||||||
compressedSize = compressedData.size();
|
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
ioDevice->write(compressedData);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_descOffset, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_descBuffer, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
compressedData = qCompress(p_descriptionString.toUtf8(), 9);
|
|
||||||
compressedSize = compressedData.size();
|
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
ioDevice->write(compressedData);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_endOfFile, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
}
|
|
||||||
else if (photoFormat == PhotoFormat::GTA5) {
|
|
||||||
char uInt32Buffer[4];
|
|
||||||
quint32 format = static_cast<quint32>(PhotoFormat::GTA5);
|
|
||||||
uInt32ToCharLE(format, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
QByteArray photoHeader = stringToUtf16LE(p_photoString);
|
|
||||||
if (photoHeader.startsWith("\xFF\xFE")) {
|
|
||||||
photoHeader.remove(0, 2);
|
|
||||||
}
|
|
||||||
qint64 photoHeaderSize = photoHeader.size();
|
|
||||||
if (photoHeaderSize > 256) {
|
|
||||||
photoHeader = photoHeader.left(256);
|
|
||||||
photoHeaderSize = 256;
|
|
||||||
}
|
|
||||||
ioDevice->write(photoHeader);
|
|
||||||
for (qint64 size = photoHeaderSize; size < 256; size++) {
|
|
||||||
ioDevice->write("\x00", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_headerSum, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_endOfFile, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_jsonOffset, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_titlOffset, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_descOffset, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
ioDevice->write("JPEG", 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_photoBuffer, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
quint32 t_photoSize = p_photoData.size();
|
|
||||||
uInt32ToCharLE(t_photoSize, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
ioDevice->write(p_photoData);
|
|
||||||
for (qint64 size = t_photoSize; size < p_photoBuffer; size++) {
|
|
||||||
ioDevice->write("\x00", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ioDevice->seek(p_jsonOffset + 264);
|
|
||||||
ioDevice->write("JSON", 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_jsonBuffer, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
qint64 dataSize = p_jsonData.size();
|
|
||||||
ioDevice->write(p_jsonData);
|
|
||||||
for (qint64 size = dataSize; size < p_jsonBuffer; size++) {
|
|
||||||
ioDevice->write("\x00", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ioDevice->seek(p_titlOffset + 264);
|
|
||||||
ioDevice->write("TITL", 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_titlBuffer, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
QByteArray data = p_titleString.toUtf8();
|
|
||||||
dataSize = data.size();
|
|
||||||
ioDevice->write(data);
|
|
||||||
for (qint64 size = dataSize; size < p_titlBuffer; size++) {
|
|
||||||
ioDevice->write("\x00", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ioDevice->seek(p_descOffset + 264);
|
|
||||||
ioDevice->write("DESC", 4);
|
|
||||||
|
|
||||||
uInt32ToCharLE(p_descBuffer, uInt32Buffer);
|
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
|
||||||
|
|
||||||
data = p_descriptionString.toUtf8();
|
|
||||||
dataSize = data.size();
|
|
||||||
ioDevice->write(data);
|
|
||||||
for (qint64 size = dataSize; size < p_descBuffer; size++) {
|
|
||||||
ioDevice->write("\x00", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ioDevice->seek(p_endOfFile + 260);
|
|
||||||
ioDevice->write("JEND", 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RagePhoto* RagePhoto::loadFile(const QString &filePath)
|
|
||||||
{
|
|
||||||
RagePhoto *ragePhoto = new RagePhoto(filePath);
|
|
||||||
ragePhoto->load();
|
|
||||||
return ragePhoto;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint32 RagePhoto::charToUInt32BE(char *x)
|
|
||||||
{
|
|
||||||
return (static_cast<unsigned char>(x[0]) << 24 |
|
|
||||||
static_cast<unsigned char>(x[1]) << 16 |
|
|
||||||
static_cast<unsigned char>(x[2]) << 8 |
|
|
||||||
static_cast<unsigned char>(x[3]));
|
|
||||||
}
|
|
||||||
|
|
||||||
quint32 RagePhoto::charToUInt32LE(char *x)
|
|
||||||
{
|
|
||||||
return (static_cast<unsigned char>(x[3]) << 24 |
|
|
||||||
static_cast<unsigned char>(x[2]) << 16 |
|
|
||||||
static_cast<unsigned char>(x[1]) << 8 |
|
|
||||||
static_cast<unsigned char>(x[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::uInt32ToCharBE(quint32 x, char *y)
|
|
||||||
{
|
|
||||||
y[0] = x >> 24;
|
|
||||||
y[1] = x >> 16;
|
|
||||||
y[2] = x >> 8;
|
|
||||||
y[3] = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RagePhoto::uInt32ToCharLE(quint32 x, char *y)
|
|
||||||
{
|
|
||||||
y[0] = x;
|
|
||||||
y[1] = x >> 8;
|
|
||||||
y[2] = x >> 16;
|
|
||||||
y[3] = x >> 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QByteArray RagePhoto::stringToUtf16LE(const QString &string)
|
|
||||||
{
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
return QStringEncoder(QStringEncoder::Utf16LE)(string);
|
|
||||||
#else
|
|
||||||
return QTextCodec::codecForName("UTF-16LE")->fromUnicode(string);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString RagePhoto::utf16LEToString(const QByteArray &data)
|
|
||||||
{
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
return QStringDecoder(QStringDecoder::Utf16LE)(data);
|
|
||||||
#else
|
|
||||||
return QTextCodec::codecForName("UTF-16LE")->toUnicode(data);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString RagePhoto::utf16LEToString(const char *data, int size)
|
|
||||||
{
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
return QStringDecoder(QStringDecoder::Utf16LE)(QByteArray::fromRawData(data, size));
|
|
||||||
#else
|
|
||||||
return QTextCodec::codecForName("UTF-16LE")->toUnicode(data, size);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
110
RagePhoto.h
110
RagePhoto.h
|
|
@ -1,110 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2020 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef RAGEPHOTO_H
|
|
||||||
#define RAGEPHOTO_H
|
|
||||||
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QIODevice>
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
class RagePhoto : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum class JsonFormat : quint8 {
|
|
||||||
Original = 0,
|
|
||||||
Compact = 1,
|
|
||||||
Indented = 2,
|
|
||||||
};
|
|
||||||
enum class ExportFormat : quint32 {
|
|
||||||
G5E1P = 0x454C0010U,
|
|
||||||
G5E2P = 0x01000032U,
|
|
||||||
G5E2S = 0x02000032U,
|
|
||||||
G5E3P = 0x01000033U,
|
|
||||||
G5E3S = 0x02000033U,
|
|
||||||
Undefined = 0,
|
|
||||||
};
|
|
||||||
enum class PhotoFormat : quint32 {
|
|
||||||
G5EX = 0x45354700U,
|
|
||||||
GTA5 = 0x01000000U,
|
|
||||||
RDR2 = 0x04000000U,
|
|
||||||
Undefined = 0,
|
|
||||||
};
|
|
||||||
explicit RagePhoto();
|
|
||||||
explicit RagePhoto(const QByteArray &data);
|
|
||||||
explicit RagePhoto(const QString &filePath);
|
|
||||||
explicit RagePhoto(QIODevice *ioDevice);
|
|
||||||
bool isLoaded();
|
|
||||||
bool load();
|
|
||||||
void clear();
|
|
||||||
void setDescription(const QString &description);
|
|
||||||
void setFileData(const QByteArray &data);
|
|
||||||
void setFilePath(const QString &filePath);
|
|
||||||
void setIODevice(QIODevice *ioDevice);
|
|
||||||
bool setJsonData(const QByteArray &data);
|
|
||||||
bool setPhotoBuffer(quint32 size, bool moveOffsets = true);
|
|
||||||
bool setPhotoData(const QByteArray &data);
|
|
||||||
bool setPhotoData(const char *data, int size);
|
|
||||||
void setPhotoFormat(PhotoFormat photoFormat);
|
|
||||||
void setTitle(const QString &title);
|
|
||||||
const QJsonObject jsonObject();
|
|
||||||
const QByteArray jsonData(JsonFormat jsonFormat = JsonFormat::Original);
|
|
||||||
const QByteArray photoData();
|
|
||||||
const QString description();
|
|
||||||
const QString photoString();
|
|
||||||
const QString title();
|
|
||||||
quint32 photoBuffer();
|
|
||||||
quint32 photoSize();
|
|
||||||
PhotoFormat photoFormat();
|
|
||||||
QByteArray save(PhotoFormat photoFormat);
|
|
||||||
void save(QIODevice *ioDevice, PhotoFormat photoFormat);
|
|
||||||
static RagePhoto* loadFile(const QString &filePath);
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline quint32 charToUInt32BE(char *x);
|
|
||||||
inline quint32 charToUInt32LE(char *x);
|
|
||||||
inline void uInt32ToCharBE(quint32 x, char *y);
|
|
||||||
inline void uInt32ToCharLE(quint32 x, char *y);
|
|
||||||
inline const QByteArray stringToUtf16LE(const QString &string);
|
|
||||||
inline const QString utf16LEToString(const QByteArray &data);
|
|
||||||
inline const QString utf16LEToString(const char *data, int size);
|
|
||||||
PhotoFormat p_photoFormat;
|
|
||||||
QJsonObject p_jsonObject;
|
|
||||||
QByteArray p_fileData;
|
|
||||||
QByteArray p_jsonData;
|
|
||||||
QByteArray p_photoData;
|
|
||||||
QIODevice *p_ioDevice;
|
|
||||||
QString p_descriptionString;
|
|
||||||
QString p_filePath;
|
|
||||||
QString p_photoString;
|
|
||||||
QString p_titleString;
|
|
||||||
quint32 p_descBuffer;
|
|
||||||
quint32 p_descOffset;
|
|
||||||
quint32 p_endOfFile;
|
|
||||||
quint32 p_headerSum;
|
|
||||||
quint32 p_jsonBuffer;
|
|
||||||
quint32 p_jsonOffset;
|
|
||||||
quint32 p_photoBuffer;
|
|
||||||
quint32 p_titlBuffer;
|
|
||||||
quint32 p_titlOffset;
|
|
||||||
bool p_isLoaded;
|
|
||||||
int p_inputMode;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RAGEPHOTO_H
|
|
||||||
30
SavegameCopy.cpp
Normal file → Executable file
30
SavegameCopy.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -18,10 +18,8 @@
|
||||||
|
|
||||||
#include "SidebarGenerator.h"
|
#include "SidebarGenerator.h"
|
||||||
#include "SavegameWidget.h"
|
#include "SavegameWidget.h"
|
||||||
#include "StandardPaths.h"
|
|
||||||
#include "SavegameCopy.h"
|
#include "SavegameCopy.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
@ -34,23 +32,20 @@ SavegameCopy::SavegameCopy()
|
||||||
void SavegameCopy::copySavegame(QWidget *parent, QString sgdPath)
|
void SavegameCopy::copySavegame(QWidget *parent, QString sgdPath)
|
||||||
{
|
{
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
|
|
||||||
settings.beginGroup("FileDialogs");
|
settings.beginGroup("FileDialogs");
|
||||||
bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool();
|
|
||||||
settings.beginGroup("SavegameCopy");
|
|
||||||
|
|
||||||
fileDialogPreSave: //Work?
|
fileDialogPreSave:
|
||||||
QFileInfo sgdFileInfo(sgdPath);
|
QFileInfo sgdFileInfo(sgdPath);
|
||||||
QFileDialog fileDialog(parent);
|
QFileDialog fileDialog(parent);
|
||||||
fileDialog.setFileMode(QFileDialog::AnyFile);
|
fileDialog.setFileMode(QFileDialog::AnyFile);
|
||||||
fileDialog.setViewMode(QFileDialog::Detail);
|
fileDialog.setViewMode(QFileDialog::Detail);
|
||||||
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
|
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
|
fileDialog.setOption(QFileDialog::DontUseNativeDialog, false);
|
||||||
fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true);
|
fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true);
|
||||||
fileDialog.setDefaultSuffix("");
|
fileDialog.setDefaultSuffix("");
|
||||||
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
fileDialog.setWindowTitle(SavegameWidget::tr(("Export Savegame...")));
|
fileDialog.setWindowTitle(SavegameWidget::tr(("Export Savegame...")));
|
||||||
fileDialog.setLabelText(QFileDialog::Accept, SavegameWidget::tr("Export"));
|
fileDialog.setLabelText(QFileDialog::Accept, SavegameWidget::tr("&Export"));
|
||||||
|
|
||||||
QStringList filters;
|
QStringList filters;
|
||||||
filters << SavegameWidget::tr("Savegame files (SGTA*)");
|
filters << SavegameWidget::tr("Savegame files (SGTA*)");
|
||||||
|
|
@ -60,8 +55,7 @@ fileDialogPreSave: //Work?
|
||||||
QList<QUrl> sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls());
|
QList<QUrl> sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls());
|
||||||
|
|
||||||
fileDialog.setSidebarUrls(sidebarUrls);
|
fileDialog.setSidebarUrls(sidebarUrls);
|
||||||
fileDialog.setDirectory(settings.value("Directory", StandardPaths::picturesLocation()).toString());
|
fileDialog.restoreState(settings.value("CopySavegame","").toByteArray());
|
||||||
fileDialog.restoreGeometry(settings.value(parent->objectName() % "+Geometry", "").toByteArray());
|
|
||||||
fileDialog.selectFile(sgdFileInfo.fileName());
|
fileDialog.selectFile(sgdFileInfo.fileName());
|
||||||
|
|
||||||
if (fileDialog.exec())
|
if (fileDialog.exec())
|
||||||
|
|
@ -78,12 +72,12 @@ fileDialogPreSave: //Work?
|
||||||
if (!QFile::remove(selectedFile))
|
if (!QFile::remove(selectedFile))
|
||||||
{
|
{
|
||||||
QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Failed to overwrite %1 with current Savegame").arg("\""+selectedFile+"\""));
|
QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Failed to overwrite %1 with current Savegame").arg("\""+selectedFile+"\""));
|
||||||
goto fileDialogPreSave; //Work?
|
goto fileDialogPreSave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
goto fileDialogPreSave; //Work?
|
goto fileDialogPreSave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,18 +85,16 @@ fileDialogPreSave: //Work?
|
||||||
if (!isCopied)
|
if (!isCopied)
|
||||||
{
|
{
|
||||||
QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Failed to export current Savegame"));
|
QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Failed to export current Savegame"));
|
||||||
goto fileDialogPreSave; //Work?
|
goto fileDialogPreSave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("No valid file is selected"));
|
QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("No valid file is selected"));
|
||||||
goto fileDialogPreSave; //Work?
|
goto fileDialogPreSave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.setValue(parent->objectName() % "+Geometry", fileDialog.saveGeometry());
|
settings.setValue("CopySavegame", fileDialog.saveState());
|
||||||
settings.setValue("Directory", fileDialog.directory().absolutePath());
|
|
||||||
settings.endGroup();
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
SavegameCopy.h
Normal file → Executable file
4
SavegameCopy.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
||||||
21
SavegameData.cpp
Normal file → Executable file
21
SavegameData.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -16,19 +16,18 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "SnapmaticPicture.h"
|
|
||||||
#include "StringParser.h"
|
#include "StringParser.h"
|
||||||
#include "SavegameData.h"
|
#include "SavegameData.h"
|
||||||
#include <QStringBuilder>
|
#include <QTextCodec>
|
||||||
#include <QByteArray>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
#define savegameHeaderLength 260
|
|
||||||
#define verificationValue QByteArray::fromHex("00000001")
|
|
||||||
|
|
||||||
SavegameData::SavegameData(const QString &fileName, QObject *parent) : QObject(parent), savegameFileName(fileName)
|
SavegameData::SavegameData(const QString &fileName, QObject *parent) : QObject(parent), savegameFileName(fileName)
|
||||||
{
|
{
|
||||||
|
// PARSE INT INIT - DO NOT CHANGE THIS VALUES
|
||||||
|
savegameHeaderLength = 260;
|
||||||
|
verificationValue = QByteArray::fromHex("00000001");
|
||||||
|
|
||||||
// INIT SAVEGAME
|
// INIT SAVEGAME
|
||||||
savegameStr = "";
|
savegameStr = "";
|
||||||
savegameOk = 0;
|
savegameOk = 0;
|
||||||
|
|
@ -42,7 +41,7 @@ bool SavegameData::readingSavegame()
|
||||||
QFile *saveFile = new QFile(savegameFileName);
|
QFile *saveFile = new QFile(savegameFileName);
|
||||||
if (!saveFile->open(QFile::ReadOnly))
|
if (!saveFile->open(QFile::ReadOnly))
|
||||||
{
|
{
|
||||||
lastStep = "1;/1,OpenFile," % SnapmaticPicture::convertDrawStringForLog(savegameFileName);
|
lastStep = "1;/1,OpenFile," + StringParser::convertDrawStringForLog(savegameFileName);
|
||||||
saveFile->deleteLater();
|
saveFile->deleteLater();
|
||||||
delete saveFile;
|
delete saveFile;
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -51,7 +50,7 @@ bool SavegameData::readingSavegame()
|
||||||
// Reading Savegame Header
|
// Reading Savegame Header
|
||||||
if (!saveFile->isReadable())
|
if (!saveFile->isReadable())
|
||||||
{
|
{
|
||||||
lastStep = "2;/3,ReadingFile," % SnapmaticPicture::convertDrawStringForLog(savegameFileName) % ",1,NOHEADER";
|
lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(savegameFileName) + ",1,NOHEADER";
|
||||||
saveFile->close();
|
saveFile->close();
|
||||||
saveFile->deleteLater();
|
saveFile->deleteLater();
|
||||||
delete saveFile;
|
delete saveFile;
|
||||||
|
|
@ -78,7 +77,7 @@ QString SavegameData::getSavegameDataString(const QByteArray &savegameHeader)
|
||||||
QList<QByteArray> savegameBytesList = savegameBytes.split(char(0x01));
|
QList<QByteArray> savegameBytesList = savegameBytes.split(char(0x01));
|
||||||
savegameBytes = savegameBytesList.at(1);
|
savegameBytes = savegameBytesList.at(1);
|
||||||
savegameBytesList.clear();
|
savegameBytesList.clear();
|
||||||
return SnapmaticPicture::parseTitleString(savegameBytes, savegameBytes.length());
|
return StringParser::parseTitleString(savegameBytes, savegameBytes.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SavegameData::readingSavegameFromFile(const QString &fileName)
|
bool SavegameData::readingSavegameFromFile(const QString &fileName)
|
||||||
|
|
|
||||||
8
SavegameData.h
Normal file → Executable file
8
SavegameData.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -40,6 +40,10 @@ private:
|
||||||
QString savegameStr;
|
QString savegameStr;
|
||||||
QString lastStep;
|
QString lastStep;
|
||||||
bool savegameOk;
|
bool savegameOk;
|
||||||
|
|
||||||
|
// PARSE INT
|
||||||
|
QByteArray verificationValue;
|
||||||
|
int savegameHeaderLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SAVEGAMEDATA_H
|
#endif // SAVEGAMEDATA_H
|
||||||
|
|
|
||||||
65
SavegameDialog.cpp
Normal file → Executable file
65
SavegameDialog.cpp
Normal file → Executable file
|
|
@ -1,65 +1,14 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2016-2018 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "SavegameDialog.h"
|
#include "SavegameDialog.h"
|
||||||
#include "ui_SavegameDialog.h"
|
#include "ui_SavegameDialog.h"
|
||||||
#include "SavegameCopy.h"
|
#include "SavegameCopy.h"
|
||||||
#include "AppEnv.h"
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
SavegameDialog::SavegameDialog(QWidget *parent) :
|
SavegameDialog::SavegameDialog(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::SavegameDialog)
|
ui(new Ui::SavegameDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup User Interface
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->cmdClose->setFocus();
|
|
||||||
savegameLabStr = ui->labSavegameText->text();
|
savegameLabStr = ui->labSavegameText->text();
|
||||||
|
|
||||||
// Set Icon for Close Button
|
|
||||||
if (QIcon::hasThemeIcon("dialog-close"))
|
|
||||||
{
|
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-close"))
|
|
||||||
{
|
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Icon for Export Button
|
|
||||||
if (QIcon::hasThemeIcon("document-export"))
|
|
||||||
{
|
|
||||||
ui->cmdCopy->setIcon(QIcon::fromTheme("document-export"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("document-save"))
|
|
||||||
{
|
|
||||||
ui->cmdCopy->setIcon(QIcon::fromTheme("document-save"));
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshWindowSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SavegameDialog::~SavegameDialog()
|
SavegameDialog::~SavegameDialog()
|
||||||
|
|
@ -67,19 +16,6 @@ SavegameDialog::~SavegameDialog()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SavegameDialog::refreshWindowSize()
|
|
||||||
{
|
|
||||||
// DPI calculation
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
int dpiWindowWidth = 400 * screenRatio;
|
|
||||||
int dpiWindowHeight = 105 * screenRatio;
|
|
||||||
if (dpiWindowHeight < heightForWidth(dpiWindowWidth))
|
|
||||||
{
|
|
||||||
dpiWindowHeight = heightForWidth(dpiWindowWidth);
|
|
||||||
}
|
|
||||||
resize(dpiWindowWidth, dpiWindowHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SavegameDialog::setSavegameData(SavegameData *savegame, QString savegamePath, bool readOk)
|
void SavegameDialog::setSavegameData(SavegameData *savegame, QString savegamePath, bool readOk)
|
||||||
{
|
{
|
||||||
// Showing error if reading error
|
// Showing error if reading error
|
||||||
|
|
@ -90,7 +26,6 @@ void SavegameDialog::setSavegameData(SavegameData *savegame, QString savegamePat
|
||||||
}
|
}
|
||||||
sgdPath = savegamePath;
|
sgdPath = savegamePath;
|
||||||
ui->labSavegameText->setText(savegameLabStr.arg(savegame->getSavegameStr()));
|
ui->labSavegameText->setText(savegameLabStr.arg(savegame->getSavegameStr()));
|
||||||
refreshWindowSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SavegameDialog::on_cmdClose_clicked()
|
void SavegameDialog::on_cmdClose_clicked()
|
||||||
|
|
|
||||||
19
SavegameDialog.h
Normal file → Executable file
19
SavegameDialog.h
Normal file → Executable file
|
|
@ -1,21 +1,3 @@
|
||||||
/*****************************************************************************
|
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
|
||||||
* Copyright (C) 2016-2018 Syping
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SAVEGAMEDIALOG_H
|
#ifndef SAVEGAMEDIALOG_H
|
||||||
#define SAVEGAMEDIALOG_H
|
#define SAVEGAMEDIALOG_H
|
||||||
|
|
||||||
|
|
@ -37,7 +19,6 @@ public:
|
||||||
private slots:
|
private slots:
|
||||||
void on_cmdClose_clicked();
|
void on_cmdClose_clicked();
|
||||||
void on_cmdCopy_clicked();
|
void on_cmdCopy_clicked();
|
||||||
void refreshWindowSize();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::SavegameDialog *ui;
|
Ui::SavegameDialog *ui;
|
||||||
|
|
|
||||||
29
SavegameDialog.ui
Normal file → Executable file
29
SavegameDialog.ui
Normal file → Executable file
|
|
@ -7,20 +7,23 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>400</width>
|
||||||
<height>112</height>
|
<height>104</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Savegame Viewer</string>
|
<string>Savegame Viewer</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="modal">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlSavegameDialog">
|
<layout class="QVBoxLayout" name="vlSavegameDialog">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="labSavegameText">
|
<widget class="QLabel" name="labSavegameText">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><span style="font-weight:600">Savegame</span><br><br>%1</string>
|
<string><span style=" font-weight:600;">Savegame</span><br><br>%1</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
|
@ -30,19 +33,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<spacer name="vsSavegame">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="hlButtons">
|
<layout class="QHBoxLayout" name="hlButtons">
|
||||||
<item>
|
<item>
|
||||||
|
|
@ -82,6 +72,9 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Close</string>
|
<string>&Close</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="dialog-close"/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
||||||
171
SavegameWidget.cpp
Normal file → Executable file
171
SavegameWidget.cpp
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -19,13 +19,11 @@
|
||||||
#include "SavegameWidget.h"
|
#include "SavegameWidget.h"
|
||||||
#include "ui_SavegameWidget.h"
|
#include "ui_SavegameWidget.h"
|
||||||
#include "SidebarGenerator.h"
|
#include "SidebarGenerator.h"
|
||||||
|
#include "ProfileInterface.h"
|
||||||
#include "SavegameDialog.h"
|
#include "SavegameDialog.h"
|
||||||
#include "StandardPaths.h"
|
#include "StandardPaths.h"
|
||||||
#include "SavegameData.h"
|
#include "SavegameData.h"
|
||||||
#include "SavegameCopy.h"
|
#include "SavegameCopy.h"
|
||||||
#include "AppEnv.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
@ -39,13 +37,6 @@
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
|
||||||
#include "TelemetryClass.h"
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QDateTime>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SavegameWidget::SavegameWidget(QWidget *parent) :
|
SavegameWidget::SavegameWidget(QWidget *parent) :
|
||||||
ProfileWidget(parent),
|
ProfileWidget(parent),
|
||||||
ui(new Ui::SavegameWidget)
|
ui(new Ui::SavegameWidget)
|
||||||
|
|
@ -56,23 +47,21 @@ SavegameWidget::SavegameWidget(QWidget *parent) :
|
||||||
ui->cmdDelete->setVisible(false);
|
ui->cmdDelete->setVisible(false);
|
||||||
ui->cbSelected->setVisible(false);
|
ui->cbSelected->setVisible(false);
|
||||||
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
ui->labSavegamePic->setFixedSize(48 * screenRatio, 27 * screenRatio);
|
|
||||||
|
|
||||||
ui->labSavegamePic->setScaledContents(true);
|
|
||||||
ui->labSavegamePic->setPixmap(QPixmap(AppEnv::getImagesFolder() % "/savegame.svgz"));
|
|
||||||
|
|
||||||
QString exportSavegameStr = tr("Export Savegame...");
|
QString exportSavegameStr = tr("Export Savegame...");
|
||||||
Q_UNUSED(exportSavegameStr)
|
Q_UNUSED(exportSavegameStr)
|
||||||
|
|
||||||
|
QPalette palette;
|
||||||
|
highlightBackColor = palette.highlight().color();
|
||||||
|
highlightTextColor = palette.highlightedText().color();
|
||||||
|
|
||||||
labelAutosaveStr = tr("AUTOSAVE - %1\n%2");
|
labelAutosaveStr = tr("AUTOSAVE - %1\n%2");
|
||||||
labelSaveStr = tr("SAVE %3 - %1\n%2");
|
labelSaveStr = tr("SAVE %3 - %1\n%2");
|
||||||
|
snwgt = parent;
|
||||||
|
sgdPath = "";
|
||||||
|
sgdStr = "";
|
||||||
|
sgdata = 0;
|
||||||
|
|
||||||
ui->SavegameFrame->setMouseTracking(true);
|
installEventFilter(this);
|
||||||
ui->labSavegamePic->setMouseTracking(true);
|
|
||||||
ui->labSavegameStr->setMouseTracking(true);
|
|
||||||
ui->cbSelected->setMouseTracking(true);
|
|
||||||
sgdata = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SavegameWidget::~SavegameWidget()
|
SavegameWidget::~SavegameWidget()
|
||||||
|
|
@ -80,22 +69,32 @@ SavegameWidget::~SavegameWidget()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SavegameWidget::eventFilter(QObject *obj, QEvent *ev)
|
||||||
|
{
|
||||||
|
if (obj == this)
|
||||||
|
{
|
||||||
|
if (ev->type() == QEvent::Enter)
|
||||||
|
{
|
||||||
|
setStyleSheet(QString("QFrame#SavegameFrame{background-color: rgb(%1, %2, %3)}QLabel#labSavegameStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue())));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(ev->type() == QEvent::Leave)
|
||||||
|
{
|
||||||
|
setStyleSheet("");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void SavegameWidget::setSavegameData(SavegameData *savegame, QString savegamePath)
|
void SavegameWidget::setSavegameData(SavegameData *savegame, QString savegamePath)
|
||||||
{
|
{
|
||||||
// BETA CODE
|
// BETA CODE
|
||||||
QString savegameString = savegame->getSavegameStr();
|
|
||||||
QString fileName = QFileInfo(savegame->getSavegameFileName()).fileName();
|
|
||||||
renderString(savegameString, fileName);
|
|
||||||
sgdStr = savegameString;
|
|
||||||
sgdPath = savegamePath;
|
|
||||||
sgdata = savegame;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SavegameWidget::renderString(const QString &savegameString, const QString &fileName)
|
|
||||||
{
|
|
||||||
bool validNumber;
|
bool validNumber;
|
||||||
QString savegameName = tr("WRONG FORMAT");
|
QString savegameName = tr("WRONG FORMAT");
|
||||||
QString savegameDate = tr("WRONG FORMAT");
|
QString savegameDate = tr("WRONG FORMAT");
|
||||||
|
QString savegameString = savegame->getSavegameStr();
|
||||||
|
QString fileName = QFileInfo(savegame->getSavegameFileName()).fileName();
|
||||||
QStringList savegameNDL = QString(savegameString).split(" - ");
|
QStringList savegameNDL = QString(savegameString).split(" - ");
|
||||||
if (savegameNDL.length() >= 2)
|
if (savegameNDL.length() >= 2)
|
||||||
{
|
{
|
||||||
|
|
@ -118,15 +117,9 @@ void SavegameWidget::renderString(const QString &savegameString, const QString &
|
||||||
{
|
{
|
||||||
ui->labSavegameStr->setText(labelSaveStr.arg(savegameDate, savegameName, tr("UNKNOWN")));
|
ui->labSavegameStr->setText(labelSaveStr.arg(savegameDate, savegameName, tr("UNKNOWN")));
|
||||||
}
|
}
|
||||||
}
|
sgdStr = savegameString;
|
||||||
|
sgdPath = savegamePath;
|
||||||
void SavegameWidget::retranslate()
|
sgdata = savegame;
|
||||||
{
|
|
||||||
labelAutosaveStr = tr("AUTOSAVE - %1\n%2");
|
|
||||||
labelSaveStr = tr("SAVE %3 - %1\n%2");
|
|
||||||
|
|
||||||
QString fileName = QFileInfo(sgdata->getSavegameFileName()).fileName();
|
|
||||||
renderString(sgdStr, fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SavegameWidget::on_cmdCopy_clicked()
|
void SavegameWidget::on_cmdCopy_clicked()
|
||||||
|
|
@ -136,60 +129,20 @@ void SavegameWidget::on_cmdCopy_clicked()
|
||||||
|
|
||||||
void SavegameWidget::on_cmdDelete_clicked()
|
void SavegameWidget::on_cmdDelete_clicked()
|
||||||
{
|
{
|
||||||
int uchoice = QMessageBox::question(this, tr("Delete Savegame"), tr("Are you sure to delete %1 from your savegames?").arg("\""+sgdStr+"\""), QMessageBox::No | QMessageBox::Yes, QMessageBox::No);
|
int uchoice = QMessageBox::question(this, tr("Delete savegame"), tr("Are you sure to delete %1 from your savegames?").arg("\""+sgdStr+"\""), QMessageBox::No | QMessageBox::Yes, QMessageBox::No);
|
||||||
if (uchoice == QMessageBox::Yes)
|
if (uchoice == QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
if (!QFile::exists(sgdPath))
|
if (!QFile::exists(sgdPath))
|
||||||
{
|
{
|
||||||
emit savegameDeleted();
|
emit savegameDeleted();
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
|
||||||
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
|
||||||
telemetrySettings.endGroup();
|
|
||||||
if (pushUsageData && Telemetry->canPush())
|
|
||||||
{
|
|
||||||
QJsonDocument jsonDocument;
|
|
||||||
QJsonObject jsonObject;
|
|
||||||
jsonObject["Type"] = "DeleteSuccess";
|
|
||||||
jsonObject["ExtraFlags"] = "Savegame";
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if(QFile::remove(sgdPath))
|
else if(QFile::remove(sgdPath))
|
||||||
{
|
{
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
|
||||||
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
|
||||||
telemetrySettings.endGroup();
|
|
||||||
if (pushUsageData && Telemetry->canPush())
|
|
||||||
{
|
|
||||||
QJsonDocument jsonDocument;
|
|
||||||
QJsonObject jsonObject;
|
|
||||||
jsonObject["Type"] = "DeleteSuccess";
|
|
||||||
jsonObject["ExtraFlags"] = "Savegame";
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
emit savegameDeleted();
|
emit savegameDeleted();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, tr("Delete Savegame"), tr("Failed at deleting %1 from your savegames").arg("\""+sgdStr+"\""));
|
QMessageBox::warning(this, tr("Delete savegame"), tr("Failed at deleting %1 from your savegames").arg("\""+sgdStr+"\""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -197,15 +150,12 @@ void SavegameWidget::on_cmdDelete_clicked()
|
||||||
void SavegameWidget::on_cmdView_clicked()
|
void SavegameWidget::on_cmdView_clicked()
|
||||||
{
|
{
|
||||||
SavegameDialog *savegameDialog = new SavegameDialog(this);
|
SavegameDialog *savegameDialog = new SavegameDialog(this);
|
||||||
|
savegameDialog->setWindowFlags(savegameDialog->windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
savegameDialog->setSavegameData(sgdata, sgdPath, true);
|
savegameDialog->setSavegameData(sgdata, sgdPath, true);
|
||||||
savegameDialog->setModal(true);
|
savegameDialog->setModal(true);
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
// Android ...
|
|
||||||
savegameDialog->showMaximized();
|
|
||||||
#else
|
|
||||||
savegameDialog->show();
|
savegameDialog->show();
|
||||||
#endif
|
|
||||||
savegameDialog->exec();
|
savegameDialog->exec();
|
||||||
|
savegameDialog->deleteLater();
|
||||||
delete savegameDialog;
|
delete savegameDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,31 +176,18 @@ void SavegameWidget::mouseReleaseEvent(QMouseEvent *ev)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const int contentMode = getContentMode();
|
if (getContentMode() == 0 && rect().contains(ev->pos()) && ev->button() == Qt::LeftButton)
|
||||||
if ((contentMode == 0 || contentMode == 10 || contentMode == 20) && rect().contains(ev->pos()) && ev->button() == Qt::LeftButton)
|
|
||||||
{
|
|
||||||
if (ev->modifiers().testFlag(Qt::ShiftModifier))
|
|
||||||
{
|
|
||||||
ui->cbSelected->setChecked(!ui->cbSelected->isChecked());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
on_cmdView_clicked();
|
on_cmdView_clicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton && ev->modifiers().testFlag(Qt::ShiftModifier))
|
|
||||||
{
|
|
||||||
ui->cbSelected->setChecked(!ui->cbSelected->isChecked());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SavegameWidget::mouseDoubleClickEvent(QMouseEvent *ev)
|
void SavegameWidget::mouseDoubleClickEvent(QMouseEvent *ev)
|
||||||
{
|
{
|
||||||
ProfileWidget::mouseDoubleClickEvent(ev);
|
ProfileWidget::mouseDoubleClickEvent(ev);
|
||||||
|
|
||||||
const int contentMode = getContentMode();
|
if (!ui->cbSelected->isVisible() && getContentMode() == 1 && ev->button() == Qt::LeftButton)
|
||||||
if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton)
|
|
||||||
{
|
{
|
||||||
on_cmdView_clicked();
|
on_cmdView_clicked();
|
||||||
}
|
}
|
||||||
|
|
@ -268,7 +205,31 @@ void SavegameWidget::savegameSelected()
|
||||||
|
|
||||||
void SavegameWidget::contextMenuEvent(QContextMenuEvent *ev)
|
void SavegameWidget::contextMenuEvent(QContextMenuEvent *ev)
|
||||||
{
|
{
|
||||||
emit contextMenuTriggered(ev);
|
QMenu contextMenu(this);
|
||||||
|
contextMenu.addAction(tr("&View"), this, SLOT(on_cmdView_clicked()));
|
||||||
|
contextMenu.addAction(tr("&Export"), this, SLOT(on_cmdCopy_clicked()));
|
||||||
|
contextMenu.addAction(tr("&Remove"), this, SLOT(on_cmdDelete_clicked()));
|
||||||
|
if (ui->cbSelected->isVisible())
|
||||||
|
{
|
||||||
|
contextMenu.addSeparator();
|
||||||
|
if (!ui->cbSelected->isChecked()) { contextMenu.addAction(tr("&Select"), this, SLOT(savegameSelected())); }
|
||||||
|
if (ui->cbSelected->isChecked()) { contextMenu.addAction(tr("&Deselect"), this, SLOT(savegameSelected())); }
|
||||||
|
contextMenu.addAction(tr("Select &All"), this, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A"));
|
||||||
|
ProfileInterface *profileInterface = (ProfileInterface*)snwgt;
|
||||||
|
if (profileInterface->selectedWidgets() != 0)
|
||||||
|
{
|
||||||
|
contextMenu.addAction(tr("&Deselect All"), this, SLOT(deselectAllWidgets()), QKeySequence::fromString("Ctrl+D"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contextMenu.addSeparator();
|
||||||
|
contextMenu.addAction(tr("&Select"), this, SLOT(savegameSelected()));
|
||||||
|
contextMenu.addAction(tr("Select &All"), this, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A"));
|
||||||
|
}
|
||||||
|
//ui->SavegameFrame->setStyleSheet(QString("QFrame#SavegameFrame{background-color: rgb(%1, %2, %3)}QLabel#labSavegameStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue())));
|
||||||
|
contextMenu.exec(ev->globalPos());
|
||||||
|
//ui->SavegameFrame->setStyleSheet("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SavegameWidget::on_cbSelected_stateChanged(int arg1)
|
void SavegameWidget::on_cbSelected_stateChanged(int arg1)
|
||||||
|
|
|
||||||
13
SavegameWidget.h
Normal file → Executable file
13
SavegameWidget.h
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5sync GRAND THEFT AUTO V SYNC
|
||||||
* Copyright (C) 2016-2017 Syping
|
* Copyright (C) 2016 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#ifndef SAVEGAMEWIDGET_H
|
#ifndef SAVEGAMEWIDGET_H
|
||||||
#define SAVEGAMEWIDGET_H
|
#define SAVEGAMEWIDGET_H
|
||||||
|
|
||||||
|
#include "ProfileInterface.h"
|
||||||
#include "ProfileWidget.h"
|
#include "ProfileWidget.h"
|
||||||
#include "SavegameData.h"
|
#include "SavegameData.h"
|
||||||
#include <QContextMenuEvent>
|
#include <QContextMenuEvent>
|
||||||
|
|
@ -41,7 +43,6 @@ public:
|
||||||
SavegameData* getSavegame();
|
SavegameData* getSavegame();
|
||||||
QString getWidgetType();
|
QString getWidgetType();
|
||||||
bool isSelected();
|
bool isSelected();
|
||||||
void retranslate();
|
|
||||||
~SavegameWidget();
|
~SavegameWidget();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
@ -54,6 +55,7 @@ private slots:
|
||||||
void deselectAllWidgets();
|
void deselectAllWidgets();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *ev);
|
||||||
void mouseDoubleClickEvent(QMouseEvent *ev);
|
void mouseDoubleClickEvent(QMouseEvent *ev);
|
||||||
void mouseReleaseEvent(QMouseEvent *ev);
|
void mouseReleaseEvent(QMouseEvent *ev);
|
||||||
void mousePressEvent(QMouseEvent *ev);
|
void mousePressEvent(QMouseEvent *ev);
|
||||||
|
|
@ -62,11 +64,13 @@ protected:
|
||||||
private:
|
private:
|
||||||
Ui::SavegameWidget *ui;
|
Ui::SavegameWidget *ui;
|
||||||
SavegameData *sgdata;
|
SavegameData *sgdata;
|
||||||
|
QColor highlightBackColor;
|
||||||
|
QColor highlightTextColor;
|
||||||
QString labelAutosaveStr;
|
QString labelAutosaveStr;
|
||||||
QString labelSaveStr;
|
QString labelSaveStr;
|
||||||
QString sgdPath;
|
QString sgdPath;
|
||||||
QString sgdStr;
|
QString sgdStr;
|
||||||
void renderString(const QString &savegameString, const QString &fileName);
|
QWidget *snwgt;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void savegameDeleted();
|
void savegameDeleted();
|
||||||
|
|
@ -74,7 +78,6 @@ signals:
|
||||||
void widgetDeselected();
|
void widgetDeselected();
|
||||||
void allWidgetsSelected();
|
void allWidgetsSelected();
|
||||||
void allWidgetsDeselected();
|
void allWidgetsDeselected();
|
||||||
void contextMenuTriggered(QContextMenuEvent *ev);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SAVEGAMEWIDGET_H
|
#endif // SAVEGAMEWIDGET_H
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue