Compare commits
47 Commits
Author | SHA1 | Date |
---|---|---|
Ray | b8e2e14244 | |
Syping | ce0721a6f4 | |
Syping | 022a5045a3 | |
Syping | 446f0b07b0 | |
Syping | 61387ee711 | |
Syping | 259e785165 | |
Syping | e7721404b6 | |
Syping | d6968792aa | |
Syping | 23663d389b | |
Syping | 51f9cffddf | |
Syping | 9c0cc39b4f | |
Syping | 8f8ef469d4 | |
Syping | 4fdde8e485 | |
Syping | 01424ef51f | |
Syping | 12c6b7425c | |
Syping | c74e9a00d0 | |
Syping | 34bc0a5e3e | |
Syping | 71b7b32f60 | |
Syping | 0a812a977a | |
Syping | 40675f605d | |
Syping | 09d79228a0 | |
Syping | 13fa4331fb | |
Syping | 392f35a96d | |
Syping | bb06af8a79 | |
Syping | 0e6a6ae34a | |
Syping | b19cfdee0f | |
Syping | 7f7b202df9 | |
Syping | 6e38894bcc | |
Syping | a10d259db1 | |
Syping | 7e13f01d6d | |
Syping | 489bf531b8 | |
Syping | 7720fb2cac | |
Syping | 557b999608 | |
Syping | aa4b2fc080 | |
Syping | 2d0830254b | |
Syping | b19152fdae | |
Syping | dca2e9fe59 | |
Syping | 4dceb52fe7 | |
Syping | 83e133ddf2 | |
Syping | bb62cc438d | |
Syping | 1528879b42 | |
Syping | a456b06ad3 | |
Syping | 3d87cebeac | |
Syping | 8d866cb44e | |
Syping | 487372f7ee | |
Syping | 050a281be8 | |
Syping | e463d2d22c |
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-2022 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
|
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.1.1"
|
||||
!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: ../
|
|
@ -27,7 +27,8 @@
|
|||
*.out
|
||||
*.app
|
||||
|
||||
# Qt project user file
|
||||
# Qt project user files
|
||||
CMakeLists.txt.user
|
||||
*.pro.user
|
||||
|
||||
# Gettext translation files
|
||||
|
|
|
@ -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/* ./
|
|
@ -0,0 +1,6 @@
|
|||
[submodule "src/libragephoto"]
|
||||
path = src/libragephoto
|
||||
url = https://github.com/Syping/libragephoto.git
|
||||
[submodule "src/json"]
|
||||
path = src/json
|
||||
url = https://github.com/boostorg/json.git
|
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: xcode12.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}
|
253
CMakeLists.txt
253
CMakeLists.txt
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.7)
|
||||
|
||||
project(gta5view LANGUAGES C CXX)
|
||||
project(gta5view VERSION 1.11.0 LANGUAGES C CXX)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
|
@ -8,7 +8,7 @@ set(CMAKE_AUTOUIC ON)
|
|||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "gta5view C++ standard")
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(FORCE_QT_VERSION "" CACHE STRING "Force Qt Version")
|
||||
|
@ -20,6 +20,9 @@ endif()
|
|||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network Svg Widgets REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET)
|
||||
|
||||
set(RAGEPHOTO_STATIC ON CACHE BOOL "Build libragephoto as static library")
|
||||
add_subdirectory(src/libragephoto)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND GTA5VIEW_LIBS
|
||||
dwmapi
|
||||
|
@ -38,7 +41,7 @@ if(APPLE)
|
|||
res/gta5view.icns
|
||||
)
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME gta5view)
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.10.1)
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${gta5view_VERSION})
|
||||
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")
|
||||
|
@ -50,111 +53,107 @@ list(APPEND GTA5VIEW_DEFINES
|
|||
)
|
||||
|
||||
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
|
||||
src/main.cpp
|
||||
src/AboutDialog.cpp
|
||||
src/AppEnv.cpp
|
||||
src/CrewDatabase.cpp
|
||||
src/DatabaseThread.cpp
|
||||
src/ExportDialog.cpp
|
||||
src/ExportThread.cpp
|
||||
src/GlobalString.cpp
|
||||
src/IconLoader.cpp
|
||||
src/ImportDialog.cpp
|
||||
src/JsonEditorDialog.cpp
|
||||
src/MapLocationDialog.cpp
|
||||
src/OptionsDialog.cpp
|
||||
src/PictureDialog.cpp
|
||||
src/PictureExport.cpp
|
||||
src/PictureWidget.cpp
|
||||
src/PlayerListDialog.cpp
|
||||
src/ProfileDatabase.cpp
|
||||
src/ProfileInterface.cpp
|
||||
src/ProfileLoader.cpp
|
||||
src/ProfileWidget.cpp
|
||||
src/SavegameCopy.cpp
|
||||
src/SavegameData.cpp
|
||||
src/SavegameDialog.cpp
|
||||
src/SavegameWidget.cpp
|
||||
src/SnapmaticEditor.cpp
|
||||
src/SnapmaticJson.cpp
|
||||
src/SnapmaticPicture.cpp
|
||||
src/SnapmaticWidget.cpp
|
||||
src/StandardPaths.cpp
|
||||
src/StringParser.cpp
|
||||
src/TranslationClass.cpp
|
||||
src/UserInterface.cpp
|
||||
src/pcg/pcg_basic.c
|
||||
src/uimod/JSHighlighter.cpp
|
||||
src/uimod/UiModLabel.cpp
|
||||
src/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
|
||||
src/config.h
|
||||
src/AboutDialog.h
|
||||
src/AppEnv.h
|
||||
src/CrewDatabase.h
|
||||
src/DatabaseThread.h
|
||||
src/ExportDialog.h
|
||||
src/ExportThread.h
|
||||
src/GlobalString.h
|
||||
src/IconLoader.h
|
||||
src/ImportDialog.h
|
||||
src/JsonEditorDialog.h
|
||||
src/MapLocationDialog.h
|
||||
src/OptionsDialog.h
|
||||
src/PictureDialog.h
|
||||
src/PictureExport.h
|
||||
src/PictureWidget.h
|
||||
src/PlayerListDialog.h
|
||||
src/ProfileDatabase.h
|
||||
src/ProfileInterface.h
|
||||
src/ProfileLoader.h
|
||||
src/ProfileWidget.h
|
||||
src/SavegameCopy.h
|
||||
src/SavegameData.h
|
||||
src/SavegameDialog.h
|
||||
src/SavegameWidget.h
|
||||
src/SnapmaticEditor.h
|
||||
src/SnapmaticJson.h
|
||||
src/SnapmaticPicture.h
|
||||
src/SnapmaticWidget.h
|
||||
src/StandardPaths.h
|
||||
src/StringParser.h
|
||||
src/TranslationClass.h
|
||||
src/UserInterface.h
|
||||
src/pcg/pcg_basic.h
|
||||
src/uimod/JSHighlighter.h
|
||||
src/uimod/UiModLabel.h
|
||||
src/uimod/UiModWidget.h
|
||||
)
|
||||
|
||||
set(GTA5VIEW_INCLUDEDIR
|
||||
anpro
|
||||
pcg
|
||||
uimod
|
||||
src
|
||||
src/anpro
|
||||
src/pcg
|
||||
src/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
|
||||
src/AboutDialog.ui
|
||||
src/ExportDialog.ui
|
||||
src/ImportDialog.ui
|
||||
src/JsonEditorDialog.ui
|
||||
src/MapLocationDialog.ui
|
||||
src/OptionsDialog.ui
|
||||
src/PictureDialog.ui
|
||||
src/PlayerListDialog.ui
|
||||
src/ProfileInterface.ui
|
||||
src/SavegameDialog.ui
|
||||
src/SavegameWidget.ui
|
||||
src/SnapmaticEditor.ui
|
||||
src/SnapmaticWidget.ui
|
||||
src/UserInterface.ui
|
||||
)
|
||||
|
||||
set(GTA5VIEW_TRANSLATIONS
|
||||
|
@ -169,7 +168,6 @@ set(GTA5VIEW_TRANSLATIONS
|
|||
|
||||
list(APPEND GTA5VIEW_RESOURCES
|
||||
res/global.qrc
|
||||
res/template.qrc
|
||||
)
|
||||
set_property(SOURCE res/global.qrc PROPERTY AUTORCC_OPTIONS "-threshold;0;-compress;9")
|
||||
|
||||
|
@ -218,14 +216,45 @@ if(FLATPAK_BUILD)
|
|||
)
|
||||
endif()
|
||||
|
||||
option(RAGEPHOTO_ABI_WRAPPER "Use libragephoto's ABI wrapper" OFF)
|
||||
if(RAGEPHOTO_ABI_WRAPPER)
|
||||
set(RAGEPHOTO_C_API ON CACHE BOOL "Build libragephoto with C API support" FORCE)
|
||||
list(APPEND GTA5VIEW_DEFINES
|
||||
-DRAGEPHOTO_USE_ABI_WRAPPER
|
||||
)
|
||||
endif()
|
||||
|
||||
option(WITH_BOOST "Use linked Boost library" OFF)
|
||||
if(WITH_BOOST)
|
||||
find_package(Boost REQUIRED
|
||||
COMPONENTS json
|
||||
)
|
||||
list(APPEND GTA5VIEW_LIBS
|
||||
Boost::json
|
||||
)
|
||||
list(APPEND GTA5VIEW_DEFINES
|
||||
-DGTA5SYNC_BOOST
|
||||
)
|
||||
list(APPEND GTA5VIEW_INCLUDEDIR
|
||||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
else()
|
||||
list(APPEND GTA5VIEW_DEFINES
|
||||
-DBOOST_JSON_STANDALONE
|
||||
)
|
||||
list(APPEND GTA5VIEW_INCLUDEDIR
|
||||
src/json/include
|
||||
)
|
||||
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
|
||||
src/anpro/QrCode.h
|
||||
)
|
||||
list(APPEND GTA5VIEW_SOURCES
|
||||
anpro/QrCode.cpp
|
||||
src/anpro/QrCode.cpp
|
||||
)
|
||||
list(APPEND GTA5VIEW_DEFINES
|
||||
-DGTA5SYNC_DONATE
|
||||
|
@ -244,10 +273,10 @@ 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
|
||||
src/MessageThread.h
|
||||
)
|
||||
list(APPEND GTA5VIEW_SOURCES
|
||||
MessageThread.cpp
|
||||
src/MessageThread.cpp
|
||||
)
|
||||
list(APPEND GTA5VIEW_DEFINES
|
||||
-DGTA5SYNC_MOTD
|
||||
|
@ -267,15 +296,15 @@ if(WITH_TELEMETRY)
|
|||
set(TELEMETRY_REGURL "" CACHE STRING "Telemetry RegURL")
|
||||
set(TELEMETRY_WEBURL "" CACHE STRING "Telemetry WebURL")
|
||||
list(APPEND GTA5VIEW_HEADERS
|
||||
TelemetryClass.h
|
||||
tmext/TelemetryClassAuthenticator.h
|
||||
src/TelemetryClass.h
|
||||
src/tmext/TelemetryClassAuthenticator.h
|
||||
)
|
||||
list(APPEND GTA5VIEW_SOURCES
|
||||
TelemetryClass.cpp
|
||||
tmext/TelemetryClassAuthenticator.cpp
|
||||
src/TelemetryClass.cpp
|
||||
src/tmext/TelemetryClassAuthenticator.cpp
|
||||
)
|
||||
list(APPEND GTA5VIEW_INCLUDEDIR
|
||||
tmext
|
||||
src/tmext
|
||||
)
|
||||
list(APPEND GTA5VIEW_DEFINES
|
||||
-DGTA5SYNC_TELEMETRY
|
||||
|
@ -351,7 +380,7 @@ if(LINGUIST_FOUND AND QCONF_BUILD)
|
|||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.16.0")
|
||||
target_precompile_headers(gta5view PRIVATE config.h)
|
||||
target_precompile_headers(gta5view PRIVATE src/config.h)
|
||||
endif()
|
||||
|
||||
if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.14.0")
|
||||
|
@ -359,8 +388,8 @@ if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.14.0")
|
|||
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})
|
||||
target_include_directories(gta5view PRIVATE ${GTA5VIEW_INCLUDEDIR} ${RAGEPHOTO_INCLUDE_DIRS})
|
||||
target_link_libraries(gta5view PRIVATE Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::Widgets ragephoto ${GTA5VIEW_LIBS})
|
||||
|
||||
install(TARGETS gta5view DESTINATION bin)
|
||||
install(FILES res/de.syping.gta5view.desktop DESTINATION share/applications)
|
||||
|
|
|
@ -15,7 +15,7 @@ Open Source Snapmatic and Savegame viewer/editor for GTA V
|
|||
|
||||
# Note: Install Docker Community Edition and Git before continuing
|
||||
docker pull sypingauto/gta5view-build:1.10-static
|
||||
git clone https://gitlab.com/Syping/gta5view
|
||||
git clone --recurse-submodules https://gitlab.com/Syping/gta5view
|
||||
docker run --rm -v "$PWD/gta5view:/gta5view" -it sypingauto/gta5view-build:1.10-static
|
||||
mingw64-qt-cmake -B /gta5view/build /gta5view
|
||||
cmake --build /gta5view/build
|
||||
|
@ -23,7 +23,7 @@ Open Source Snapmatic and Savegame viewer/editor for GTA V
|
|||
#### Build gta5view for Debian/Ubuntu
|
||||
|
||||
sudo apt-get install cmake git gcc g++ libqt5svg5-dev make qtbase5-dev qttranslations5-l10n
|
||||
git clone https://gitlab.com/Syping/gta5view
|
||||
git clone --recurse-submodules https://gitlab.com/Syping/gta5view
|
||||
cmake -B gta5view-build gta5view
|
||||
cmake --build gta5view-build
|
||||
sudo cmake --install gta5view-build
|
||||
|
@ -31,7 +31,7 @@ Open Source Snapmatic and Savegame viewer/editor for GTA V
|
|||
#### Build gta5view for Arch/Manjaro
|
||||
|
||||
sudo pacman -S cmake gcc git make qt5-base qt5-svg qt5-tools qt5-translations
|
||||
git clone https://gitlab.com/Syping/gta5view
|
||||
git clone --recurse-submodules https://gitlab.com/Syping/gta5view
|
||||
cmake -B gta5view-build gta5view
|
||||
cmake --build gta5view-build
|
||||
sudo cmake --install gta5view-build
|
||||
|
@ -39,7 +39,7 @@ Open Source Snapmatic and Savegame viewer/editor for GTA V
|
|||
#### 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
|
||||
git clone --recurse-submodules https://gitlab.com/Syping/gta5view
|
||||
cmake -B gta5view-build gta5view
|
||||
cmake --build gta5view-build
|
||||
sudo cmake --install gta5view-build
|
||||
|
|
865
RagePhoto.cpp
865
RagePhoto.cpp
|
@ -1,865 +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
|
||||
|
||||
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_jsonData = t_jsonDocument.toJson(QJsonDocument::Compact);
|
||||
p_jsonObject = t_jsonDocument.object();
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RagePhoto::setPhotoData(const char *data, int size)
|
||||
{
|
||||
if (static_cast<quint32>(size) > p_photoBuffer)
|
||||
return false;
|
||||
p_photoData = QByteArray(data, size);
|
||||
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)
|
||||
{
|
||||
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
|
|
@ -1,61 +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/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SidebarGenerator.h"
|
||||
#include "StandardPaths.h"
|
||||
#include "AppEnv.h"
|
||||
#include <QList>
|
||||
#include <QUrl>
|
||||
#include <QDir>
|
||||
|
||||
SidebarGenerator::SidebarGenerator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QList<QUrl> SidebarGenerator::generateSidebarUrls(QList<QUrl> sidebarUrls)
|
||||
{
|
||||
QDir dir;
|
||||
|
||||
dir.setPath(StandardPaths::picturesLocation());
|
||||
if (dir.exists())
|
||||
{
|
||||
sidebarUrls += QUrl::fromLocalFile(dir.absolutePath());
|
||||
}
|
||||
|
||||
dir.setPath(StandardPaths::documentsLocation());
|
||||
if (dir.exists())
|
||||
{
|
||||
sidebarUrls += QUrl::fromLocalFile(dir.absolutePath());
|
||||
}
|
||||
|
||||
bool gameFolderExists;
|
||||
QString gameFolder = AppEnv::getGameFolder(&gameFolderExists);
|
||||
if (gameFolderExists)
|
||||
{
|
||||
sidebarUrls += QUrl::fromLocalFile(gameFolder);
|
||||
}
|
||||
|
||||
dir.setPath(StandardPaths::desktopLocation());
|
||||
if (dir.exists())
|
||||
{
|
||||
sidebarUrls += QUrl::fromLocalFile(dir.absolutePath());
|
||||
}
|
||||
|
||||
return sidebarUrls;
|
||||
}
|
|
@ -1,836 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5spv Grand Theft Auto Snapmatic Picture 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 "SnapmaticPicture.h"
|
||||
#include <QStringBuilder>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QStringList>
|
||||
#include <QVariantMap>
|
||||
#include <QJsonArray>
|
||||
#include <QFileInfo>
|
||||
#include <QPainter>
|
||||
#include <QString>
|
||||
#include <QBuffer>
|
||||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QSize>
|
||||
#include <QFile>
|
||||
|
||||
#if QT_VERSION < 0x060000
|
||||
#include <QTextCodec>
|
||||
#else
|
||||
#include <QStringDecoder>
|
||||
#endif
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QSaveFile>
|
||||
#else
|
||||
#include "StandardPaths.h"
|
||||
#endif
|
||||
|
||||
// IMAGES VALUES
|
||||
#define snapmaticResolutionW 960
|
||||
#define snapmaticResolutionH 536
|
||||
#define snapmaticResolution QSize(snapmaticResolutionW, snapmaticResolutionH)
|
||||
|
||||
SnapmaticPicture::SnapmaticPicture(const QString &fileName, QObject *parent) : QObject(parent), picFilePath(fileName)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
SnapmaticPicture::~SnapmaticPicture()
|
||||
{
|
||||
}
|
||||
|
||||
void SnapmaticPicture::reset()
|
||||
{
|
||||
// INIT PIC
|
||||
p_ragePhoto.clear();
|
||||
cachePicture = QImage();
|
||||
picExportFileName = QString();
|
||||
pictureStr = QString();
|
||||
lastStep = QString();
|
||||
sortStr = QString();
|
||||
|
||||
// INIT PIC BOOLS
|
||||
isFormatSwitch = false;
|
||||
picOk = false;
|
||||
|
||||
// INIT JSON
|
||||
jsonOk = false;
|
||||
|
||||
// SNAPMATIC PROPERTIES
|
||||
localProperties = {};
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::preloadFile()
|
||||
{
|
||||
QFile *picFile = new QFile(picFilePath);
|
||||
picFileName = QFileInfo(picFilePath).fileName();
|
||||
|
||||
isFormatSwitch = false;
|
||||
|
||||
if (!picFile->open(QFile::ReadOnly)) {
|
||||
lastStep = "1;/1,OpenFile," % convertDrawStringForLog(picFilePath);
|
||||
delete picFile;
|
||||
return false;
|
||||
}
|
||||
|
||||
p_ragePhoto.setIODevice(picFile);
|
||||
bool ok = p_ragePhoto.load();
|
||||
picFile->close();
|
||||
delete picFile;
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (picFilePath.right(4) != QLatin1String(".g5e")) {
|
||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX)
|
||||
isFormatSwitch = true;
|
||||
}
|
||||
emit preloaded();
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::readingPicture(bool cacheEnabled_)
|
||||
{
|
||||
// Start opening file
|
||||
// lastStep is like currentStep
|
||||
|
||||
// Set boolean values
|
||||
cacheEnabled = cacheEnabled_;
|
||||
|
||||
bool ok = true;
|
||||
if (!p_ragePhoto.isLoaded())
|
||||
ok = preloadFile();
|
||||
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (cacheEnabled)
|
||||
picOk = cachePicture.loadFromData(p_ragePhoto.photoData(), "JPEG");
|
||||
if (!cacheEnabled) {
|
||||
QImage tempPicture;
|
||||
picOk = tempPicture.loadFromData(p_ragePhoto.photoData(), "JPEG");
|
||||
}
|
||||
|
||||
parseJsonContent(); // JSON parsing is own function
|
||||
updateStrings();
|
||||
|
||||
emit loaded();
|
||||
return picOk;
|
||||
}
|
||||
|
||||
void SnapmaticPicture::updateStrings()
|
||||
{
|
||||
QString cmpPicTitl = p_ragePhoto.title();
|
||||
cmpPicTitl.replace('\"', "''");
|
||||
cmpPicTitl.replace(' ', '_');
|
||||
cmpPicTitl.replace(':', '-');
|
||||
cmpPicTitl.remove('\\');
|
||||
cmpPicTitl.remove('{');
|
||||
cmpPicTitl.remove('}');
|
||||
cmpPicTitl.remove('/');
|
||||
cmpPicTitl.remove('<');
|
||||
cmpPicTitl.remove('>');
|
||||
cmpPicTitl.remove('*');
|
||||
cmpPicTitl.remove('?');
|
||||
cmpPicTitl.remove('.');
|
||||
pictureStr = tr("PHOTO - %1").arg(localProperties.createdDateTime.toString("MM/dd/yy HH:mm:ss"));
|
||||
sortStr = localProperties.createdDateTime.toString("yyMMddHHmmss") % QString::number(localProperties.uid);
|
||||
QString exportStr = localProperties.createdDateTime.toString("yyyyMMdd") % "-" % QString::number(localProperties.uid);
|
||||
if (getSnapmaticFormat() == SnapmaticFormat::G5E_Format)
|
||||
picFileName = "PGTA5" % QString::number(localProperties.uid);
|
||||
picExportFileName = exportStr % "_" % cmpPicTitl;
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::readingPictureFromFile(const QString &fileName, bool cacheEnabled_)
|
||||
{
|
||||
if (!fileName.isEmpty()) {
|
||||
picFilePath = fileName;
|
||||
return readingPicture(cacheEnabled_);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::setImage(const QImage &picture, bool eXtendMode)
|
||||
{
|
||||
#ifdef GTA5SYNC_DYNAMIC_PHOTOBUFFER
|
||||
quint32 jpegPicStreamLength = p_ragePhoto.photoBuffer();
|
||||
#else
|
||||
quint32 jpegPicStreamLength = 524288U;
|
||||
#endif
|
||||
QByteArray picByteArray;
|
||||
int comLvl = 100;
|
||||
bool saveSuccess = false;
|
||||
while (comLvl != 0 && !saveSuccess) {
|
||||
QByteArray picByteArrayT;
|
||||
QBuffer picStreamT(&picByteArrayT);
|
||||
picStreamT.open(QIODevice::WriteOnly);
|
||||
saveSuccess = picture.save(&picStreamT, "JPEG", comLvl);
|
||||
picStreamT.close();
|
||||
if (saveSuccess) {
|
||||
quint32 size = picByteArrayT.length();
|
||||
if (size > jpegPicStreamLength) {
|
||||
if (!eXtendMode) {
|
||||
comLvl--;
|
||||
saveSuccess = false;
|
||||
}
|
||||
else {
|
||||
p_ragePhoto.setPhotoBuffer(size, true);
|
||||
picByteArray = picByteArrayT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifndef GTA5SYNC_DYNAMIC_PHOTOBUFFER
|
||||
if (p_ragePhoto.photoBuffer() != jpegPicStreamLength)
|
||||
p_ragePhoto.setPhotoData(QByteArray()); // avoid buffer set fail
|
||||
p_ragePhoto.setPhotoBuffer(jpegPicStreamLength, true);
|
||||
#endif
|
||||
picByteArray = picByteArrayT;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (saveSuccess)
|
||||
return setPictureStream(picByteArray);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::setPictureStream(const QByteArray &streamArray) // clean method
|
||||
{
|
||||
bool success = p_ragePhoto.setPhotoData(streamArray);
|
||||
if (success) {
|
||||
if (cacheEnabled) {
|
||||
QImage replacedPicture;
|
||||
replacedPicture.loadFromData(streamArray);
|
||||
cachePicture = replacedPicture;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::setPictureTitl(const QString &newTitle_)
|
||||
{
|
||||
QString newTitle = newTitle_;
|
||||
if (newTitle.length() > 39) {
|
||||
newTitle = newTitle.left(39);
|
||||
}
|
||||
p_ragePhoto.setTitle(newTitle);
|
||||
return true;
|
||||
}
|
||||
|
||||
int SnapmaticPicture::getContentMaxLength()
|
||||
{
|
||||
return p_ragePhoto.photoBuffer();
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getExportPictureFileName()
|
||||
{
|
||||
return picExportFileName;
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getOriginalPictureFileName()
|
||||
{
|
||||
QString newPicFileName = picFileName;
|
||||
if (picFileName.right(4) == ".bak") {
|
||||
newPicFileName = QString(picFileName).remove(picFileName.length() - 4, 4);
|
||||
}
|
||||
if (picFileName.right(7) == ".hidden") {
|
||||
newPicFileName = QString(picFileName).remove(picFileName.length() - 7, 7);
|
||||
}
|
||||
return newPicFileName;
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getOriginalPictureFilePath()
|
||||
{
|
||||
QString newPicFilePath = picFilePath;
|
||||
if (picFilePath.right(4) == ".bak") {
|
||||
newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 4, 4);
|
||||
}
|
||||
if (picFilePath.right(7) == ".hidden") {
|
||||
newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7);
|
||||
}
|
||||
return newPicFilePath;
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getPictureFileName()
|
||||
{
|
||||
return picFileName;
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getPictureFilePath()
|
||||
{
|
||||
return picFilePath;
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getPictureSortStr()
|
||||
{
|
||||
return sortStr;
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getPictureTitl()
|
||||
{
|
||||
return p_ragePhoto.title();
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getPictureStr()
|
||||
{
|
||||
return pictureStr;
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getLastStep(bool readable)
|
||||
{
|
||||
if (readable) {
|
||||
QStringList lastStepList = lastStep.split(";/");
|
||||
if (lastStepList.length() < 2)
|
||||
return lastStep;
|
||||
bool intOk;
|
||||
QStringList descStepList = lastStepList.at(1).split(",");
|
||||
if (descStepList.length() < 1)
|
||||
return lastStep;
|
||||
int argsCount = descStepList.at(0).toInt(&intOk);
|
||||
if (!intOk) { return lastStep; }
|
||||
if (argsCount == 1) {
|
||||
QString currentAction = descStepList.at(1);
|
||||
QString actionFile = descStepList.at(2);
|
||||
if (currentAction == "OpenFile") {
|
||||
return tr("open file %1").arg(actionFile);
|
||||
}
|
||||
}
|
||||
else if (argsCount == 3 || argsCount == 4) {
|
||||
QString currentAction = descStepList.at(1);
|
||||
QString actionFile = descStepList.at(2);
|
||||
QString actionError = descStepList.at(4);
|
||||
QString actionError2;
|
||||
if (argsCount == 4) { actionError2 = descStepList.at(5); }
|
||||
if (currentAction == "ReadingFile") {
|
||||
QString readableError = actionError;
|
||||
if (actionError == "NOHEADER") {
|
||||
readableError = tr("header not exists");
|
||||
}
|
||||
else if (actionError == "MALFORMEDHEADER") {
|
||||
readableError = tr("header is malformed");
|
||||
}
|
||||
else if (actionError == "NOJPEG" || actionError == "NOPIC") {
|
||||
readableError = tr("picture not exists (%1)").arg(actionError);
|
||||
}
|
||||
else if (actionError == "NOJSON" || actionError == "CTJSON") {
|
||||
readableError = tr("JSON not exists (%1)").arg(actionError);
|
||||
}
|
||||
else if (actionError == "NOTITL" || actionError == "CTTITL") {
|
||||
readableError = tr("title not exists (%1)").arg(actionError);
|
||||
}
|
||||
else if (actionError == "NODESC" || actionError == "CTDESC") {
|
||||
readableError = tr("description not exists (%1)").arg(actionError);
|
||||
}
|
||||
else if (actionError == "JSONINCOMPLETE" && actionError2 == "JSONERROR") {
|
||||
readableError = tr("JSON is incomplete and malformed");
|
||||
}
|
||||
else if (actionError == "JSONINCOMPLETE") {
|
||||
readableError = tr("JSON is incomplete");
|
||||
}
|
||||
else if (actionError == "JSONERROR") {
|
||||
readableError = tr("JSON is malformed");
|
||||
}
|
||||
return tr("reading file %1 because of %2", "Example for %2: JSON is malformed error").arg(actionFile, readableError);
|
||||
}
|
||||
else {
|
||||
return lastStep;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return lastStep;
|
||||
}
|
||||
}
|
||||
return lastStep;
|
||||
|
||||
}
|
||||
|
||||
QImage SnapmaticPicture::getImage()
|
||||
{
|
||||
if (cacheEnabled) {
|
||||
return cachePicture;
|
||||
}
|
||||
else {
|
||||
return QImage::fromData(p_ragePhoto.photoData(), "JPEG");
|
||||
}
|
||||
return QImage();
|
||||
}
|
||||
|
||||
QByteArray SnapmaticPicture::getPictureStream()
|
||||
{
|
||||
return p_ragePhoto.photoData();
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::isPicOk()
|
||||
{
|
||||
return picOk;
|
||||
}
|
||||
|
||||
void SnapmaticPicture::clearCache()
|
||||
{
|
||||
cacheEnabled = false;
|
||||
cachePicture = QImage();
|
||||
}
|
||||
|
||||
void SnapmaticPicture::emitUpdate()
|
||||
{
|
||||
emit updated();
|
||||
}
|
||||
|
||||
void SnapmaticPicture::emitCustomSignal(const QString &signal)
|
||||
{
|
||||
emit customSignal(signal);
|
||||
}
|
||||
|
||||
// JSON part
|
||||
|
||||
bool SnapmaticPicture::isJsonOk()
|
||||
{
|
||||
return jsonOk;
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::getJsonStr()
|
||||
{
|
||||
return QString::fromUtf8(p_ragePhoto.jsonData());
|
||||
}
|
||||
|
||||
SnapmaticProperties SnapmaticPicture::getSnapmaticProperties()
|
||||
{
|
||||
return localProperties;
|
||||
}
|
||||
|
||||
void SnapmaticPicture::parseJsonContent()
|
||||
{
|
||||
QJsonObject jsonObject = p_ragePhoto.jsonObject();
|
||||
QVariantMap jsonMap = jsonObject.toVariantMap();
|
||||
|
||||
bool jsonIncomplete = false;
|
||||
bool jsonError = false;
|
||||
if (jsonObject.contains("loc")) {
|
||||
if (jsonObject["loc"].isObject()) {
|
||||
QJsonObject locObject = jsonObject["loc"].toObject();
|
||||
if (locObject.contains("x")) {
|
||||
if (locObject["x"].isDouble()) { localProperties.location.x = locObject["x"].toDouble(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (locObject.contains("y")) {
|
||||
if (locObject["y"].isDouble()) { localProperties.location.y = locObject["y"].toDouble(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (locObject.contains("z")) {
|
||||
if (locObject["z"].isDouble()) { localProperties.location.z = locObject["z"].toDouble(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
}
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("uid")) {
|
||||
bool uidOk;
|
||||
localProperties.uid = jsonMap["uid"].toInt(&uidOk);
|
||||
if (!uidOk) { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("area")) {
|
||||
if (jsonObject["area"].isString()) { localProperties.location.area = jsonObject["area"].toString(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("crewid")) {
|
||||
bool crewIDOk;
|
||||
localProperties.crewID = jsonMap["crewid"].toInt(&crewIDOk);
|
||||
if (!crewIDOk) { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("street")) {
|
||||
bool streetIDOk;
|
||||
localProperties.streetID = jsonMap["street"].toInt(&streetIDOk);
|
||||
if (!streetIDOk) { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("creat")) {
|
||||
bool timestampOk;
|
||||
QDateTime createdTimestamp;
|
||||
localProperties.createdTimestamp = jsonMap["creat"].toUInt(×tampOk);
|
||||
#if QT_VERSION >= 0x060000
|
||||
createdTimestamp.setSecsSinceEpoch(localProperties.createdTimestamp);
|
||||
#else
|
||||
createdTimestamp.setTime_t(localProperties.createdTimestamp);
|
||||
#endif
|
||||
localProperties.createdDateTime = createdTimestamp;
|
||||
if (!timestampOk) { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("plyrs")) {
|
||||
if (jsonObject["plyrs"].isArray()) { localProperties.playersList = jsonMap["plyrs"].toStringList(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
// else { jsonIncomplete = true; } // 2016 Snapmatic pictures left out plyrs when none are captured, so don't force exists on that one
|
||||
if (jsonObject.contains("meme")) {
|
||||
if (jsonObject["meme"].isBool()) { localProperties.isMeme = jsonObject["meme"].toBool(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("mug")) {
|
||||
if (jsonObject["mug"].isBool()) { localProperties.isMug = jsonObject["mug"].toBool(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("slf")) {
|
||||
if (jsonObject["slf"].isBool()) { localProperties.isSelfie = jsonObject["slf"].toBool(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("drctr")) {
|
||||
if (jsonObject["drctr"].isBool()) { localProperties.isFromDirector = jsonObject["drctr"].toBool(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { jsonIncomplete = true; }
|
||||
if (jsonObject.contains("rsedtr")) {
|
||||
if (jsonObject["rsedtr"].isBool()) { localProperties.isFromRSEditor = jsonObject["rsedtr"].toBool(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { localProperties.isFromRSEditor = false; }
|
||||
if (jsonObject.contains("onislandx")) {
|
||||
if (jsonObject["onislandx"].isBool()) { localProperties.location.isCayoPerico = jsonObject["onislandx"].toBool(); }
|
||||
else { jsonError = true; }
|
||||
}
|
||||
else { localProperties.location.isCayoPerico = false; }
|
||||
|
||||
if (!jsonIncomplete && !jsonError) {
|
||||
jsonOk = true;
|
||||
}
|
||||
else {
|
||||
if (jsonIncomplete && jsonError) {
|
||||
lastStep = "2;/4,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE,JSONERROR";
|
||||
}
|
||||
else if (jsonIncomplete) {
|
||||
lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE";
|
||||
}
|
||||
else if (jsonError) {
|
||||
lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONERROR";
|
||||
}
|
||||
jsonOk = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::setSnapmaticProperties(SnapmaticProperties properties)
|
||||
{
|
||||
QJsonObject jsonObject = p_ragePhoto.jsonObject();
|
||||
|
||||
QJsonObject locObject;
|
||||
locObject["x"] = properties.location.x;
|
||||
locObject["y"] = properties.location.y;
|
||||
locObject["z"] = properties.location.z;
|
||||
|
||||
jsonObject["loc"] = locObject;
|
||||
jsonObject["uid"] = properties.uid;
|
||||
jsonObject["area"] = properties.location.area;
|
||||
jsonObject["crewid"] = properties.crewID;
|
||||
jsonObject["street"] = properties.streetID;
|
||||
jsonObject["creat"] = QJsonValue::fromVariant(properties.createdTimestamp);
|
||||
jsonObject["plyrs"] = QJsonValue::fromVariant(properties.playersList);
|
||||
jsonObject["meme"] = properties.isMeme;
|
||||
jsonObject["mug"] = properties.isMug;
|
||||
jsonObject["slf"] = properties.isSelfie;
|
||||
jsonObject["drctr"] = properties.isFromDirector;
|
||||
jsonObject["rsedtr"] = properties.isFromRSEditor;
|
||||
jsonObject["onislandx"] = properties.location.isCayoPerico;
|
||||
|
||||
QJsonDocument jsonDocument(jsonObject);
|
||||
if (setJsonStr(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Compact)))) {
|
||||
localProperties = properties;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::setJsonStr(const QString &newJsonStr, bool updateProperties)
|
||||
{
|
||||
if (p_ragePhoto.setJsonData(newJsonStr.toUtf8())) {
|
||||
if (updateProperties)
|
||||
parseJsonContent();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE MANAGEMENT
|
||||
|
||||
bool SnapmaticPicture::exportPicture(const QString &fileName, SnapmaticFormat format_)
|
||||
{
|
||||
// Keep current format when Auto_Format is used
|
||||
SnapmaticFormat format = format_;
|
||||
if (format_ == SnapmaticFormat::Auto_Format) {
|
||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
|
||||
format = SnapmaticFormat::G5E_Format;
|
||||
}
|
||||
else {
|
||||
format = SnapmaticFormat::PGTA_Format;
|
||||
}
|
||||
}
|
||||
|
||||
bool saveSuccess = false;
|
||||
#if QT_VERSION >= 0x050000
|
||||
QSaveFile *picFile = new QSaveFile(fileName);
|
||||
#else
|
||||
QFile *picFile = new QFile(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp");
|
||||
#endif
|
||||
if (picFile->open(QIODevice::WriteOnly)) {
|
||||
if (format == SnapmaticFormat::G5E_Format) {
|
||||
p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::G5EX);
|
||||
#if QT_VERSION >= 0x050000
|
||||
saveSuccess = picFile->commit();
|
||||
#else
|
||||
saveSuccess = true;
|
||||
picFile->close();
|
||||
#endif
|
||||
delete picFile;
|
||||
}
|
||||
else if (format == SnapmaticFormat::JPEG_Format) {
|
||||
picFile->write(p_ragePhoto.photoData());
|
||||
#if QT_VERSION >= 0x050000
|
||||
saveSuccess = picFile->commit();
|
||||
#else
|
||||
saveSuccess = true;
|
||||
picFile->close();
|
||||
#endif
|
||||
delete picFile;
|
||||
}
|
||||
else {
|
||||
p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::GTA5);
|
||||
#if QT_VERSION >= 0x050000
|
||||
saveSuccess = picFile->commit();
|
||||
#else
|
||||
saveSuccess = true;
|
||||
picFile->close();
|
||||
#endif
|
||||
delete picFile;
|
||||
}
|
||||
#if QT_VERSION <= 0x050000
|
||||
if (saveSuccess) {
|
||||
bool tempBakCreated = false;
|
||||
if (QFile::exists(fileName)) {
|
||||
if (!QFile::rename(fileName, fileName % ".tmp")) {
|
||||
QFile::remove(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp");
|
||||
return false;
|
||||
}
|
||||
tempBakCreated = true;
|
||||
}
|
||||
if (!QFile::rename(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp", fileName)) {
|
||||
QFile::remove(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp");
|
||||
if (tempBakCreated)
|
||||
QFile::rename(fileName % ".tmp", fileName);
|
||||
return false;
|
||||
}
|
||||
if (tempBakCreated)
|
||||
QFile::remove(fileName % ".tmp");
|
||||
}
|
||||
#endif
|
||||
return saveSuccess;
|
||||
}
|
||||
else {
|
||||
delete picFile;
|
||||
return saveSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
void SnapmaticPicture::setPicFileName(const QString &picFileName_)
|
||||
{
|
||||
picFileName = picFileName_;
|
||||
}
|
||||
|
||||
void SnapmaticPicture::setPicFilePath(const QString &picFilePath_)
|
||||
{
|
||||
picFilePath = picFilePath_;
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::deletePicFile()
|
||||
{
|
||||
bool success = false;
|
||||
if (!QFile::exists(picFilePath)) {
|
||||
success = true;
|
||||
}
|
||||
else if (QFile::remove(picFilePath)) {
|
||||
success = true;
|
||||
}
|
||||
if (isHidden()) {
|
||||
const QString picBakPath = QString(picFilePath).remove(picFilePath.length() - 7, 7) % ".bak";
|
||||
if (QFile::exists(picBakPath)) QFile::remove(picBakPath);
|
||||
}
|
||||
else {
|
||||
const QString picBakPath = picFilePath % ".bak";
|
||||
if (QFile::exists(picBakPath)) QFile::remove(picBakPath);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
// VISIBILITY
|
||||
|
||||
bool SnapmaticPicture::isHidden()
|
||||
{
|
||||
if (picFilePath.right(7) == QLatin1String(".hidden")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::isVisible()
|
||||
{
|
||||
if (picFilePath.right(7) == QLatin1String(".hidden")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::setPictureHidden()
|
||||
{
|
||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
|
||||
return false;
|
||||
}
|
||||
if (!isHidden()) {
|
||||
QString newPicFilePath = QString(picFilePath % ".hidden");
|
||||
if (QFile::rename(picFilePath, newPicFilePath)) {
|
||||
picFilePath = newPicFilePath;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::setPictureVisible()
|
||||
{
|
||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
|
||||
return false;
|
||||
}
|
||||
if (isHidden()) {
|
||||
QString newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7);
|
||||
if (QFile::rename(picFilePath, newPicFilePath)) {
|
||||
picFilePath = newPicFilePath;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// PREDEFINED PROPERTIES
|
||||
|
||||
QSize SnapmaticPicture::getSnapmaticResolution()
|
||||
{
|
||||
return snapmaticResolution;
|
||||
}
|
||||
|
||||
// SNAPMATIC FORMAT
|
||||
|
||||
SnapmaticFormat SnapmaticPicture::getSnapmaticFormat()
|
||||
{
|
||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
|
||||
return SnapmaticFormat::G5E_Format;
|
||||
}
|
||||
return SnapmaticFormat::PGTA_Format;
|
||||
}
|
||||
|
||||
void SnapmaticPicture::setSnapmaticFormat(SnapmaticFormat format)
|
||||
{
|
||||
if (format == SnapmaticFormat::G5E_Format) {
|
||||
p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::G5EX);
|
||||
return;
|
||||
}
|
||||
else if (format == SnapmaticFormat::PGTA_Format) {
|
||||
p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::GTA5);
|
||||
return;
|
||||
}
|
||||
qDebug() << "setSnapmaticFormat: Invalid SnapmaticFormat defined, valid SnapmaticFormats are G5E_Format and PGTA_Format";
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::isFormatSwitched()
|
||||
{
|
||||
return isFormatSwitch;
|
||||
}
|
||||
|
||||
// VERIFY CONTENT
|
||||
|
||||
bool SnapmaticPicture::verifyTitle(const QString &title)
|
||||
{
|
||||
// VERIFY TITLE FOR BE A VALID SNAPMATIC TITLE
|
||||
if (title.length() <= 39 && title.length() > 0) {
|
||||
for (const QChar &titleChar : title) {
|
||||
if (!verifyTitleChar(titleChar)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SnapmaticPicture::verifyTitleChar(const QChar &titleChar)
|
||||
{
|
||||
// VERIFY CHAR FOR BE A VALID SNAPMATIC CHARACTER
|
||||
if (titleChar.isLetterOrNumber() || titleChar.isPrint()) {
|
||||
if (titleChar == '<' || titleChar == '>' || titleChar == '\\') return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// STRING OPERATIONS
|
||||
|
||||
QString SnapmaticPicture::parseTitleString(const QByteArray &commitBytes, int maxLength)
|
||||
{
|
||||
Q_UNUSED(maxLength)
|
||||
#if QT_VERSION >= 0x060000
|
||||
QStringDecoder strDecoder = QStringDecoder(QStringDecoder::Utf16LE);
|
||||
QString retStr = strDecoder(commitBytes);
|
||||
retStr = retStr.trimmed();
|
||||
#else
|
||||
QString retStr = QTextCodec::codecForName("UTF-16LE")->toUnicode(commitBytes).trimmed();
|
||||
#endif
|
||||
retStr.remove(QChar('\x00'));
|
||||
return retStr;
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::convertDrawStringForLog(const QString &inputStr)
|
||||
{
|
||||
QString outputStr = inputStr;
|
||||
return outputStr.replace("&","&u;").replace(",", "&c;");
|
||||
}
|
||||
|
||||
QString SnapmaticPicture::convertLogStringForDraw(const QString &inputStr)
|
||||
{
|
||||
QString outputStr = inputStr;
|
||||
return outputStr.replace("&c;",",").replace("&u;", "&");
|
||||
}
|
||||
|
||||
// RAGEPHOTO
|
||||
|
||||
RagePhoto* SnapmaticPicture::ragePhoto()
|
||||
{
|
||||
return &p_ragePhoto;
|
||||
}
|
|
@ -1,537 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* ImageCropper Qt Widget for cropping images
|
||||
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
|
||||
* Copyright (C) 2020 Syping
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "imagecropper.h"
|
||||
#include "AppEnv.h"
|
||||
|
||||
#include <QPainterPath>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
namespace {
|
||||
static const QSize WIDGET_MINIMUM_SIZE(470, 470);
|
||||
}
|
||||
|
||||
ImageCropper::ImageCropper(QWidget* parent) :
|
||||
QWidget(parent),
|
||||
pimpl(new ImageCropperPrivate)
|
||||
{
|
||||
setMinimumSize(WIDGET_MINIMUM_SIZE);
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
ImageCropper::~ImageCropper()
|
||||
{
|
||||
delete pimpl;
|
||||
}
|
||||
|
||||
void ImageCropper::setImage(const QPixmap& _image)
|
||||
{
|
||||
pimpl->imageForCropping = _image;
|
||||
update();
|
||||
}
|
||||
|
||||
void ImageCropper::setBackgroundColor(const QColor& _backgroundColor)
|
||||
{
|
||||
pimpl->backgroundColor = _backgroundColor;
|
||||
update();
|
||||
}
|
||||
|
||||
void ImageCropper::setCroppingRectBorderColor(const QColor& _borderColor)
|
||||
{
|
||||
pimpl->croppingRectBorderColor = _borderColor;
|
||||
update();
|
||||
}
|
||||
|
||||
void ImageCropper::setProportion(const QSizeF& _proportion)
|
||||
{
|
||||
// Пропорции хранятся в коэффициентах приращения сторон
|
||||
// Таким образом, при изменении размера области выделения,
|
||||
// размеры сторон изменяются на размер зависящий от
|
||||
// коэффициентов приращения.
|
||||
|
||||
// Сохраним пропорциональную зависимость области выделения в коэффициентах приращения сторон
|
||||
if (pimpl->proportion != _proportion) {
|
||||
pimpl->proportion = _proportion;
|
||||
// ... расчитаем коэффициенты
|
||||
float heightDelta = (float)_proportion.height() / _proportion.width();
|
||||
float widthDelta = (float)_proportion.width() / _proportion.height();
|
||||
// ... сохраним коэффициенты
|
||||
pimpl->deltas.setHeight(heightDelta);
|
||||
pimpl->deltas.setWidth(widthDelta);
|
||||
}
|
||||
|
||||
// Обновим пропорции области выделения
|
||||
if ( pimpl->isProportionFixed ) {
|
||||
float croppintRectSideRelation =
|
||||
(float)pimpl->croppingRect.width() / pimpl->croppingRect.height();
|
||||
float proportionSideRelation =
|
||||
(float)pimpl->proportion.width() / pimpl->proportion.height();
|
||||
// Если область выделения не соответствует необходимым пропорциям обновим её
|
||||
if (croppintRectSideRelation != proportionSideRelation) {
|
||||
bool widthShotrerThenHeight =
|
||||
pimpl->croppingRect.width() < pimpl->croppingRect.height();
|
||||
// ... установим размер той стороны, что длиннее
|
||||
if (widthShotrerThenHeight) {
|
||||
pimpl->croppingRect.setHeight(
|
||||
pimpl->croppingRect.width() * pimpl->deltas.height());
|
||||
} else {
|
||||
pimpl->croppingRect.setWidth(
|
||||
pimpl->croppingRect.height() * pimpl->deltas.width());
|
||||
}
|
||||
// ... перерисуем виджет
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ImageCropper::setProportionFixed(const bool _isFixed)
|
||||
{
|
||||
if (pimpl->isProportionFixed != _isFixed) {
|
||||
pimpl->isProportionFixed = _isFixed;
|
||||
setProportion(pimpl->proportion);
|
||||
}
|
||||
}
|
||||
|
||||
const QPixmap ImageCropper::cropImage()
|
||||
{
|
||||
// Получим размер отображаемого изображения
|
||||
QSize scaledImageSize =
|
||||
pimpl->imageForCropping.scaled(
|
||||
size(), Qt::KeepAspectRatio, Qt::SmoothTransformation
|
||||
).size();
|
||||
// Определим расстояние от левого и верхнего краёв
|
||||
float leftDelta = 0;
|
||||
float topDelta = 0;
|
||||
const float HALF_COUNT = 2;
|
||||
if (size().height() == scaledImageSize.height()) {
|
||||
leftDelta = (width() - scaledImageSize.width()) / HALF_COUNT;
|
||||
} else {
|
||||
topDelta = (height() - scaledImageSize.height()) / HALF_COUNT;
|
||||
}
|
||||
// Определим пропорцию области обрезки по отношению к исходному изображению
|
||||
float xScale = (float)pimpl->imageForCropping.width() / scaledImageSize.width();
|
||||
float yScale = (float)pimpl->imageForCropping.height() / scaledImageSize.height();
|
||||
// Расчитаем область обрезки с учётом коррекции размеров исходного изображения
|
||||
QRectF realSizeRect(
|
||||
QPointF(pimpl->croppingRect.left() - leftDelta, pimpl->croppingRect.top() - topDelta),
|
||||
pimpl->croppingRect.size());
|
||||
// ... корректируем левый и верхний края
|
||||
realSizeRect.setLeft((pimpl->croppingRect.left() - leftDelta) * xScale);
|
||||
realSizeRect.setTop ((pimpl->croppingRect.top() - topDelta) * yScale);
|
||||
// ... корректируем размер
|
||||
realSizeRect.setWidth(pimpl->croppingRect.width() * xScale);
|
||||
realSizeRect.setHeight(pimpl->croppingRect.height() * yScale);
|
||||
// Получаем обрезанное изображение
|
||||
return pimpl->imageForCropping.copy(realSizeRect.toRect());
|
||||
}
|
||||
|
||||
// ********
|
||||
// Protected section
|
||||
|
||||
void ImageCropper::paintEvent(QPaintEvent* _event)
|
||||
{
|
||||
QWidget::paintEvent(_event);
|
||||
//
|
||||
QPainter widgetPainter(this);
|
||||
// Рисуем изображение по центру виджета
|
||||
{
|
||||
#if QT_VERSION >= 0x050600
|
||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
||||
// ... подгоним изображение для отображения по размеру виджета
|
||||
QPixmap scaledImage =
|
||||
pimpl->imageForCropping.scaled(qRound((double)width() * screenRatioPR), qRound((double)height() * screenRatioPR), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
scaledImage.setDevicePixelRatio(screenRatioPR);
|
||||
#else
|
||||
QPixmap scaledImage =
|
||||
pimpl->imageForCropping.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
#endif
|
||||
// ... заливаем фон
|
||||
widgetPainter.fillRect(rect(), pimpl->backgroundColor);
|
||||
// ... рисуем изображение по центру виджета
|
||||
#if QT_VERSION >= 0x050600
|
||||
if (qRound((double)height() * screenRatioPR) == scaledImage.height()) {
|
||||
widgetPainter.drawPixmap( ( qRound((double)width() * screenRatioPR) - scaledImage.width() ) / 2, 0, scaledImage );
|
||||
} else {
|
||||
widgetPainter.drawPixmap( 0, ( qRound((double)height() * screenRatioPR) - scaledImage.height() ) / 2, scaledImage );
|
||||
}
|
||||
#else
|
||||
if (height() == scaledImage.height()) {
|
||||
widgetPainter.drawPixmap( ( width()- scaledImage.width() ) / 2, 0, scaledImage );
|
||||
} else {
|
||||
widgetPainter.drawPixmap( 0, ( height() - scaledImage.height() ) / 2, scaledImage );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// Рисуем область обрезки
|
||||
{
|
||||
// ... если это первое отображение после инициилизации, то центруем областо обрезки
|
||||
if (pimpl->croppingRect.isNull()) {
|
||||
const int cwidth = WIDGET_MINIMUM_SIZE.width()/2;
|
||||
const int cheight = WIDGET_MINIMUM_SIZE.height()/2;
|
||||
pimpl->croppingRect.setSize(QSize(cwidth, cheight));
|
||||
float x = (width() - pimpl->croppingRect.width())/2;
|
||||
float y = (height() - pimpl->croppingRect.height())/2;
|
||||
pimpl->croppingRect.moveTo(x, y);
|
||||
}
|
||||
|
||||
// ... рисуем затемненную область
|
||||
QPainterPath p;
|
||||
p.addRect(pimpl->croppingRect);
|
||||
p.addRect(rect());
|
||||
widgetPainter.setBrush(QBrush(QColor(0,0,0,120)));
|
||||
widgetPainter.setPen(Qt::transparent);
|
||||
widgetPainter.drawPath(p);
|
||||
// Рамка и контрольные точки
|
||||
widgetPainter.setPen(pimpl->croppingRectBorderColor);
|
||||
// ... рисуем прямоугольник области обрезки
|
||||
{
|
||||
widgetPainter.setBrush(QBrush(Qt::transparent));
|
||||
widgetPainter.drawRect(pimpl->croppingRect);
|
||||
}
|
||||
// ... рисуем контрольные точки
|
||||
{
|
||||
widgetPainter.setBrush(QBrush(pimpl->croppingRectBorderColor));
|
||||
// Вспомогательные X координаты
|
||||
int leftXCoord = pimpl->croppingRect.left() - 2;
|
||||
int centerXCoord = pimpl->croppingRect.center().x() - 3;
|
||||
int rightXCoord = pimpl->croppingRect.right() - 2;
|
||||
// Вспомогательные Y координаты
|
||||
int topYCoord = pimpl->croppingRect.top() - 2;
|
||||
int middleYCoord = pimpl->croppingRect.center().y() - 3;
|
||||
int bottomYCoord = pimpl->croppingRect.bottom() - 2;
|
||||
//
|
||||
const QSize pointSize(6, 6);
|
||||
//
|
||||
QVector<QRect> points;
|
||||
points
|
||||
// левая сторона
|
||||
<< QRect( QPoint(leftXCoord, topYCoord), pointSize )
|
||||
<< QRect( QPoint(leftXCoord, middleYCoord), pointSize )
|
||||
<< QRect( QPoint(leftXCoord, bottomYCoord), pointSize )
|
||||
// центр
|
||||
<< QRect( QPoint(centerXCoord, topYCoord), pointSize )
|
||||
<< QRect( QPoint(centerXCoord, middleYCoord), pointSize )
|
||||
<< QRect( QPoint(centerXCoord, bottomYCoord), pointSize )
|
||||
// правая сторона
|
||||
<< QRect( QPoint(rightXCoord, topYCoord), pointSize )
|
||||
<< QRect( QPoint(rightXCoord, middleYCoord), pointSize )
|
||||
<< QRect( QPoint(rightXCoord, bottomYCoord), pointSize );
|
||||
//
|
||||
widgetPainter.drawRects( points );
|
||||
}
|
||||
// ... рисуем пунктирные линии
|
||||
{
|
||||
QPen dashPen(pimpl->croppingRectBorderColor);
|
||||
dashPen.setStyle(Qt::DashLine);
|
||||
widgetPainter.setPen(dashPen);
|
||||
// ... вертикальная
|
||||
widgetPainter.drawLine(
|
||||
QPoint(pimpl->croppingRect.center().x(), pimpl->croppingRect.top()),
|
||||
QPoint(pimpl->croppingRect.center().x(), pimpl->croppingRect.bottom()) );
|
||||
// ... горизонтальная
|
||||
widgetPainter.drawLine(
|
||||
QPoint(pimpl->croppingRect.left(), pimpl->croppingRect.center().y()),
|
||||
QPoint(pimpl->croppingRect.right(), pimpl->croppingRect.center().y()) );
|
||||
}
|
||||
}
|
||||
//
|
||||
widgetPainter.end();
|
||||
}
|
||||
|
||||
void ImageCropper::mousePressEvent(QMouseEvent* _event)
|
||||
{
|
||||
if (_event->button() == Qt::LeftButton) {
|
||||
pimpl->isMousePressed = true;
|
||||
pimpl->startMousePos = _event->pos();
|
||||
pimpl->lastStaticCroppingRect = pimpl->croppingRect;
|
||||
}
|
||||
//
|
||||
updateCursorIcon(_event->pos());
|
||||
}
|
||||
|
||||
void ImageCropper::mouseMoveEvent(QMouseEvent* _event)
|
||||
{
|
||||
QPointF mousePos = _event->pos(); // относительно себя (виджета)
|
||||
//
|
||||
if (!pimpl->isMousePressed) {
|
||||
// Обработка обычного состояния, т.е. не изменяется размер
|
||||
// области обрезки, и она не перемещается по виджету
|
||||
pimpl->cursorPosition = cursorPosition(pimpl->croppingRect, mousePos);
|
||||
updateCursorIcon(mousePos);
|
||||
} else if (pimpl->cursorPosition != CursorPositionUndefined) {
|
||||
// Обработка действий над областью обрезки
|
||||
// ... определим смещение курсора мышки
|
||||
QPointF mouseDelta;
|
||||
mouseDelta.setX( mousePos.x() - pimpl->startMousePos.x() );
|
||||
mouseDelta.setY( mousePos.y() - pimpl->startMousePos.y() );
|
||||
//
|
||||
if (pimpl->cursorPosition != CursorPositionMiddle) {
|
||||
// ... изменяем размер области обрезки
|
||||
QRectF newGeometry =
|
||||
calculateGeometry(
|
||||
pimpl->lastStaticCroppingRect,
|
||||
pimpl->cursorPosition,
|
||||
mouseDelta);
|
||||
// ... пользователь пытается вывернуть область обрезки наизнанку
|
||||
if (!newGeometry.isNull()) {
|
||||
pimpl->croppingRect = newGeometry;
|
||||
}
|
||||
} else {
|
||||
// ... перемещаем область обрезки
|
||||
pimpl->croppingRect.moveTo( pimpl->lastStaticCroppingRect.topLeft() + mouseDelta );
|
||||
}
|
||||
// Перерисуем виджет
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageCropper::mouseReleaseEvent(QMouseEvent* _event)
|
||||
{
|
||||
pimpl->isMousePressed = false;
|
||||
updateCursorIcon(_event->pos());
|
||||
}
|
||||
|
||||
// ********
|
||||
// Private section
|
||||
|
||||
namespace {
|
||||
// Находится ли точка рядом с координатой стороны
|
||||
static bool isPointNearSide (const int _sideCoordinate, const int _pointCoordinate)
|
||||
{
|
||||
static const int indent = 10;
|
||||
return (_sideCoordinate - indent) < _pointCoordinate && _pointCoordinate < (_sideCoordinate + indent);
|
||||
}
|
||||
}
|
||||
|
||||
CursorPosition ImageCropper::cursorPosition(const QRectF& _cropRect, const QPointF& _mousePosition)
|
||||
{
|
||||
CursorPosition cursorPosition = CursorPositionUndefined;
|
||||
//
|
||||
if ( _cropRect.contains( _mousePosition ) ) {
|
||||
// Двухстороннее направление
|
||||
if (isPointNearSide(_cropRect.top(), _mousePosition.y()) &&
|
||||
isPointNearSide(_cropRect.left(), _mousePosition.x())) {
|
||||
cursorPosition = CursorPositionTopLeft;
|
||||
} else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y()) &&
|
||||
isPointNearSide(_cropRect.left(), _mousePosition.x())) {
|
||||
cursorPosition = CursorPositionBottomLeft;
|
||||
} else if (isPointNearSide(_cropRect.top(), _mousePosition.y()) &&
|
||||
isPointNearSide(_cropRect.right(), _mousePosition.x())) {
|
||||
cursorPosition = CursorPositionTopRight;
|
||||
} else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y()) &&
|
||||
isPointNearSide(_cropRect.right(), _mousePosition.x())) {
|
||||
cursorPosition = CursorPositionBottomRight;
|
||||
// Одностороннее направление
|
||||
} else if (isPointNearSide(_cropRect.left(), _mousePosition.x())) {
|
||||
cursorPosition = CursorPositionLeft;
|
||||
} else if (isPointNearSide(_cropRect.right(), _mousePosition.x())) {
|
||||
cursorPosition = CursorPositionRight;
|
||||
} else if (isPointNearSide(_cropRect.top(), _mousePosition.y())) {
|
||||
cursorPosition = CursorPositionTop;
|
||||
} else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y())) {
|
||||
cursorPosition = CursorPositionBottom;
|
||||
// Без направления
|
||||
} else {
|
||||
cursorPosition = CursorPositionMiddle;
|
||||
}
|
||||
}
|
||||
//
|
||||
return cursorPosition;
|
||||
}
|
||||
|
||||
void ImageCropper::updateCursorIcon(const QPointF& _mousePosition)
|
||||
{
|
||||
QCursor cursorIcon;
|
||||
//
|
||||
switch (cursorPosition(pimpl->croppingRect, _mousePosition))
|
||||
{
|
||||
case CursorPositionTopRight:
|
||||
case CursorPositionBottomLeft:
|
||||
cursorIcon = QCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
case CursorPositionTopLeft:
|
||||
case CursorPositionBottomRight:
|
||||
cursorIcon = QCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
case CursorPositionTop:
|
||||
case CursorPositionBottom:
|
||||
cursorIcon = QCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
case CursorPositionLeft:
|
||||
case CursorPositionRight:
|
||||
cursorIcon = QCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
case CursorPositionMiddle:
|
||||
cursorIcon = pimpl->isMousePressed ?
|
||||
QCursor(Qt::ClosedHandCursor) :
|
||||
QCursor(Qt::OpenHandCursor);
|
||||
break;
|
||||
case CursorPositionUndefined:
|
||||
default:
|
||||
cursorIcon = QCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
}
|
||||
//
|
||||
this->setCursor(cursorIcon);
|
||||
}
|
||||
|
||||
const QRectF ImageCropper::calculateGeometry(
|
||||
const QRectF& _sourceGeometry,
|
||||
const CursorPosition _cursorPosition,
|
||||
const QPointF& _mouseDelta
|
||||
)
|
||||
{
|
||||
QRectF resultGeometry;
|
||||
//
|
||||
if ( pimpl->isProportionFixed ) {
|
||||
resultGeometry =
|
||||
calculateGeometryWithFixedProportions(
|
||||
_sourceGeometry, _cursorPosition, _mouseDelta, pimpl->deltas);
|
||||
} else {
|
||||
resultGeometry =
|
||||
calculateGeometryWithCustomProportions(
|
||||
_sourceGeometry, _cursorPosition, _mouseDelta);
|
||||
}
|
||||
// Если пользователь пытается вывернуть область обрезки наизнанку,
|
||||
// возвращаем null-прямоугольник
|
||||
if ((resultGeometry.left() >= resultGeometry.right()) ||
|
||||
(resultGeometry.top() >= resultGeometry.bottom())) {
|
||||
resultGeometry = QRect();
|
||||
}
|
||||
//
|
||||
return resultGeometry;
|
||||
}
|
||||
|
||||
const QRectF ImageCropper::calculateGeometryWithCustomProportions(
|
||||
const QRectF& _sourceGeometry,
|
||||
const CursorPosition _cursorPosition,
|
||||
const QPointF& _mouseDelta
|
||||
)
|
||||
{
|
||||
QRectF resultGeometry = _sourceGeometry;
|
||||
//
|
||||
switch ( _cursorPosition )
|
||||
{
|
||||
case CursorPositionTopLeft:
|
||||
resultGeometry.setLeft( _sourceGeometry.left() + _mouseDelta.x() );
|
||||
resultGeometry.setTop ( _sourceGeometry.top() + _mouseDelta.y() );
|
||||
break;
|
||||
case CursorPositionTopRight:
|
||||
resultGeometry.setTop ( _sourceGeometry.top() + _mouseDelta.y() );
|
||||
resultGeometry.setRight( _sourceGeometry.right() + _mouseDelta.x() );
|
||||
break;
|
||||
case CursorPositionBottomLeft:
|
||||
resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() );
|
||||
resultGeometry.setLeft ( _sourceGeometry.left() + _mouseDelta.x() );
|
||||
break;
|
||||
case CursorPositionBottomRight:
|
||||
resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() );
|
||||
resultGeometry.setRight ( _sourceGeometry.right() + _mouseDelta.x() );
|
||||
break;
|
||||
case CursorPositionTop:
|
||||
resultGeometry.setTop( _sourceGeometry.top() + _mouseDelta.y() );
|
||||
break;
|
||||
case CursorPositionBottom:
|
||||
resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() );
|
||||
break;
|
||||
case CursorPositionLeft:
|
||||
resultGeometry.setLeft( _sourceGeometry.left() + _mouseDelta.x() );
|
||||
break;
|
||||
case CursorPositionRight:
|
||||
resultGeometry.setRight( _sourceGeometry.right() + _mouseDelta.x() );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//
|
||||
return resultGeometry;
|
||||
}
|
||||
|
||||
const QRectF ImageCropper::calculateGeometryWithFixedProportions(
|
||||
const QRectF& _sourceGeometry,
|
||||
const CursorPosition _cursorPosition,
|
||||
const QPointF& _mouseDelta,
|
||||
const QSizeF& _deltas
|
||||
)
|
||||
{
|
||||
QRectF resultGeometry = _sourceGeometry;
|
||||
//
|
||||
switch (_cursorPosition)
|
||||
{
|
||||
case CursorPositionLeft:
|
||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.x() * _deltas.height());
|
||||
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x());
|
||||
break;
|
||||
case CursorPositionRight:
|
||||
resultGeometry.setTop(_sourceGeometry.top() - _mouseDelta.x() * _deltas.height());
|
||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x());
|
||||
break;
|
||||
case CursorPositionTop:
|
||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y());
|
||||
resultGeometry.setRight(_sourceGeometry.right() - _mouseDelta.y() * _deltas.width());
|
||||
break;
|
||||
case CursorPositionBottom:
|
||||
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y());
|
||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.y() * _deltas.width());
|
||||
break;
|
||||
case CursorPositionTopLeft:
|
||||
if ((_mouseDelta.x() * _deltas.height()) < (_mouseDelta.y())) {
|
||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.x() * _deltas.height());
|
||||
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x());
|
||||
} else {
|
||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y());
|
||||
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.y() * _deltas.width());
|
||||
}
|
||||
break;
|
||||
case CursorPositionTopRight:
|
||||
if ((_mouseDelta.x() * _deltas.height() * -1) < (_mouseDelta.y())) {
|
||||
resultGeometry.setTop(_sourceGeometry.top() - _mouseDelta.x() * _deltas.height());
|
||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x() );
|
||||
} else {
|
||||
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y());
|
||||
resultGeometry.setRight(_sourceGeometry.right() - _mouseDelta.y() * _deltas.width());
|
||||
}
|
||||
break;
|
||||
case CursorPositionBottomLeft:
|
||||
if ((_mouseDelta.x() * _deltas.height()) < (_mouseDelta.y() * -1)) {
|
||||
resultGeometry.setBottom(_sourceGeometry.bottom() - _mouseDelta.x() * _deltas.height());
|
||||
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x());
|
||||
} else {
|
||||
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y());
|
||||
resultGeometry.setLeft(_sourceGeometry.left() - _mouseDelta.y() * _deltas.width());
|
||||
}
|
||||
break;
|
||||
case CursorPositionBottomRight:
|
||||
if ((_mouseDelta.x() * _deltas.height()) > (_mouseDelta.y())) {
|
||||
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.x() * _deltas.height());
|
||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x());
|
||||
} else {
|
||||
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y());
|
||||
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.y() * _deltas.width());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//
|
||||
return resultGeometry;
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* ImageCropper Qt Widget for cropping images
|
||||
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef IMAGECROPPER_H
|
||||
#define IMAGECROPPER_H
|
||||
|
||||
#include "imagecropper_p.h"
|
||||
#include "imagecropper_e.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class ImageCropper : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ImageCropper(QWidget *parent = 0);
|
||||
~ImageCropper();
|
||||
|
||||
public slots:
|
||||
// Установить изображение для обрезки
|
||||
void setImage(const QPixmap& _image);
|
||||
// Установить цвет фона виджета обрезки
|
||||
void setBackgroundColor(const QColor& _backgroundColor);
|
||||
// Установить цвет рамки области обрезки
|
||||
void setCroppingRectBorderColor(const QColor& _borderColor);
|
||||
// Установить пропорции области выделения
|
||||
void setProportion(const QSizeF& _proportion);
|
||||
// Использовать фиксированные пропорции области виделения
|
||||
void setProportionFixed(const bool _isFixed);
|
||||
|
||||
public:
|
||||
// Обрезать изображение
|
||||
const QPixmap cropImage();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* _event);
|
||||
virtual void mousePressEvent(QMouseEvent* _event);
|
||||
virtual void mouseMoveEvent(QMouseEvent* _event);
|
||||
virtual void mouseReleaseEvent(QMouseEvent* _event);
|
||||
|
||||
private:
|
||||
// Определение местоположения курсора над виджетом
|
||||
CursorPosition cursorPosition(const QRectF& _cropRect, const QPointF& _mousePosition);
|
||||
// Обновить иконку курсора соответствующую местоположению мыши
|
||||
void updateCursorIcon(const QPointF& _mousePosition);
|
||||
|
||||
// Получить размер виджета после его изменения мышью
|
||||
// --------
|
||||
// Контракты:
|
||||
// 1. Метод должен вызываться, только при зажатой кнопке мыши
|
||||
// (т.е. при перемещении или изменении размера виджета)
|
||||
// --------
|
||||
// В случае неудачи возвращает null-прямоугольник
|
||||
const QRectF calculateGeometry(
|
||||
const QRectF& _sourceGeometry,
|
||||
const CursorPosition _cursorPosition,
|
||||
const QPointF& _mouseDelta
|
||||
);
|
||||
// Получить размер виджета после его изменения мышью
|
||||
// Метод изменяет виджет не сохраняя начальных пропорций сторон
|
||||
// ------
|
||||
// Контракты:
|
||||
// 1. Метод должен вызываться, только при зажатой кнопке мыши
|
||||
// (т.е. при перемещении или изменении размера виджета)
|
||||
const QRectF calculateGeometryWithCustomProportions(
|
||||
const QRectF& _sourceGeometry,
|
||||
const CursorPosition _cursorPosition,
|
||||
const QPointF& _mouseDelta
|
||||
);
|
||||
// Получить размер виджета после его изменения мышью
|
||||
// Метод изменяет виджет сохраняя начальные пропорции сторон
|
||||
// ------
|
||||
// Контракты:
|
||||
// 1. Метод должен вызываться, только при зажатой кнопке мыши
|
||||
// (т.е. при перемещении или изменении размера виджета)
|
||||
const QRectF calculateGeometryWithFixedProportions(const QRectF &_sourceGeometry,
|
||||
const CursorPosition _cursorPosition,
|
||||
const QPointF &_mouseDelta,
|
||||
const QSizeF &_deltas
|
||||
);
|
||||
|
||||
private:
|
||||
// Private data implementation
|
||||
ImageCropperPrivate* pimpl;
|
||||
};
|
||||
|
||||
#endif // IMAGECROPPER_H
|
|
@ -1,36 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* ImageCropper Qt Widget for cropping images
|
||||
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef IMAGECROPPER_E_H
|
||||
#define IMAGECROPPER_E_H
|
||||
|
||||
enum CursorPosition
|
||||
{
|
||||
CursorPositionUndefined,
|
||||
CursorPositionMiddle,
|
||||
CursorPositionTop,
|
||||
CursorPositionBottom,
|
||||
CursorPositionLeft,
|
||||
CursorPositionRight,
|
||||
CursorPositionTopLeft,
|
||||
CursorPositionTopRight,
|
||||
CursorPositionBottomLeft,
|
||||
CursorPositionBottomRight
|
||||
};
|
||||
|
||||
#endif // IMAGECROPPER_E_H
|
|
@ -1,76 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* ImageCropper Qt Widget for cropping images
|
||||
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef IMAGECROPPER_P_H
|
||||
#define IMAGECROPPER_P_H
|
||||
|
||||
#include "imagecropper_e.h"
|
||||
|
||||
#include <QtCore/QRect>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QColor>
|
||||
|
||||
namespace {
|
||||
const QRect INIT_CROPPING_RECT = QRect();
|
||||
const QSizeF INIT_PROPORTION = QSizeF(1.0, 1.0);
|
||||
}
|
||||
|
||||
class ImageCropperPrivate {
|
||||
public:
|
||||
ImageCropperPrivate() :
|
||||
imageForCropping(QPixmap()),
|
||||
croppingRect(INIT_CROPPING_RECT),
|
||||
lastStaticCroppingRect(QRect()),
|
||||
cursorPosition(CursorPositionUndefined),
|
||||
isMousePressed(false),
|
||||
isProportionFixed(false),
|
||||
startMousePos(QPoint()),
|
||||
proportion(INIT_PROPORTION),
|
||||
deltas(INIT_PROPORTION),
|
||||
backgroundColor(Qt::black),
|
||||
croppingRectBorderColor(Qt::white)
|
||||
{}
|
||||
|
||||
public:
|
||||
// Изображение для обрезки
|
||||
QPixmap imageForCropping;
|
||||
// Область обрезки
|
||||
QRectF croppingRect;
|
||||
// Последняя фиксированная область обрезки
|
||||
QRectF lastStaticCroppingRect;
|
||||
// Позиция курсора относительно области обрезки
|
||||
CursorPosition cursorPosition;
|
||||
// Зажата ли левая кнопка мыши
|
||||
bool isMousePressed;
|
||||
// Фиксировать пропорции области обрезки
|
||||
bool isProportionFixed;
|
||||
// Начальная позиция курсора при изменении размера области обрезки
|
||||
QPointF startMousePos;
|
||||
// Пропорции
|
||||
QSizeF proportion;
|
||||
// Приращения
|
||||
// width - приращение по x
|
||||
// height - приращение по y
|
||||
QSizeF deltas;
|
||||
// Цвет заливки фона под изображением
|
||||
QColor backgroundColor;
|
||||
// Цвет рамки области обрезки
|
||||
QColor croppingRectBorderColor;
|
||||
};
|
||||
|
||||
#endif // IMAGECROPPER_P_H
|
285
gta5view.pro
285
gta5view.pro
|
@ -1,285 +0,0 @@
|
|||
#/*****************************************************************************
|
||||
#* gta5view Grand Theft Auto V Profile Viewer
|
||||
#* Copyright (C) 2015-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/>.
|
||||
#*****************************************************************************/
|
||||
|
||||
QT += core gui network svg
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
greaterThan(QT_MAJOR_VERSION, 4): win32: LIBS += -ldwmapi
|
||||
|
||||
DEPLOYMENT.display_name = gta5view
|
||||
TARGET = gta5view
|
||||
TEMPLATE = app
|
||||
|
||||
HEADERS += config.h \
|
||||
wrapper.h
|
||||
PRECOMPILED_HEADER += config.h
|
||||
|
||||
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 \
|
||||
MessageThread.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 \
|
||||
TelemetryClass.cpp \
|
||||
TranslationClass.cpp \
|
||||
UserInterface.cpp \
|
||||
anpro/imagecropper.cpp \
|
||||
pcg/pcg_basic.c \
|
||||
tmext/TelemetryClassAuthenticator.cpp \
|
||||
uimod/JSHighlighter.cpp \
|
||||
uimod/UiModLabel.cpp \
|
||||
uimod/UiModWidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
AboutDialog.h \
|
||||
AppEnv.h \
|
||||
CrewDatabase.h \
|
||||
DatabaseThread.h \
|
||||
ExportDialog.h \
|
||||
ExportThread.h \
|
||||
GlobalString.h \
|
||||
IconLoader.h \
|
||||
ImportDialog.h \
|
||||
JsonEditorDialog.h \
|
||||
MapLocationDialog.h \
|
||||
MessageThread.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 \
|
||||
TelemetryClass.h \
|
||||
TranslationClass.h \
|
||||
UserInterface.h \
|
||||
anpro/imagecropper.h \
|
||||
anpro/imagecropper_e.h \
|
||||
anpro/imagecropper_p.h \
|
||||
pcg/pcg_basic.h \
|
||||
tmext/TelemetryClassAuthenticator.h \
|
||||
uimod/JSHighlighter.h \
|
||||
uimod/UiModLabel.h \
|
||||
uimod/UiModWidget.h
|
||||
|
||||
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
|
||||
|
||||
TRANSLATIONS += \
|
||||
res/gta5sync.ts \
|
||||
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
|
||||
|
||||
RESOURCES += \
|
||||
res/img.qrc \
|
||||
res/template.qrc \
|
||||
res/tr_g5p.qrc
|
||||
|
||||
DISTFILES += \
|
||||
res/gta5view-16.png \
|
||||
res/gta5view-24.png \
|
||||
res/gta5view-32.png \
|
||||
res/gta5view-40.png \
|
||||
res/gta5view-48.png \
|
||||
res/gta5view-64.png \
|
||||
res/gta5view-96.png \
|
||||
res/gta5view-128.png \
|
||||
res/gta5view-256.png \
|
||||
res/gta5view-512.png \
|
||||
res/app.rc \
|
||||
res/de.syping.gta5view.desktop \
|
||||
res/de.syping.gta5view.png \
|
||||
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 \
|
||||
res/gta5view.exe.manifest \
|
||||
res/gta5view.png \
|
||||
lang/README.txt
|
||||
|
||||
INCLUDEPATH += ./anpro ./pcg ./tmext ./uimod
|
||||
|
||||
# GTA5SYNC/GTA5VIEW ONLY
|
||||
|
||||
DEFINES += GTA5SYNC_QMAKE # We using qmake do we?
|
||||
DEFINES += GTA5SYNC_PROJECT # Enable exclusive gta5sync/gta5view functions
|
||||
|
||||
# WINDOWS ONLY
|
||||
|
||||
win32: RC_FILE += res/app.rc
|
||||
win32: CONFIG -= embed_manifest_exe
|
||||
contains(DEFINES, GTA5SYNC_TELEMETRY): win32: LIBS += -ld3d9 # Required for getting information about GPU
|
||||
|
||||
# MAC OS X ONLY
|
||||
macx: ICON = res/gta5view.icns
|
||||
|
||||
# QT4 ONLY STUFF
|
||||
|
||||
isEqual(QT_MAJOR_VERSION, 4): INCLUDEPATH += ./qjson4
|
||||
isEqual(QT_MAJOR_VERSION, 4): HEADERS += qjson4/QJsonArray.h \
|
||||
qjson4/QJsonDocument.h \
|
||||
qjson4/QJsonObject.h \
|
||||
qjson4/QJsonParseError.h \
|
||||
qjson4/QJsonValue.h \
|
||||
qjson4/QJsonValueRef.h \
|
||||
qjson4/QJsonParser.h \
|
||||
qjson4/QJsonRoot.h
|
||||
|
||||
isEqual(QT_MAJOR_VERSION, 4): SOURCES += qjson4/QJsonArray.cpp \
|
||||
qjson4/QJsonDocument.cpp \
|
||||
qjson4/QJsonObject.cpp \
|
||||
qjson4/QJsonParseError.cpp \
|
||||
qjson4/QJsonValue.cpp \
|
||||
qjson4/QJsonValueRef.cpp \
|
||||
qjson4/QJsonParser.cpp
|
||||
|
||||
isEqual(QT_MAJOR_VERSION, 4): RESOURCES += res/qt4/tr_qt.qrc
|
||||
isEqual(QT_MAJOR_VERSION, 4): GTA5SYNC_RCC = $$[QT_INSTALL_BINS]/rcc
|
||||
|
||||
# QT5 ONLY STUFF
|
||||
|
||||
isEqual(QT_MAJOR_VERSION, 5): RESOURCES += res/qt5/tr_qt.qrc
|
||||
|
||||
# QT5+ ONLY STUFF
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): GTA5SYNC_RCC = $$[QT_HOST_BINS]/rcc
|
||||
|
||||
# QT6 ONLY STUFF
|
||||
|
||||
isEqual(QT_MAJOR_VERSION, 6): RESOURCES += res/qt6/tr_qt.qrc
|
||||
|
||||
# RESOURCE COMPILATION
|
||||
|
||||
system($$GTA5SYNC_RCC -threshold 0 -compress 9 $$PWD/res/global.qrc -o $$OUT_PWD/qrc_global.cpp) {
|
||||
SOURCES += $$OUT_PWD/qrc_global.cpp
|
||||
} else {
|
||||
message("Failed to generate qrc_global.cpp")
|
||||
}
|
||||
|
||||
# PROJECT INSTALLATION
|
||||
|
||||
isEmpty(GTA5SYNC_PREFIX): GTA5SYNC_PREFIX = /usr/local
|
||||
|
||||
appfiles.path = $$GTA5SYNC_PREFIX/share/applications
|
||||
appfiles.files = $$PWD/res/de.syping.gta5view.desktop
|
||||
pixmaps.path = $$GTA5SYNC_PREFIX/share/pixmaps
|
||||
pixmaps.files = $$PWD/res/de.syping.gta5view.png
|
||||
target.path = $$GTA5SYNC_PREFIX/bin
|
||||
INSTALLS += target pixmaps appfiles
|
||||
|
||||
# QCONF BASED BUILD STUFF
|
||||
|
||||
contains(DEFINES, GTA5SYNC_QCONF) {
|
||||
isEqual(QT_MAJOR_VERSION, 4): RESOURCES -= res/qt4/tr_qt.qrc
|
||||
isEqual(QT_MAJOR_VERSION, 5): RESOURCES -= res/qt5/tr_qt.qrc
|
||||
isEqual(QT_MAJOR_VERSION, 6): RESOURCES -= res/qt6/tr_qt.qrc
|
||||
!contains(DEFINES, GTA5SYNC_QCONF_IN) {
|
||||
RESOURCES -= res/tr_g5p.qrc
|
||||
langfiles.path = $$GTA5SYNC_PREFIX/share/gta5view/translations
|
||||
langfiles.files = $$PWD/res/gta5sync_en_US.qm $$PWD/res/gta5sync_de.qm $$PWD/res/gta5sync_fr.qm $$PWD/res/gta5sync_ko.qm $$PWD/res/gta5sync_ru.qm $$PWD/res/gta5sync_uk.qm $$PWD/res/gta5sync_zh_TW.qm $$PWD/res/qtbase_en_GB.qm
|
||||
INSTALLS += langfiles
|
||||
}
|
||||
}
|
||||
|
||||
# TELEMETRY BASED STUFF
|
||||
|
||||
!contains(DEFINES, GTA5SYNC_TELEMETRY) {
|
||||
SOURCES -= TelemetryClass.cpp \
|
||||
tmext/TelemetryClassAuthenticator.cpp
|
||||
HEADERS -= TelemetryClass.h \
|
||||
tmext/TelemetryClassAuthenticator.h
|
||||
}
|
||||
|
||||
!contains(DEFINES, GTA5SYNC_MOTD) {
|
||||
SOURCES -= MessageThread.cpp
|
||||
HEADERS -= MessageThread.h
|
||||
} else {
|
||||
lessThan(QT_MAJOR_VERSION, 5) {
|
||||
SOURCES -= MessageThread.cpp
|
||||
HEADERS -= MessageThread.h
|
||||
DEFINES -= GTA5SYNC_MOTD
|
||||
message("Messages require Qt5 or newer!")
|
||||
}
|
||||
}
|
||||
|
||||
# CMAKE BASED STUFF
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||
message("Building gta5view with QMake is deprecated, please use CMake instead!")
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
Community translation files
|
||||
|
||||
They get loaded in ApplicationPathExecFileFolder/lang
|
||||
|
||||
You can help translate with using Qt Linguist, after you've translated you'll need to send me a pull request on https://github.com/SyDevTeam/gta5view
|
|
@ -1 +0,0 @@
|
|||
#include "QJsonArray.h"
|
|
@ -1,410 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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 "QJsonArray.h"
|
||||
#include "QJsonValueRef.h"
|
||||
#include "QJsonValue.h"
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonArray
|
||||
// Desc: default constructor
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::QJsonArray() {
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonArray
|
||||
// Desc: copy constructor
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::QJsonArray(const QJsonArray &other) : values_(other.values_) {
|
||||
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonArray
|
||||
// Desc: Creates an array initialized from args initialization list.
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::QJsonArray(std::initializer_list<QJsonValue> args) {
|
||||
for(const QJsonValue &arg : args) {
|
||||
values_.append(arg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: ~QJsonArray
|
||||
// Desc: destructor
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::~QJsonArray() {
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator=
|
||||
// Desc: assignment operator
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray &QJsonArray::operator=(const QJsonArray &other) {
|
||||
QJsonArray(other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator+=
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray &QJsonArray::operator+=(const QJsonValue &value) {
|
||||
values_.append(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator<<
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray &QJsonArray::operator<<(const QJsonValue &value) {
|
||||
values_.append(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator+
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray QJsonArray::operator+(const QJsonValue &value) const {
|
||||
QJsonArray arr(*this);
|
||||
arr.append(value);
|
||||
return arr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator!=
|
||||
// Desc: returns true if the compared array IS NOT equal to this
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonArray::operator!=(const QJsonArray &other) const {
|
||||
return values_ != other.values_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator==
|
||||
// Desc: returns true if the compared array IS equal to this
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonArray::operator==(const QJsonArray &other) const {
|
||||
return values_ == other.values_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: begin
|
||||
// Desc: returns an iterator to the first contained element
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::const_iterator QJsonArray::begin() const {
|
||||
return values_.begin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: end
|
||||
// Desc: returns an iterator to one past the last contained element
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::const_iterator QJsonArray::end() const {
|
||||
return values_.end();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: begin
|
||||
// Desc: returns an iterator to the first contained element
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::iterator QJsonArray::begin() {
|
||||
return values_.begin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: end
|
||||
// Desc: returns an iterator to one past the last contained element
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::iterator QJsonArray::end() {
|
||||
return values_.end();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: constBegin
|
||||
// Desc: returns an iterator to the first contained element
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::const_iterator QJsonArray::constBegin() const {
|
||||
return begin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: constEnd
|
||||
// Desc: returns an iterator to one past the last contained element
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::const_iterator QJsonArray::constEnd() const {
|
||||
return end();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: first
|
||||
// Desc: returns the first element by value
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonArray::first() const {
|
||||
Q_ASSERT(!empty());
|
||||
return values_.first();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: last
|
||||
// Desc: returns the last element by value
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonArray::last() const {
|
||||
Q_ASSERT(!empty());
|
||||
return values_.last();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator[]
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValueRef QJsonArray::operator[](int i) {
|
||||
return QJsonValueRef(this, i);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator[]
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonArray::operator[](int i) const {
|
||||
return values_[i];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: at
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonArray::at(int i) const {
|
||||
return values_.at(i);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: size
|
||||
//------------------------------------------------------------------------------
|
||||
int QJsonArray::size() const {
|
||||
return values_.size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: count
|
||||
//------------------------------------------------------------------------------
|
||||
int QJsonArray::count() const {
|
||||
return size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: empty
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonArray::empty() const {
|
||||
return values_.empty();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isEmpty
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonArray::isEmpty() const {
|
||||
return empty();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: pop_back
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::pop_back() {
|
||||
values_.pop_back();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: pop_front
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::pop_front() {
|
||||
values_.pop_front();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: push_back
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::push_back(const QJsonValue &value) {
|
||||
values_.push_back(value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: push_front
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::push_front(const QJsonValue &value) {
|
||||
values_.push_front(value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::append(const QJsonValue &value) {
|
||||
values_.append(value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonArray::contains(const QJsonValue &value) const {
|
||||
return values_.contains(value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::iterator QJsonArray::erase(iterator it) {
|
||||
return values_.erase(it);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::insert(int i, const QJsonValue &value) {
|
||||
values_.insert(i, value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray::iterator QJsonArray::insert(iterator before, const QJsonValue &value) {
|
||||
return values_.insert(before, value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::prepend(const QJsonValue &value) {
|
||||
values_.prepend(value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::removeAt(int i) {
|
||||
values_.removeAt(i);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::removeFirst() {
|
||||
values_.removeFirst();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::removeLast() {
|
||||
values_.removeLast();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::replace(int i, const QJsonValue &value) {
|
||||
values_.replace(i, value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonArray::takeAt(int i) {
|
||||
return values_.takeAt(i);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toVariantList
|
||||
//------------------------------------------------------------------------------
|
||||
QVariantList QJsonArray::toVariantList() const {
|
||||
QVariantList a;
|
||||
Q_FOREACH(const QJsonValue &v, *this) {
|
||||
a.push_back(v.toVariant());
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray QJsonArray::fromStringList(const QStringList &list) {
|
||||
QJsonArray a;
|
||||
Q_FOREACH(const QString &s, list) {
|
||||
a.push_back(QJsonValue(s));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray QJsonArray::fromVariantList(const QVariantList &list) {
|
||||
QJsonArray a;
|
||||
Q_FOREACH(const QVariant &v, list) {
|
||||
a.push_back(QJsonValue::fromVariant(v));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonRoot *QJsonArray::clone() const {
|
||||
return new QJsonArray(*this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
const QJsonObject *QJsonArray::toObject() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject *QJsonArray::toObject() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray *QJsonArray::toArray() {
|
||||
return this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
const QJsonArray *QJsonArray::toArray() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonArray::swap(QJsonArray &other) {
|
||||
qSwap(values_, other.values_);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,139 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QJSON_ARRAY_H_
|
||||
#define QJSON_ARRAY_H_
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QtCore/QJsonArray>
|
||||
#else
|
||||
|
||||
#include "QJsonRoot.h"
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QVariantList>
|
||||
|
||||
class QJsonValue;
|
||||
class QJsonValueRef;
|
||||
|
||||
class QJsonArray : public QJsonRoot {
|
||||
friend class QJsonDocument;
|
||||
friend class QJsonValue;
|
||||
friend class QJsonValueRef;
|
||||
friend class QJsonParser;
|
||||
public:
|
||||
// TODO(eteran): manually implement the array, for now we use QList
|
||||
// but the real thing has a custom implementation
|
||||
// I guess for the purposes of less interdependancies?
|
||||
// maybe so it's easier to forward declare the iterators?
|
||||
|
||||
typedef QList<QJsonValue>::const_iterator const_iterator;
|
||||
typedef QList<QJsonValue>::iterator iterator;
|
||||
typedef const_iterator ConstIterator;
|
||||
typedef iterator Iterator;
|
||||
typedef QList<QJsonValue>::const_pointer const_pointer;
|
||||
typedef QList<QJsonValue>::const_reference const_reference;
|
||||
typedef QList<QJsonValue>::difference_type difference_type;
|
||||
typedef QList<QJsonValue>::pointer pointer;
|
||||
typedef QList<QJsonValue>::reference reference;
|
||||
typedef QList<QJsonValue>::size_type size_type;
|
||||
typedef QList<QJsonValue>::value_type value_type;
|
||||
|
||||
public:
|
||||
QJsonArray();
|
||||
QJsonArray(const QJsonArray &other);
|
||||
#if __cplusplus >= 201103L
|
||||
QJsonArray(std::initializer_list<QJsonValue> args);
|
||||
#endif
|
||||
~QJsonArray();
|
||||
|
||||
public:
|
||||
QJsonArray &operator=(const QJsonArray &other);
|
||||
|
||||
public:
|
||||
bool operator!=(const QJsonArray &other) const;
|
||||
bool operator==(const QJsonArray &other) const;
|
||||
QJsonArray operator+(const QJsonValue &value) const;
|
||||
QJsonArray &operator+=(const QJsonValue &value);
|
||||
QJsonArray &operator<<(const QJsonValue &value);
|
||||
|
||||
public:
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator constBegin() const;
|
||||
const_iterator constEnd() const;
|
||||
|
||||
public:
|
||||
QJsonValueRef operator[](int i);
|
||||
QJsonValue operator[](int i) const;
|
||||
QJsonValue at(int i) const;
|
||||
QJsonValue first() const;
|
||||
QJsonValue last() const;
|
||||
|
||||
public:
|
||||
int size() const;
|
||||
int count() const;
|
||||
bool empty() const;
|
||||
bool isEmpty() const;
|
||||
|
||||
public:
|
||||
void pop_back();
|
||||
void pop_front();
|
||||
void push_back(const QJsonValue &value);
|
||||
void push_front(const QJsonValue &value);
|
||||
|
||||
public:
|
||||
void append(const QJsonValue &value);
|
||||
bool contains(const QJsonValue &value) const;
|
||||
iterator erase(iterator it);
|
||||
void insert(int i, const QJsonValue &value);
|
||||
iterator insert(iterator before, const QJsonValue &value);
|
||||
void prepend(const QJsonValue &value);
|
||||
void removeAt(int i);
|
||||
void removeFirst();
|
||||
void removeLast();
|
||||
void replace(int i, const QJsonValue &value);
|
||||
QJsonValue takeAt(int i);
|
||||
|
||||
public:
|
||||
QVariantList toVariantList() const;
|
||||
|
||||
public:
|
||||
static QJsonArray fromStringList(const QStringList &list);
|
||||
static QJsonArray fromVariantList(const QVariantList &list);
|
||||
|
||||
private:
|
||||
virtual QJsonRoot *clone() const;
|
||||
virtual QJsonArray *toArray();
|
||||
virtual QJsonObject *toObject();
|
||||
virtual const QJsonArray *toArray() const;
|
||||
virtual const QJsonObject *toObject() const;
|
||||
|
||||
private:
|
||||
void swap(QJsonArray &other);
|
||||
|
||||
private:
|
||||
QList<QJsonValue> values_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
#include "QJsonDocument.h"
|
|
@ -1,424 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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 "QJsonDocument.h"
|
||||
#include "QJsonObject.h"
|
||||
#include "QJsonArray.h"
|
||||
#include "QJsonParser.h"
|
||||
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QTextCodec>
|
||||
#include <QtCore/QtCore>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonDocument
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument::QJsonDocument() : root_(0) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonDocument
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument::QJsonDocument(const QJsonObject &object) : root_(0) {
|
||||
setObject(object);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonDocument
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument::QJsonDocument(const QJsonArray &array) : root_(0) {
|
||||
setArray(array);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonDocument
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument::QJsonDocument(const QJsonDocument &other) : root_(0) {
|
||||
if(other.root_) {
|
||||
root_ = other.root_->clone();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: ~QJsonDocument
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument::~QJsonDocument() {
|
||||
delete root_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator=
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument &QJsonDocument::operator=(const QJsonDocument &other) {
|
||||
QJsonDocument(other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator!=
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonDocument::operator!=(const QJsonDocument &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator==
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonDocument::operator==(const QJsonDocument &other) const {
|
||||
|
||||
if(isArray() && other.isArray()) {
|
||||
return array() == other.array();
|
||||
}
|
||||
|
||||
if(isObject() && other.isObject()) {
|
||||
return object() == other.object();
|
||||
}
|
||||
|
||||
if(isEmpty() && other.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(isNull() && other.isNull()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isArray
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonDocument::isArray() const {
|
||||
return root_ && root_->toArray();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isEmpty
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonDocument::isEmpty() const {
|
||||
|
||||
// TODO(eteran): figure out the rules here that Qt5 uses
|
||||
// it *looks* like they define empty as being NULL
|
||||
// which is obviously different than this
|
||||
|
||||
return !root_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isNull
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonDocument::isNull() const {
|
||||
return !root_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isObject
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonDocument::isObject() const {
|
||||
return root_ && root_->toObject();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: setArray
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonDocument::setArray(const QJsonArray &array) {
|
||||
setRoot(array);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: setObject
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonDocument::setObject(const QJsonObject &object) {
|
||||
setRoot(object);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: setRoot
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonDocument::setRoot(const QJsonRoot &root) {
|
||||
delete root_;
|
||||
root_ = root.clone();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toBinaryData
|
||||
//------------------------------------------------------------------------------
|
||||
QByteArray QJsonDocument::toBinaryData() const {
|
||||
QByteArray r;
|
||||
// TODO(eteran): implement this
|
||||
return r;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: escapeString
|
||||
//------------------------------------------------------------------------------
|
||||
QString QJsonDocument::escapeString(const QString &s) const {
|
||||
|
||||
QString r;
|
||||
|
||||
Q_FOREACH(QChar ch, s) {
|
||||
switch(ch.toLatin1()) {
|
||||
case '\"': r.append("\\\""); break;
|
||||
case '\\': r.append("\\\\"); break;
|
||||
#if 0
|
||||
case '/': r.append("\\/"); break;
|
||||
#endif
|
||||
case '\b': r.append("\\b"); break;
|
||||
case '\f': r.append("\\f"); break;
|
||||
case '\n': r.append("\\n"); break;
|
||||
case '\r': r.append("\\r"); break;
|
||||
case '\t': r.append("\\t"); break;
|
||||
default:
|
||||
r += ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toJson
|
||||
//------------------------------------------------------------------------------
|
||||
QString QJsonDocument::toJson(const QJsonValue &v, JsonFormat format, int indent) const {
|
||||
|
||||
QString b;
|
||||
QTextStream ss(&b, QIODevice::WriteOnly | QIODevice::Text);
|
||||
bool compact = (format == JsonFormat::Compact);
|
||||
|
||||
switch(v.type()) {
|
||||
case QJsonValue::Null:
|
||||
ss << "null";
|
||||
break;
|
||||
case QJsonValue::Bool:
|
||||
ss << (v.toBool() ? "true" : "false");
|
||||
break;
|
||||
case QJsonValue::Double:
|
||||
{
|
||||
double d = v.toDouble ();
|
||||
if (qIsFinite(d)) {
|
||||
// +2 to format to ensure the expected precision
|
||||
ss << QByteArray::number(d, 'g', 15 + 2); // ::digits10 is 15
|
||||
} else {
|
||||
ss << "null"; // +INF || -INF || NaN (see RFC4627#section2.4)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QJsonValue::String:
|
||||
ss << '"' << escapeString(v.toString()) << '"';
|
||||
break;
|
||||
case QJsonValue::Array:
|
||||
{
|
||||
const QJsonArray a = v.toArray();
|
||||
ss << (compact ? "[" : "[\n");
|
||||
if(!a.empty()) {
|
||||
QJsonArray::const_iterator it = a.begin();
|
||||
QJsonArray::const_iterator e = a.end();
|
||||
|
||||
if (!compact) ss << QByteArray(4*indent, ' ');
|
||||
ss << toJson(*it++, format, indent+1);
|
||||
|
||||
for(;it != e; ++it) {
|
||||
ss << (compact ? "," : ",\n");
|
||||
if (!compact) ss << QByteArray(4*indent, ' ');
|
||||
ss << toJson(*it, format, indent+1);
|
||||
}
|
||||
}
|
||||
indent--;
|
||||
ss << (compact ? "]" : QString("\n%1]").arg(QString(4*indent, ' ')));
|
||||
}
|
||||
break;
|
||||
case QJsonValue::Object:
|
||||
{
|
||||
const QJsonObject o = v.toObject();
|
||||
ss << (compact ? "{" : "{\n");
|
||||
if(!o.empty()) {
|
||||
QJsonObject::const_iterator it = o.begin();
|
||||
QJsonObject::const_iterator e = o.end();
|
||||
|
||||
if (!compact) ss << QByteArray(4*indent, ' ');
|
||||
ss << '"' << escapeString(it.key()) << (compact ? "\":" : "\": ") << toJson(it.value(), format, indent+1);
|
||||
++it;
|
||||
for(;it != e; ++it) {
|
||||
ss << (compact ? "," : ",\n");
|
||||
if (!compact) ss << QByteArray(4*indent, ' ');
|
||||
ss << '"' << escapeString(it.key()) << (compact ? "\":" : "\": ") << toJson(it.value(), format, indent+1);
|
||||
}
|
||||
}
|
||||
indent--;
|
||||
ss << (compact ? "}" : QString("\n%1}").arg(QString(4*indent, ' ')));
|
||||
}
|
||||
break;
|
||||
case QJsonValue::Undefined:
|
||||
Q_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toJson
|
||||
//------------------------------------------------------------------------------
|
||||
QByteArray QJsonDocument::toJson(JsonFormat format) const {
|
||||
|
||||
Q_UNUSED(format);
|
||||
|
||||
if(isArray()) {
|
||||
QString s = toJson(array(), format);
|
||||
return s.toUtf8();
|
||||
}
|
||||
|
||||
if(isObject()) {
|
||||
QString s = toJson(object(), format);
|
||||
return s.toUtf8();
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toVariant
|
||||
//------------------------------------------------------------------------------
|
||||
QVariant QJsonDocument::toVariant() const {
|
||||
|
||||
if(!isEmpty()) {
|
||||
if(QJsonObject *const object = root_->toObject()) {
|
||||
return object->toVariantMap();
|
||||
}
|
||||
|
||||
if(QJsonArray *const array = root_->toArray()) {
|
||||
return array->toVariantList();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: array
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray QJsonDocument::array() const {
|
||||
|
||||
if(!isEmpty()) {
|
||||
if(QJsonArray *const array = root_->toArray()) {
|
||||
return *array;
|
||||
}
|
||||
}
|
||||
|
||||
return QJsonArray();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: object
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject QJsonDocument::object() const {
|
||||
|
||||
if(!isEmpty()) {
|
||||
if(QJsonObject *const object = root_->toObject()) {
|
||||
return *object;
|
||||
}
|
||||
}
|
||||
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: rawData
|
||||
//------------------------------------------------------------------------------
|
||||
const char *QJsonDocument::rawData(int *size) const {
|
||||
Q_UNUSED(size);
|
||||
// TODO(eteran): implement this
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: fromBinaryData
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation) {
|
||||
Q_UNUSED(data);
|
||||
Q_UNUSED(validation);
|
||||
|
||||
QJsonDocument doc;
|
||||
// TODO(eteran): implement this
|
||||
return doc;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: fromJson
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error) {
|
||||
QJsonDocument doc;
|
||||
|
||||
const char *const begin = json.constData();
|
||||
const char *const end = begin + json.size();
|
||||
|
||||
QJsonParser parser(begin, end);
|
||||
|
||||
doc.root_ = parser.parse();
|
||||
|
||||
if(error) {
|
||||
*error = parser.state();
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: fromRawData
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidation validation) {
|
||||
|
||||
// data has to be aligned to a 4 byte boundary.
|
||||
Q_ASSERT(!(reinterpret_cast<quintptr>(data) % 3));
|
||||
|
||||
return fromBinaryData(QByteArray::fromRawData(data, size), validation);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: fromVariant
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonDocument QJsonDocument::fromVariant(const QVariant &variant) {
|
||||
|
||||
QJsonDocument doc;
|
||||
|
||||
if (variant.type() == QVariant::Map) {
|
||||
doc.setObject(QJsonObject::fromVariantMap(variant.toMap()));
|
||||
} else if (variant.type() == QVariant::Hash) {
|
||||
doc.setObject(QJsonObject::fromVariantHash(variant.toHash()));
|
||||
} else if (variant.type() == QVariant::List) {
|
||||
doc.setArray(QJsonArray::fromVariantList(variant.toList()));
|
||||
} else if (variant.type() == QVariant::StringList) {
|
||||
doc.setArray(QJsonArray::fromStringList(variant.toStringList()));
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: swap
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonDocument::swap(QJsonDocument &other) {
|
||||
qSwap(root_, other.root_);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,103 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QJSON_DOCUMENT_H_
|
||||
#define QJSON_DOCUMENT_H_
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QtCore/QJsonDocument>
|
||||
#else
|
||||
|
||||
class QVariant;
|
||||
class QByteArray;
|
||||
class QTextStream;
|
||||
class QJsonObject;
|
||||
class QJsonValue;
|
||||
class QJsonArray;
|
||||
class QJsonParseError;
|
||||
class QJsonRoot;
|
||||
|
||||
class QJsonDocument {
|
||||
public:
|
||||
enum DataValidation {
|
||||
Validate = 0,
|
||||
BypassValidation = 1
|
||||
};
|
||||
|
||||
enum JsonFormat {
|
||||
Indented,
|
||||
Compact
|
||||
};
|
||||
|
||||
public:
|
||||
QJsonDocument();
|
||||
QJsonDocument(const QJsonObject &object);
|
||||
QJsonDocument(const QJsonArray &array);
|
||||
QJsonDocument(const QJsonDocument &other);
|
||||
~QJsonDocument();
|
||||
|
||||
public:
|
||||
QJsonDocument &operator=(const QJsonDocument &other);
|
||||
|
||||
public:
|
||||
bool operator!=(const QJsonDocument &other) const;
|
||||
bool operator==(const QJsonDocument &other) const;
|
||||
|
||||
public:
|
||||
bool isArray() const;
|
||||
bool isEmpty() const;
|
||||
bool isNull() const;
|
||||
bool isObject() const;
|
||||
|
||||
public:
|
||||
QByteArray toBinaryData() const;
|
||||
QByteArray toJson(JsonFormat format = Indented) const;
|
||||
QVariant toVariant() const;
|
||||
|
||||
public:
|
||||
QJsonArray array() const;
|
||||
QJsonObject object() const;
|
||||
const char *rawData(int *size) const;
|
||||
|
||||
public:
|
||||
void setArray(const QJsonArray &array);
|
||||
void setObject(const QJsonObject &object);
|
||||
|
||||
public:
|
||||
static QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate);
|
||||
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = 0);
|
||||
static QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate);
|
||||
static QJsonDocument fromVariant(const QVariant &variant);
|
||||
|
||||
private:
|
||||
void setRoot(const QJsonRoot &root);
|
||||
QString toJson(const QJsonValue &v, JsonFormat format, int indent = 1) const;
|
||||
QString escapeString(const QString &s) const;
|
||||
|
||||
private:
|
||||
void swap(QJsonDocument &other);
|
||||
|
||||
private:
|
||||
QJsonRoot *root_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
#include "QJsonObject.h"
|
|
@ -1,322 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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 "QJsonObject.h"
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonObject
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::QJsonObject() {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonObject
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::QJsonObject(const QJsonObject &other) : values_(other.values_) {
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonObject
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args) {
|
||||
for(const QPair<QString, QJsonValue> &arg : args) {
|
||||
values_.insert(arg.first, arg.second);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: ~QJsonObject
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::~QJsonObject() {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject &QJsonObject::operator=(const QJsonObject &other) {
|
||||
QJsonObject(other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::iterator QJsonObject::begin() {
|
||||
return values_.begin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::const_iterator QJsonObject::begin() const {
|
||||
return values_.begin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::iterator QJsonObject::end() {
|
||||
return values_.end();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::const_iterator QJsonObject::end() const {
|
||||
return values_.end();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::const_iterator QJsonObject::constBegin() const {
|
||||
return begin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::const_iterator QJsonObject::constEnd() const {
|
||||
return end();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
int QJsonObject::count() const {
|
||||
return size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
int QJsonObject::length() const {
|
||||
return size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
int QJsonObject::size() const {
|
||||
return values_.size();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonObject::empty() const {
|
||||
return values_.empty();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonObject::isEmpty() const {
|
||||
return empty();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const {
|
||||
return values_.find(key);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonObject::contains(const QString &key) const {
|
||||
return values_.contains(key);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::iterator QJsonObject::find(const QString &key) {
|
||||
return values_.find(key);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::const_iterator QJsonObject::find(const QString &key) const {
|
||||
return values_.find(key);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::iterator QJsonObject::erase(iterator it) {
|
||||
return values_.erase(it);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &value) {
|
||||
return values_.insert(key, value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QStringList QJsonObject::keys() const {
|
||||
return values_.keys();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonObject::remove(const QString &key) {
|
||||
values_.remove(key);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonObject::take(const QString &key) {
|
||||
return values_.take(key);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonObject::value(const QString &key) const {
|
||||
return values_.value(key);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonObject::operator!=(const QJsonObject &other) const {
|
||||
return values_ != other.values_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonObject::operator==(const QJsonObject &other) const {
|
||||
return values_ != other.values_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonObject::operator[](const QString &key) const {
|
||||
return values_[key];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValueRef QJsonObject::operator[](const QString &key) {
|
||||
return QJsonValueRef(this, key);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QVariantMap QJsonObject::toVariantMap() const {
|
||||
QVariantMap a;
|
||||
for(const_iterator it = begin(); it != end(); ++it) {
|
||||
a.insert(it.key(), it.value().toVariant());
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QVariantHash QJsonObject::toVariantHash() const {
|
||||
QVariantHash a;
|
||||
for(const_iterator it = begin(); it != end(); ++it) {
|
||||
a.insert(it.key(), it.value().toVariant());
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject QJsonObject::fromVariantMap(const QVariantMap &map) {
|
||||
QJsonObject o;
|
||||
for(QVariantMap::const_iterator it = map.begin(); it != map.end(); ++it) {
|
||||
o.insert(it.key(), QJsonValue::fromVariant(it.value()));
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject QJsonObject::fromVariantHash(const QVariantHash &hash) {
|
||||
QJsonObject o;
|
||||
for(QVariantHash::const_iterator it = hash.begin(); it != hash.end(); ++it) {
|
||||
o.insert(it.key(), QJsonValue::fromVariant(it.value()));
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonRoot *QJsonObject::clone() const {
|
||||
return new QJsonObject(*this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
const QJsonObject *QJsonObject::toObject() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject *QJsonObject::toObject() {
|
||||
return this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray *QJsonObject::toArray() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
//------------------------------------------------------------------------------
|
||||
const QJsonArray *QJsonObject::toArray() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: swap
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonObject::swap(QJsonObject &other) {
|
||||
qSwap(values_, other.values_);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,121 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QJSON_OBJECT_H_
|
||||
#define QJSON_OBJECT_H_
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QtCore/QJsonObject>
|
||||
#else
|
||||
|
||||
#include "QJsonRoot.h"
|
||||
#include "QJsonValueRef.h"
|
||||
#include "QJsonValue.h"
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariantMap>
|
||||
#include <QtCore/QMap>
|
||||
|
||||
class QJsonObject : public QJsonRoot {
|
||||
friend class QJsonDocument;
|
||||
friend class QJsonValue;
|
||||
friend class QJsonValueRef;
|
||||
friend class QJsonParser;
|
||||
public:
|
||||
// TODO(eteran): manually implement the map, for now we use QMap
|
||||
// but the real thing has a custom implementation
|
||||
// I guess for the purposes of less interdependancies?
|
||||
// maybe so it's easier to forward declare the iterators?
|
||||
|
||||
typedef QMap<QString, QJsonValue>::const_iterator const_iterator;
|
||||
typedef QMap<QString, QJsonValue>::iterator iterator;
|
||||
typedef const_iterator ConstIterator;
|
||||
typedef iterator Iterator;
|
||||
typedef QMap<QString, QJsonValue>::key_type key_type;
|
||||
typedef QMap<QString, QJsonValue>::mapped_type mapped_type;
|
||||
typedef QMap<QString, QJsonValue>::size_type size_type;
|
||||
|
||||
public:
|
||||
QJsonObject();
|
||||
#if __cplusplus >= 201103L
|
||||
QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args);
|
||||
#endif
|
||||
QJsonObject(const QJsonObject &other);
|
||||
~QJsonObject();
|
||||
QJsonObject &operator=(const QJsonObject &other);
|
||||
|
||||
public:
|
||||
iterator begin();
|
||||
const_iterator begin() const;
|
||||
iterator end();
|
||||
const_iterator end() const;
|
||||
const_iterator constBegin() const;
|
||||
const_iterator constEnd() const;
|
||||
|
||||
public:
|
||||
int count() const;
|
||||
int length() const;
|
||||
int size() const;
|
||||
bool empty() const;
|
||||
bool isEmpty() const;
|
||||
|
||||
public:
|
||||
const_iterator constFind(const QString &key) const;
|
||||
bool contains(const QString &key) const;
|
||||
iterator find(const QString &key);
|
||||
const_iterator find(const QString &key) const;
|
||||
|
||||
public:
|
||||
iterator erase(iterator it);
|
||||
iterator insert(const QString &key, const QJsonValue &value);
|
||||
QStringList keys() const;
|
||||
void remove(const QString &key);
|
||||
QJsonValue take(const QString &key);
|
||||
QJsonValue value(const QString &key) const;
|
||||
bool operator!=(const QJsonObject &other) const;
|
||||
bool operator==(const QJsonObject &other) const;
|
||||
QJsonValue operator[](const QString &key) const;
|
||||
QJsonValueRef operator[](const QString &key);
|
||||
|
||||
public:
|
||||
QVariantMap toVariantMap() const;
|
||||
QVariantHash toVariantHash() const;
|
||||
|
||||
public:
|
||||
static QJsonObject fromVariantMap(const QVariantMap &map);
|
||||
static QJsonObject fromVariantHash(const QVariantHash &hash);
|
||||
|
||||
private:
|
||||
virtual QJsonRoot *clone() const;
|
||||
virtual QJsonArray *toArray();
|
||||
virtual QJsonObject *toObject();
|
||||
virtual const QJsonArray *toArray() const;
|
||||
virtual const QJsonObject *toObject() const;
|
||||
|
||||
private:
|
||||
void swap(QJsonObject &other);
|
||||
|
||||
private:
|
||||
QMap<QString, QJsonValue> values_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
#include "QJsonParseError.h"
|
|
@ -1,64 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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 "QJsonParseError.h"
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: errorString
|
||||
// Desc: The QJsonParseError class is used to report errors during JSON parsing.
|
||||
//------------------------------------------------------------------------------
|
||||
QString QJsonParseError::errorString() const {
|
||||
switch(error) {
|
||||
case NoError:
|
||||
return "No error occurred";
|
||||
case UnterminatedObject:
|
||||
return "unterminated object";
|
||||
case MissingNameSeparator:
|
||||
return "missing name separator";
|
||||
case UnterminatedArray:
|
||||
return "unterminated array";
|
||||
case MissingValueSeparator:
|
||||
return "missing value separator";
|
||||
case IllegalValue:
|
||||
return "illegal value";
|
||||
case TerminationByNumber:
|
||||
return "invalid termination by number";
|
||||
case IllegalNumber:
|
||||
return "illegal number";
|
||||
case IllegalEscapeSequence:
|
||||
return "illegal escape sequence";
|
||||
case IllegalUTF8String:
|
||||
return "invalid UTF8 string";
|
||||
case UnterminatedString:
|
||||
return "unterminated string";
|
||||
case MissingObject:
|
||||
return "object is missing after a comma";
|
||||
case DeepNesting:
|
||||
return "too deeply nested document";
|
||||
case DocumentTooLarge:
|
||||
return "too large document";
|
||||
case GarbageAtEnd:
|
||||
return "garbage at the end of the document";
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,60 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QJSON_PARSE_ERROR_H_
|
||||
#define QJSON_PARSE_ERROR_H_
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QtCore/QJsonParseError>
|
||||
#else
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
class QJsonParseError {
|
||||
public:
|
||||
enum ParseError {
|
||||
NoError = 0,
|
||||
UnterminatedObject = 1,
|
||||
MissingNameSeparator = 2,
|
||||
UnterminatedArray = 3,
|
||||
MissingValueSeparator = 4,
|
||||
IllegalValue = 5,
|
||||
TerminationByNumber = 6,
|
||||
IllegalNumber = 7,
|
||||
IllegalEscapeSequence = 8,
|
||||
IllegalUTF8String = 9,
|
||||
UnterminatedString = 10,
|
||||
MissingObject = 11,
|
||||
DeepNesting = 12,
|
||||
DocumentTooLarge = 13,
|
||||
GarbageAtEnd = 14
|
||||
};
|
||||
|
||||
public:
|
||||
QString errorString() const;
|
||||
|
||||
public:
|
||||
ParseError error;
|
||||
int offset;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,455 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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 "QJsonParser.h"
|
||||
#include "QJsonArray.h"
|
||||
#include "QJsonObject.h"
|
||||
#include "QJsonValue.h"
|
||||
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
|
||||
#include <cctype>
|
||||
#include <QScopedPointer>
|
||||
#include <QVector>
|
||||
|
||||
namespace {
|
||||
|
||||
unsigned int to_hex(int ch) {
|
||||
|
||||
static const int hexval[256] = {
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
};
|
||||
|
||||
if(static_cast<unsigned int>(ch) < 256) {
|
||||
return hexval[static_cast<unsigned int>(ch)];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonParser
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonParser::QJsonParser(const char *begin, const char *end) : begin_(begin), end_(end), p_(begin) {
|
||||
state_.error = QJsonParseError::NoError;
|
||||
state_.offset = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: parse
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonRoot *QJsonParser::parse() {
|
||||
if(begin_ == end_) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
QJsonRoot *ret = 0;
|
||||
|
||||
try {
|
||||
const char ch = peek();
|
||||
switch(ch) {
|
||||
case ArrayBegin:
|
||||
ret = getArray();
|
||||
break;
|
||||
case ObjectBegin:
|
||||
ret = getObject();
|
||||
break;
|
||||
default:
|
||||
state_.error = QJsonParseError::IllegalValue;
|
||||
state_.offset = p_ - begin_;
|
||||
break;
|
||||
}
|
||||
} catch(const QJsonParseError &e) {
|
||||
state_ = e;
|
||||
}
|
||||
|
||||
if(ret) {
|
||||
// eat up trailing white space...
|
||||
while(p_ != end_ && std::isspace(*p_)) {
|
||||
++p_;
|
||||
}
|
||||
|
||||
//detect trailing garbage
|
||||
if(p_ != end_) {
|
||||
state_.error = QJsonParseError::GarbageAtEnd;
|
||||
state_.offset = p_ - begin_;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: peek
|
||||
//------------------------------------------------------------------------------
|
||||
char QJsonParser::peek() {
|
||||
// first eat up some whitespace
|
||||
while(p_ != end_ && std::isspace(*p_)) {
|
||||
++p_;
|
||||
}
|
||||
|
||||
return *p_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: getValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonParser::getValue() {
|
||||
|
||||
switch(peek()) {
|
||||
case ObjectBegin:
|
||||
{
|
||||
QScopedPointer<QJsonObject> obj(getObject());
|
||||
return QJsonValue(*obj);
|
||||
}
|
||||
case ArrayBegin:
|
||||
{
|
||||
QScopedPointer<QJsonArray> arr(getArray());
|
||||
return QJsonValue(*arr);
|
||||
}
|
||||
case Quote:
|
||||
return QJsonValue(getString());
|
||||
case 't':
|
||||
return getTrue();
|
||||
case 'f':
|
||||
return getFalse();
|
||||
case 'n':
|
||||
return getNull();
|
||||
default:
|
||||
return getNumber();
|
||||
}
|
||||
|
||||
throwError(QJsonParseError::MissingObject);
|
||||
return QJsonValue();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: getObject
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject *QJsonParser::getObject() {
|
||||
|
||||
QScopedPointer<QJsonObject> obj(new QJsonObject);
|
||||
|
||||
char tok = peek();
|
||||
if(tok != ObjectBegin) {
|
||||
throwError(QJsonParseError::IllegalValue);
|
||||
}
|
||||
|
||||
++p_;
|
||||
|
||||
// handle empty object
|
||||
tok = peek();
|
||||
if(peek() == ObjectEnd) {
|
||||
++p_;
|
||||
} else {
|
||||
|
||||
do {
|
||||
QPair<QString, QJsonValue> p = getPair();
|
||||
obj->values_.insert(p.first, p.second);
|
||||
|
||||
tok = peek();
|
||||
++p_;
|
||||
|
||||
} while(tok == ValueSeparator);
|
||||
}
|
||||
|
||||
if(tok != ObjectEnd) {
|
||||
throwError(QJsonParseError::UnterminatedObject);
|
||||
}
|
||||
|
||||
return obj.take();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: getArray
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray *QJsonParser::getArray() {
|
||||
|
||||
QScopedPointer<QJsonArray> arr(new QJsonArray);
|
||||
|
||||
char tok = peek();
|
||||
|
||||
if(tok != ArrayBegin) {
|
||||
throwError(QJsonParseError::IllegalValue);
|
||||
}
|
||||
|
||||
++p_;
|
||||
|
||||
// handle empty object
|
||||
tok = peek();
|
||||
if(tok == ArrayEnd) {
|
||||
++p_;
|
||||
} else {
|
||||
do {
|
||||
arr->values_.push_back(getValue());
|
||||
|
||||
tok = peek();
|
||||
++p_;
|
||||
|
||||
} while(tok == ValueSeparator);
|
||||
}
|
||||
|
||||
if(tok != ArrayEnd) {
|
||||
throwError(QJsonParseError::MissingValueSeparator);
|
||||
}
|
||||
|
||||
return arr.take();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: getPair
|
||||
//------------------------------------------------------------------------------
|
||||
QPair<QString, QJsonValue> QJsonParser::getPair() {
|
||||
|
||||
QString key = getString();
|
||||
|
||||
if(peek() != NameSeparator) {
|
||||
throwError(QJsonParseError::MissingNameSeparator);
|
||||
}
|
||||
++p_;
|
||||
|
||||
return qMakePair(key, getValue());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: getString
|
||||
//------------------------------------------------------------------------------
|
||||
QString QJsonParser::getString() {
|
||||
|
||||
if(peek() != Quote) {
|
||||
throwError(QJsonParseError::IllegalUTF8String);
|
||||
}
|
||||
++p_;
|
||||
|
||||
QByteArray s;
|
||||
|
||||
while(p_ != end_ && *p_ != Quote && *p_ != '\n') {
|
||||
if(*p_ == '\\') {
|
||||
++p_;
|
||||
if(p_ != end_) {
|
||||
switch(*p_) {
|
||||
case '"': s.append('"'); break;
|
||||
case '\\': s.append('\\'); break;
|
||||
case '/': s.append('/'); break;
|
||||
case 'b': s.append('\b'); break;
|
||||
case 'f': s.append('\f'); break;
|
||||
case 'n': s.append('\n'); break;
|
||||
case 'r': s.append('\r'); break;
|
||||
case 't': s.append('\t'); break;
|
||||
case 'u':
|
||||
{
|
||||
|
||||
QString hexChar;
|
||||
|
||||
// convert \uXXXX escape sequences to UTF-8
|
||||
char hex[4];
|
||||
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[0] = *++p_;
|
||||
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[1] = *++p_;
|
||||
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[2] = *++p_;
|
||||
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[3] = *++p_;
|
||||
|
||||
if(!std::isxdigit(hex[0])) throwError(QJsonParseError::IllegalUTF8String);
|
||||
if(!std::isxdigit(hex[1])) throwError(QJsonParseError::IllegalUTF8String);
|
||||
if(!std::isxdigit(hex[2])) throwError(QJsonParseError::IllegalUTF8String);
|
||||
if(!std::isxdigit(hex[3])) throwError(QJsonParseError::IllegalUTF8String);
|
||||
|
||||
quint16 w1 = 0;
|
||||
quint16 w2 = 0;
|
||||
|
||||
w1 |= (to_hex(hex[0]) << 12);
|
||||
w1 |= (to_hex(hex[1]) << 8);
|
||||
w1 |= (to_hex(hex[2]) << 4);
|
||||
w1 |= (to_hex(hex[3]));
|
||||
|
||||
hexChar.append(QChar(w1));
|
||||
|
||||
if((w1 & 0xfc00) == 0xdc00) {
|
||||
throwError(QJsonParseError::IllegalUTF8String);
|
||||
}
|
||||
|
||||
if((w1 & 0xfc00) == 0xd800) {
|
||||
// part of a surrogate pair
|
||||
if(p_ == end_ || *++p_ != '\\') { throwError(QJsonParseError::IllegalEscapeSequence); }
|
||||
if(p_ == end_ || *++p_ != 'u') { throwError(QJsonParseError::IllegalEscapeSequence); }
|
||||
|
||||
// convert \uXXXX escape sequences to UTF-8
|
||||
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[0] = *++p_;
|
||||
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[1] = *++p_;
|
||||
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[2] = *++p_;
|
||||
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[3] = *++p_;
|
||||
|
||||
if(!std::isxdigit(hex[0])) throwError(QJsonParseError::IllegalUTF8String);
|
||||
if(!std::isxdigit(hex[1])) throwError(QJsonParseError::IllegalUTF8String);
|
||||
if(!std::isxdigit(hex[2])) throwError(QJsonParseError::IllegalUTF8String);
|
||||
if(!std::isxdigit(hex[3])) throwError(QJsonParseError::IllegalUTF8String);
|
||||
|
||||
w2 |= (to_hex(hex[0]) << 12);
|
||||
w2 |= (to_hex(hex[1]) << 8);
|
||||
w2 |= (to_hex(hex[2]) << 4);
|
||||
w2 |= (to_hex(hex[3]));
|
||||
|
||||
hexChar.append(QChar(w2));
|
||||
}
|
||||
|
||||
s.append(hexChar.toUtf8());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
s.append('\\');
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s.append(*p_);
|
||||
}
|
||||
++p_;
|
||||
}
|
||||
|
||||
if(*p_ != Quote || p_ == end_) {
|
||||
throwError(QJsonParseError::UnterminatedString);
|
||||
}
|
||||
|
||||
++p_;
|
||||
|
||||
return QString::fromUtf8(s, s.size());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: getNull
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonParser::getNull() {
|
||||
if(p_ == end_ || *p_++ != 'n') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 'u') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 'l') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 'l') { throwError(QJsonParseError::IllegalValue); }
|
||||
|
||||
return QJsonValue();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: getTrue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonParser::getTrue() {
|
||||
if(p_ == end_ || *p_++ != 't') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 'r') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 'u') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 'e') { throwError(QJsonParseError::IllegalValue); }
|
||||
|
||||
return QJsonValue(true);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: getFalse
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonParser::getFalse() {
|
||||
if(p_ == end_ || *p_++ != 'f') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 'a') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 'l') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 's') { throwError(QJsonParseError::IllegalValue); }
|
||||
if(p_ == end_ || *p_++ != 'e') { throwError(QJsonParseError::IllegalValue); }
|
||||
|
||||
return QJsonValue(false);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: getNumber
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonParser::getNumber() {
|
||||
// JSON numbers fit the regex: -?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?
|
||||
|
||||
const char *const first = p_;
|
||||
|
||||
// -?
|
||||
if(p_ != end_ && *p_ == '-') {
|
||||
++p_;
|
||||
}
|
||||
|
||||
// (0|[1-9][0-9]*)
|
||||
if(p_ != end_) {
|
||||
if(*p_ >= '1' && *p_ <= '9') {
|
||||
while(p_ != end_ && std::isdigit(*p_)) {
|
||||
++p_;
|
||||
}
|
||||
} else if(*p_ == '0') {
|
||||
++p_;
|
||||
} else {
|
||||
throwError(QJsonParseError::IllegalNumber);
|
||||
}
|
||||
}
|
||||
|
||||
// (\.[0-9]+)?
|
||||
if(p_ != end_ && *p_ == '.') {
|
||||
++p_;
|
||||
if(!std::isdigit(*p_)) {
|
||||
throwError(QJsonParseError::IllegalNumber);
|
||||
}
|
||||
|
||||
while(p_ != end_ && std::isdigit(*p_)) {
|
||||
++p_;
|
||||
}
|
||||
}
|
||||
|
||||
// ([eE][+-]?[0-9]+)?
|
||||
if(p_ != end_ && (*p_ == 'e' || *p_ == 'E')) {
|
||||
++p_;
|
||||
if(p_ != end_ && (*p_ == '+' || *p_ == '-')) {
|
||||
++p_;
|
||||
}
|
||||
if(!std::isdigit(*p_)) {
|
||||
throwError(QJsonParseError::IllegalNumber);
|
||||
}
|
||||
while(p_ != end_ && std::isdigit(*p_)) {
|
||||
++p_;
|
||||
}
|
||||
}
|
||||
|
||||
if(p_ == end_) {
|
||||
throwError(QJsonParseError::TerminationByNumber);
|
||||
}
|
||||
|
||||
return QJsonValue(QByteArray::fromRawData(first, p_ - first).toDouble());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: state
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonParseError QJsonParser::state() const {
|
||||
return state_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: throwError
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonParser::throwError(QJsonParseError::ParseError e) {
|
||||
QJsonParseError err;
|
||||
err.error = e;
|
||||
err.offset = p_ - begin_;
|
||||
throw err;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,81 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
|
||||
// NOTE: this is not part of the "public" Qt API, so using this class directly
|
||||
// is not recomended
|
||||
|
||||
#ifndef QJSON_PARSER_H_
|
||||
#define QJSON_PARSER_H_
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
|
||||
#include "QJsonParseError.h"
|
||||
#include <QPair>
|
||||
class QJsonRoot;
|
||||
class QJsonObject;
|
||||
class QJsonArray;
|
||||
class QJsonValue;
|
||||
|
||||
class QJsonParser {
|
||||
friend class QJsonDocument;
|
||||
|
||||
public:
|
||||
QJsonParser(const char *begin, const char *end);
|
||||
|
||||
public:
|
||||
QJsonRoot *parse();
|
||||
|
||||
public:
|
||||
QJsonParseError state() const;
|
||||
|
||||
private:
|
||||
static const char ArrayBegin = '[';
|
||||
static const char ArrayEnd = ']';
|
||||
static const char NameSeparator = ':';
|
||||
static const char ValueSeparator = ',';
|
||||
static const char ObjectBegin = '{';
|
||||
static const char ObjectEnd = '}';
|
||||
static const char Quote = '"';
|
||||
|
||||
private:
|
||||
char peek();
|
||||
QJsonObject *getObject();
|
||||
QJsonArray *getArray();
|
||||
QJsonValue getValue();
|
||||
QString getString();
|
||||
QJsonValue getTrue();
|
||||
QJsonValue getFalse();
|
||||
QJsonValue getNull();
|
||||
QJsonValue getNumber();
|
||||
QPair<QString, QJsonValue> getPair();
|
||||
|
||||
private:
|
||||
void throwError(QJsonParseError::ParseError e);
|
||||
|
||||
private:
|
||||
QJsonParseError state_;
|
||||
const char *const begin_;
|
||||
const char *const end_;
|
||||
const char * p_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
#include "QJsonRoot.h"
|
|
@ -1,45 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QJSON_ROOT_H_
|
||||
#define QJSON_ROOT_H_
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
|
||||
class QJsonObject;
|
||||
class QJsonArray;
|
||||
|
||||
class QJsonRoot {
|
||||
public:
|
||||
virtual ~QJsonRoot() {};
|
||||
|
||||
public:
|
||||
virtual QJsonRoot *clone() const = 0;
|
||||
|
||||
public:
|
||||
virtual QJsonArray *toArray() = 0;
|
||||
virtual QJsonObject *toObject() = 0;
|
||||
virtual const QJsonArray *toArray() const = 0;
|
||||
virtual const QJsonObject *toObject() const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
#include "QJsonValue.h"
|
|
@ -1,391 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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 "QJsonValue.h"
|
||||
#include "QJsonArray.h"
|
||||
#include "QJsonObject.h"
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
#include <QtCore/QtAlgorithms>
|
||||
#include <QtCore/qmath.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(Type type) : type_(type) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(bool b) : type_(Bool) {
|
||||
value_.b = b;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(double n) : type_(Double) {
|
||||
value_.n = n;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(const QString &s) : type_(String) {
|
||||
value_.s = new QString(s);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(QLatin1String s) : type_(String) {
|
||||
value_.s = new QString(s);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(const char *s) : type_(String) {
|
||||
value_.s = new QString(QString::fromUtf8(s));
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(const QJsonArray &a) : type_(Array) {
|
||||
value_.r = a.clone();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(const QJsonObject &o) : type_(Object) {
|
||||
value_.r = o.clone();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(int n) : type_(Double) {
|
||||
value_.n = n;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(qint64 n) : type_(Double) {
|
||||
value_.n = n;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::QJsonValue(const QJsonValue &other) : type_(other.type_) {
|
||||
|
||||
switch(other.type_) {
|
||||
case Bool:
|
||||
value_.b = other.value_.b;
|
||||
break;
|
||||
case Double:
|
||||
value_.n = other.value_.n;
|
||||
break;
|
||||
case String:
|
||||
value_.s = new QString(*other.value_.s);
|
||||
break;
|
||||
case Array:
|
||||
case Object:
|
||||
value_.r = other.value_.r->clone();
|
||||
break;
|
||||
case Undefined:
|
||||
case Null:
|
||||
value_ = other.value_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: ~QJsonValue
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::~QJsonValue() {
|
||||
switch(type_) {
|
||||
case Null:
|
||||
case Bool:
|
||||
case Double:
|
||||
case Undefined:
|
||||
break;
|
||||
case String:
|
||||
delete value_.s;
|
||||
break;
|
||||
case Object:
|
||||
case Array:
|
||||
delete value_.r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator=
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue &QJsonValue::operator=(const QJsonValue &other) {
|
||||
QJsonValue(other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator!=
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::operator!=(const QJsonValue &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator==
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::operator==(const QJsonValue &other) const {
|
||||
if(type_ == other.type_) {
|
||||
switch(type_) {
|
||||
case Null:
|
||||
return true;
|
||||
case Bool:
|
||||
return value_.b == other.value_.b;
|
||||
case Double:
|
||||
return value_.n == other.value_.n;
|
||||
case Undefined:
|
||||
return true;
|
||||
case String:
|
||||
return *value_.s == *other.value_.s;
|
||||
case Array:
|
||||
return *(value_.r->toArray()) == *(other.value_.r->toArray());
|
||||
case Object:
|
||||
return *(value_.r->toObject()) == *(other.value_.r->toObject());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isArray
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::isArray() const {
|
||||
return type_ == Array;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isBool
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::isBool() const {
|
||||
return type_ == Bool;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isDouble
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::isDouble() const {
|
||||
return type_ == Double;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isNull
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::isNull() const {
|
||||
return type_ == Null;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isObject
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::isObject() const {
|
||||
return type_ == Object;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isString
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::isString() const {
|
||||
return type_ == String;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isUndefined
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::isUndefined() const {
|
||||
return type_ == Undefined;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: type
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::Type QJsonValue::type() const {
|
||||
return type_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toArray
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray QJsonValue::toArray(const QJsonArray &defaultValue) const {
|
||||
if(isArray()) {
|
||||
return *(value_.r->toArray());
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toArray
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray QJsonValue::toArray() const {
|
||||
return toArray(QJsonArray());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toBool
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValue::toBool(bool defaultValue) const {
|
||||
if(isBool()) {
|
||||
return value_.b;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toDouble
|
||||
//------------------------------------------------------------------------------
|
||||
double QJsonValue::toDouble(double defaultValue) const {
|
||||
if(isDouble()) {
|
||||
return value_.n;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toInt
|
||||
//------------------------------------------------------------------------------
|
||||
int QJsonValue::toInt(int defaultValue) const {
|
||||
if(isDouble() && qFloor(value_.n) == value_.n) {
|
||||
return value_.n;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toObject
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject QJsonValue::toObject(const QJsonObject &defaultValue) const {
|
||||
if(isObject()) {
|
||||
return *(value_.r->toObject());
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toObject
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject QJsonValue::toObject() const {
|
||||
return toObject(QJsonObject());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toString
|
||||
//------------------------------------------------------------------------------
|
||||
QString QJsonValue::toString(const QString &defaultValue) const {
|
||||
|
||||
if(isString()) {
|
||||
return *value_.s;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toVariant
|
||||
//------------------------------------------------------------------------------
|
||||
QVariant QJsonValue::toVariant() const {
|
||||
switch(type_) {
|
||||
case Null:
|
||||
return QVariant();
|
||||
case Bool:
|
||||
return QVariant::fromValue(value_.b);
|
||||
case Double:
|
||||
return QVariant::fromValue(value_.n);
|
||||
case String:
|
||||
return QVariant::fromValue(*value_.s);
|
||||
case Array:
|
||||
return value_.r->toArray()->toVariantList();
|
||||
case Object:
|
||||
return value_.r->toObject()->toVariantMap();
|
||||
case Undefined:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: fromVariant
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonValue::fromVariant(const QVariant &variant) {
|
||||
if(variant.isNull()) {
|
||||
return QJsonValue(Null);
|
||||
}
|
||||
|
||||
switch(variant.type()) {
|
||||
case QVariant::Bool:
|
||||
return QJsonValue(variant.toBool());
|
||||
case QVariant::Int:
|
||||
return QJsonValue(variant.toInt());
|
||||
case QVariant::Double:
|
||||
case QVariant::LongLong:
|
||||
case QVariant::ULongLong:
|
||||
case QVariant::UInt:
|
||||
return QJsonValue(variant.toDouble());
|
||||
case QVariant::String:
|
||||
return QJsonValue(variant.toString());
|
||||
case QVariant::List:
|
||||
return QJsonArray::fromVariantList(variant.toList());
|
||||
case QVariant::StringList:
|
||||
return QJsonArray::fromStringList(variant.toStringList());
|
||||
case QVariant::Map:
|
||||
return QJsonObject::fromVariantMap(variant.toMap());
|
||||
default:
|
||||
const QString s = variant.toString();
|
||||
if(!s.isEmpty()) {
|
||||
return QJsonValue(s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return QJsonValue(Null);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: swap
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonValue::swap(QJsonValue &other) {
|
||||
qSwap(type_, other.type_);
|
||||
qSwap(value_, other.value_);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,120 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QJSON_VALUE_H_
|
||||
#define QJSON_VALUE_H_
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QtCore/QJsonValue>
|
||||
#else
|
||||
|
||||
class QString;
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
class QJsonRoot;
|
||||
class QJsonArray;
|
||||
class QJsonObject;
|
||||
|
||||
class QJsonValue {
|
||||
public:
|
||||
enum Type {
|
||||
Null = 0x0,
|
||||
Bool = 0x1,
|
||||
Double = 0x2,
|
||||
String = 0x3,
|
||||
Array = 0x4,
|
||||
Object = 0x5,
|
||||
Undefined = 0x80
|
||||
};
|
||||
|
||||
public:
|
||||
QJsonValue(Type type = Null);
|
||||
QJsonValue(bool b);
|
||||
QJsonValue(double n);
|
||||
QJsonValue(int n);
|
||||
QJsonValue(qint64 n);
|
||||
QJsonValue(const QString &s);
|
||||
QJsonValue(QLatin1String s);
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
QJsonValue(const char *s);
|
||||
#endif
|
||||
QJsonValue(const QJsonArray &a);
|
||||
QJsonValue(const QJsonObject &o);
|
||||
QJsonValue(const QJsonValue &other);
|
||||
|
||||
~QJsonValue();
|
||||
|
||||
private:
|
||||
// to protect against incorrect usage due to passing a const char *
|
||||
QJsonValue(const void *);
|
||||
|
||||
public:
|
||||
QJsonValue &operator=(const QJsonValue &other);
|
||||
|
||||
public:
|
||||
bool operator!=(const QJsonValue &other) const;
|
||||
bool operator==(const QJsonValue &other) const;
|
||||
|
||||
public:
|
||||
bool isArray() const;
|
||||
bool isBool() const;
|
||||
bool isDouble() const;
|
||||
bool isNull() const;
|
||||
bool isObject() const;
|
||||
bool isString() const;
|
||||
bool isUndefined() const;
|
||||
|
||||
public:
|
||||
QJsonArray toArray(const QJsonArray &defaultValue) const;
|
||||
QJsonArray toArray() const;
|
||||
bool toBool(bool defaultValue = false) const;
|
||||
double toDouble(double defaultValue = 0) const;
|
||||
int toInt(int defaultValue = 0) const;
|
||||
QJsonObject toObject(const QJsonObject &defaultValue) const;
|
||||
QJsonObject toObject() const;
|
||||
QString toString(const QString &defaultValue = QString()) const;
|
||||
QVariant toVariant() const;
|
||||
|
||||
public:
|
||||
Type type() const;
|
||||
|
||||
public:
|
||||
static QJsonValue fromVariant(const QVariant &variant);
|
||||
|
||||
private:
|
||||
void swap(QJsonValue &other);
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
|
||||
union ValueType {
|
||||
bool b;
|
||||
double n;
|
||||
QString *s;
|
||||
QJsonRoot *r; // OJsonObject or QJsonArray
|
||||
};
|
||||
|
||||
ValueType value_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
#include "QJsonValueRef.h"
|
|
@ -1,228 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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 "QJsonValueRef.h"
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
|
||||
#include "QJsonArray.h"
|
||||
#include "QJsonObject.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValueRef::QJsonValueRef(QJsonArray *array, int idx) : p_(array), index_(idx) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValueRef::QJsonValueRef(QJsonObject *object, const QString &key) : p_(object), index_(0), key_(key) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValueRef::operator QJsonValue() const {
|
||||
return toValue();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValueRef &QJsonValueRef::operator=(const QJsonValue &val) {
|
||||
|
||||
if(QJsonObject *const o = p_->toObject()) {
|
||||
o->values_[key_] = val;
|
||||
} else if(QJsonArray *const a = p_->toArray()) {
|
||||
a->values_[index_] = val;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name:
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValueRef &QJsonValueRef::operator=(const QJsonValueRef &ref) {
|
||||
|
||||
if(QJsonObject *const o = p_->toObject()) {
|
||||
o->values_[key_] = ref;
|
||||
} else if(QJsonArray *const a = p_->toArray()) {
|
||||
a->values_[index_] = ref;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: type
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue::Type QJsonValueRef::type() const {
|
||||
return toValue().type();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isNull
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::isNull() const {
|
||||
return toValue().isNull();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isBool
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::isBool() const {
|
||||
return toValue().isBool();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isDouble
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::isDouble() const {
|
||||
return toValue().isDouble();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isString
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::isString() const {
|
||||
return toValue().isString();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isArray
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::isArray() const {
|
||||
return toValue().isArray();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isObject
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::isObject() const {
|
||||
return toValue().isObject();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: isUndefined
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::isUndefined() const {
|
||||
return toValue().isUndefined();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toBool
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::toBool() const {
|
||||
return toValue().toBool();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toDouble
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
double QJsonValueRef::toDouble() const {
|
||||
return toValue().toDouble();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toInt
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
int QJsonValueRef::toInt(int defaultValue) const {
|
||||
return toValue().toInt(defaultValue);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toString
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QString QJsonValueRef::toString() const {
|
||||
return toValue().toString();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toArray
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonArray QJsonValueRef::toArray() const {
|
||||
return toValue().toArray();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toObject
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonObject QJsonValueRef::toObject() const {
|
||||
return toValue().toObject();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator==
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::operator==(const QJsonValue &other) const {
|
||||
return toValue() == other;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: operator!=
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
bool QJsonValueRef::operator!=(const QJsonValue &other) const {
|
||||
return toValue() != other;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: toValue
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
QJsonValue QJsonValueRef::toValue() const {
|
||||
if(QJsonObject *const o = p_->toObject()) {
|
||||
return o->values_[key_];
|
||||
} else if(QJsonArray *const a = p_->toArray()) {
|
||||
return a->values_[index_];
|
||||
}
|
||||
|
||||
return QJsonValue();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: swap
|
||||
// Desc:
|
||||
//------------------------------------------------------------------------------
|
||||
void QJsonValueRef::swap(QJsonValueRef &other) {
|
||||
qSwap(p_, other.p_);
|
||||
qSwap(key_, other.key_);
|
||||
qSwap(index_, other.index_);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,79 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QJSON_VALUEREF_H_
|
||||
#define QJSON_VALUEREF_H_
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QtCore/QJsonValueRef>
|
||||
#else
|
||||
|
||||
#include "QJsonValue.h"
|
||||
class QJsonRoot;
|
||||
|
||||
class QJsonValueRef {
|
||||
public:
|
||||
QJsonValueRef(QJsonArray *array, int idx);
|
||||
|
||||
// slight variant from official APIs implementation
|
||||
QJsonValueRef(QJsonObject *object, const QString &key);
|
||||
|
||||
public:
|
||||
operator QJsonValue() const;
|
||||
|
||||
public:
|
||||
QJsonValueRef &operator=(const QJsonValue &val);
|
||||
QJsonValueRef &operator=(const QJsonValueRef &val);
|
||||
|
||||
public:
|
||||
QJsonValue::Type type() const;
|
||||
bool isNull() const;
|
||||
bool isBool() const;
|
||||
bool isDouble() const;
|
||||
bool isString() const;
|
||||
bool isArray() const;
|
||||
bool isObject() const;
|
||||
bool isUndefined() const;
|
||||
|
||||
public:
|
||||
bool toBool() const;
|
||||
double toDouble() const;
|
||||
QString toString() const;
|
||||
QJsonArray toArray() const;
|
||||
QJsonObject toObject() const;
|
||||
int toInt(int defaultValue = 0) const;
|
||||
|
||||
public:
|
||||
bool operator==(const QJsonValue &other) const;
|
||||
bool operator!=(const QJsonValue &other) const;
|
||||
|
||||
private:
|
||||
QJsonValue toValue() const;
|
||||
void swap(QJsonValueRef &other);
|
||||
|
||||
private:
|
||||
QJsonRoot *p_;
|
||||
int index_;
|
||||
QString key_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
1636
res/gta5sync.ts
1636
res/gta5sync.ts
File diff suppressed because it is too large
Load Diff
Binary file not shown.
1596
res/gta5sync_de.ts
1596
res/gta5sync_de.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1596
res/gta5sync_fr.ts
1596
res/gta5sync_fr.ts
File diff suppressed because it is too large
Load Diff
1598
res/gta5sync_ko.ts
1598
res/gta5sync_ko.ts
File diff suppressed because it is too large
Load Diff
1599
res/gta5sync_ru.ts
1599
res/gta5sync_ru.ts
File diff suppressed because it is too large
Load Diff
1596
res/gta5sync_uk.ts
1596
res/gta5sync_uk.ts
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
res/qt4/qt_de.qm
BIN
res/qt4/qt_de.qm
Binary file not shown.
BIN
res/qt4/qt_fr.qm
BIN
res/qt4/qt_fr.qm
Binary file not shown.
BIN
res/qt4/qt_ko.qm
BIN
res/qt4/qt_ko.qm
Binary file not shown.
BIN
res/qt4/qt_ru.qm
BIN
res/qt4/qt_ru.qm
Binary file not shown.
BIN
res/qt4/qt_uk.qm
BIN
res/qt4/qt_uk.qm
Binary file not shown.
Binary file not shown.
|
@ -1,10 +0,0 @@
|
|||
<RCC>
|
||||
<qresource prefix="/tr">
|
||||
<file>qt_de.qm</file>
|
||||
<file>qt_fr.qm</file>
|
||||
<file>qt_ko.qm</file>
|
||||
<file>qt_ru.qm</file>
|
||||
<file>qt_uk.qm</file>
|
||||
<file>qt_zh_TW.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
Binary file not shown.
Binary file not shown.
BIN
res/template.g5e
BIN
res/template.g5e
Binary file not shown.
|
@ -1,5 +0,0 @@
|
|||
<RCC>
|
||||
<qresource prefix="/template">
|
||||
<file>template.g5e</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* Copyright (C) 2016-2021 Syping
|
||||
* Copyright (C) 2016-2023 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
|
||||
|
@ -29,11 +29,7 @@ AboutDialog::AboutDialog(QWidget *parent) :
|
|||
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();
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* Copyright (C) 2016-2021 Syping
|
||||
* Copyright (C) 2016-2023 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
|
||||
|
@ -51,21 +51,25 @@ QString AppEnv::getBuildCode()
|
|||
|
||||
// Folder Stuff
|
||||
|
||||
QString AppEnv::getGameFolder(bool *ok)
|
||||
QString AppEnv::getGTAVFolder(bool *ok)
|
||||
{
|
||||
QDir dir;
|
||||
QString GTAV_FOLDER = QString::fromUtf8(qgetenv("GTAV_FOLDER"));
|
||||
if (GTAV_FOLDER != "") {
|
||||
if (!GTAV_FOLDER.isEmpty()) {
|
||||
dir.setPath(GTAV_FOLDER);
|
||||
if (dir.exists()) {
|
||||
if (ok != NULL)
|
||||
if (ok)
|
||||
*ok = true;
|
||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||
return dir.absolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
// TODO: Try to locate the Steam Proton GTA V folder
|
||||
const QString GTAV_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/GTA V";
|
||||
#else
|
||||
const QString GTAV_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/GTA V";
|
||||
#endif
|
||||
QString GTAV_returnFolder = GTAV_defaultFolder;
|
||||
|
||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||
|
@ -74,48 +78,100 @@ QString AppEnv::getGameFolder(bool *ok)
|
|||
GTAV_returnFolder = settings.value("dir", GTAV_defaultFolder).toString();
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("GameDirectory");
|
||||
settings.beginGroup("GTA V");
|
||||
forceDir = settings.value("ForceCustom", forceDir).toBool();
|
||||
GTAV_returnFolder = settings.value("Directory", GTAV_returnFolder).toString();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
|
||||
if (forceDir) {
|
||||
dir.setPath(GTAV_returnFolder);
|
||||
if (dir.exists()) {
|
||||
if (ok != 0)
|
||||
if (ok)
|
||||
*ok = true;
|
||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||
return dir.absolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
dir.setPath(GTAV_defaultFolder);
|
||||
if (dir.exists()) {
|
||||
if (ok != 0)
|
||||
if (ok)
|
||||
*ok = true;
|
||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||
return dir.absolutePath();
|
||||
}
|
||||
|
||||
if (!forceDir) {
|
||||
dir.setPath(GTAV_returnFolder);
|
||||
if (dir.exists()) {
|
||||
if (ok != 0)
|
||||
if (ok)
|
||||
*ok = true;
|
||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||
return dir.absolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
if (ok != 0)
|
||||
if (ok)
|
||||
*ok = false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool AppEnv::setGameFolder(QString gameFolder)
|
||||
QString AppEnv::getRDR2Folder(bool *ok)
|
||||
{
|
||||
QDir dir;
|
||||
dir.setPath(gameFolder);
|
||||
if (dir.exists()) {
|
||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||
return true;
|
||||
QString RDR2_FOLDER = QString::fromUtf8(qgetenv("RDR2_FOLDER"));
|
||||
if (!RDR2_FOLDER.isEmpty()) {
|
||||
dir.setPath(RDR2_FOLDER);
|
||||
if (dir.exists()) {
|
||||
if (ok)
|
||||
*ok = true;
|
||||
return dir.absolutePath();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
// TODO: Try to locate the Steam Proton RDR 2 folder
|
||||
const QString RDR2_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/Red Dead Redemption 2";
|
||||
#else
|
||||
const QString RDR2_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/Red Dead Redemption 2";
|
||||
#endif
|
||||
QString RDR2_returnFolder = RDR2_defaultFolder;
|
||||
|
||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||
settings.beginGroup("GameDirectory");
|
||||
settings.beginGroup("RDR 2");
|
||||
bool forceDir = settings.value("ForceCustom", false).toBool();
|
||||
RDR2_returnFolder = settings.value("Directory", RDR2_defaultFolder).toString();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
|
||||
if (forceDir) {
|
||||
dir.setPath(RDR2_returnFolder);
|
||||
if (dir.exists()) {
|
||||
if (ok)
|
||||
*ok = true;
|
||||
return dir.absolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
dir.setPath(RDR2_defaultFolder);
|
||||
if (dir.exists()) {
|
||||
if (ok)
|
||||
*ok = true;
|
||||
return dir.absolutePath();
|
||||
}
|
||||
|
||||
if (!forceDir) {
|
||||
dir.setPath(RDR2_returnFolder);
|
||||
if (dir.exists()) {
|
||||
if (ok)
|
||||
*ok = true;
|
||||
return dir.absolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
*ok = false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString AppEnv::getExLangFolder()
|
||||
|
@ -167,33 +223,7 @@ QString AppEnv::getShareFolder()
|
|||
|
||||
QByteArray AppEnv::getUserAgent()
|
||||
{
|
||||
#if QT_VERSION >= 0x050400
|
||||
#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)
|
||||
|
@ -213,7 +243,7 @@ QUrl AppEnv::getPlayerFetchingUrl(QString crewID, int pageNumber)
|
|||
|
||||
// Game Stuff
|
||||
|
||||
GameVersion AppEnv::getGameVersion()
|
||||
GameVersion AppEnv::getGTAVVersion()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QString argumentValue;
|
||||
|
@ -262,7 +292,7 @@ GameVersion AppEnv::getGameVersion()
|
|||
#endif
|
||||
}
|
||||
|
||||
GameLanguage AppEnv::getGameLanguage(GameVersion gameVersion)
|
||||
GameLanguage AppEnv::getGTAVLanguage(GameVersion gameVersion)
|
||||
{
|
||||
if (gameVersion == GameVersion::SocialClubVersion) {
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -369,77 +399,11 @@ QString AppEnv::gameLanguageToString(GameLanguage gameLanguage)
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -449,9 +413,5 @@ qreal AppEnv::screenRatio()
|
|||
|
||||
qreal AppEnv::screenRatioPR()
|
||||
{
|
||||
#if QT_VERSION >= 0x050600
|
||||
return QApplication::primaryScreen()->devicePixelRatio();
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* Copyright (C) 2016-2021 Syping
|
||||
* Copyright (C) 2016-2023 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
|
||||
|
@ -35,8 +35,8 @@ public:
|
|||
static QString getBuildCode();
|
||||
|
||||
// Folder Stuff
|
||||
static QString getGameFolder(bool *ok = 0);
|
||||
static bool setGameFolder(QString gameFolder);
|
||||
static QString getGTAVFolder(bool *ok = 0);
|
||||
static QString getRDR2Folder(bool *ok = 0);
|
||||
static QString getExLangFolder();
|
||||
static QString getInLangFolder();
|
||||
static QString getImagesFolder();
|
||||
|
@ -50,11 +50,10 @@ public:
|
|||
static QUrl getPlayerFetchingUrl(QString crewID, int pageNumber);
|
||||
|
||||
// Game Stuff
|
||||
static GameVersion getGameVersion();
|
||||
static GameLanguage getGameLanguage(GameVersion gameVersion);
|
||||
static GameVersion getGTAVVersion();
|
||||
static GameLanguage getGTAVLanguage(GameVersion gameVersion);
|
||||
static GameLanguage gameLanguageFromString(QString gameLanguage);
|
||||
static QString gameLanguageToString(GameLanguage gameLanguage);
|
||||
static bool setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage);
|
||||
|
||||
// Screen Stuff
|
||||
static qreal screenRatio();
|
|
@ -26,6 +26,7 @@
|
|||
#include "config.h"
|
||||
#include <QStringBuilder>
|
||||
#include <QApplication>
|
||||
#include <QSaveFile>
|
||||
#include <QFileInfo>
|
||||
#include <QFile>
|
||||
|
||||
|
@ -35,131 +36,56 @@
|
|||
#include <QDesktopWidget>
|
||||
#endif
|
||||
|
||||
ExportThread::ExportThread(QMap<ProfileWidget*,QString> profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent) : QThread(parent),
|
||||
ExportThread::ExportThread(QHash<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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ExportThread::run()
|
||||
{
|
||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||
|
||||
// Picture Settings
|
||||
// Quality Settings
|
||||
settings.beginGroup("Pictures");
|
||||
int defaultQuality = 100;
|
||||
QSize defExportSize = SnapmaticPicture::getSnapmaticResolution();
|
||||
int customQuality = settings.value("CustomQuality", defaultQuality).toInt();
|
||||
if (customQuality < 1 || customQuality > 100)
|
||||
{
|
||||
customQuality = 100;
|
||||
}
|
||||
bool useCustomQuality = settings.value("CustomQualityEnabled", false).toBool();
|
||||
|
||||
// Size Settings
|
||||
QSize cusExportSize = settings.value("CustomSize", defExportSize).toSize();
|
||||
if (cusExportSize.width() > 3840)
|
||||
{
|
||||
cusExportSize.setWidth(3840);
|
||||
}
|
||||
else if (cusExportSize.height() > 2160)
|
||||
{
|
||||
cusExportSize.setHeight(2160);
|
||||
}
|
||||
if (cusExportSize.width() < 1)
|
||||
{
|
||||
cusExportSize.setWidth(1);
|
||||
}
|
||||
else if (cusExportSize.height() < 1)
|
||||
{
|
||||
cusExportSize.setHeight(1);
|
||||
}
|
||||
QString sizeMode = settings.value("ExportSizeMode", "Default").toString();
|
||||
Qt::AspectRatioMode aspectRatio = (Qt::AspectRatioMode)settings.value("AspectRatio", Qt::KeepAspectRatio).toInt();
|
||||
settings.endGroup();
|
||||
// End Picture Settings
|
||||
|
||||
int intExportProgress = 0;
|
||||
for (ProfileWidget *widget : profileMap.keys())
|
||||
{
|
||||
if (widget->isSelected())
|
||||
{
|
||||
if (widget->getWidgetType() == "SnapmaticWidget")
|
||||
{
|
||||
size_t intExportProgress = 0;
|
||||
for (ProfileWidget *widget : profileMap.keys()) {
|
||||
if (widget->isSelected()) {
|
||||
if (widget->getWidgetType() == "SnapmaticWidget") {
|
||||
SnapmaticWidget *picWidget = qobject_cast<SnapmaticWidget*>(widget);
|
||||
SnapmaticPicture *picture = picWidget->getPicture();
|
||||
|
||||
if (pictureExportEnabled)
|
||||
{
|
||||
if (pictureExportEnabled) {
|
||||
QString exportFileName = PictureExport::getPictureFileName(picture);
|
||||
if (exportFileName.right(4) != ".jpg" && exportFileName.right(4) != ".png")
|
||||
{
|
||||
if (!exportFileName.endsWith(".jpg"))
|
||||
exportFileName += ".jpg";
|
||||
}
|
||||
|
||||
intExportProgress++;
|
||||
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
|
||||
emit exportProgressUpdate(intExportProgress);
|
||||
|
||||
// Scale Picture
|
||||
QImage exportPicture = picture->getImage();
|
||||
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();
|
||||
int desktopSizeWidth = desktopResolution.width();
|
||||
int desktopSizeHeight = desktopResolution.height();
|
||||
#endif
|
||||
exportPicture = exportPicture.scaled(desktopSizeWidth, desktopSizeHeight, aspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
else if (sizeMode == "Custom")
|
||||
{
|
||||
exportPicture = exportPicture.scaled(cusExportSize, aspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
bool isSaved;
|
||||
if (useCustomQuality)
|
||||
{
|
||||
isSaved = exportPicture.save(exportDirectory % "/" % exportFileName, "JPEG", customQuality);
|
||||
}
|
||||
else
|
||||
{
|
||||
isSaved = exportPicture.save(exportDirectory % "/" % exportFileName, "JPEG", 100);
|
||||
bool isSaved = false;
|
||||
QSaveFile exportFile(exportDirectory % "/" % exportFileName);
|
||||
if (exportFile.open(QIODevice::WriteOnly)) {
|
||||
exportFile.write(picture->getPictureStream());
|
||||
isSaved = exportFile.commit();
|
||||
}
|
||||
|
||||
if (!isSaved)
|
||||
{
|
||||
failedExportPictures += exportFileName;
|
||||
}
|
||||
}
|
||||
if (pictureCopyEnabled)
|
||||
{
|
||||
if (pictureCopyEnabled) {
|
||||
QString exportFileName = PictureExport::getPictureFileName(picture);
|
||||
if (exportFileName.right(4) != ".g5e")
|
||||
{
|
||||
if (!exportFileName.endsWith(".g5e"))
|
||||
exportFileName += ".g5e";
|
||||
}
|
||||
|
||||
intExportProgress++;
|
||||
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
|
||||
emit exportProgressUpdate(intExportProgress);
|
||||
|
||||
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))
|
||||
{
|
||||
failedCopyPictures += exportFileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (widget->getWidgetType() == "SavegameWidget")
|
||||
{
|
||||
else if (widget->getWidgetType() == "SavegameWidget") {
|
||||
SavegameWidget *sgdWidget = qobject_cast<SavegameWidget*>(widget);
|
||||
SavegameData *savegame = sgdWidget->getSavegame();
|
||||
|
||||
|
@ -172,11 +98,10 @@ void ExportThread::run()
|
|||
emit exportProgressUpdate(intExportProgress);
|
||||
|
||||
QString exportFilePath = exportDirectory % "/" % exportFileName;
|
||||
if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);}
|
||||
if (QFile::exists(exportFilePath))
|
||||
QFile::remove(exportFilePath);
|
||||
if (!QFile::copy(originalFileName, exportFilePath))
|
||||
{
|
||||
failedSavegames += exportFileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
* gta5view Grand Theft Auto V Profile Viewer
|
||||
* Copyright (C) 2016-2017 Syping
|
||||
* Copyright (C) 2016-2023 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
|
||||
|
@ -29,7 +29,7 @@ class ExportThread : public QThread
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ExportThread(QMap<ProfileWidget*,QString> profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent = 0);
|
||||
explicit ExportThread(QHash<ProfileWidget*,QString> profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent = 0);
|
||||
QStringList getFailedSavegames();
|
||||
QStringList getFailedCopyPictures();
|
||||
QStringList getFailedExportPictures();
|
||||
|
@ -38,7 +38,7 @@ protected:
|
|||
void run();
|
||||
|
||||
private:
|
||||
QMap <ProfileWidget*, QString> profileMap;
|
||||
QHash<ProfileWidget*,QString> profileMap;
|
||||
QString exportDirectory;
|
||||
bool pictureCopyEnabled;
|
||||
bool pictureExportEnabled;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue