Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
Syping | 98cfa7c5de | |
Syping | b8ad311912 |
|
@ -24,7 +24,7 @@ BEGIN
|
||||||
VALUE "FileDescription", "gta5view"
|
VALUE "FileDescription", "gta5view"
|
||||||
VALUE "FileVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER"
|
VALUE "FileVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER"
|
||||||
VALUE "InternalName", "gta5view"
|
VALUE "InternalName", "gta5view"
|
||||||
VALUE "LegalCopyright", "Copyright © 2016-2023 Syping"
|
VALUE "LegalCopyright", "Copyright © 2016-2021 Syping"
|
||||||
VALUE "OriginalFilename", "gta5view.exe"
|
VALUE "OriginalFilename", "gta5view.exe"
|
||||||
VALUE "ProductName", "gta5view"
|
VALUE "ProductName", "gta5view"
|
||||||
VALUE "ProductVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER"
|
VALUE "ProductVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER"
|
||||||
|
|
52
.ci/ci.sh
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
if [ $(git name-rev --tags --name-only $(git rev-parse HEAD)) == "undefined" ]; then
|
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')
|
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')
|
||||||
|
@ -16,7 +16,7 @@ export APPLICATION_PATCH_VERSION=$(cut -d. -f3 <<< $APPLICATION_VERSION)
|
||||||
if [ "${PACKAGE_BUILD}" == "" ]; then
|
if [ "${PACKAGE_BUILD}" == "" ]; then
|
||||||
export PACKAGE_BUILD=1
|
export PACKAGE_BUILD=1
|
||||||
else
|
else
|
||||||
export APPLICATION_BUILD_INT_VERSION=$(grep -oE '[1-9]*$' <<< $PACKAGE_BUILD)
|
export APPLICATION_BUILD_INT_VERSION=$(grep -oE "[1-9]*$" <<< $PACKAGE_BUILD)
|
||||||
export APPLICATION_BUILD_STR_VERSION=-${PACKAGE_BUILD}
|
export APPLICATION_BUILD_STR_VERSION=-${PACKAGE_BUILD}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -30,41 +30,41 @@ cat ".ci/app.rc" | sed \
|
||||||
> "res/app.rc"
|
> "res/app.rc"
|
||||||
|
|
||||||
if [ "${BUILD_TYPE}" == "ALPHA" ]; then
|
if [ "${BUILD_TYPE}" == "ALPHA" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Alpha"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_ALPHA=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Alpha\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_ALPHA"
|
||||||
elif [ "${BUILD_TYPE}" == "Alpha" ]; then
|
elif [ "${BUILD_TYPE}" == "Alpha" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Alpha"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_ALPHA=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Alpha\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_ALPHA"
|
||||||
elif [ "${BUILD_TYPE}" == "BETA" ]; then
|
elif [ "${BUILD_TYPE}" == "BETA" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Beta"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_BETA=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Beta\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_BETA"
|
||||||
elif [ "${BUILD_TYPE}" == "Beta" ]; then
|
elif [ "${BUILD_TYPE}" == "Beta" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Beta"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_BETA=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Beta\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_BETA"
|
||||||
elif [ "${BUILD_TYPE}" == "DEV" ]; then
|
elif [ "${BUILD_TYPE}" == "DEV" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Developer"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_DEV=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Developer\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_DEV"
|
||||||
elif [ "${BUILD_TYPE}" == "Development" ]; then
|
elif [ "${BUILD_TYPE}" == "Development" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Developer"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_DEV=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Developer\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_DEV"
|
||||||
elif [ "${BUILD_TYPE}" == "DAILY" ]; then
|
elif [ "${BUILD_TYPE}" == "DAILY" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Daily Build"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_DAILY=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Daily Build\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_DAILY"
|
||||||
elif [ "${BUILD_TYPE}" == "Daily" ]; then
|
elif [ "${BUILD_TYPE}" == "Daily" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Daily Build"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_DAILY=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Daily Build\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_DAILY"
|
||||||
elif [ "${BUILD_TYPE}" == "RC" ]; then
|
elif [ "${BUILD_TYPE}" == "RC" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release Candidate"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_RC=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release Candidate\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_RC"
|
||||||
elif [ "${BUILD_TYPE}" == "Release Candidate" ]; then
|
elif [ "${BUILD_TYPE}" == "Release Candidate" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release Candidate"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_RC=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release Candidate\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_RC"
|
||||||
elif [ "${BUILD_TYPE}" == "REL" ]; then
|
elif [ "${BUILD_TYPE}" == "REL" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_REL=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_REL"
|
||||||
elif [ "${BUILD_TYPE}" == "Release" ]; then
|
elif [ "${BUILD_TYPE}" == "Release" ]; then
|
||||||
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release"
|
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE_REL=TRUE"
|
||||||
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release\\\\\\\""
|
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_REL"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export PROJECT_DIR=$(pwd)
|
export PROJECT_DIR=$(pwd)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Creating folders
|
# Creating folders
|
||||||
cd ${PROJECT_DIR} && \
|
cd ${PROJECT_DIR} && \
|
||||||
|
@ -7,6 +7,10 @@ mkdir -p build && \
|
||||||
mkdir -p assets && \
|
mkdir -p assets && \
|
||||||
chmod -x res/gta5sync_*.qm res/*.desktop res/*gta5view*.png && \
|
chmod -x res/gta5sync_*.qm res/*.desktop res/*gta5view*.png && \
|
||||||
cd build && \
|
cd build && \
|
||||||
|
mkdir -p qt4 && \
|
||||||
|
cd qt4 && \
|
||||||
|
echo "Grand Theft Auto V Snapmatic and Savegame viewer/editor" > ./description-pak && \
|
||||||
|
cd .. && \
|
||||||
mkdir -p qt5 && \
|
mkdir -p qt5 && \
|
||||||
cd qt5 && \
|
cd qt5 && \
|
||||||
echo "Grand Theft Auto V Snapmatic and Savegame viewer/editor" > ./description-pak && \
|
echo "Grand Theft Auto V Snapmatic and Savegame viewer/editor" > ./description-pak && \
|
||||||
|
@ -23,16 +27,18 @@ mkdir -p /usr/share/gta5view && \
|
||||||
cd qt5 && \
|
cd qt5 && \
|
||||||
cmake \
|
cmake \
|
||||||
"-DCMAKE_INSTALL_PREFIX=/usr" \
|
"-DCMAKE_INSTALL_PREFIX=/usr" \
|
||||||
"${CMAKE_BUILD_TYPE}" \
|
${CMAKE_BUILD_TYPE} \
|
||||||
"-DFORCE_QT_VERSION=5" \
|
|
||||||
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
||||||
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
||||||
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
||||||
"-DWITH_DONATE=ON" \
|
|
||||||
"-DWITH_TELEMETRY=ON" \
|
"-DWITH_TELEMETRY=ON" \
|
||||||
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
|
|
||||||
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
||||||
"-DQCONF_BUILD=ON" \
|
"-DQCONF_BUILD=ON" \
|
||||||
../../ && \
|
../../ && \
|
||||||
make -j 4 && \
|
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
|
checkinstall -D --default --nodoc --install=no --pkgname=gta5view-qt5 --pkgversion=${PACKAGE_VERSION} --pkgrelease=${PACKAGE_BUILD} --pkggroup=utility --maintainer="Syping \<dpkg@syping.de\>" --requires=libqt5core5a,libqt5gui5,libqt5network5,libqt5svg5,libqt5widgets5,qttranslations5-l10n --conflicts=gta5view,gta5view-qt4 --replaces=gta5view,gta5view-qt4 --pakdir=${PROJECT_DIR}/assets && \
|
||||||
|
cd .. && \
|
||||||
|
cd qt4 && \
|
||||||
|
qmake -qt=4 GTA5SYNC_PREFIX=/usr QMAKE_CXXFLAGS+=-std=gnu++11 ${QMAKE_FLAGS_QT4} ${QMAKE_BUILD_TYPE} "DEFINES+=GTA5SYNC_BUILDCODE=\\\\\\\"${PACKAGE_CODE}\\\\\\\"" "DEFINES+=GTA5SYNC_APPVER=\\\\\\\"${APPLICATION_VERSION}\\\\\\\"" DEFINES+=GTA5SYNC_QCONF ../../gta5view.pro && \
|
||||||
|
make -j 4 && \
|
||||||
|
checkinstall -D --default --nodoc --install=no --pkgname=gta5view-qt4 --pkgversion=${PACKAGE_VERSION} --pkgrelease=${PACKAGE_BUILD} --pkggroup=utility --maintainer="Syping \<dpkg@syping.de\>" --requires=libqtcore4,libqtgui4,libqt4-network,libqt4-svg,qtcore4-l10n --conflicts=gta5view,gta5view-qt5 --replaces=gta5view,gta5view-qt5 --pakdir=${PROJECT_DIR}/assets
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Install packages
|
# Install packages
|
||||||
.ci/debian_install.sh && \
|
.ci/debian_install.sh && \
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
if [ "${DOCKER_USER}" != "" ]; then
|
if [ "${DOCKER_USER}" != "" ]; then
|
||||||
DOCKER_IMAGE=${DOCKER_USER}/debian:${DEBIAN_VERSION}
|
DOCKER_IMAGE=${DOCKER_USER}/debian:${DEBIAN_VERSION}
|
||||||
else
|
else
|
||||||
DOCKER_IMAGE=debian:${DEBIAN_VERSION}
|
DOCKER_IMAGE=debian:${DEBIAN_VERSION}
|
||||||
fi
|
fi
|
||||||
PROJECT_DIR_DOCKER=/gta5view
|
PROJECT_DIR_DOCKER=/gta5view
|
||||||
|
|
||||||
cd ${PROJECT_DIR} && \
|
cd ${PROJECT_DIR} && \
|
||||||
docker pull ${DOCKER_IMAGE} && \
|
docker pull ${DOCKER_IMAGE} && \
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
|
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
|
||||||
${DOCKER_IMAGE} \
|
${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"
|
/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 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/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
|
# Install packages
|
||||||
apt-get update -qq && \
|
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
|
apt-get install -qq ${APT_INSTALL} checkinstall cmake dpkg-dev fakeroot g++ gcc qtbase5-dev qt5-qmake qttranslations5-l10n libqt4-dev libqt5svg5-dev
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
btc:187NSQSPzdMpQDGhxZAuw4AhZ7LgoAPV7D,eth:0x19d71DfCa86104d37a13D3c5d419936421CDC569,ltc:LKr6yvBoMMGmcxViS8Kc1A2sDjVSWTXn4m,xmr:43TB3ZMP5nk1pu5EQXRGPzdTKvmFEBGgccX3tNhRknLLiUYQ7z7dNedVHEA6WrWdByZv1isvFmjSGhCF7ddx3eRxFdm5Fzz
|
|
|
@ -1,12 +1,11 @@
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
!define APP_NAME "gta5view"
|
!define APP_NAME "gta5view"
|
||||||
!define APP_EXT ".g5e"
|
|
||||||
!define COMP_NAME "Syping"
|
!define COMP_NAME "Syping"
|
||||||
!define WEB_SITE "https://gta5view.syping.de/"
|
!define WEB_SITE "https://gta5view.syping.de/"
|
||||||
!define VERSION "1.10.2.0"
|
!define VERSION "1.9.2.0"
|
||||||
!define COPYRIGHT "Copyright © 2016-2022 Syping"
|
!define COPYRIGHT "Copyright © 2016-2021 Syping"
|
||||||
!define DESCRIPTION "Open Source Snapmatic and Savegame viewer/editor for GTA V"
|
!define DESCRIPTION "Grand Theft Auto V Savegame and Snapmatic Viewer/Editor"
|
||||||
!define INSTALLER_NAME "gta5view_setup.exe"
|
!define INSTALLER_NAME "gta5view_setup.exe"
|
||||||
!define MAIN_APP_EXE "gta5view.exe"
|
!define MAIN_APP_EXE "gta5view.exe"
|
||||||
!define INSTALL_TYPE "SetShellVarContext all"
|
!define INSTALL_TYPE "SetShellVarContext all"
|
||||||
|
@ -114,6 +113,7 @@ 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/Qt5Network.dll"
|
||||||
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Svg.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"
|
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Widgets.dll"
|
||||||
|
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5WinExtras.dll"
|
||||||
SetOutPath "$INSTDIR\lang"
|
SetOutPath "$INSTDIR\lang"
|
||||||
File "../build/gta5sync_en_US.qm"
|
File "../build/gta5sync_en_US.qm"
|
||||||
File "../build/gta5sync_de.qm"
|
File "../build/gta5sync_de.qm"
|
||||||
|
@ -129,39 +129,6 @@ File "../res/qt5/qtbase_ko.qm"
|
||||||
File "../res/qt5/qtbase_ru.qm"
|
File "../res/qt5/qtbase_ru.qm"
|
||||||
File "../res/qt5/qtbase_uk.qm"
|
File "../res/qt5/qtbase_uk.qm"
|
||||||
File "../res/qt5/qtbase_zh_TW.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"
|
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/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/qicns.dll"
|
||||||
|
@ -224,30 +191,6 @@ 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
|
Section Uninstall
|
||||||
${INSTALL_TYPE}
|
${INSTALL_TYPE}
|
||||||
Delete "$INSTDIR\gta5view.exe"
|
Delete "$INSTDIR\gta5view.exe"
|
||||||
|
@ -260,6 +203,7 @@ Delete "$INSTDIR\Qt5Gui.dll"
|
||||||
Delete "$INSTDIR\Qt5Network.dll"
|
Delete "$INSTDIR\Qt5Network.dll"
|
||||||
Delete "$INSTDIR\Qt5Svg.dll"
|
Delete "$INSTDIR\Qt5Svg.dll"
|
||||||
Delete "$INSTDIR\Qt5Widgets.dll"
|
Delete "$INSTDIR\Qt5Widgets.dll"
|
||||||
|
Delete "$INSTDIR\Qt5WinExtras.dll"
|
||||||
Delete "$INSTDIR\lang\gta5sync_en_US.qm"
|
Delete "$INSTDIR\lang\gta5sync_en_US.qm"
|
||||||
Delete "$INSTDIR\lang\gta5sync_de.qm"
|
Delete "$INSTDIR\lang\gta5sync_de.qm"
|
||||||
Delete "$INSTDIR\lang\gta5sync_fr.qm"
|
Delete "$INSTDIR\lang\gta5sync_fr.qm"
|
||||||
|
@ -274,38 +218,6 @@ Delete "$INSTDIR\lang\qtbase_ko.qm"
|
||||||
Delete "$INSTDIR\lang\qtbase_ru.qm"
|
Delete "$INSTDIR\lang\qtbase_ru.qm"
|
||||||
Delete "$INSTDIR\lang\qtbase_uk.qm"
|
Delete "$INSTDIR\lang\qtbase_uk.qm"
|
||||||
Delete "$INSTDIR\lang\qtbase_zh_TW.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\qgif.dll"
|
||||||
Delete "$INSTDIR\imageformats\qicns.dll"
|
Delete "$INSTDIR\imageformats\qicns.dll"
|
||||||
Delete "$INSTDIR\imageformats\qico.dll"
|
Delete "$INSTDIR\imageformats\qico.dll"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Creating folders
|
# Creating folders
|
||||||
cd ${PROJECT_DIR} && \
|
cd ${PROJECT_DIR} && \
|
||||||
|
@ -8,17 +8,7 @@ mkdir -p build && \
|
||||||
mkdir -p assets && \
|
mkdir -p assets && \
|
||||||
cd build && \
|
cd build && \
|
||||||
|
|
||||||
/usr/local/bin/cmake \
|
/usr/local/opt/qt/bin/qmake ${QMAKE_FLAGS_QT5} ${QMAKE_BUILD_TYPE} "DEFINES+=GTA5SYNC_BUILDCODE=\\\\\\\"${PACKAGE_CODE}\\\\\\\"" "DEFINES+=GTA5SYNC_APPVER=\\\\\\\"${APPLICATION_VERSION}\\\\\\\"" "DEFINES+=GTA5SYNC_COMMIT=\\\\\\\"${APPLICATION_COMMIT}\\\\\\\"" DEFINES+=GTA5SYNC_TELEMETRY "DEFINES+=GTA5SYNC_TELEMETRY_WEBURL=\\\\\\\"https://dev.syping.de/gta5view-userstats/\\\\\\\"" ../gta5view.pro && \
|
||||||
"-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 && \
|
make -j 4 && \
|
||||||
/usr/local/opt/qt/bin/macdeployqt gta5view.app -dmg && \
|
/usr/local/opt/qt/bin/macdeployqt gta5view.app -dmg && \
|
||||||
cp -Rf gta5view.dmg ../assets/gta5view-osx_${APPLICATION_VERSION}.dmg
|
cp -Rf gta5view.dmg ../assets/gta5view-osx_${APPLICATION_VERSION}.dmg
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Install packages
|
# Install packages
|
||||||
.ci/osx_install.sh && \
|
.ci/osx_install.sh && \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Install packages
|
# Install packages
|
||||||
brew upgrade cmake qt
|
brew upgrade qt
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Prepare environment variable
|
# Prepare environment variable
|
||||||
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
|
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
|
||||||
|
@ -13,13 +13,11 @@ mkdir -p assets && \
|
||||||
# Starting build
|
# Starting build
|
||||||
cd build && \
|
cd build && \
|
||||||
mingw64-qt-cmake \
|
mingw64-qt-cmake \
|
||||||
"${CMAKE_BUILD_TYPE}" \
|
${CMAKE_BUILD_TYPE} \
|
||||||
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
||||||
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
||||||
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
||||||
"-DWITH_DONATE=ON" \
|
|
||||||
"-DWITH_TELEMETRY=ON" \
|
"-DWITH_TELEMETRY=ON" \
|
||||||
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
|
|
||||||
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
||||||
.. && \
|
.. && \
|
||||||
make -j 4 && \
|
make -j 4 && \
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
DOCKER_IMAGE=sypingauto/gta5view-build:1.10-static
|
DOCKER_IMAGE=sypingauto/gta5view-build:1.9-static
|
||||||
PROJECT_DIR_DOCKER=/gta5view
|
PROJECT_DIR_DOCKER=/gta5view
|
||||||
|
|
||||||
cd ${PROJECT_DIR} && \
|
cd ${PROJECT_DIR} && \
|
||||||
docker pull ${DOCKER_IMAGE} && \
|
docker pull ${DOCKER_IMAGE} && \
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
|
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
|
||||||
${DOCKER_IMAGE} \
|
${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" && \
|
/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
|
# Prepare environment variable
|
||||||
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
|
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
|
||||||
|
|
||||||
# Upload Assets to Dropbox
|
# Upload Assets to Dropbox
|
||||||
if [ "${PACKAGE_CODE}" == "gta5-mods" ]; then
|
if [ "${PACKAGE_CODE}" == "gta5-mods" ]; then
|
||||||
${PROJECT_DIR}/.ci/dropbox_uploader.sh mkdir gta5-mods/${PACKAGE_VERSION}
|
${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} && \
|
${PROJECT_DIR}/.ci/dropbox_uploader.sh upload ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} gta5-mods/${PACKAGE_VERSION}/${GTA5VIEW_EXECUTABLE} && \
|
||||||
rm -rf ${GTA5VIEW_EXECUTABLE}
|
rm -rf ${GTA5VIEW_EXECUTABLE}
|
||||||
elif [ "${PACKAGE_CODE}" == "gtainside" ]; then
|
elif [ "${PACKAGE_CODE}" == "gtainside" ]; then
|
||||||
${PROJECT_DIR}/.ci/dropbox_uploader.sh mkdir gtainside/${PACKAGE_VERSION}
|
${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} && \
|
${PROJECT_DIR}/.ci/dropbox_uploader.sh upload ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} gtainside/${PACKAGE_VERSION}/${GTA5VIEW_EXECUTABLE} && \
|
||||||
rm -rf ${GTA5VIEW_EXECUTABLE}
|
rm -rf ${GTA5VIEW_EXECUTABLE}
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Creating folders
|
# Creating folders
|
||||||
cd ${PROJECT_DIR} && \
|
cd ${PROJECT_DIR} && \
|
||||||
|
@ -9,13 +9,11 @@ mkdir -p assets && \
|
||||||
# Starting build
|
# Starting build
|
||||||
cd build && \
|
cd build && \
|
||||||
mingw64-qt-cmake \
|
mingw64-qt-cmake \
|
||||||
"${CMAKE_BUILD_TYPE}" \
|
${CMAKE_BUILD_TYPE} \
|
||||||
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
|
||||||
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
|
||||||
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
|
||||||
"-DWITH_DONATE=ON" \
|
|
||||||
"-DWITH_TELEMETRY=ON" \
|
"-DWITH_TELEMETRY=ON" \
|
||||||
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
|
|
||||||
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
|
||||||
"-DQCONF_BUILD=ON" \
|
"-DQCONF_BUILD=ON" \
|
||||||
"-DGTA5VIEW_INLANG=RUNDIR:SEPARATOR:lang" \
|
"-DGTA5VIEW_INLANG=RUNDIR:SEPARATOR:lang" \
|
||||||
|
@ -25,5 +23,5 @@ mingw64-qt-cmake \
|
||||||
make -j 4 && \
|
make -j 4 && \
|
||||||
x86_64-w64-mingw32-strip -s gta5view.exe && \
|
x86_64-w64-mingw32-strip -s gta5view.exe && \
|
||||||
cd ${PROJECT_DIR}/assets && \
|
cd ${PROJECT_DIR}/assets && \
|
||||||
makensis "-XTarget amd64-unicode" -NOCD ${PROJECT_DIR}/.ci/gta5view.nsi && \
|
makensis -NOCD ${PROJECT_DIR}/.ci/gta5view.nsi && \
|
||||||
mv -f gta5view_setup.exe gta5view-${EXECUTABLE_VERSION}_setup.exe
|
mv -f gta5view_setup.exe gta5view-${EXECUTABLE_VERSION}_setup.exe
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
DOCKER_IMAGE=sypingauto/gta5view-build:1.10-shared
|
DOCKER_IMAGE=sypingauto/gta5view-build:1.9-shared
|
||||||
PROJECT_DIR_DOCKER=/gta5view
|
PROJECT_DIR_DOCKER=/gta5view
|
||||||
|
|
||||||
cd ${PROJECT_DIR} && \
|
cd ${PROJECT_DIR} && \
|
||||||
docker pull ${DOCKER_IMAGE} && \
|
docker pull ${DOCKER_IMAGE} && \
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
|
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
|
||||||
${DOCKER_IMAGE} \
|
${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"
|
/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"
|
||||||
|
|
|
@ -6,7 +6,7 @@ environment:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Windows Installer
|
- name: Windows Installer
|
||||||
image: sypingauto/gta5view-build:1.10-shared
|
image: sypingauto/gta5view-build:1.9-shared
|
||||||
environment:
|
environment:
|
||||||
BUILD_SCRIPT: "wininstall_build.sh"
|
BUILD_SCRIPT: "wininstall_build.sh"
|
||||||
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
||||||
|
@ -18,7 +18,7 @@ steps:
|
||||||
- name: gta5view
|
- name: gta5view
|
||||||
path: /srv/gta5view
|
path: /srv/gta5view
|
||||||
- name: Windows Portable
|
- name: Windows Portable
|
||||||
image: sypingauto/gta5view-build:1.10-static
|
image: sypingauto/gta5view-build:1.9-static
|
||||||
environment:
|
environment:
|
||||||
BUILD_SCRIPT: "windows_build.sh"
|
BUILD_SCRIPT: "windows_build.sh"
|
||||||
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
app-id: de.syping.gta5view
|
app-id: de.syping.gta5view
|
||||||
runtime: org.kde.Platform
|
runtime: org.kde.Platform
|
||||||
runtime-version: '5.15-21.08'
|
runtime-version: '5.15'
|
||||||
sdk: org.kde.Sdk
|
sdk: org.kde.Sdk
|
||||||
command: gta5view
|
command: gta5view
|
||||||
finish-args:
|
finish-args:
|
||||||
|
@ -15,8 +15,6 @@ modules:
|
||||||
config-opts:
|
config-opts:
|
||||||
- -DFLATPAK_BUILD=ON
|
- -DFLATPAK_BUILD=ON
|
||||||
- -DQCONF_BUILD=ON
|
- -DQCONF_BUILD=ON
|
||||||
- -DGTA5VIEW_BUILDCODE=Flatpak
|
|
||||||
- -DGTA5VIEW_BUILDTYPE=Release
|
|
||||||
sources:
|
sources:
|
||||||
- type: dir
|
- type: dir
|
||||||
path: ../
|
path: ../
|
||||||
|
|
|
@ -6,7 +6,7 @@ variables:
|
||||||
|
|
||||||
Windows Installer:
|
Windows Installer:
|
||||||
stage: build
|
stage: build
|
||||||
image: sypingauto/gta5view-build:1.10-shared
|
image: sypingauto/gta5view-build:1.9-shared
|
||||||
variables:
|
variables:
|
||||||
BUILD_SCRIPT: "wininstall_build.sh"
|
BUILD_SCRIPT: "wininstall_build.sh"
|
||||||
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
||||||
|
@ -19,7 +19,7 @@ Windows Installer:
|
||||||
|
|
||||||
Windows Portable:
|
Windows Portable:
|
||||||
stage: build
|
stage: build
|
||||||
image: sypingauto/gta5view-build:1.10-static
|
image: sypingauto/gta5view-build:1.9-static
|
||||||
variables:
|
variables:
|
||||||
BUILD_SCRIPT: "windows_build.sh"
|
BUILD_SCRIPT: "windows_build.sh"
|
||||||
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
QT_SELECT: "qt5-x86_64-w64-mingw32"
|
||||||
|
|
16
.travis.yml
|
@ -5,7 +5,7 @@ language: cpp
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- BUILD_TYPE=REL
|
- BUILD_TYPE=REL
|
||||||
|
@ -15,19 +15,29 @@ matrix:
|
||||||
- env:
|
- env:
|
||||||
- BUILD_SCRIPT=debian_docker.sh
|
- BUILD_SCRIPT=debian_docker.sh
|
||||||
- RELEASE_LABEL="Debian 64-Bit Package"
|
- RELEASE_LABEL="Debian 64-Bit Package"
|
||||||
- DEBIAN_VERSION=buster
|
- DEBIAN_VERSION=stretch
|
||||||
- DOCKER_USER=amd64
|
- DOCKER_USER=amd64
|
||||||
- APT_INSTALL=clang
|
- APT_INSTALL=clang
|
||||||
- env:
|
- env:
|
||||||
- BUILD_SCRIPT=windows_docker.sh
|
- BUILD_SCRIPT=windows_docker.sh
|
||||||
- QT_SELECT=qt5-x86_64-w64-mingw32
|
- QT_SELECT=qt5-x86_64-w64-mingw32
|
||||||
- RELEASE_LABEL="Windows 64-Bit Portable"
|
- RELEASE_LABEL="Windows 64-Bit Portable"
|
||||||
|
- env:
|
||||||
|
- BUILD_SCRIPT=windows_docker.sh
|
||||||
|
- QT_SELECT=qt5-x86_64-w64-mingw32
|
||||||
|
- RELEASE_LABEL="Windows 64-Bit Portable for gta5-mods"
|
||||||
|
- PACKAGE_CODE=gta5-mods
|
||||||
|
- env:
|
||||||
|
- BUILD_SCRIPT=windows_docker.sh
|
||||||
|
- QT_SELECT=qt5-x86_64-w64-mingw32
|
||||||
|
- RELEASE_LABEL="Windows 64-Bit Portable for gtainside"
|
||||||
|
- PACKAGE_CODE=gtainside
|
||||||
- env:
|
- env:
|
||||||
- BUILD_SCRIPT=wininstall_docker.sh
|
- BUILD_SCRIPT=wininstall_docker.sh
|
||||||
- QT_SELECT=qt5-x86_64-w64-mingw32
|
- QT_SELECT=qt5-x86_64-w64-mingw32
|
||||||
- RELEASE_LABEL="Windows 64-Bit Installer"
|
- RELEASE_LABEL="Windows 64-Bit Installer"
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode14.2
|
osx_image: xcode10.3
|
||||||
env:
|
env:
|
||||||
- BUILD_SCRIPT=osx_ci.sh
|
- BUILD_SCRIPT=osx_ci.sh
|
||||||
- RELEASE_LABEL="Mac OS X 64-Bit Disk Image"
|
- RELEASE_LABEL="Mac OS X 64-Bit Disk Image"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2019 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -29,21 +29,19 @@ AboutDialog::AboutDialog(QWidget *parent) :
|
||||||
ui(new Ui::AboutDialog)
|
ui(new Ui::AboutDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
// Set Window Flags
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Build Strings
|
// Build Strings
|
||||||
QString appVersion = QApplication::applicationVersion();
|
const QString appVersion = QApplication::applicationVersion();
|
||||||
const char* literalBuildType = GTA5SYNC_BUILDTYPE;
|
QString buildType = tr(GTA5SYNC_BUILDTYPE);
|
||||||
const QString buildType = tr(literalBuildType);
|
buildType.replace("_", " ");
|
||||||
const QString projectBuild = AppEnv::getBuildDateTime();
|
const QString projectBuild = AppEnv::getBuildDateTime();
|
||||||
const QString buildStr = GTA5SYNC_BUILDSTRING;
|
const QString buildStr = GTA5SYNC_BUILDSTRING;
|
||||||
|
#ifndef GTA5SYNC_BUILDTYPE_REL
|
||||||
#ifdef GTA5SYNC_COMMIT
|
#ifdef GTA5SYNC_COMMIT
|
||||||
if ((strcmp(literalBuildType, REL_BUILDTYPE) != 0) && !appVersion.contains("-"))
|
if (!appVersion.contains("-"))
|
||||||
appVersion = appVersion % "-" % GTA5SYNC_COMMIT;
|
appVersion = appVersion % "-" % GTA5SYNC_COMMIT;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Translator Comments
|
// Translator Comments
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -28,6 +28,7 @@ class AboutDialog;
|
||||||
class AboutDialog : public QDialog
|
class AboutDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AboutDialog(QWidget *parent = 0);
|
explicit AboutDialog(QWidget *parent = 0);
|
||||||
~AboutDialog();
|
~AboutDialog();
|
||||||
|
|
261
AppEnv.cpp
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -33,8 +33,12 @@
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
AppEnv::AppEnv()
|
AppEnv::AppEnv()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build Stuff
|
// Build Stuff
|
||||||
|
@ -55,17 +59,18 @@ QString AppEnv::getGameFolder(bool *ok)
|
||||||
{
|
{
|
||||||
QDir dir;
|
QDir dir;
|
||||||
QString GTAV_FOLDER = QString::fromUtf8(qgetenv("GTAV_FOLDER"));
|
QString GTAV_FOLDER = QString::fromUtf8(qgetenv("GTAV_FOLDER"));
|
||||||
if (GTAV_FOLDER != "") {
|
if (GTAV_FOLDER != "")
|
||||||
|
{
|
||||||
dir.setPath(GTAV_FOLDER);
|
dir.setPath(GTAV_FOLDER);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
if (ok != NULL)
|
{
|
||||||
*ok = true;
|
if (ok != NULL) *ok = true;
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return dir.absolutePath();
|
return dir.absolutePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString GTAV_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/GTA V";
|
QString GTAV_defaultFolder = StandardPaths::documentsLocation() % QDir::separator() % "Rockstar Games" % QDir::separator() % "GTA V";
|
||||||
QString GTAV_returnFolder = GTAV_defaultFolder;
|
QString GTAV_returnFolder = GTAV_defaultFolder;
|
||||||
|
|
||||||
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
|
@ -74,44 +79,46 @@ QString AppEnv::getGameFolder(bool *ok)
|
||||||
GTAV_returnFolder = settings.value("dir", GTAV_defaultFolder).toString();
|
GTAV_returnFolder = settings.value("dir", GTAV_defaultFolder).toString();
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
if (forceDir) {
|
if (forceDir)
|
||||||
|
{
|
||||||
dir.setPath(GTAV_returnFolder);
|
dir.setPath(GTAV_returnFolder);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
if (ok != 0)
|
{
|
||||||
*ok = true;
|
if (ok != 0) *ok = true;
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return dir.absolutePath();
|
return dir.absolutePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dir.setPath(GTAV_defaultFolder);
|
dir.setPath(GTAV_defaultFolder);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
if (ok != 0)
|
{
|
||||||
*ok = true;
|
if (ok != 0) *ok = true;
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return dir.absolutePath();
|
return dir.absolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!forceDir) {
|
if (!forceDir)
|
||||||
|
{
|
||||||
dir.setPath(GTAV_returnFolder);
|
dir.setPath(GTAV_returnFolder);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
if (ok != 0)
|
{
|
||||||
*ok = true;
|
if (ok != 0) *ok = true;
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return dir.absolutePath();
|
return dir.absolutePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok != 0)
|
if (ok != 0) *ok = false;
|
||||||
*ok = false;
|
return "";
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppEnv::setGameFolder(QString gameFolder)
|
bool AppEnv::setGameFolder(QString gameFolder)
|
||||||
{
|
{
|
||||||
QDir dir;
|
QDir dir;
|
||||||
dir.setPath(gameFolder);
|
dir.setPath(gameFolder);
|
||||||
if (dir.exists()) {
|
if (dir.exists())
|
||||||
|
{
|
||||||
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -129,13 +136,13 @@ QString AppEnv::getInLangFolder()
|
||||||
#ifdef GTA5SYNC_INLANG
|
#ifdef GTA5SYNC_INLANG
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_INLANG);
|
return StringParser::convertBuildedString(GTA5SYNC_INLANG);
|
||||||
#else
|
#else
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("/APPNAME:/translations"));
|
return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("SEPARATOR:APPNAME:SEPARATOR:translations"));
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifdef GTA5SYNC_INLANG
|
#ifdef GTA5SYNC_INLANG
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_INLANG);
|
return StringParser::convertBuildedString(GTA5SYNC_INLANG);
|
||||||
#else
|
#else
|
||||||
return QLatin1String(":/tr");
|
return QString(":/tr");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -145,24 +152,6 @@ QString AppEnv::getPluginsFolder()
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_PLUG);
|
return StringParser::convertBuildedString(GTA5SYNC_PLUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AppEnv::getImagesFolder()
|
|
||||||
{
|
|
||||||
#if defined(GTA5SYNC_QCONF) && defined(GTA5SYNC_CMAKE)
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("/resources"));
|
|
||||||
#else
|
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("/APPNAME:/resources"));
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
return QLatin1String(":/img");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AppEnv::getShareFolder()
|
|
||||||
{
|
|
||||||
return StringParser::convertBuildedString(GTA5SYNC_SHARE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Web Stuff
|
// Web Stuff
|
||||||
|
|
||||||
QByteArray AppEnv::getUserAgent()
|
QByteArray AppEnv::getUserAgent()
|
||||||
|
@ -171,19 +160,24 @@ QByteArray AppEnv::getUserAgent()
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString kernelVersion = QSysInfo::kernelVersion();
|
QString kernelVersion = QSysInfo::kernelVersion();
|
||||||
const QStringList &kernelVersionList = kernelVersion.split(".");
|
const QStringList &kernelVersionList = kernelVersion.split(".");
|
||||||
if (kernelVersionList.length() > 2) {
|
if (kernelVersionList.length() > 2)
|
||||||
|
{
|
||||||
kernelVersion = kernelVersionList.at(0) % "." % kernelVersionList.at(1);
|
kernelVersion = kernelVersionList.at(0) % "." % kernelVersionList.at(1);
|
||||||
}
|
}
|
||||||
QString runArch = QSysInfo::buildCpuArchitecture();
|
QString runArch = QSysInfo::buildCpuArchitecture();
|
||||||
if (runArch == "x86_64") {
|
if (runArch == "x86_64")
|
||||||
|
{
|
||||||
runArch = "Win64; x64";
|
runArch = "Win64; x64";
|
||||||
}
|
}
|
||||||
else if (runArch == "i686") {
|
else if (runArch == "i686")
|
||||||
|
{
|
||||||
const QString &curArch = QSysInfo::currentCpuArchitecture();
|
const QString &curArch = QSysInfo::currentCpuArchitecture();
|
||||||
if (curArch == "x86_64") {
|
if (curArch == "x86_64")
|
||||||
|
{
|
||||||
runArch = "WOW64";
|
runArch = "WOW64";
|
||||||
}
|
}
|
||||||
else if (curArch == "i686") {
|
else if (curArch == "i686")
|
||||||
|
{
|
||||||
runArch = "Win32; x86";
|
runArch = "Win32; x86";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,6 +190,11 @@ QByteArray AppEnv::getUserAgent()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QUrl AppEnv::getCrewFetchingUrl(QString crewID)
|
||||||
|
// {
|
||||||
|
// return QUrl(QString("https://socialclub.rockstargames.com/reference/crewfeed/%1").arg(crewID));
|
||||||
|
// }
|
||||||
|
|
||||||
QUrl AppEnv::getCrewFetchingUrl(QString crewID)
|
QUrl AppEnv::getCrewFetchingUrl(QString crewID)
|
||||||
{
|
{
|
||||||
return QUrl(QString("https://socialclub.rockstargames.com/crew/%1/%1").arg(crewID));
|
return QUrl(QString("https://socialclub.rockstargames.com/crew/%1/%1").arg(crewID));
|
||||||
|
@ -224,7 +223,8 @@ GameVersion AppEnv::getGameVersion()
|
||||||
QString installFolderSc = registrySettingsSc.value("InstallFolder", "").toString();
|
QString installFolderSc = registrySettingsSc.value("InstallFolder", "").toString();
|
||||||
QDir installFolderScDir(installFolderSc);
|
QDir installFolderScDir(installFolderSc);
|
||||||
bool scVersionInstalled = false;
|
bool scVersionInstalled = false;
|
||||||
if (!installFolderSc.isEmpty() && installFolderScDir.exists()) {
|
if (!installFolderSc.isEmpty() && installFolderScDir.exists())
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "gameVersionFoundSocialClubVersion";
|
qDebug() << "gameVersionFoundSocialClubVersion";
|
||||||
#endif
|
#endif
|
||||||
|
@ -233,28 +233,34 @@ GameVersion AppEnv::getGameVersion()
|
||||||
|
|
||||||
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\GTAV").arg(argumentValue), QSettings::NativeFormat);
|
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\GTAV").arg(argumentValue), QSettings::NativeFormat);
|
||||||
QString installFolderSteam = registrySettingsSteam.value("installfoldersteam", "").toString();
|
QString installFolderSteam = registrySettingsSteam.value("installfoldersteam", "").toString();
|
||||||
if (installFolderSteam.right(5) == "\\GTAV") {
|
if (installFolderSteam.right(5) == "\\GTAV")
|
||||||
|
{
|
||||||
installFolderSteam = installFolderSteam.remove(installFolderSteam.length() - 5, 5);
|
installFolderSteam = installFolderSteam.remove(installFolderSteam.length() - 5, 5);
|
||||||
}
|
}
|
||||||
QDir installFolderSteamDir(installFolderSteam);
|
QDir installFolderSteamDir(installFolderSteam);
|
||||||
bool steamVersionInstalled = false;
|
bool steamVersionInstalled = false;
|
||||||
if (!installFolderSteam.isEmpty() && installFolderSteamDir.exists()) {
|
if (!installFolderSteam.isEmpty() && installFolderSteamDir.exists())
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "gameVersionFoundSteamVersion";
|
qDebug() << "gameVersionFoundSteamVersion";
|
||||||
#endif
|
#endif
|
||||||
steamVersionInstalled = true;
|
steamVersionInstalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scVersionInstalled && steamVersionInstalled) {
|
if (scVersionInstalled && steamVersionInstalled)
|
||||||
|
{
|
||||||
return GameVersion::BothVersions;
|
return GameVersion::BothVersions;
|
||||||
}
|
}
|
||||||
else if (scVersionInstalled) {
|
else if (scVersionInstalled)
|
||||||
|
{
|
||||||
return GameVersion::SocialClubVersion;
|
return GameVersion::SocialClubVersion;
|
||||||
}
|
}
|
||||||
else if (steamVersionInstalled) {
|
else if (steamVersionInstalled)
|
||||||
|
{
|
||||||
return GameVersion::SteamVersion;
|
return GameVersion::SteamVersion;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
return GameVersion::NoVersion;
|
return GameVersion::NoVersion;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -264,7 +270,8 @@ GameVersion AppEnv::getGameVersion()
|
||||||
|
|
||||||
GameLanguage AppEnv::getGameLanguage(GameVersion gameVersion)
|
GameLanguage AppEnv::getGameLanguage(GameVersion gameVersion)
|
||||||
{
|
{
|
||||||
if (gameVersion == GameVersion::SocialClubVersion) {
|
if (gameVersion == GameVersion::SocialClubVersion)
|
||||||
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString argumentValue;
|
QString argumentValue;
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
@ -277,7 +284,8 @@ GameLanguage AppEnv::getGameLanguage(GameVersion gameVersion)
|
||||||
return GameLanguage::Undefined;
|
return GameLanguage::Undefined;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (gameVersion == GameVersion::SteamVersion) {
|
else if (gameVersion == GameVersion::SteamVersion)
|
||||||
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString argumentValue;
|
QString argumentValue;
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
@ -290,81 +298,128 @@ GameLanguage AppEnv::getGameLanguage(GameVersion gameVersion)
|
||||||
return GameLanguage::Undefined;
|
return GameLanguage::Undefined;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return GameLanguage::Undefined;
|
else
|
||||||
|
{
|
||||||
|
return GameLanguage::Undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GameLanguage AppEnv::gameLanguageFromString(QString gameLanguage)
|
GameLanguage AppEnv::gameLanguageFromString(QString gameLanguage)
|
||||||
{
|
{
|
||||||
if (gameLanguage == "en-US") {
|
if (gameLanguage == "en-US")
|
||||||
|
{
|
||||||
return GameLanguage::English;
|
return GameLanguage::English;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "fr-FR") {
|
else if (gameLanguage == "fr-FR")
|
||||||
|
{
|
||||||
return GameLanguage::French;
|
return GameLanguage::French;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "it-IT") {
|
else if (gameLanguage == "it-IT")
|
||||||
|
{
|
||||||
return GameLanguage::Italian;
|
return GameLanguage::Italian;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "de-DE") {
|
else if (gameLanguage == "de-DE")
|
||||||
|
{
|
||||||
return GameLanguage::German;
|
return GameLanguage::German;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "es-ES") {
|
else if (gameLanguage == "es-ES")
|
||||||
|
{
|
||||||
return GameLanguage::Spanish;
|
return GameLanguage::Spanish;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "es-MX") {
|
else if (gameLanguage == "es-MX")
|
||||||
|
{
|
||||||
return GameLanguage::Mexican;
|
return GameLanguage::Mexican;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "pt-BR") {
|
else if (gameLanguage == "pt-BR")
|
||||||
|
{
|
||||||
return GameLanguage::Brasilian;
|
return GameLanguage::Brasilian;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "ru-RU") {
|
else if (gameLanguage == "ru-RU")
|
||||||
|
{
|
||||||
return GameLanguage::Russian;
|
return GameLanguage::Russian;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "pl-PL") {
|
else if (gameLanguage == "pl-PL")
|
||||||
|
{
|
||||||
return GameLanguage::Polish;
|
return GameLanguage::Polish;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "ja-JP") {
|
else if (gameLanguage == "ja-JP")
|
||||||
|
{
|
||||||
return GameLanguage::Japanese;
|
return GameLanguage::Japanese;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "zh-CHS") {
|
else if (gameLanguage == "zh-CHS")
|
||||||
|
{
|
||||||
return GameLanguage::SChinese;
|
return GameLanguage::SChinese;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "zh-CHT") {
|
else if (gameLanguage == "zh-CHT")
|
||||||
|
{
|
||||||
return GameLanguage::TChinese;
|
return GameLanguage::TChinese;
|
||||||
}
|
}
|
||||||
else if (gameLanguage == "ko-KR") {
|
else if (gameLanguage == "ko-KR")
|
||||||
return GameLanguage::Korean;
|
{
|
||||||
|
return GameLanguage::Koreana;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return GameLanguage::Undefined;
|
||||||
}
|
}
|
||||||
return GameLanguage::Undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AppEnv::gameLanguageToString(GameLanguage gameLanguage)
|
QString AppEnv::gameLanguageToString(GameLanguage gameLanguage)
|
||||||
{
|
{
|
||||||
switch (gameLanguage) {
|
if (gameLanguage == GameLanguage::English)
|
||||||
case GameLanguage::English:
|
{
|
||||||
return "en-US";
|
return "en-US";
|
||||||
case GameLanguage::French:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::French)
|
||||||
|
{
|
||||||
return "fr-FR";
|
return "fr-FR";
|
||||||
case GameLanguage::Italian:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::Italian)
|
||||||
|
{
|
||||||
return "it-IT";
|
return "it-IT";
|
||||||
case GameLanguage::German:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::German)
|
||||||
|
{
|
||||||
return "de-DE";
|
return "de-DE";
|
||||||
case GameLanguage::Spanish:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::Spanish)
|
||||||
|
{
|
||||||
return "es-ES";
|
return "es-ES";
|
||||||
case GameLanguage::Mexican:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::Mexican)
|
||||||
|
{
|
||||||
return "es-MX";
|
return "es-MX";
|
||||||
case GameLanguage::Brasilian:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::Brasilian)
|
||||||
|
{
|
||||||
return "pt-BR";
|
return "pt-BR";
|
||||||
case GameLanguage::Polish:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::Russian)
|
||||||
|
{
|
||||||
|
return "ru-RU";
|
||||||
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::Polish)
|
||||||
|
{
|
||||||
return "pl-PL";
|
return "pl-PL";
|
||||||
case GameLanguage::Japanese:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::Japanese)
|
||||||
|
{
|
||||||
return "ja-JP";
|
return "ja-JP";
|
||||||
case GameLanguage::SChinese:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::SChinese)
|
||||||
|
{
|
||||||
return "zh-CHS";
|
return "zh-CHS";
|
||||||
case GameLanguage::TChinese:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::TChinese)
|
||||||
|
{
|
||||||
return "zh-CHT";
|
return "zh-CHT";
|
||||||
case GameLanguage::Korean:
|
}
|
||||||
|
else if (gameLanguage == GameLanguage::Koreana)
|
||||||
|
{
|
||||||
return "ko-KR";
|
return "ko-KR";
|
||||||
default:
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return "Undefinied";
|
return "Undefinied";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,55 +428,67 @@ bool AppEnv::setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage)
|
||||||
{
|
{
|
||||||
bool socialClubVersion = false;
|
bool socialClubVersion = false;
|
||||||
bool steamVersion = false;
|
bool steamVersion = false;
|
||||||
if (gameVersion == GameVersion::SocialClubVersion) {
|
if (gameVersion == GameVersion::SocialClubVersion)
|
||||||
|
{
|
||||||
socialClubVersion = true;
|
socialClubVersion = true;
|
||||||
}
|
}
|
||||||
else if (gameVersion == GameVersion::SteamVersion) {
|
else if (gameVersion == GameVersion::SteamVersion)
|
||||||
|
{
|
||||||
steamVersion = true;
|
steamVersion = true;
|
||||||
}
|
}
|
||||||
else if (gameVersion == GameVersion::BothVersions) {
|
else if (gameVersion == GameVersion::BothVersions)
|
||||||
|
{
|
||||||
socialClubVersion = true;
|
socialClubVersion = true;
|
||||||
steamVersion = true;
|
steamVersion = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (socialClubVersion) {
|
if (socialClubVersion)
|
||||||
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString argumentValue;
|
QString argumentValue;
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
argumentValue = "\\WOW6432Node";
|
argumentValue = "\\WOW6432Node";
|
||||||
#endif
|
#endif
|
||||||
QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat);
|
QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat);
|
||||||
if (gameLanguage != GameLanguage::Undefined) {
|
if (gameLanguage != GameLanguage::Undefined)
|
||||||
|
{
|
||||||
registrySettingsSc.setValue("Language", gameLanguageToString(gameLanguage));
|
registrySettingsSc.setValue("Language", gameLanguageToString(gameLanguage));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
registrySettingsSc.remove("Language");
|
registrySettingsSc.remove("Language");
|
||||||
}
|
}
|
||||||
registrySettingsSc.sync();
|
registrySettingsSc.sync();
|
||||||
if (registrySettingsSc.status() != QSettings::NoError) {
|
if (registrySettingsSc.status() != QSettings::NoError)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(gameLanguage)
|
Q_UNUSED(gameLanguage)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (steamVersion) {
|
if (steamVersion)
|
||||||
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString argumentValue;
|
QString argumentValue;
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
argumentValue = "\\WOW6432Node";
|
argumentValue = "\\WOW6432Node";
|
||||||
#endif
|
#endif
|
||||||
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V Steam").arg(argumentValue), QSettings::NativeFormat);
|
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V Steam").arg(argumentValue), QSettings::NativeFormat);
|
||||||
if (gameLanguage != GameLanguage::Undefined) {
|
if (gameLanguage != GameLanguage::Undefined)
|
||||||
|
{
|
||||||
registrySettingsSteam.setValue("Language", gameLanguageToString(gameLanguage));
|
registrySettingsSteam.setValue("Language", gameLanguageToString(gameLanguage));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
registrySettingsSteam.remove("Language");
|
registrySettingsSteam.remove("Language");
|
||||||
}
|
}
|
||||||
registrySettingsSteam.sync();
|
registrySettingsSteam.sync();
|
||||||
if (registrySettingsSteam.status() != QSettings::NoError) {
|
if (registrySettingsSteam.status() != QSettings::NoError)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
6
AppEnv.h
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2018 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
enum class GameVersion : int { NoVersion = 0, SocialClubVersion = 1, SteamVersion = 2, BothVersions = 3 };
|
enum class GameVersion : int { NoVersion = 0, SocialClubVersion = 1, SteamVersion = 2, BothVersions = 3 };
|
||||||
enum class GameLanguage : int { Undefined = 0, English = 1, French = 2, Italian = 3, German = 4, Spanish = 5, Mexican = 6, Brasilian = 7, Russian = 8, Polish = 9, Japanese = 10, SChinese = 11, TChinese = 12, Korean = 13 };
|
enum class GameLanguage : int { Undefined = 0, English = 1, French = 2, Italian = 3, German = 4, Spanish = 5, Mexican = 6, Brasilian = 7, Russian = 8, Polish = 9, Japanese = 10, SChinese = 11, TChinese = 12, Koreana = 13 };
|
||||||
|
|
||||||
class AppEnv
|
class AppEnv
|
||||||
{
|
{
|
||||||
|
@ -39,9 +39,7 @@ public:
|
||||||
static bool setGameFolder(QString gameFolder);
|
static bool setGameFolder(QString gameFolder);
|
||||||
static QString getExLangFolder();
|
static QString getExLangFolder();
|
||||||
static QString getInLangFolder();
|
static QString getInLangFolder();
|
||||||
static QString getImagesFolder();
|
|
||||||
static QString getPluginsFolder();
|
static QString getPluginsFolder();
|
||||||
static QString getShareFolder();
|
|
||||||
|
|
||||||
// Web Stuff
|
// Web Stuff
|
||||||
static QByteArray getUserAgent();
|
static QByteArray getUserAgent();
|
||||||
|
|
125
CMakeLists.txt
|
@ -11,18 +11,20 @@ set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
set(FORCE_QT_VERSION "" CACHE STRING "Force Qt Version")
|
option(QT6_BUILD "Build gta5view with Qt6" OFF)
|
||||||
if(FORCE_QT_VERSION)
|
if(QT6_BUILD)
|
||||||
set(QT_VERSION_MAJOR ${FORCE_QT_VERSION})
|
set(QT_VERSION_MAJOR 6)
|
||||||
else()
|
else()
|
||||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
set(QT_VERSION_MAJOR 5)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network Svg Widgets REQUIRED)
|
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network Svg Widgets REQUIRED)
|
||||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET)
|
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS WinExtras REQUIRED)
|
||||||
list(APPEND GTA5VIEW_LIBS
|
list(APPEND GTA5VIEW_LIBS
|
||||||
dwmapi
|
Qt${QT_VERSION_MAJOR}::WinExtras
|
||||||
)
|
)
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
-DUNICODE
|
-DUNICODE
|
||||||
|
@ -33,20 +35,11 @@ if(WIN32)
|
||||||
res/app.rc
|
res/app.rc
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
if(APPLE)
|
|
||||||
list(APPEND GTA5VIEW_RESOURCES
|
|
||||||
res/gta5view.icns
|
|
||||||
)
|
|
||||||
set(MACOSX_BUNDLE_BUNDLE_NAME gta5view)
|
|
||||||
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.10.2)
|
|
||||||
set(MACOSX_BUNDLE_ICON_FILE gta5view.icns)
|
|
||||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER de.syping.gta5view)
|
|
||||||
set_source_files_properties(res/gta5view.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
-DGTA5SYNC_CMAKE
|
-DGTA5SYNC_CMAKE
|
||||||
-DGTA5SYNC_PROJECT
|
-DGTA5SYNC_PROJECT
|
||||||
|
-DSNAPMATIC_NODEFAULT
|
||||||
)
|
)
|
||||||
|
|
||||||
set(GTA5VIEW_SOURCES
|
set(GTA5VIEW_SOURCES
|
||||||
|
@ -93,7 +86,6 @@ set(GTA5VIEW_SOURCES
|
||||||
|
|
||||||
set(GTA5VIEW_HEADERS
|
set(GTA5VIEW_HEADERS
|
||||||
config.h
|
config.h
|
||||||
wrapper.h
|
|
||||||
AboutDialog.h
|
AboutDialog.h
|
||||||
AppEnv.h
|
AppEnv.h
|
||||||
CrewDatabase.h
|
CrewDatabase.h
|
||||||
|
@ -157,36 +149,26 @@ set(GTA5VIEW_FORMS
|
||||||
UserInterface.ui
|
UserInterface.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
set(GTA5VIEW_TRANSLATIONS
|
|
||||||
res/gta5sync_de.ts
|
|
||||||
res/gta5sync_en_US.ts
|
|
||||||
res/gta5sync_fr.ts
|
|
||||||
res/gta5sync_ko.ts
|
|
||||||
res/gta5sync_ru.ts
|
|
||||||
res/gta5sync_uk.ts
|
|
||||||
res/gta5sync_zh_TW.ts
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND GTA5VIEW_RESOURCES
|
list(APPEND GTA5VIEW_RESOURCES
|
||||||
|
res/app.qrc
|
||||||
res/global.qrc
|
res/global.qrc
|
||||||
res/template.qrc
|
|
||||||
)
|
)
|
||||||
set_property(SOURCE res/global.qrc PROPERTY AUTORCC_OPTIONS "-threshold;0;-compress;9")
|
set_property(SOURCE res/global.qrc PROPERTY AUTORCC_OPTIONS "-threshold;0;-compress;9")
|
||||||
|
|
||||||
if(Qt5LinguistTools_FOUND)
|
if(Qt5LinguistTools_FOUND)
|
||||||
qt5_add_translation(GTA5VIEW_QMFILES
|
qt5_add_translation(GTA5VIEW_TRANSLATIONS
|
||||||
${GTA5VIEW_TRANSLATIONS}
|
res/gta5sync_de.ts
|
||||||
|
res/gta5sync_en_US.ts
|
||||||
|
res/gta5sync_fr.ts
|
||||||
|
res/gta5sync_ko.ts
|
||||||
|
res/gta5sync_ru.ts
|
||||||
|
res/gta5sync_uk.ts
|
||||||
|
res/gta5sync_zh_TW.ts
|
||||||
res/qt5/qtbase_en_GB.ts
|
res/qt5/qtbase_en_GB.ts
|
||||||
)
|
)
|
||||||
set(LINGUIST_FOUND TRUE)
|
add_custom_target(translations DEPENDS ${GTA5VIEW_TRANSLATIONS})
|
||||||
elseif(Qt6LinguistTools_FOUND)
|
|
||||||
qt6_add_translation(GTA5VIEW_QMFILES
|
|
||||||
${GTA5VIEW_TRANSLATIONS}
|
|
||||||
res/qt6/qtbase_en_GB.ts
|
|
||||||
)
|
|
||||||
set(LINGUIST_FOUND TRUE)
|
|
||||||
else()
|
else()
|
||||||
set(GTA5VIEW_QMFILES
|
set(GTA5VIEW_TRANSLATIONS
|
||||||
res/gta5sync_de.qm
|
res/gta5sync_de.qm
|
||||||
res/gta5sync_en_US.qm
|
res/gta5sync_en_US.qm
|
||||||
res/gta5sync_fr.qm
|
res/gta5sync_fr.qm
|
||||||
|
@ -205,41 +187,20 @@ if(QCONF_BUILD)
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
list(APPEND GTA5VIEW_RESOURCES
|
list(APPEND GTA5VIEW_RESOURCES
|
||||||
res/img.qrc
|
|
||||||
res/tr_g5p.qrc
|
res/tr_g5p.qrc
|
||||||
res/qt${QT_VERSION_MAJOR}/tr_qt.qrc
|
res/qt${QT_VERSION_MAJOR}/tr_qt.qrc
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(FLATPAK_BUILD "Flatpak modifications and optimisations" OFF)
|
option(FLATPAK_BUILD "Flatpak modifications and identifications" OFF)
|
||||||
if(FLATPAK_BUILD)
|
if(FLATPAK_BUILD)
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
|
"-DGTA5SYNC_BUILDCODE=\"Flatpak\""
|
||||||
|
"-DGTA5SYNC_BUILDTYPE=\"Flatpak\""
|
||||||
-DGTA5SYNC_FLATPAK
|
-DGTA5SYNC_FLATPAK
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(WITH_DONATE "Donate menu option and donation dialog" OFF)
|
|
||||||
if(WITH_DONATE)
|
|
||||||
set(DONATE_ADDRESSES "" CACHE STRING "Donation addresses")
|
|
||||||
list(APPEND GTA5VIEW_HEADERS
|
|
||||||
anpro/QrCode.h
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_SOURCES
|
|
||||||
anpro/QrCode.cpp
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
-DGTA5SYNC_DONATE
|
|
||||||
)
|
|
||||||
list(APPEND GTA5VIEW_RESOURCES
|
|
||||||
res/donate.qrc
|
|
||||||
)
|
|
||||||
if(DONATE_ADDRESSES)
|
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
|
||||||
"-DGTA5SYNC_DONATE_ADDRESSES=\"${DONATE_ADDRESSES}\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(WITH_MOTD "Developer message system directed to users" OFF)
|
option(WITH_MOTD "Developer message system directed to users" OFF)
|
||||||
if(WITH_MOTD)
|
if(WITH_MOTD)
|
||||||
set(MOTD_WEBURL "" CACHE STRING "Messages WebURL")
|
set(MOTD_WEBURL "" CACHE STRING "Messages WebURL")
|
||||||
|
@ -314,6 +275,37 @@ if(GTA5VIEW_BUILDTYPE)
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
"-DGTA5SYNC_BUILDTYPE=\"${GTA5VIEW_BUILDTYPE}\""
|
"-DGTA5SYNC_BUILDTYPE=\"${GTA5VIEW_BUILDTYPE}\""
|
||||||
)
|
)
|
||||||
|
else()
|
||||||
|
if(GTA5VIEW_BUILDTYPE_ALPHA)
|
||||||
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
|
-DGTA5SYNC_BUILDTYPE_ALPHA
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(GTA5VIEW_BUILDTYPE_BETA)
|
||||||
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
|
-DGTA5SYNC_BUILDTYPE_BETA
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(GTA5VIEW_BUILDTYPE_DEV)
|
||||||
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
|
-DGTA5SYNC_BUILDTYPE_DEV
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(GTA5VIEW_BUILDTYPE_DAILY)
|
||||||
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
|
-DGTA5SYNC_BUILDTYPE_DAILY
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(GTA5VIEW_BUILDTYPE_RC)
|
||||||
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
|
-DGTA5SYNC_BUILDTYPE_RC
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(GTA5VIEW_BUILDTYPE_REL)
|
||||||
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
|
-DGTA5SYNC_BUILDTYPE_REL
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(GTA5VIEW_COMMIT)
|
if(GTA5VIEW_COMMIT)
|
||||||
list(APPEND GTA5VIEW_DEFINES
|
list(APPEND GTA5VIEW_DEFINES
|
||||||
|
@ -345,8 +337,7 @@ add_executable(gta5view
|
||||||
${GTA5VIEW_RESOURCES}
|
${GTA5VIEW_RESOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(LINGUIST_FOUND AND QCONF_BUILD)
|
if(Qt5LinguistTools_FOUND AND QCONF_BUILD)
|
||||||
add_custom_target(translations DEPENDS ${GTA5VIEW_QMFILES})
|
|
||||||
add_dependencies(gta5view translations)
|
add_dependencies(gta5view translations)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -356,6 +347,8 @@ endif()
|
||||||
|
|
||||||
if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.14.0")
|
if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.14.0")
|
||||||
qt5_import_plugins(gta5view INCLUDE Qt5::QSvgPlugin)
|
qt5_import_plugins(gta5view INCLUDE Qt5::QSvgPlugin)
|
||||||
|
elseif(Qt6Core_VERSION VERSION_GREATER_EQUAL "6.0")
|
||||||
|
qt6_import_plugins(gta5view INCLUDE Qt6::QSvgPlugin)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_compile_definitions(gta5view PRIVATE ${GTA5VIEW_DEFINES})
|
target_compile_definitions(gta5view PRIVATE ${GTA5VIEW_DEFINES})
|
||||||
|
@ -365,7 +358,6 @@ target_link_libraries(gta5view PRIVATE Qt${QT_VERSION_MAJOR}::Network Qt${QT_VER
|
||||||
install(TARGETS gta5view DESTINATION bin)
|
install(TARGETS gta5view DESTINATION bin)
|
||||||
install(FILES res/de.syping.gta5view.desktop DESTINATION share/applications)
|
install(FILES res/de.syping.gta5view.desktop DESTINATION share/applications)
|
||||||
install(FILES res/de.syping.gta5view.metainfo.xml DESTINATION share/metainfo)
|
install(FILES res/de.syping.gta5view.metainfo.xml DESTINATION share/metainfo)
|
||||||
install(FILES res/de.syping.gta5view.xml DESTINATION share/mime/packages)
|
|
||||||
install(FILES res/gta5view-16.png DESTINATION share/icons/hicolor/16x16/apps RENAME de.syping.gta5view.png)
|
install(FILES res/gta5view-16.png DESTINATION share/icons/hicolor/16x16/apps RENAME de.syping.gta5view.png)
|
||||||
install(FILES res/gta5view-24.png DESTINATION share/icons/hicolor/24x24/apps RENAME de.syping.gta5view.png)
|
install(FILES res/gta5view-24.png DESTINATION share/icons/hicolor/24x24/apps RENAME de.syping.gta5view.png)
|
||||||
install(FILES res/gta5view-32.png DESTINATION share/icons/hicolor/32x32/apps RENAME de.syping.gta5view.png)
|
install(FILES res/gta5view-32.png DESTINATION share/icons/hicolor/32x32/apps RENAME de.syping.gta5view.png)
|
||||||
|
@ -375,8 +367,7 @@ install(FILES res/gta5view-96.png DESTINATION share/icons/hicolor/96x96/apps REN
|
||||||
install(FILES res/gta5view-128.png DESTINATION share/icons/hicolor/128x128/apps RENAME de.syping.gta5view.png)
|
install(FILES res/gta5view-128.png DESTINATION share/icons/hicolor/128x128/apps RENAME de.syping.gta5view.png)
|
||||||
install(FILES res/gta5view-256.png DESTINATION share/icons/hicolor/256x256/apps RENAME de.syping.gta5view.png)
|
install(FILES res/gta5view-256.png DESTINATION share/icons/hicolor/256x256/apps RENAME de.syping.gta5view.png)
|
||||||
install(FILES res/gta5view-512.png DESTINATION share/icons/hicolor/512x512/apps RENAME de.syping.gta5view.png)
|
install(FILES res/gta5view-512.png DESTINATION share/icons/hicolor/512x512/apps RENAME de.syping.gta5view.png)
|
||||||
|
install(FILES res/de.syping.gta5view.png DESTINATION share/pixmaps)
|
||||||
if(QCONF_BUILD)
|
if(QCONF_BUILD)
|
||||||
include(res/img.cmake)
|
install(FILES ${GTA5VIEW_TRANSLATIONS} DESTINATION share/gta5view/translations)
|
||||||
install(FILES ${GTA5VIEW_IMGFILES} DESTINATION share/gta5view/resources)
|
|
||||||
install(FILES ${GTA5VIEW_QMFILES} DESTINATION share/gta5view/translations)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -46,7 +46,8 @@ void DatabaseThread::run()
|
||||||
|
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit()));
|
QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit()));
|
||||||
|
|
||||||
while (threadRunning) {
|
while (threadRunning)
|
||||||
|
{
|
||||||
QTimer::singleShot(300000, &threadLoop, SLOT(quit()));
|
QTimer::singleShot(300000, &threadLoop, SLOT(quit()));
|
||||||
threadLoop.exec();
|
threadLoop.exec();
|
||||||
}
|
}
|
||||||
|
@ -54,8 +55,10 @@ void DatabaseThread::run()
|
||||||
|
|
||||||
void DatabaseThread::scanCrewReference(const QStringList &crewList, const int &requestDelay)
|
void DatabaseThread::scanCrewReference(const QStringList &crewList, const int &requestDelay)
|
||||||
{
|
{
|
||||||
for (const QString &crewID : crewList) {
|
for (QString crewID : crewList)
|
||||||
if (threadRunning && crewID != QLatin1String("0")) {
|
{
|
||||||
|
if (threadRunning && crewID != QLatin1String("0"))
|
||||||
|
{
|
||||||
QNetworkAccessManager *netManager = new QNetworkAccessManager();
|
QNetworkAccessManager *netManager = new QNetworkAccessManager();
|
||||||
QNetworkRequest netRequest(AppEnv::getCrewFetchingUrl(crewID));
|
QNetworkRequest netRequest(AppEnv::getCrewFetchingUrl(crewID));
|
||||||
#if QT_VERSION >= 0x050600
|
#if QT_VERSION >= 0x050600
|
||||||
|
@ -73,36 +76,40 @@ void DatabaseThread::scanCrewReference(const QStringList &crewList, const int &r
|
||||||
|
|
||||||
QEventLoop *downloadLoop = new QEventLoop();
|
QEventLoop *downloadLoop = new QEventLoop();
|
||||||
QObject::connect(netReply, SIGNAL(finished()), downloadLoop, SLOT(quit()));
|
QObject::connect(netReply, SIGNAL(finished()), downloadLoop, SLOT(quit()));
|
||||||
if (!continueLastCrew)
|
if (!continueLastCrew) { QObject::connect(this, SIGNAL(threadTerminated()), downloadLoop, SLOT(quit())); }
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), downloadLoop, SLOT(quit()));
|
|
||||||
QTimer::singleShot(30000, downloadLoop, SLOT(quit()));
|
QTimer::singleShot(30000, downloadLoop, SLOT(quit()));
|
||||||
downloadLoop->exec();
|
downloadLoop->exec();
|
||||||
downloadLoop->disconnect();
|
downloadLoop->disconnect();
|
||||||
delete downloadLoop;
|
delete downloadLoop;
|
||||||
|
|
||||||
if (netReply->isFinished()) {
|
if (netReply->isFinished())
|
||||||
|
{
|
||||||
QString crewName;
|
QString crewName;
|
||||||
QByteArray crewHtml = netReply->readAll();
|
QByteArray crewHtml = netReply->readAll();
|
||||||
QStringList crewHtmlSplit1 = QString::fromUtf8(crewHtml).split("<title>Rockstar Games Social Club - Crew : ");
|
QStringList crewHtmlSplit1 = QString::fromUtf8(crewHtml).split("<title>Rockstar Games Social Club - Crew : ");
|
||||||
if (crewHtmlSplit1.length() >= 2) {
|
if (crewHtmlSplit1.length() >= 2)
|
||||||
|
{
|
||||||
QStringList crewHtmlSplit2 = QString(crewHtmlSplit1.at(1)).split("</title>");
|
QStringList crewHtmlSplit2 = QString(crewHtmlSplit1.at(1)).split("</title>");
|
||||||
if (crewHtmlSplit2.length() >= 1) {
|
if (crewHtmlSplit2.length() >= 1)
|
||||||
|
{
|
||||||
crewName = crewHtmlSplit2.at(0);
|
crewName = crewHtmlSplit2.at(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!crewName.isEmpty()) {
|
if (!crewName.isEmpty())
|
||||||
|
{
|
||||||
emit crewNameFound(crewID.toInt(), crewName);
|
emit crewNameFound(crewID.toInt(), crewName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
netReply->abort();
|
netReply->abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threadRunning) {
|
if (threadRunning)
|
||||||
|
{
|
||||||
QEventLoop *waitingLoop = new QEventLoop();
|
QEventLoop *waitingLoop = new QEventLoop();
|
||||||
QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit()));
|
QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit()));
|
||||||
if (!continueLastCrew)
|
if (!continueLastCrew) { QObject::connect(this, SIGNAL(threadTerminated()), waitingLoop, SLOT(quit())); }
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), waitingLoop, SLOT(quit()));
|
|
||||||
waitingLoop->exec();
|
waitingLoop->exec();
|
||||||
waitingLoop->disconnect();
|
waitingLoop->disconnect();
|
||||||
delete waitingLoop;
|
delete waitingLoop;
|
||||||
|
@ -116,14 +123,17 @@ void DatabaseThread::scanCrewReference(const QStringList &crewList, const int &r
|
||||||
|
|
||||||
void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int &maxPages, const int &requestDelay)
|
void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int &maxPages, const int &requestDelay)
|
||||||
{
|
{
|
||||||
for (const QString &crewID : crewList) {
|
for (QString crewID : crewList)
|
||||||
if (threadRunning && crewID != QLatin1String("0")) {
|
{
|
||||||
|
if (threadRunning && crewID != QLatin1String("0"))
|
||||||
|
{
|
||||||
int currentFail = 0;
|
int currentFail = 0;
|
||||||
int currentPage = 0;
|
int currentPage = 0;
|
||||||
int foundPlayers = 0;
|
int foundPlayers = 0;
|
||||||
int totalPlayers = 1000;
|
int totalPlayers = 1000;
|
||||||
|
|
||||||
while(foundPlayers < totalPlayers && currentPage < maxPages && (continueLastCrew ? true : threadRunning)) {
|
while(foundPlayers < totalPlayers && currentPage < maxPages && (continueLastCrew ? true : threadRunning))
|
||||||
|
{
|
||||||
QNetworkAccessManager *netManager = new QNetworkAccessManager();
|
QNetworkAccessManager *netManager = new QNetworkAccessManager();
|
||||||
QNetworkRequest netRequest(AppEnv::getPlayerFetchingUrl(crewID, currentPage));
|
QNetworkRequest netRequest(AppEnv::getPlayerFetchingUrl(crewID, currentPage));
|
||||||
#if QT_VERSION >= 0x050600
|
#if QT_VERSION >= 0x050600
|
||||||
|
@ -141,14 +151,14 @@ void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int
|
||||||
|
|
||||||
QEventLoop *downloadLoop = new QEventLoop();
|
QEventLoop *downloadLoop = new QEventLoop();
|
||||||
QObject::connect(netReply, SIGNAL(finished()), downloadLoop, SLOT(quit()));
|
QObject::connect(netReply, SIGNAL(finished()), downloadLoop, SLOT(quit()));
|
||||||
if (!continueLastCrew)
|
if (!continueLastCrew) { QObject::connect(this, SIGNAL(threadTerminated()), downloadLoop, SLOT(quit())); }
|
||||||
QObject::connect(this, SIGNAL(threadTerminated()), downloadLoop, SLOT(quit()));
|
|
||||||
QTimer::singleShot(30000, downloadLoop, SLOT(quit()));
|
QTimer::singleShot(30000, downloadLoop, SLOT(quit()));
|
||||||
downloadLoop->exec();
|
downloadLoop->exec();
|
||||||
downloadLoop->disconnect();
|
downloadLoop->disconnect();
|
||||||
delete downloadLoop;
|
delete downloadLoop;
|
||||||
|
|
||||||
if (netReply->isFinished()) {
|
if (netReply->isFinished())
|
||||||
|
{
|
||||||
QByteArray crewJson = netReply->readAll();
|
QByteArray crewJson = netReply->readAll();
|
||||||
QJsonDocument crewDocument = QJsonDocument::fromJson(crewJson);
|
QJsonDocument crewDocument = QJsonDocument::fromJson(crewJson);
|
||||||
QJsonObject crewObject = crewDocument.object();
|
QJsonObject crewObject = crewDocument.object();
|
||||||
|
@ -156,25 +166,32 @@ void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int
|
||||||
|
|
||||||
if (crewMap.contains("Total")) { totalPlayers = crewMap["Total"].toInt(); }
|
if (crewMap.contains("Total")) { totalPlayers = crewMap["Total"].toInt(); }
|
||||||
|
|
||||||
if (crewMap.contains("Members")) {
|
if (crewMap.contains("Members"))
|
||||||
|
{
|
||||||
const QList<QVariant> memberList = crewMap["Members"].toList();
|
const QList<QVariant> memberList = crewMap["Members"].toList();
|
||||||
for (const QVariant &memberVariant : memberList) {
|
for (QVariant memberVariant : memberList)
|
||||||
|
{
|
||||||
QMap<QString, QVariant> memberMap = memberVariant.toMap();
|
QMap<QString, QVariant> memberMap = memberVariant.toMap();
|
||||||
if (memberMap.contains("RockstarId") && memberMap.contains("Name")) {
|
if (memberMap.contains("RockstarId") && memberMap.contains("Name"))
|
||||||
|
{
|
||||||
int RockstarId = memberMap["RockstarId"].toInt();
|
int RockstarId = memberMap["RockstarId"].toInt();
|
||||||
QString memberName = memberMap["Name"].toString();
|
QString memberName = memberMap["Name"].toString();
|
||||||
if (!memberName.isEmpty() && RockstarId != 0) {
|
if (!memberName.isEmpty() && RockstarId != 0)
|
||||||
|
{
|
||||||
foundPlayers++;
|
foundPlayers++;
|
||||||
emit playerNameFound(RockstarId, memberName);
|
emit playerNameFound(RockstarId, memberName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentPage++;
|
currentPage++;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
currentFail++;
|
currentFail++;
|
||||||
if (currentFail == maxLoadFails) {
|
if (currentFail == maxLoadFails)
|
||||||
|
{
|
||||||
currentFail = 0;
|
currentFail = 0;
|
||||||
currentPage++;
|
currentPage++;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +200,8 @@ void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int
|
||||||
delete netReply;
|
delete netReply;
|
||||||
delete netManager;
|
delete netManager;
|
||||||
|
|
||||||
if (foundPlayers < totalPlayers && currentPage < maxPages && (continueLastCrew ? true : threadRunning)) {
|
if (foundPlayers < totalPlayers && currentPage < maxPages && (continueLastCrew ? true : threadRunning))
|
||||||
|
{
|
||||||
QEventLoop *waitingLoop = new QEventLoop();
|
QEventLoop *waitingLoop = new QEventLoop();
|
||||||
QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit()));
|
QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit()));
|
||||||
if (!continueLastCrew) { QObject::connect(this, SIGNAL(threadTerminated()), waitingLoop, SLOT(quit())); }
|
if (!continueLastCrew) { QObject::connect(this, SIGNAL(threadTerminated()), waitingLoop, SLOT(quit())); }
|
||||||
|
@ -198,8 +216,10 @@ void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int
|
||||||
|
|
||||||
void DatabaseThread::deleteCompatibleCrews(QStringList *crewList)
|
void DatabaseThread::deleteCompatibleCrews(QStringList *crewList)
|
||||||
{
|
{
|
||||||
for (const QString &crewNID : *crewList) {
|
for (QString crewNID : *crewList)
|
||||||
if (crewDB->isCompatibleCrew(crewNID)) {
|
{
|
||||||
|
if (crewDB->isCompatibleCrew(crewNID))
|
||||||
|
{
|
||||||
crewList->removeAll(crewNID);
|
crewList->removeAll(crewNID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,8 +228,10 @@ void DatabaseThread::deleteCompatibleCrews(QStringList *crewList)
|
||||||
QStringList DatabaseThread::deleteCompatibleCrews(const QStringList &crewList)
|
QStringList DatabaseThread::deleteCompatibleCrews(const QStringList &crewList)
|
||||||
{
|
{
|
||||||
QStringList crewListR = crewList;
|
QStringList crewListR = crewList;
|
||||||
for (const QString &crewNID : crewListR) {
|
for (QString crewNID : crewListR)
|
||||||
if (crewDB->isCompatibleCrew(crewNID)) {
|
{
|
||||||
|
if (crewDB->isCompatibleCrew(crewNID))
|
||||||
|
{
|
||||||
crewListR.removeAll(crewNID);
|
crewListR.removeAll(crewNID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
GlobalString::GlobalString()
|
GlobalString::GlobalString()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, QString> GlobalString::getGlobalMap()
|
QMap<QString, QString> GlobalString::getGlobalMap()
|
||||||
|
@ -38,7 +39,8 @@ QMap<QString, QString> GlobalString::getGlobalMap()
|
||||||
globalFile.setIniCodec("UTF-8");
|
globalFile.setIniCodec("UTF-8");
|
||||||
#endif
|
#endif
|
||||||
globalFile.beginGroup("Global");
|
globalFile.beginGroup("Global");
|
||||||
for (const QString &globalStr : globalFile.childKeys()) {
|
for (const QString &globalStr : globalFile.childKeys())
|
||||||
|
{
|
||||||
globalMap[globalStr] = globalFile.value(globalStr, globalStr).toString();
|
globalMap[globalStr] = globalFile.value(globalStr, globalStr).toString();
|
||||||
}
|
}
|
||||||
globalFile.endGroup();
|
globalFile.endGroup();
|
||||||
|
@ -54,9 +56,9 @@ QString GlobalString::getString(QString valueStr, bool *ok)
|
||||||
#endif
|
#endif
|
||||||
globalFile.beginGroup("Global");
|
globalFile.beginGroup("Global");
|
||||||
QStringList globalStrList = globalFile.childKeys();
|
QStringList globalStrList = globalFile.childKeys();
|
||||||
if (globalStrList.contains(valueStr)) {
|
if (globalStrList.contains(valueStr))
|
||||||
if (ok != nullptr)
|
{
|
||||||
*ok = true;
|
if (ok != nullptr) *ok = true;
|
||||||
globalString = globalFile.value(valueStr, valueStr).toString();
|
globalString = globalFile.value(valueStr, valueStr).toString();
|
||||||
}
|
}
|
||||||
globalFile.endGroup();
|
globalFile.endGroup();
|
||||||
|
@ -67,14 +69,10 @@ QString GlobalString::getLanguageFile()
|
||||||
{
|
{
|
||||||
QString language = getLanguage();
|
QString language = getLanguage();
|
||||||
QString languageFile = ":/global/global." % language % ".ini";
|
QString languageFile = ":/global/global." % language % ".ini";
|
||||||
#if QT_VERSION >= 0x050200
|
|
||||||
if (!QFileInfo::exists(languageFile))
|
|
||||||
languageFile = ":/global/global.en.ini";
|
|
||||||
#else
|
|
||||||
if (!QFileInfo(languageFile).exists())
|
if (!QFileInfo(languageFile).exists())
|
||||||
|
{
|
||||||
languageFile = ":/global/global.en.ini";
|
languageFile = ":/global/global.en.ini";
|
||||||
#endif
|
}
|
||||||
|
|
||||||
return languageFile;
|
return languageFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -17,45 +17,34 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "IconLoader.h"
|
#include "IconLoader.h"
|
||||||
#include "AppEnv.h"
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
IconLoader::IconLoader()
|
IconLoader::IconLoader()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon IconLoader::loadingAppIcon()
|
QIcon IconLoader::loadingAppIcon()
|
||||||
{
|
{
|
||||||
QIcon appIcon;
|
QIcon appIcon;
|
||||||
#if defined(GTA5SYNC_QCONF) && defined(GTA5SYNC_CMAKE)
|
appIcon.addFile(":/img/gta5view-16.png", QSize(16, 16));
|
||||||
#ifdef Q_OS_WIN
|
appIcon.addFile(":/img/gta5view-24.png", QSize(24, 24));
|
||||||
const QString pattern = AppEnv::getImagesFolder() % QLatin1String("/gta5view-%1.png");
|
appIcon.addFile(":/img/gta5view-32.png", QSize(32, 32));
|
||||||
#else
|
appIcon.addFile(":/img/gta5view-40.png", QSize(40, 40));
|
||||||
const QString pattern = AppEnv::getShareFolder() % QLatin1String("/icons/hicolor/%1x%1/apps/de.syping.gta5view.png");
|
appIcon.addFile(":/img/gta5view-48.png", QSize(48, 48));
|
||||||
#endif
|
appIcon.addFile(":/img/gta5view-64.png", QSize(64, 64));
|
||||||
#else
|
appIcon.addFile(":/img/gta5view-96.png", QSize(96, 96));
|
||||||
const QString pattern = AppEnv::getImagesFolder() % QLatin1String("/gta5view-%1.png");
|
appIcon.addFile(":/img/gta5view-128.png", QSize(128, 128));
|
||||||
#endif
|
appIcon.addFile(":/img/gta5view-256.png", QSize(256, 256));
|
||||||
appIcon.addFile(pattern.arg("16"), QSize(16, 16));
|
|
||||||
appIcon.addFile(pattern.arg("24"), QSize(24, 24));
|
|
||||||
appIcon.addFile(pattern.arg("32"), QSize(32, 32));
|
|
||||||
appIcon.addFile(pattern.arg("40"), QSize(40, 40));
|
|
||||||
appIcon.addFile(pattern.arg("48"), QSize(48, 48));
|
|
||||||
appIcon.addFile(pattern.arg("64"), QSize(64, 64));
|
|
||||||
appIcon.addFile(pattern.arg("96"), QSize(96, 96));
|
|
||||||
appIcon.addFile(pattern.arg("128"), QSize(128, 128));
|
|
||||||
appIcon.addFile(pattern.arg("256"), QSize(256, 256));
|
|
||||||
return appIcon;
|
return appIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon IconLoader::loadingPointmakerIcon()
|
QIcon IconLoader::loadingPointmakerIcon()
|
||||||
{
|
{
|
||||||
QIcon pointmakerIcon;
|
QIcon pointmakerIcon;
|
||||||
const QString pattern = AppEnv::getImagesFolder() % QLatin1String("/pointmaker-%1.png");
|
pointmakerIcon.addFile(":/img/pointmaker-8.png", QSize(8, 8));
|
||||||
pointmakerIcon.addFile(pattern.arg("8"), QSize(8, 8));
|
pointmakerIcon.addFile(":/img/pointmaker-16.png", QSize(16, 16));
|
||||||
pointmakerIcon.addFile(pattern.arg("16"), QSize(16, 16));
|
pointmakerIcon.addFile(":/img/pointmaker-24.png", QSize(24, 24));
|
||||||
pointmakerIcon.addFile(pattern.arg("24"), QSize(24, 24));
|
pointmakerIcon.addFile(":/img/pointmaker-32.png", QSize(32, 32));
|
||||||
pointmakerIcon.addFile(pattern.arg("32"), QSize(32, 32));
|
|
||||||
return pointmakerIcon;
|
return pointmakerIcon;
|
||||||
}
|
}
|
||||||
|
|
209
ImportDialog.cpp
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2017-2022 Syping
|
* Copyright (C) 2017-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -49,11 +49,7 @@ ImportDialog::ImportDialog(QString profileName, QWidget *parent) :
|
||||||
ui(new Ui::ImportDialog)
|
ui(new Ui::ImportDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
// Set Window Flags
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
#endif
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->cmdOK->setDefault(true);
|
ui->cmdOK->setDefault(true);
|
||||||
|
@ -63,22 +59,26 @@ ImportDialog::ImportDialog(QString profileName, QWidget *parent) :
|
||||||
watermarkAvatar = true;
|
watermarkAvatar = true;
|
||||||
watermarkPicture = false;
|
watermarkPicture = false;
|
||||||
insideAvatarZone = false;
|
insideAvatarZone = false;
|
||||||
avatarAreaImage = QImage(AppEnv::getImagesFolder() % "/avatarareaimport.png");
|
avatarAreaImage = QImage(":/img/avatarareaimport.png");
|
||||||
selectedColour = QColor::fromRgb(0, 0, 0, 255);
|
selectedColour = QColor::fromRgb(0, 0, 0, 255);
|
||||||
|
|
||||||
// Set Icon for OK Button
|
// Set Icon for OK Button
|
||||||
if (QIcon::hasThemeIcon("dialog-ok")) {
|
if (QIcon::hasThemeIcon("dialog-ok"))
|
||||||
|
{
|
||||||
ui->cmdOK->setIcon(QIcon::fromTheme("dialog-ok"));
|
ui->cmdOK->setIcon(QIcon::fromTheme("dialog-ok"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-ok")) {
|
else if (QIcon::hasThemeIcon("gtk-ok"))
|
||||||
|
{
|
||||||
ui->cmdOK->setIcon(QIcon::fromTheme("gtk-ok"));
|
ui->cmdOK->setIcon(QIcon::fromTheme("gtk-ok"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Cancel Button
|
// Set Icon for Cancel Button
|
||||||
if (QIcon::hasThemeIcon("dialog-cancel")) {
|
if (QIcon::hasThemeIcon("dialog-cancel"))
|
||||||
|
{
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-cancel")) {
|
else if (QIcon::hasThemeIcon("gtk-cancel"))
|
||||||
|
{
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,14 +112,12 @@ ImportDialog::ImportDialog(QString profileName, QWidget *parent) :
|
||||||
#ifndef Q_OS_MAC
|
#ifndef Q_OS_MAC
|
||||||
ui->vlButtom->setContentsMargins(9 * screenRatio, 6 * screenRatio, 9 * screenRatio, 9 * screenRatio);
|
ui->vlButtom->setContentsMargins(9 * screenRatio, 6 * screenRatio, 9 * screenRatio, 9 * screenRatio);
|
||||||
#else
|
#else
|
||||||
#if QT_VERSION >= 0x060000
|
if (QApplication::style()->objectName() == "macintosh")
|
||||||
if (QApplication::style()->objectName() == "macos") {
|
{
|
||||||
#else
|
|
||||||
if (QApplication::style()->objectName() == "macintosh") {
|
|
||||||
#endif
|
|
||||||
ui->vlButtom->setContentsMargins(9 * screenRatio, 9 * screenRatio, 9 * screenRatio, 9 * screenRatio);
|
ui->vlButtom->setContentsMargins(9 * screenRatio, 9 * screenRatio, 9 * screenRatio, 9 * screenRatio);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->vlButtom->setContentsMargins(9 * screenRatio, 6 * screenRatio, 9 * screenRatio, 9 * screenRatio);
|
ui->vlButtom->setContentsMargins(9 * screenRatio, 6 * screenRatio, 9 * screenRatio, 9 * screenRatio);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -132,9 +130,9 @@ ImportDialog::ImportDialog(QString profileName, QWidget *parent) :
|
||||||
optionsMenu.addAction(tr("&Save Settings..."), this, SLOT(saveImportSettings()));
|
optionsMenu.addAction(tr("&Save Settings..."), this, SLOT(saveImportSettings()));
|
||||||
ui->cmdOptions->setMenu(&optionsMenu);
|
ui->cmdOptions->setMenu(&optionsMenu);
|
||||||
|
|
||||||
const QSize windowSize = sizeHint();
|
setMaximumSize(sizeHint());
|
||||||
setMinimumSize(windowSize);
|
setMinimumSize(sizeHint());
|
||||||
setMaximumSize(windowSize);
|
setFixedSize(sizeHint());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportDialog::~ImportDialog()
|
ImportDialog::~ImportDialog()
|
||||||
|
@ -177,33 +175,7 @@ void ImportDialog::processImage()
|
||||||
// Avatar mode
|
// Avatar mode
|
||||||
int diffWidth = 0;
|
int diffWidth = 0;
|
||||||
int diffHeight = 0;
|
int diffHeight = 0;
|
||||||
if (ui->cbIgnore->isChecked()) {
|
if (!ui->cbIgnore->isChecked()) {
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
}
|
|
||||||
else if (ui->cbBorderless->isChecked()) {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
|
||||||
if (snapmaticImage.width() > snapmaticAvatarResolution) {
|
|
||||||
int diffWidth = snapmaticImage.width() - snapmaticAvatarResolution;
|
|
||||||
diffWidth = diffWidth / 2;
|
|
||||||
QImage croppedImage(snapmaticAvatarResolution, snapmaticAvatarResolution, QImage::Format_ARGB32);
|
|
||||||
croppedImage.fill(Qt::transparent);
|
|
||||||
QPainter croppedPainter(&croppedImage);
|
|
||||||
croppedPainter.drawImage(0 - diffWidth, 0, snapmaticImage);
|
|
||||||
croppedPainter.end();
|
|
||||||
snapmaticImage = croppedImage;
|
|
||||||
}
|
|
||||||
else if (snapmaticImage.height() > snapmaticAvatarResolution) {
|
|
||||||
int diffHeight = snapmaticImage.height() - snapmaticAvatarResolution;
|
|
||||||
diffHeight = diffHeight / 2;
|
|
||||||
QImage croppedImage(snapmaticAvatarResolution, snapmaticAvatarResolution, QImage::Format_ARGB32);
|
|
||||||
croppedImage.fill(Qt::transparent);
|
|
||||||
QPainter croppedPainter(&croppedImage);
|
|
||||||
croppedPainter.drawImage(0, 0 - diffHeight, snapmaticImage);
|
|
||||||
croppedPainter.end();
|
|
||||||
snapmaticImage = croppedImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
if (snapmaticImage.width() > snapmaticImage.height()) {
|
if (snapmaticImage.width() > snapmaticImage.height()) {
|
||||||
diffHeight = snapmaticAvatarResolution - snapmaticImage.height();
|
diffHeight = snapmaticAvatarResolution - snapmaticImage.height();
|
||||||
|
@ -214,6 +186,9 @@ void ImportDialog::processImage()
|
||||||
diffWidth = diffWidth / 2;
|
diffWidth = diffWidth / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
snapmaticPainter.drawImage(snapmaticAvatarPlacementW + diffWidth, snapmaticAvatarPlacementH + diffHeight, snapmaticImage);
|
snapmaticPainter.drawImage(snapmaticAvatarPlacementW + diffWidth, snapmaticAvatarPlacementH + diffHeight, snapmaticImage);
|
||||||
if (ui->cbWatermark->isChecked())
|
if (ui->cbWatermark->isChecked())
|
||||||
processWatermark(&snapmaticPainter);
|
processWatermark(&snapmaticPainter);
|
||||||
|
@ -223,33 +198,7 @@ void ImportDialog::processImage()
|
||||||
// Picture mode
|
// Picture mode
|
||||||
int diffWidth = 0;
|
int diffWidth = 0;
|
||||||
int diffHeight = 0;
|
int diffHeight = 0;
|
||||||
if (ui->cbIgnore->isChecked()) {
|
if (!ui->cbIgnore->isChecked()) {
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
}
|
|
||||||
else if (ui->cbBorderless->isChecked()) {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
|
||||||
if (snapmaticImage.width() > snapmaticResolution.width()) {
|
|
||||||
int diffWidth = snapmaticImage.width() - snapmaticResolution.width();
|
|
||||||
diffWidth = diffWidth / 2;
|
|
||||||
QImage croppedImage(snapmaticResolution, QImage::Format_ARGB32);
|
|
||||||
croppedImage.fill(Qt::transparent);
|
|
||||||
QPainter croppedPainter(&croppedImage);
|
|
||||||
croppedPainter.drawImage(0 - diffWidth, 0, snapmaticImage);
|
|
||||||
croppedPainter.end();
|
|
||||||
snapmaticImage = croppedImage;
|
|
||||||
}
|
|
||||||
else if (snapmaticImage.height() > snapmaticResolution.height()) {
|
|
||||||
int diffHeight = snapmaticImage.height() - snapmaticResolution.height();
|
|
||||||
diffHeight = diffHeight / 2;
|
|
||||||
QImage croppedImage(snapmaticResolution, QImage::Format_ARGB32);
|
|
||||||
croppedImage.fill(Qt::transparent);
|
|
||||||
QPainter croppedPainter(&croppedImage);
|
|
||||||
croppedPainter.drawImage(0, 0 - diffHeight, snapmaticImage);
|
|
||||||
croppedPainter.end();
|
|
||||||
snapmaticImage = croppedImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
if (snapmaticImage.width() != snapmaticResolution.width()) {
|
if (snapmaticImage.width() != snapmaticResolution.width()) {
|
||||||
diffWidth = snapmaticResolution.width() - snapmaticImage.width();
|
diffWidth = snapmaticResolution.width() - snapmaticImage.width();
|
||||||
|
@ -260,6 +209,9 @@ void ImportDialog::processImage()
|
||||||
diffHeight = diffHeight / 2;
|
diffHeight = diffHeight / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
snapmaticPainter.drawImage(0 + diffWidth, 0 + diffHeight, snapmaticImage);
|
snapmaticPainter.drawImage(0 + diffWidth, 0 + diffHeight, snapmaticImage);
|
||||||
if (ui->cbWatermark->isChecked())
|
if (ui->cbWatermark->isChecked())
|
||||||
processWatermark(&snapmaticPainter);
|
processWatermark(&snapmaticPainter);
|
||||||
|
@ -327,18 +279,18 @@ void ImportDialog::processWatermark(QPainter *snapmaticPainter)
|
||||||
}
|
}
|
||||||
// draw watermark
|
// draw watermark
|
||||||
if (redWatermark) {
|
if (redWatermark) {
|
||||||
const QImage viewWatermark = QImage(AppEnv::getImagesFolder() % "/watermark_2r.png");
|
const QImage viewWatermark = QImage(":/img/watermark_2r.png");
|
||||||
snapmaticPainter->drawImage(snapmaticResolution.width() - viewWatermark.width(), 0, viewWatermark);
|
snapmaticPainter->drawImage(snapmaticResolution.width() - viewWatermark.width(), 0, viewWatermark);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QImage viewWatermark = QImage(AppEnv::getImagesFolder() % "/watermark_2b.png");
|
QImage viewWatermark = QImage(":/img/watermark_2b.png");
|
||||||
if (!blackWatermark) {
|
if (!blackWatermark) {
|
||||||
viewWatermark.invertPixels(QImage::InvertRgb);
|
viewWatermark.invertPixels(QImage::InvertRgb);
|
||||||
}
|
}
|
||||||
snapmaticPainter->drawImage(snapmaticResolution.width() - viewWatermark.width(), 0, viewWatermark);
|
snapmaticPainter->drawImage(snapmaticResolution.width() - viewWatermark.width(), 0, viewWatermark);
|
||||||
}
|
}
|
||||||
QImage textWatermark = QImage(AppEnv::getImagesFolder() % "/watermark_1b.png");
|
QImage textWatermark = QImage(":/img/watermark_1b.png");
|
||||||
if (!blackWatermark) {
|
if (!blackWatermark) {
|
||||||
textWatermark.invertPixels(QImage::InvertRgb);
|
textWatermark.invertPixels(QImage::InvertRgb);
|
||||||
}
|
}
|
||||||
|
@ -357,7 +309,6 @@ void ImportDialog::processSettings(QString settingsProfile, bool setDefault)
|
||||||
watermarkPicture = false;
|
watermarkPicture = false;
|
||||||
selectedColour = QColor::fromRgb(0, 0, 0, 255);
|
selectedColour = QColor::fromRgb(0, 0, 0, 255);
|
||||||
backImage = QImage();
|
backImage = QImage();
|
||||||
ui->cbBorderless->setChecked(false);
|
|
||||||
ui->cbStretch->setChecked(false);
|
ui->cbStretch->setChecked(false);
|
||||||
ui->cbForceAvatarColour->setChecked(false);
|
ui->cbForceAvatarColour->setChecked(false);
|
||||||
ui->cbUnlimited->setChecked(false);
|
ui->cbUnlimited->setChecked(false);
|
||||||
|
@ -370,7 +321,6 @@ void ImportDialog::processSettings(QString settingsProfile, bool setDefault)
|
||||||
watermarkPicture = settings.value("WatermarkPicture", false).toBool();
|
watermarkPicture = settings.value("WatermarkPicture", false).toBool();
|
||||||
backImage = qvariant_cast<QImage>(settings.value("BackgroundImage", QImage()));
|
backImage = qvariant_cast<QImage>(settings.value("BackgroundImage", QImage()));
|
||||||
selectedColour = qvariant_cast<QColor>(settings.value("SelectedColour", QColor::fromRgb(0, 0, 0, 255)));
|
selectedColour = qvariant_cast<QColor>(settings.value("SelectedColour", QColor::fromRgb(0, 0, 0, 255)));
|
||||||
ui->cbBorderless->setChecked(settings.value("BorderlessImage", false).toBool());
|
|
||||||
ui->cbStretch->setChecked(settings.value("BackgroundStretch", false).toBool());
|
ui->cbStretch->setChecked(settings.value("BackgroundStretch", false).toBool());
|
||||||
ui->cbForceAvatarColour->setChecked(settings.value("ForceAvatarColour", false).toBool());
|
ui->cbForceAvatarColour->setChecked(settings.value("ForceAvatarColour", false).toBool());
|
||||||
ui->cbUnlimited->setChecked(settings.value("UnlimitedBuffer", false).toBool());
|
ui->cbUnlimited->setChecked(settings.value("UnlimitedBuffer", false).toBool());
|
||||||
|
@ -418,7 +368,6 @@ void ImportDialog::saveSettings(QString settingsProfile)
|
||||||
settings.setValue("WatermarkPicture", watermarkPicture);
|
settings.setValue("WatermarkPicture", watermarkPicture);
|
||||||
settings.setValue("BackgroundImage", backImage);
|
settings.setValue("BackgroundImage", backImage);
|
||||||
settings.setValue("SelectedColour", selectedColour);
|
settings.setValue("SelectedColour", selectedColour);
|
||||||
settings.setValue("BorderlessImage", ui->cbBorderless->isChecked());
|
|
||||||
settings.setValue("BackgroundStretch", ui->cbStretch->isChecked());
|
settings.setValue("BackgroundStretch", ui->cbStretch->isChecked());
|
||||||
settings.setValue("ForceAvatarColour", ui->cbForceAvatarColour->isChecked());
|
settings.setValue("ForceAvatarColour", ui->cbForceAvatarColour->isChecked());
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
|
@ -504,7 +453,8 @@ void ImportDialog::cropPicture()
|
||||||
|
|
||||||
cropDialog.show();
|
cropDialog.show();
|
||||||
cropDialog.setFixedSize(cropDialog.sizeHint());
|
cropDialog.setFixedSize(cropDialog.sizeHint());
|
||||||
if (cropDialog.exec() == QDialog::Accepted) {
|
if (cropDialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
QImage *croppedImage = new QImage(imageCropper.cropImage().toImage());
|
QImage *croppedImage = new QImage(imageCropper.cropImage().toImage());
|
||||||
setImage(croppedImage);
|
setImage(croppedImage);
|
||||||
}
|
}
|
||||||
|
@ -529,7 +479,8 @@ fileDialogPreOpen: //Work?
|
||||||
|
|
||||||
// Getting readable Image formats
|
// Getting readable Image formats
|
||||||
QString imageFormatsStr = " ";
|
QString imageFormatsStr = " ";
|
||||||
for (const QByteArray &imageFormat : QImageReader::supportedImageFormats()) {
|
for (QByteArray imageFormat : QImageReader::supportedImageFormats())
|
||||||
|
{
|
||||||
imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " ";
|
imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,14 +495,17 @@ fileDialogPreOpen: //Work?
|
||||||
fileDialog.setDirectory(settings.value(profileName % "+Directory", StandardPaths::documentsLocation()).toString());
|
fileDialog.setDirectory(settings.value(profileName % "+Directory", StandardPaths::documentsLocation()).toString());
|
||||||
fileDialog.restoreGeometry(settings.value(profileName % "+Geometry", "").toByteArray());
|
fileDialog.restoreGeometry(settings.value(profileName % "+Geometry", "").toByteArray());
|
||||||
|
|
||||||
if (fileDialog.exec()) {
|
if (fileDialog.exec())
|
||||||
|
{
|
||||||
QStringList selectedFiles = fileDialog.selectedFiles();
|
QStringList selectedFiles = fileDialog.selectedFiles();
|
||||||
if (selectedFiles.length() == 1) {
|
if (selectedFiles.length() == 1)
|
||||||
|
{
|
||||||
QString selectedFile = selectedFiles.at(0);
|
QString selectedFile = selectedFiles.at(0);
|
||||||
QString selectedFileName = QFileInfo(selectedFile).fileName();
|
QString selectedFileName = QFileInfo(selectedFile).fileName();
|
||||||
|
|
||||||
QFile snapmaticFile(selectedFile);
|
QFile snapmaticFile(selectedFile);
|
||||||
if (!snapmaticFile.open(QFile::ReadOnly)) {
|
if (!snapmaticFile.open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be open").arg("\""+selectedFileName+"\""));
|
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be open").arg("\""+selectedFileName+"\""));
|
||||||
goto fileDialogPreOpen;
|
goto fileDialogPreOpen;
|
||||||
}
|
}
|
||||||
|
@ -559,7 +513,8 @@ fileDialogPreOpen: //Work?
|
||||||
QImageReader snapmaticImageReader;
|
QImageReader snapmaticImageReader;
|
||||||
snapmaticImageReader.setDecideFormatFromContent(true);
|
snapmaticImageReader.setDecideFormatFromContent(true);
|
||||||
snapmaticImageReader.setDevice(&snapmaticFile);
|
snapmaticImageReader.setDevice(&snapmaticFile);
|
||||||
if (!snapmaticImageReader.read(importImage)) {
|
if (!snapmaticImageReader.read(importImage))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\""));
|
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\""));
|
||||||
delete importImage;
|
delete importImage;
|
||||||
goto fileDialogPreOpen;
|
goto fileDialogPreOpen;
|
||||||
|
@ -576,7 +531,8 @@ fileDialogPreOpen: //Work?
|
||||||
|
|
||||||
void ImportDialog::loadImportSettings()
|
void ImportDialog::loadImportSettings()
|
||||||
{
|
{
|
||||||
if (settingsLocked) {
|
if (settingsLocked)
|
||||||
|
{
|
||||||
QMessageBox::information(this, tr("Load Settings..."), tr("Please import a new picture first"));
|
QMessageBox::information(this, tr("Load Settings..."), tr("Please import a new picture first"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -589,25 +545,31 @@ void ImportDialog::loadImportSettings()
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("4")
|
<< tr("Profile %1", "Profile %1 as Profile 1").arg("4")
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("5");
|
<< tr("Profile %1", "Profile %1 as Profile 1").arg("5");
|
||||||
QString sProfile = QInputDialog::getItem(this, tr("Load Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags());
|
QString sProfile = QInputDialog::getItem(this, tr("Load Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags());
|
||||||
if (ok) {
|
if (ok)
|
||||||
|
{
|
||||||
QString pProfile;
|
QString pProfile;
|
||||||
if (sProfile == tr("Default", "Default as Default Profile")) {
|
if (sProfile == tr("Default", "Default as Default Profile"))
|
||||||
|
{
|
||||||
pProfile = "Default";
|
pProfile = "Default";
|
||||||
}
|
}
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1")) {
|
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1"))
|
||||||
|
{
|
||||||
pProfile = "Profile 1";
|
pProfile = "Profile 1";
|
||||||
}
|
}
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2")) {
|
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2"))
|
||||||
|
{
|
||||||
pProfile = "Profile 2";
|
pProfile = "Profile 2";
|
||||||
}
|
}
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3")) {
|
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3"))
|
||||||
|
{
|
||||||
pProfile = "Profile 3";
|
pProfile = "Profile 3";
|
||||||
}
|
}
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4"))
|
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4"))
|
||||||
{
|
{
|
||||||
pProfile = "Profile 4";
|
pProfile = "Profile 4";
|
||||||
}
|
}
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5")) {
|
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5"))
|
||||||
|
{
|
||||||
pProfile = "Profile 5";
|
pProfile = "Profile 5";
|
||||||
}
|
}
|
||||||
processSettings(pProfile, true);
|
processSettings(pProfile, true);
|
||||||
|
@ -617,7 +579,8 @@ void ImportDialog::loadImportSettings()
|
||||||
|
|
||||||
void ImportDialog::saveImportSettings()
|
void ImportDialog::saveImportSettings()
|
||||||
{
|
{
|
||||||
if (settingsLocked) {
|
if (settingsLocked)
|
||||||
|
{
|
||||||
QMessageBox::information(this, tr("Save Settings..."), tr("Please import a new picture first"));
|
QMessageBox::information(this, tr("Save Settings..."), tr("Please import a new picture first"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -629,21 +592,27 @@ void ImportDialog::saveImportSettings()
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("4")
|
<< tr("Profile %1", "Profile %1 as Profile 1").arg("4")
|
||||||
<< tr("Profile %1", "Profile %1 as Profile 1").arg("5");
|
<< tr("Profile %1", "Profile %1 as Profile 1").arg("5");
|
||||||
QString sProfile = QInputDialog::getItem(this, tr("Save Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags());
|
QString sProfile = QInputDialog::getItem(this, tr("Save Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags());
|
||||||
if (ok) {
|
if (ok)
|
||||||
|
{
|
||||||
QString pProfile;
|
QString pProfile;
|
||||||
if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1")) {
|
if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1"))
|
||||||
|
{
|
||||||
pProfile = "Profile 1";
|
pProfile = "Profile 1";
|
||||||
}
|
}
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2")) {
|
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2"))
|
||||||
|
{
|
||||||
pProfile = "Profile 2";
|
pProfile = "Profile 2";
|
||||||
}
|
}
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3")) {
|
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3"))
|
||||||
|
{
|
||||||
pProfile = "Profile 3";
|
pProfile = "Profile 3";
|
||||||
}
|
}
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4")) {
|
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4"))
|
||||||
|
{
|
||||||
pProfile = "Profile 4";
|
pProfile = "Profile 4";
|
||||||
}
|
}
|
||||||
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5")) {
|
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5"))
|
||||||
|
{
|
||||||
pProfile = "Profile 5";
|
pProfile = "Profile 5";
|
||||||
}
|
}
|
||||||
saveSettings(pProfile);
|
saveSettings(pProfile);
|
||||||
|
@ -748,17 +717,12 @@ bool ImportDialog::areSettingsLocked()
|
||||||
|
|
||||||
QString ImportDialog::getImageTitle()
|
QString ImportDialog::getImageTitle()
|
||||||
{
|
{
|
||||||
if (ui->cbImportAsIs->isChecked()) {
|
return imageTitle;
|
||||||
return tr("Custom Picture", "Custom Picture Description in SC, don't use Special Character!");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return imageTitle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportDialog::on_cbIgnore_toggled(bool checked)
|
void ImportDialog::on_cbIgnore_toggled(bool checked)
|
||||||
{
|
{
|
||||||
ui->cbBorderless->setDisabled(checked);
|
Q_UNUSED(checked)
|
||||||
processImage();
|
processImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,9 +763,11 @@ void ImportDialog::on_cmdOK_clicked()
|
||||||
|
|
||||||
void ImportDialog::on_labPicture_labelPainted()
|
void ImportDialog::on_labPicture_labelPainted()
|
||||||
{
|
{
|
||||||
if (insideAvatarZone) {
|
if (insideAvatarZone)
|
||||||
|
{
|
||||||
QImage avatarAreaFinalImage(avatarAreaImage);
|
QImage avatarAreaFinalImage(avatarAreaImage);
|
||||||
if (selectedColour.lightness() > 127) {
|
if (selectedColour.lightness() > 127)
|
||||||
|
{
|
||||||
avatarAreaFinalImage.setColor(1, qRgb(0, 0, 0));
|
avatarAreaFinalImage.setColor(1, qRgb(0, 0, 0));
|
||||||
}
|
}
|
||||||
QPainter labelPainter(ui->labPicture);
|
QPainter labelPainter(ui->labPicture);
|
||||||
|
@ -813,7 +779,8 @@ void ImportDialog::on_labPicture_labelPainted()
|
||||||
void ImportDialog::on_cmdColourChange_clicked()
|
void ImportDialog::on_cmdColourChange_clicked()
|
||||||
{
|
{
|
||||||
QColor newSelectedColour = QColorDialog::getColor(selectedColour, this, tr("Select Colour..."));
|
QColor newSelectedColour = QColorDialog::getColor(selectedColour, this, tr("Select Colour..."));
|
||||||
if (newSelectedColour.isValid()) {
|
if (newSelectedColour.isValid())
|
||||||
|
{
|
||||||
selectedColour = newSelectedColour;
|
selectedColour = newSelectedColour;
|
||||||
ui->labColour->setText(tr("Background Colour: <span style=\"color: %1\">%1</span>").arg(selectedColour.name()));
|
ui->labColour->setText(tr("Background Colour: <span style=\"color: %1\">%1</span>").arg(selectedColour.name()));
|
||||||
processImage();
|
processImage();
|
||||||
|
@ -839,7 +806,8 @@ fileDialogPreOpen:
|
||||||
|
|
||||||
// Getting readable Image formats
|
// Getting readable Image formats
|
||||||
QString imageFormatsStr = " ";
|
QString imageFormatsStr = " ";
|
||||||
for (const QByteArray &imageFormat : QImageReader::supportedImageFormats()) {
|
for (QByteArray imageFormat : QImageReader::supportedImageFormats())
|
||||||
|
{
|
||||||
imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " ";
|
imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,14 +822,17 @@ fileDialogPreOpen:
|
||||||
fileDialog.setDirectory(settings.value("Directory", StandardPaths::documentsLocation()).toString());
|
fileDialog.setDirectory(settings.value("Directory", StandardPaths::documentsLocation()).toString());
|
||||||
fileDialog.restoreGeometry(settings.value("Geometry", "").toByteArray());
|
fileDialog.restoreGeometry(settings.value("Geometry", "").toByteArray());
|
||||||
|
|
||||||
if (fileDialog.exec()) {
|
if (fileDialog.exec())
|
||||||
|
{
|
||||||
QStringList selectedFiles = fileDialog.selectedFiles();
|
QStringList selectedFiles = fileDialog.selectedFiles();
|
||||||
if (selectedFiles.length() == 1) {
|
if (selectedFiles.length() == 1)
|
||||||
|
{
|
||||||
QString selectedFile = selectedFiles.at(0);
|
QString selectedFile = selectedFiles.at(0);
|
||||||
QString selectedFileName = QFileInfo(selectedFile).fileName();
|
QString selectedFileName = QFileInfo(selectedFile).fileName();
|
||||||
|
|
||||||
QFile snapmaticFile(selectedFile);
|
QFile snapmaticFile(selectedFile);
|
||||||
if (!snapmaticFile.open(QFile::ReadOnly)) {
|
if (!snapmaticFile.open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be open").arg("\""+selectedFileName+"\""));
|
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be open").arg("\""+selectedFileName+"\""));
|
||||||
goto fileDialogPreOpen;
|
goto fileDialogPreOpen;
|
||||||
}
|
}
|
||||||
|
@ -869,7 +840,8 @@ fileDialogPreOpen:
|
||||||
QImageReader snapmaticImageReader;
|
QImageReader snapmaticImageReader;
|
||||||
snapmaticImageReader.setDecideFormatFromContent(true);
|
snapmaticImageReader.setDecideFormatFromContent(true);
|
||||||
snapmaticImageReader.setDevice(&snapmaticFile);
|
snapmaticImageReader.setDevice(&snapmaticFile);
|
||||||
if (!snapmaticImageReader.read(&importImage)) {
|
if (!snapmaticImageReader.read(&importImage))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\""));
|
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\""));
|
||||||
goto fileDialogPreOpen;
|
goto fileDialogPreOpen;
|
||||||
}
|
}
|
||||||
|
@ -909,7 +881,8 @@ void ImportDialog::on_cbForceAvatarColour_toggled(bool checked)
|
||||||
|
|
||||||
void ImportDialog::on_cbWatermark_toggled(bool checked)
|
void ImportDialog::on_cbWatermark_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (!watermarkBlock) {
|
if (!watermarkBlock)
|
||||||
|
{
|
||||||
if (insideAvatarZone) {
|
if (insideAvatarZone) {
|
||||||
watermarkAvatar = checked;
|
watermarkAvatar = checked;
|
||||||
}
|
}
|
||||||
|
@ -920,12 +893,6 @@ void ImportDialog::on_cbWatermark_toggled(bool checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportDialog::on_cbBorderless_toggled(bool checked)
|
|
||||||
{
|
|
||||||
ui->cbIgnore->setDisabled(checked);
|
|
||||||
processImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportDialog::on_cbImportAsIs_toggled(bool checked)
|
void ImportDialog::on_cbImportAsIs_toggled(bool checked)
|
||||||
{
|
{
|
||||||
ui->cbResolution->setDisabled(checked);
|
ui->cbResolution->setDisabled(checked);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2017-2021 Syping
|
* Copyright (C) 2017-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -60,7 +60,6 @@ private slots:
|
||||||
void on_cbStretch_toggled(bool checked);
|
void on_cbStretch_toggled(bool checked);
|
||||||
void on_cbForceAvatarColour_toggled(bool checked);
|
void on_cbForceAvatarColour_toggled(bool checked);
|
||||||
void on_cbWatermark_toggled(bool checked);
|
void on_cbWatermark_toggled(bool checked);
|
||||||
void on_cbBorderless_toggled(bool checked);
|
|
||||||
void on_cbImportAsIs_toggled(bool checked);
|
void on_cbImportAsIs_toggled(bool checked);
|
||||||
void on_cbResolution_currentIndexChanged(int index);
|
void on_cbResolution_currentIndexChanged(int index);
|
||||||
|
|
||||||
|
|
181
ImportDialog.ui
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>516</width>
|
<width>516</width>
|
||||||
<height>673</height>
|
<height>677</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
|
@ -85,32 +85,47 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="vlSettings">
|
<layout class="QVBoxLayout" name="vlSettings">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="glPicture">
|
<layout class="QHBoxLayout" name="hlCheckboxesTop">
|
||||||
<item row="0" column="1">
|
<item>
|
||||||
<widget class="QCheckBox" name="cbIgnore">
|
|
||||||
<property name="text">
|
|
||||||
<string>Ignore Aspect Ratio</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QCheckBox" name="cbAvatar">
|
<widget class="QCheckBox" name="cbAvatar">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Avatar</string>
|
<string>Avatar</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item>
|
||||||
<widget class="QCheckBox" name="cbWatermark">
|
<widget class="QCheckBox" name="cbIgnore">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Watermark</string>
|
<string>Ignore Aspect Ratio</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
</layout>
|
||||||
<widget class="QCheckBox" name="cbBorderless">
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="hlCheckboxesButtom">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="cbWatermark">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Crop to Aspect Ratio</string>
|
<string>Watermark</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -126,8 +141,8 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="vlBackground">
|
<layout class="QVBoxLayout" name="vlBackground">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="glBackground">
|
<layout class="QHBoxLayout" name="hlColour">
|
||||||
<item row="0" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="hlColourManage">
|
<layout class="QHBoxLayout" name="hlColourManage">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="labColour">
|
<widget class="QLabel" name="labColour">
|
||||||
|
@ -180,24 +195,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item>
|
||||||
<widget class="QCheckBox" name="cbStretch">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Ignore Aspect Ratio</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QCheckBox" name="cbForceAvatarColour">
|
|
||||||
<property name="text">
|
|
||||||
<string>Force Colour in Avatar Zone</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="hlBackgroundManage">
|
<layout class="QHBoxLayout" name="hlBackgroundManage">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="labBackgroundImage">
|
<widget class="QLabel" name="labBackgroundImage">
|
||||||
|
@ -262,61 +260,25 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gbAdvanced">
|
|
||||||
<property name="title">
|
|
||||||
<string>Advanced</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="vlAdvanced">
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="glAdvanced">
|
<layout class="QHBoxLayout" name="hlBackground">
|
||||||
<item row="1" column="0">
|
<item>
|
||||||
<widget class="QCheckBox" name="cbUnlimited">
|
<widget class="QCheckBox" name="cbForceAvatarColour">
|
||||||
<property name="toolTip">
|
|
||||||
<string>Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Unlimited Buffer</string>
|
<string>Force Colour in Avatar Zone</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item>
|
||||||
<widget class="QCheckBox" name="cbImportAsIs">
|
<widget class="QCheckBox" name="cbStretch">
|
||||||
<property name="toolTip">
|
<property name="enabled">
|
||||||
<string>Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing</string>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Import as-is</string>
|
<string>Ignore Aspect Ratio</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" colspan="2">
|
|
||||||
<layout class="QHBoxLayout" name="hlResolution">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labResolution">
|
|
||||||
<property name="text">
|
|
||||||
<string>Resolution:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="cbResolution">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Snapmatic resolution</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -335,6 +297,63 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="gbAdvanced">
|
||||||
|
<property name="title">
|
||||||
|
<string>Advanced</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="vlAdvanced">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="hlResolution">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labResolution">
|
||||||
|
<property name="text">
|
||||||
|
<string>Resolution:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="cbResolution">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Snapmatic resolution</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="hlExpert">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="cbUnlimited">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Unlimited Buffer</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="cbImportAsIs">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Import as-is</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="hlButtons">
|
<layout class="QHBoxLayout" name="hlButtons">
|
||||||
<item>
|
<item>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2017-2021 Syping
|
* Copyright (C) 2017-2018 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050200
|
#if QT_VERSION >= 0x050200
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
|
#include <QDebug>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
#ifdef GTA5SYNC_TELEMETRY
|
||||||
|
@ -39,30 +40,29 @@ JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) :
|
||||||
ui(new Ui::JsonEditorDialog)
|
ui(new Ui::JsonEditorDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
// Set Window Flags
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
setWindowFlag(Qt::WindowMinMaxButtonsHint, true);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowMinMaxButtonsHint);
|
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowMinMaxButtonsHint);
|
||||||
#endif
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->cmdClose->setDefault(true);
|
ui->cmdClose->setDefault(true);
|
||||||
ui->cmdClose->setFocus();
|
ui->cmdClose->setFocus();
|
||||||
|
|
||||||
// Set Icon for Close Button
|
// Set Icon for Close Button
|
||||||
if (QIcon::hasThemeIcon("dialog-close")) {
|
if (QIcon::hasThemeIcon("dialog-close"))
|
||||||
|
{
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
|
ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-close")) {
|
else if (QIcon::hasThemeIcon("gtk-close"))
|
||||||
|
{
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
|
ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Save Button
|
// Set Icon for Save Button
|
||||||
if (QIcon::hasThemeIcon("document-save")) {
|
if (QIcon::hasThemeIcon("document-save"))
|
||||||
|
{
|
||||||
ui->cmdSave->setIcon(QIcon::fromTheme("document-save"));
|
ui->cmdSave->setIcon(QIcon::fromTheme("document-save"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-save")) {
|
else if (QIcon::hasThemeIcon("gtk-save"))
|
||||||
|
{
|
||||||
ui->cmdSave->setIcon(QIcon::fromTheme("gtk-save"));
|
ui->cmdSave->setIcon(QIcon::fromTheme("gtk-save"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,8 @@ JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) :
|
||||||
ui->hlButtons->setContentsMargins(9 * screenRatio, 0, 9 * screenRatio, 0);
|
ui->hlButtons->setContentsMargins(9 * screenRatio, 0, 9 * screenRatio, 0);
|
||||||
ui->vlInterface->setContentsMargins(0, 0, 0, 9 * screenRatio);
|
ui->vlInterface->setContentsMargins(0, 0, 0, 9 * screenRatio);
|
||||||
#endif
|
#endif
|
||||||
if (screenRatio > 1) {
|
if (screenRatio > 1)
|
||||||
|
{
|
||||||
ui->lineJSON->setMinimumHeight(qRound(1 * screenRatio));
|
ui->lineJSON->setMinimumHeight(qRound(1 * screenRatio));
|
||||||
ui->lineJSON->setMaximumHeight(qRound(1 * screenRatio));
|
ui->lineJSON->setMaximumHeight(qRound(1 * screenRatio));
|
||||||
ui->lineJSON->setLineWidth(qRound(1 * screenRatio));
|
ui->lineJSON->setLineWidth(qRound(1 * screenRatio));
|
||||||
|
@ -120,22 +121,28 @@ void JsonEditorDialog::closeEvent(QCloseEvent *ev)
|
||||||
QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8());
|
QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8());
|
||||||
QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact));
|
QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact));
|
||||||
QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact));
|
QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact));
|
||||||
if (newCode != originalCode) {
|
if (newCode != originalCode)
|
||||||
|
{
|
||||||
QMessageBox::StandardButton button = QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("<h4>Unsaved changes detected</h4>You want to save the JSON content before you quit?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel);
|
QMessageBox::StandardButton button = QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("<h4>Unsaved changes detected</h4>You want to save the JSON content before you quit?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel);
|
||||||
if (button == QMessageBox::Yes) {
|
if (button == QMessageBox::Yes)
|
||||||
if (saveJsonContent()) {
|
{
|
||||||
|
if (saveJsonContent())
|
||||||
|
{
|
||||||
ev->accept();
|
ev->accept();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ev->ignore();
|
ev->ignore();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (button == QMessageBox::No) {
|
else if (button == QMessageBox::No)
|
||||||
|
{
|
||||||
ev->accept();
|
ev->accept();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ev->ignore();
|
ev->ignore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -146,38 +153,47 @@ bool JsonEditorDialog::saveJsonContent()
|
||||||
{
|
{
|
||||||
QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " ");
|
QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " ");
|
||||||
QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8());
|
QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8());
|
||||||
if (!jsonNew.isEmpty()) {
|
if (!jsonNew.isEmpty())
|
||||||
|
{
|
||||||
QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8());
|
QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8());
|
||||||
QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact));
|
QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact));
|
||||||
QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact));
|
QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact));
|
||||||
if (newCode != originalCode) {
|
if (newCode != originalCode)
|
||||||
|
{
|
||||||
QString currentFilePath = smpic->getPictureFilePath();
|
QString currentFilePath = smpic->getPictureFilePath();
|
||||||
QString originalFilePath = smpic->getOriginalPictureFilePath();
|
QString originalFilePath = smpic->getOriginalPictureFilePath();
|
||||||
QString backupFileName = originalFilePath % ".bak";
|
QString backupFileName = originalFilePath % ".bak";
|
||||||
if (!QFile::exists(backupFileName)) {
|
if (!QFile::exists(backupFileName))
|
||||||
|
{
|
||||||
QFile::copy(currentFilePath, backupFileName);
|
QFile::copy(currentFilePath, backupFileName);
|
||||||
}
|
}
|
||||||
smpic->setJsonStr(newCode, true);
|
smpic->setJsonStr(newCode, true);
|
||||||
if (!smpic->isJsonOk()) {
|
if (!smpic->isJsonOk())
|
||||||
|
{
|
||||||
QString lastStep = smpic->getLastStep(false);
|
QString lastStep = smpic->getLastStep(false);
|
||||||
QString readableError;
|
QString readableError;
|
||||||
if (lastStep.contains("JSONINCOMPLETE") && lastStep.contains("JSONERROR")) {
|
if (lastStep.contains("JSONINCOMPLETE") && lastStep.contains("JSONERROR"))
|
||||||
|
{
|
||||||
readableError = SnapmaticPicture::tr("JSON is incomplete and malformed");
|
readableError = SnapmaticPicture::tr("JSON is incomplete and malformed");
|
||||||
}
|
}
|
||||||
else if (lastStep.contains("JSONINCOMPLETE")) {
|
else if (lastStep.contains("JSONINCOMPLETE"))
|
||||||
|
{
|
||||||
readableError = SnapmaticPicture::tr("JSON is incomplete");
|
readableError = SnapmaticPicture::tr("JSON is incomplete");
|
||||||
}
|
}
|
||||||
else if (lastStep.contains("JSONERROR")) {
|
else if (lastStep.contains("JSONERROR"))
|
||||||
|
{
|
||||||
readableError = SnapmaticPicture::tr("JSON is malformed");
|
readableError = SnapmaticPicture::tr("JSON is malformed");
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
readableError = tr("JSON Error");
|
readableError = tr("JSON Error");
|
||||||
}
|
}
|
||||||
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of %1").arg(readableError));
|
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of %1").arg(readableError));
|
||||||
smpic->setJsonStr(originalCode, true);
|
smpic->setJsonStr(originalCode, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!smpic->exportPicture(currentFilePath)) {
|
if (!smpic->exportPicture(currentFilePath))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error"));
|
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error"));
|
||||||
smpic->setJsonStr(originalCode, true);
|
smpic->setJsonStr(originalCode, true);
|
||||||
return false;
|
return false;
|
||||||
|
@ -190,16 +206,13 @@ bool JsonEditorDialog::saveJsonContent()
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
telemetrySettings.beginGroup("Telemetry");
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
||||||
telemetrySettings.endGroup();
|
telemetrySettings.endGroup();
|
||||||
if (pushUsageData && Telemetry->canPush()) {
|
if (pushUsageData && Telemetry->canPush())
|
||||||
|
{
|
||||||
QJsonDocument jsonDocument;
|
QJsonDocument jsonDocument;
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "JSONEdited";
|
jsonObject["Type"] = "JSONEdited";
|
||||||
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
|
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +221,8 @@ bool JsonEditorDialog::saveJsonContent()
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of JSON Error"));
|
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of JSON Error"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -222,5 +236,7 @@ void JsonEditorDialog::on_cmdClose_clicked()
|
||||||
void JsonEditorDialog::on_cmdSave_clicked()
|
void JsonEditorDialog::on_cmdSave_clicked()
|
||||||
{
|
{
|
||||||
if (saveJsonContent())
|
if (saveJsonContent())
|
||||||
|
{
|
||||||
close();
|
close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2017-2021 Syping
|
* Copyright (C) 2017-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,8 +20,8 @@
|
||||||
#include "ui_MapLocationDialog.h"
|
#include "ui_MapLocationDialog.h"
|
||||||
#include "IconLoader.h"
|
#include "IconLoader.h"
|
||||||
#include "AppEnv.h"
|
#include "AppEnv.h"
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QDebug>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
|
||||||
MapLocationDialog::MapLocationDialog(double x, double y, QWidget *parent) :
|
MapLocationDialog::MapLocationDialog(double x, double y, QWidget *parent) :
|
||||||
|
@ -29,11 +29,7 @@ MapLocationDialog::MapLocationDialog(double x, double y, QWidget *parent) :
|
||||||
ui(new Ui::MapLocationDialog)
|
ui(new Ui::MapLocationDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
// Set Window Flags
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
#endif
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->cmdDone->setVisible(false);
|
ui->cmdDone->setVisible(false);
|
||||||
|
@ -49,10 +45,12 @@ MapLocationDialog::MapLocationDialog(double x, double y, QWidget *parent) :
|
||||||
ui->vlMapDialog->setSpacing(widgetMargin);
|
ui->vlMapDialog->setSpacing(widgetMargin);
|
||||||
setMinimumSize(500 * screenRatio, 600 * screenRatio);
|
setMinimumSize(500 * screenRatio, 600 * screenRatio);
|
||||||
setMaximumSize(500 * screenRatio, 600 * screenRatio);
|
setMaximumSize(500 * screenRatio, 600 * screenRatio);
|
||||||
|
setFixedSize(500 * screenRatio, 600 * screenRatio);
|
||||||
|
setMouseTracking(true);
|
||||||
|
|
||||||
zoomPercent = 100;
|
|
||||||
changeMode = false;
|
changeMode = false;
|
||||||
propUpdate = false;
|
propUpdate = false;
|
||||||
|
drawPointOnMap(xpos_old, ypos_old);
|
||||||
}
|
}
|
||||||
|
|
||||||
MapLocationDialog::~MapLocationDialog()
|
MapLocationDialog::~MapLocationDialog()
|
||||||
|
@ -68,220 +66,6 @@ void MapLocationDialog::drawPointOnMap(double xpos_d, double ypos_d)
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapLocationDialog::setCayoPerico(bool isCayoPerico)
|
|
||||||
{
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
p_isCayoPerico = isCayoPerico;
|
|
||||||
if (isCayoPerico) {
|
|
||||||
setMinimumSize(500 * screenRatio, 500 * screenRatio);
|
|
||||||
setMaximumSize(500 * screenRatio, 500 * screenRatio);
|
|
||||||
ui->hlMapDialog->removeItem(ui->vlMapDialog);
|
|
||||||
ui->hlMapDialog->insertLayout(0, ui->vlMapDialog);
|
|
||||||
ui->hlMapDialog->removeItem(ui->vlPosLayout);
|
|
||||||
ui->hlMapDialog->addLayout(ui->vlPosLayout);
|
|
||||||
ui->labPos->setAlignment(Qt::AlignRight);
|
|
||||||
mapImage = QImage(AppEnv::getImagesFolder() % "/mapcayoperico.jpg");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mapImage = QImage(AppEnv::getImagesFolder() % "/mappreview.jpg");
|
|
||||||
}
|
|
||||||
drawPointOnMap(xpos_old, ypos_old);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::updatePosFromEvent(double x, double y)
|
|
||||||
{
|
|
||||||
QSize mapPixelSize = size();
|
|
||||||
double x_per = x / mapPixelSize.width(); // get X %
|
|
||||||
double y_per = y / mapPixelSize.height(); // get Y %
|
|
||||||
double x_pos, y_pos;
|
|
||||||
if (p_isCayoPerico) {
|
|
||||||
x_pos = x_per * 2340; // 2340 is 100% for X (Cayo Perico)
|
|
||||||
y_pos = y_per * -2340; // -2340 is 100% for Y (Cayo Perico)
|
|
||||||
x_pos = x_pos + 3560; // +3560 gets corrected for X (Cayo Perico)
|
|
||||||
y_pos = y_pos - 3980; // -3980 gets corrected for Y (Cayo Perico)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x_pos = x_per * 10000; // 10000 is 100% for X (Los Santos)
|
|
||||||
y_pos = y_per * -12000; // -12000 is 100% for Y (Los Santos)
|
|
||||||
x_pos = x_pos - 4000; // -4000 gets corrected for X (Los Santos)
|
|
||||||
y_pos = y_pos + 8000; // +8000 gets corrected for Y (Los Santos)
|
|
||||||
}
|
|
||||||
drawPointOnMap(x_pos, y_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::paintEvent(QPaintEvent *ev)
|
|
||||||
{
|
|
||||||
QPainter painter(this);
|
|
||||||
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
|
||||||
|
|
||||||
// Screen Ratio
|
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
|
|
||||||
// Paint Map
|
|
||||||
const double zoomLevel = static_cast<double>(zoomPercent) / 100;
|
|
||||||
const QSize mapImageSize = mapImage.size();
|
|
||||||
const QPointF mapImageMid(static_cast<double>(mapImageSize.width()) / 2, static_cast<double>(mapImageSize.height()) / 2);
|
|
||||||
const QSizeF srcImageSize(static_cast<double>(mapImageSize.width()) / zoomLevel , static_cast<double>(mapImageSize.height()) / zoomLevel);
|
|
||||||
const QPointF mapImageTopLeft(mapImageMid.x() - (srcImageSize.width() / 2), mapImageMid.y() - (srcImageSize.height() / 2));
|
|
||||||
const QPointF mapImageBottomRight(mapImageMid.x() + (srcImageSize.width() / 2), mapImageMid.y() + (srcImageSize.height() / 2));
|
|
||||||
painter.drawImage(QRect(QPoint(0, 0), size()), mapImage, QRectF(mapImageTopLeft, mapImageBottomRight));
|
|
||||||
|
|
||||||
// Paint Marker
|
|
||||||
QSize mapPixelSize = size();
|
|
||||||
int pointMarkerSize = 8 * screenRatio;
|
|
||||||
int pointMarkerHalfSize = pointMarkerSize / 2;
|
|
||||||
double xpos_mp, ypos_mp;
|
|
||||||
if (p_isCayoPerico) {
|
|
||||||
double xpos_per = xpos_new - 3560; // correct X in reserve
|
|
||||||
double ypos_per = ypos_new + 3980; // correct y in reserve
|
|
||||||
xpos_per = xpos_per / 2340; // divide 100% for X
|
|
||||||
ypos_per = ypos_per / -2340; // divide 100% for Y
|
|
||||||
xpos_mp = xpos_per * mapPixelSize.width(); // locate window width pos
|
|
||||||
ypos_mp = ypos_per * mapPixelSize.height(); // locate window height pos
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
double xpos_per = xpos_new + 4000; // correct X in reserve
|
|
||||||
double ypos_per = ypos_new - 8000; // correct y in reserve
|
|
||||||
xpos_per = xpos_per / 10000; // divide 100% for X
|
|
||||||
ypos_per = ypos_per / -12000; // divide 100% for Y
|
|
||||||
xpos_mp = xpos_per * mapPixelSize.width(); // locate window width pos
|
|
||||||
ypos_mp = ypos_per * mapPixelSize.height(); // locate window height pos
|
|
||||||
}
|
|
||||||
QPointF pointMarkerPos(xpos_mp, ypos_mp);
|
|
||||||
if (screenRatioPR != 1) {
|
|
||||||
pointMarkerPos.setX(pointMarkerPos.x() - pointMarkerHalfSize + screenRatioPR);
|
|
||||||
pointMarkerPos.setY(pointMarkerPos.y() - pointMarkerHalfSize + screenRatioPR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pointMarkerPos.setX(pointMarkerPos.x() - pointMarkerHalfSize);
|
|
||||||
pointMarkerPos.setY(pointMarkerPos.y() - pointMarkerHalfSize);
|
|
||||||
}
|
|
||||||
QPixmap mapMarkerPixmap = IconLoader::loadingPointmakerIcon().pixmap(QSize(pointMarkerSize, pointMarkerSize));
|
|
||||||
painter.drawPixmap(pointMarkerPos, mapMarkerPixmap);
|
|
||||||
|
|
||||||
QDialog::paintEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::mouseMoveEvent(QMouseEvent *ev)
|
|
||||||
{
|
|
||||||
if (changeMode && ev->buttons() & Qt::LeftButton) {
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
const QPointF localPos = ev->position();
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
const QPointF localPos = ev->localPos();
|
|
||||||
#else
|
|
||||||
const QPointF localPos = ev->posF();
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
if (screenRatioPR != 1) {
|
|
||||||
updatePosFromEvent(localPos.x() - screenRatioPR, localPos.y() - screenRatioPR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updatePosFromEvent(localPos.x(), localPos.y());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
updatePosFromEvent(localPos.x(), localPos.y());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (dragStart && ev->buttons() & Qt::LeftButton) {
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
const QPointF dragNewPosition = ev->position();
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
const QPointF dragNewPosition = ev->localPos();
|
|
||||||
#else
|
|
||||||
const QPointF dragNewPosition = ev->posF();
|
|
||||||
#endif
|
|
||||||
mapDiffPosition = dragNewPosition - dragPosition + mapDiffPosition;
|
|
||||||
dragPosition = dragNewPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::mousePressEvent(QMouseEvent *ev)
|
|
||||||
{
|
|
||||||
if (!changeMode && ev->button() == Qt::LeftButton) {
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
dragPosition = ev->position();
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
dragPosition = ev->localPos();
|
|
||||||
#else
|
|
||||||
dragPosition = ev->posF();
|
|
||||||
#endif
|
|
||||||
dragStart = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::mouseReleaseEvent(QMouseEvent *ev)
|
|
||||||
{
|
|
||||||
if (changeMode && ev->button() == Qt::LeftButton) {
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
const QPointF localPos = ev->position();
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
const QPointF localPos = ev->localPos();
|
|
||||||
#else
|
|
||||||
const QPointF localPos = ev->posF();
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
if (screenRatioPR != 1) {
|
|
||||||
updatePosFromEvent(localPos.x() - screenRatioPR, localPos.y() - screenRatioPR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updatePosFromEvent(localPos.x(), localPos.y());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
updatePosFromEvent(localPos.x(), localPos.y());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (dragStart && ev->button() == Qt::LeftButton) {
|
|
||||||
dragStart = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::wheelEvent(QWheelEvent *ev)
|
|
||||||
{
|
|
||||||
#ifdef GTA5SYNC_EXPERIMENTAL
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
const QPoint numPixels = ev->pixelDelta();
|
|
||||||
const QPoint numDegrees = ev->angleDelta();
|
|
||||||
#else
|
|
||||||
QPoint numDegrees;
|
|
||||||
if (ev->orientation() == Qt::Horizontal) {
|
|
||||||
numDegrees.setX(ev->delta());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
numDegrees.setY(ev->delta());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
if (!numPixels.isNull()) {
|
|
||||||
if (numPixels.y() < 0 && zoomPercent != 100) {
|
|
||||||
zoomPercent = zoomPercent - 10;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
else if (numPixels.y() > 0 && zoomPercent != 400) {
|
|
||||||
zoomPercent = zoomPercent + 10;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!numDegrees.isNull()) {
|
|
||||||
if (numDegrees.y() < 0 && zoomPercent != 100) {
|
|
||||||
zoomPercent = zoomPercent - 10;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
else if (numDegrees.y() > 0 && zoomPercent != 400) {
|
|
||||||
zoomPercent = zoomPercent + 10;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Q_UNUSED(ev)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapLocationDialog::on_cmdChange_clicked()
|
void MapLocationDialog::on_cmdChange_clicked()
|
||||||
{
|
{
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
qreal screenRatio = AppEnv::screenRatio();
|
||||||
|
@ -301,14 +85,124 @@ void MapLocationDialog::on_cmdDone_clicked()
|
||||||
{
|
{
|
||||||
ui->cmdDone->setVisible(false);
|
ui->cmdDone->setVisible(false);
|
||||||
ui->cmdChange->setVisible(true);
|
ui->cmdChange->setVisible(true);
|
||||||
if (xpos_new != xpos_old || ypos_new != ypos_old) {
|
if (xpos_new != xpos_old || ypos_new != ypos_old)
|
||||||
|
{
|
||||||
ui->cmdApply->setVisible(true);
|
ui->cmdApply->setVisible(true);
|
||||||
ui->cmdRevert->setVisible(true);
|
ui->cmdRevert->setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
setCursor(Qt::ArrowCursor);
|
setCursor(Qt::ArrowCursor);
|
||||||
changeMode = false;
|
changeMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x060000
|
||||||
|
void MapLocationDialog::updatePosFromEvent(double x, double y)
|
||||||
|
{
|
||||||
|
QSize mapPixelSize = size();
|
||||||
|
double xpos_ad = x;
|
||||||
|
double ypos_ad = mapPixelSize.height() - y;
|
||||||
|
double xrat = 10000 / (double)mapPixelSize.width();
|
||||||
|
double yrat = 12000 / (double)mapPixelSize.height();
|
||||||
|
double xpos_rv = xrat * xpos_ad;
|
||||||
|
double ypos_rv = yrat * ypos_ad;
|
||||||
|
double xpos_fp = xpos_rv - 4000;
|
||||||
|
double ypos_fp = ypos_rv - 4000;
|
||||||
|
drawPointOnMap(xpos_fp, ypos_fp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void MapLocationDialog::updatePosFromEvent(int x, int y)
|
||||||
|
{
|
||||||
|
QSize mapPixelSize = size();
|
||||||
|
int xpos_ad = x;
|
||||||
|
int ypos_ad = mapPixelSize.height() - y;
|
||||||
|
double xrat = 10000 / (double)mapPixelSize.width();
|
||||||
|
double yrat = 12000 / (double)mapPixelSize.height();
|
||||||
|
double xpos_rv = xrat * xpos_ad;
|
||||||
|
double ypos_rv = yrat * ypos_ad;
|
||||||
|
double xpos_fp = xpos_rv - 4000;
|
||||||
|
double ypos_fp = ypos_rv - 4000;
|
||||||
|
drawPointOnMap(xpos_fp, ypos_fp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MapLocationDialog::paintEvent(QPaintEvent *ev)
|
||||||
|
{
|
||||||
|
QPainter painter(this);
|
||||||
|
qreal screenRatio = AppEnv::screenRatio();
|
||||||
|
qreal screenRatioPR = AppEnv::screenRatioPR();
|
||||||
|
|
||||||
|
// Paint Map
|
||||||
|
QSize mapPixelSize = QSize(width() * screenRatioPR, height() * screenRatioPR);
|
||||||
|
painter.drawPixmap(0, 0, width(), height(), QPixmap(":/img/mappreview.jpg").scaled(mapPixelSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
|
||||||
|
// Paint Marker
|
||||||
|
int pointMarkerSize = 8 * screenRatio;
|
||||||
|
int pointMarkerHalfSize = pointMarkerSize / 2;
|
||||||
|
long xpos_ms = qRound(xpos_new);
|
||||||
|
long ypos_ms = qRound(ypos_new);
|
||||||
|
double xpos_ma = xpos_ms + 4000;
|
||||||
|
double ypos_ma = ypos_ms + 4000;
|
||||||
|
double xrat = (double)width() / 10000;
|
||||||
|
double yrat = (double)height() / 12000;
|
||||||
|
long xpos_mp = qRound(xpos_ma * xrat);
|
||||||
|
long ypos_mp = qRound(ypos_ma * yrat);
|
||||||
|
long xpos_pr;
|
||||||
|
long ypos_pr;
|
||||||
|
if (screenRatioPR != 1) {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
xpos_pr = xpos_mp - pointMarkerHalfSize;
|
||||||
|
ypos_pr = ypos_mp + pointMarkerHalfSize;
|
||||||
|
#else
|
||||||
|
xpos_pr = xpos_mp - pointMarkerHalfSize + screenRatioPR;
|
||||||
|
ypos_pr = ypos_mp + pointMarkerHalfSize - screenRatioPR;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xpos_pr = xpos_mp - pointMarkerHalfSize;
|
||||||
|
ypos_pr = ypos_mp + pointMarkerHalfSize;
|
||||||
|
}
|
||||||
|
QPixmap mapMarkerPixmap = IconLoader::loadingPointmakerIcon().pixmap(QSize(pointMarkerSize, pointMarkerSize));
|
||||||
|
painter.drawPixmap(xpos_pr, height() - ypos_pr, pointMarkerSize, pointMarkerSize, mapMarkerPixmap);
|
||||||
|
|
||||||
|
QDialog::paintEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapLocationDialog::mouseMoveEvent(QMouseEvent *ev)
|
||||||
|
{
|
||||||
|
if (!changeMode) { ev->ignore(); }
|
||||||
|
else if (ev->buttons() & Qt::LeftButton)
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= 0x060000
|
||||||
|
updatePosFromEvent(ev->position().x(), ev->position().y());
|
||||||
|
#else
|
||||||
|
updatePosFromEvent(ev->x(), ev->y());
|
||||||
|
#endif
|
||||||
|
ev->accept();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ev->ignore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapLocationDialog::mouseReleaseEvent(QMouseEvent *ev)
|
||||||
|
{
|
||||||
|
if (!changeMode) { ev->ignore(); }
|
||||||
|
else if (ev->button() == Qt::LeftButton)
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= 0x060000
|
||||||
|
updatePosFromEvent(ev->position().x(), ev->position().y());
|
||||||
|
#else
|
||||||
|
updatePosFromEvent(ev->x(), ev->y());
|
||||||
|
#endif
|
||||||
|
ev->accept();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ev->ignore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MapLocationDialog::on_cmdApply_clicked()
|
void MapLocationDialog::on_cmdApply_clicked()
|
||||||
{
|
{
|
||||||
propUpdate = true;
|
propUpdate = true;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2017-2021 Syping
|
* Copyright (C) 2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -33,7 +33,6 @@ class MapLocationDialog : public QDialog
|
||||||
public:
|
public:
|
||||||
explicit MapLocationDialog(double x, double y, QWidget *parent = 0);
|
explicit MapLocationDialog(double x, double y, QWidget *parent = 0);
|
||||||
void drawPointOnMap(double x, double y);
|
void drawPointOnMap(double x, double y);
|
||||||
void setCayoPerico(bool isCayoPerico);
|
|
||||||
bool propUpdated();
|
bool propUpdated();
|
||||||
double getXpos();
|
double getXpos();
|
||||||
double getYpos();
|
double getYpos();
|
||||||
|
@ -42,31 +41,27 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *ev);
|
void paintEvent(QPaintEvent *ev);
|
||||||
void mouseMoveEvent(QMouseEvent *ev);
|
void mouseMoveEvent(QMouseEvent *ev);
|
||||||
void mousePressEvent(QMouseEvent *ev);
|
|
||||||
void mouseReleaseEvent(QMouseEvent *ev);
|
void mouseReleaseEvent(QMouseEvent *ev);
|
||||||
void wheelEvent(QWheelEvent *ev);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_cmdApply_clicked();
|
|
||||||
void on_cmdDone_clicked();
|
void on_cmdDone_clicked();
|
||||||
void on_cmdClose_clicked();
|
void on_cmdApply_clicked();
|
||||||
void on_cmdChange_clicked();
|
void on_cmdChange_clicked();
|
||||||
void on_cmdRevert_clicked();
|
void on_cmdRevert_clicked();
|
||||||
|
#if QT_VERSION >= 0x060000
|
||||||
void updatePosFromEvent(double x, double y);
|
void updatePosFromEvent(double x, double y);
|
||||||
|
#else
|
||||||
|
void updatePosFromEvent(int x, int y);
|
||||||
|
#endif
|
||||||
|
void on_cmdClose_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int zoomPercent;
|
|
||||||
double xpos_old;
|
double xpos_old;
|
||||||
double ypos_old;
|
double ypos_old;
|
||||||
double xpos_new;
|
double xpos_new;
|
||||||
double ypos_new;
|
double ypos_new;
|
||||||
bool dragStart;
|
|
||||||
bool propUpdate;
|
bool propUpdate;
|
||||||
bool changeMode;
|
bool changeMode;
|
||||||
bool p_isCayoPerico;
|
|
||||||
QImage mapImage;
|
|
||||||
QPointF dragPosition;
|
|
||||||
QPointF mapDiffPosition;
|
|
||||||
Ui::MapLocationDialog *ui;
|
Ui::MapLocationDialog *ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -21,7 +21,6 @@
|
||||||
#include "TranslationClass.h"
|
#include "TranslationClass.h"
|
||||||
#include "StandardPaths.h"
|
#include "StandardPaths.h"
|
||||||
#include "UserInterface.h"
|
#include "UserInterface.h"
|
||||||
#include "wrapper.h"
|
|
||||||
#include "AppEnv.h"
|
#include "AppEnv.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
|
@ -56,11 +55,7 @@ OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) :
|
||||||
ui(new Ui::OptionsDialog)
|
ui(new Ui::OptionsDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
// Set Window Flags
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup User Interface
|
// Setup User Interface
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
@ -93,26 +88,25 @@ OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) :
|
||||||
ui->rbPicDefaultRes->setText(ui->rbPicDefaultRes->text().arg(QString::number(defExportSize.width()), QString::number(defExportSize.height())));
|
ui->rbPicDefaultRes->setText(ui->rbPicDefaultRes->text().arg(QString::number(defExportSize.width()), QString::number(defExportSize.height())));
|
||||||
|
|
||||||
// Set Icon for OK Button
|
// Set Icon for OK Button
|
||||||
if (QIcon::hasThemeIcon("dialog-ok")) {
|
if (QIcon::hasThemeIcon("dialog-ok"))
|
||||||
|
{
|
||||||
ui->cmdOK->setIcon(QIcon::fromTheme("dialog-ok"));
|
ui->cmdOK->setIcon(QIcon::fromTheme("dialog-ok"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-ok")) {
|
else if (QIcon::hasThemeIcon("gtk-ok"))
|
||||||
|
{
|
||||||
ui->cmdOK->setIcon(QIcon::fromTheme("gtk-ok"));
|
ui->cmdOK->setIcon(QIcon::fromTheme("gtk-ok"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Cancel Button
|
// Set Icon for Cancel Button
|
||||||
if (QIcon::hasThemeIcon("dialog-cancel")) {
|
if (QIcon::hasThemeIcon("dialog-cancel"))
|
||||||
|
{
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-cancel")) {
|
else if (QIcon::hasThemeIcon("gtk-cancel"))
|
||||||
|
{
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Copy Button
|
|
||||||
if (QIcon::hasThemeIcon("edit-copy")) {
|
|
||||||
ui->cmdCopyStatsID->setIcon(QIcon::fromTheme("edit-copy"));
|
|
||||||
}
|
|
||||||
|
|
||||||
setupTreeWidget();
|
setupTreeWidget();
|
||||||
setupLanguageBox();
|
setupLanguageBox();
|
||||||
setupRadioButtons();
|
setupRadioButtons();
|
||||||
|
@ -147,11 +141,15 @@ void OptionsDialog::setupTreeWidget()
|
||||||
{
|
{
|
||||||
const QStringList players = profileDB->getPlayers();
|
const QStringList players = profileDB->getPlayers();
|
||||||
if (players.length() != 0) {
|
if (players.length() != 0) {
|
||||||
for (auto it = players.constBegin(); it != players.constEnd(); it++) {
|
QStringList::const_iterator it = players.constBegin();
|
||||||
|
QStringList::const_iterator end = players.constEnd();
|
||||||
|
while (it != end)
|
||||||
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
int playerID = it->toInt(&ok);
|
int playerID = it->toInt(&ok);
|
||||||
if (ok) {
|
if (ok)
|
||||||
const QString playerName = profileDB->getPlayerName(playerID);
|
{
|
||||||
|
QString playerName = profileDB->getPlayerName(playerID);
|
||||||
|
|
||||||
QStringList playerTreeViewList;
|
QStringList playerTreeViewList;
|
||||||
playerTreeViewList += *it;
|
playerTreeViewList += *it;
|
||||||
|
@ -161,6 +159,7 @@ void OptionsDialog::setupTreeWidget()
|
||||||
ui->twPlayers->addTopLevelItem(playerItem);
|
ui->twPlayers->addTopLevelItem(playerItem);
|
||||||
playerItems += playerItem;
|
playerItems += playerItem;
|
||||||
}
|
}
|
||||||
|
it++;
|
||||||
}
|
}
|
||||||
ui->twPlayers->sortItems(1, Qt::AscendingOrder);
|
ui->twPlayers->sortItems(1, Qt::AscendingOrder);
|
||||||
}
|
}
|
||||||
|
@ -176,18 +175,20 @@ void OptionsDialog::setupLanguageBox()
|
||||||
currentAreaLanguage = settings->value("AreaLanguage", "Auto").toString();
|
currentAreaLanguage = settings->value("AreaLanguage", "Auto").toString();
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
const QString cbSysStr = tr("%1 (Language priority)", "First language a person can talk with a different person/application. \"Native\" or \"Not Native\".").arg(tr("System",
|
QString cbSysStr = tr("%1 (Language priority)", "First language a person can talk with a different person/application. \"Native\" or \"Not Native\".").arg(tr("System",
|
||||||
"System in context of System default"));
|
"System in context of System default"));
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString cbAutoStr;
|
QString cbAutoStr;
|
||||||
if (AppEnv::getGameLanguage(AppEnv::getGameVersion()) != GameLanguage::Undefined) {
|
if (AppEnv::getGameLanguage(AppEnv::getGameVersion()) != GameLanguage::Undefined)
|
||||||
|
{
|
||||||
cbAutoStr = tr("%1 (Game language)", "Next closest language compared to the Game settings").arg(tr("Auto", "Automatic language choice."));
|
cbAutoStr = tr("%1 (Game language)", "Next closest language compared to the Game settings").arg(tr("Auto", "Automatic language choice."));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
cbAutoStr = tr("%1 (Closest to Interface)", "Next closest language compared to the Interface").arg(tr("Auto", "Automatic language choice."));
|
cbAutoStr = tr("%1 (Closest to Interface)", "Next closest language compared to the Interface").arg(tr("Auto", "Automatic language choice."));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
const QString cbAutoStr = tr("%1 (Closest to Interface)", "Next closest language compared to the Interface").arg(tr("Auto", "Automatic language choice."));
|
QString cbAutoStr = tr("%1 (Closest to Interface)", "Next closest language compared to the Interface").arg(tr("Auto", "Automatic language choice."));
|
||||||
#endif
|
#endif
|
||||||
ui->cbLanguage->addItem(cbSysStr, "System");
|
ui->cbLanguage->addItem(cbSysStr, "System");
|
||||||
ui->cbAreaLanguage->addItem(cbAutoStr, "Auto");
|
ui->cbAreaLanguage->addItem(cbAutoStr, "Auto");
|
||||||
|
@ -201,18 +202,15 @@ void OptionsDialog::setupLanguageBox()
|
||||||
availableLanguages.removeDuplicates();
|
availableLanguages.removeDuplicates();
|
||||||
availableLanguages.sort();
|
availableLanguages.sort();
|
||||||
|
|
||||||
for (const QString &lang : qAsConst(availableLanguages)) {
|
for (QString lang : availableLanguages)
|
||||||
|
{
|
||||||
QLocale langLocale(lang);
|
QLocale langLocale(lang);
|
||||||
const QString cbLangStr = langLocale.nativeLanguageName() % " (" % langLocale.nativeCountryName() % ") [" % lang % "]";
|
QString cbLangStr = langLocale.nativeLanguageName() % " (" % langLocale.nativeCountryName() % ") [" % lang % "]";
|
||||||
const QString langIconPath = AppEnv::getImagesFolder() % "/flag-" % TranslationClass::getCountryCode(langLocale) % ".png";
|
QString langIconStr = "flag-" % TranslationClass::getCountryCode(langLocale);
|
||||||
|
|
||||||
if (QFile::exists(langIconPath)) {
|
ui->cbLanguage->addItem(QIcon::fromTheme(langIconStr), cbLangStr, lang);
|
||||||
ui->cbLanguage->addItem(QIcon(langIconPath), cbLangStr, lang);
|
if (currentLanguage == lang)
|
||||||
}
|
{
|
||||||
else {
|
|
||||||
ui->cbLanguage->addItem(cbLangStr, lang);
|
|
||||||
}
|
|
||||||
if (currentLanguage == lang) {
|
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
ui->cbLanguage->setCurrentText(cbLangStr);
|
ui->cbLanguage->setCurrentText(cbLangStr);
|
||||||
#else
|
#else
|
||||||
|
@ -223,8 +221,7 @@ void OptionsDialog::setupLanguageBox()
|
||||||
}
|
}
|
||||||
|
|
||||||
QString aCurrentLanguage = QString("en_GB");
|
QString aCurrentLanguage = QString("en_GB");
|
||||||
if (Translator->isLanguageLoaded())
|
if (Translator->isLanguageLoaded()) { aCurrentLanguage = Translator->getCurrentLanguage(); }
|
||||||
aCurrentLanguage = Translator->getCurrentLanguage();
|
|
||||||
QLocale currentLocale = QLocale(aCurrentLanguage);
|
QLocale currentLocale = QLocale(aCurrentLanguage);
|
||||||
ui->labCurrentLanguage->setText(tr("Current: %1").arg(currentLocale.nativeLanguageName() % " (" % currentLocale.nativeCountryName() % ") [" % aCurrentLanguage % "]"));
|
ui->labCurrentLanguage->setText(tr("Current: %1").arg(currentLocale.nativeLanguageName() % " (" % currentLocale.nativeCountryName() % ") [" % aCurrentLanguage % "]"));
|
||||||
|
|
||||||
|
@ -233,21 +230,27 @@ void OptionsDialog::setupLanguageBox()
|
||||||
availableLanguages.removeDuplicates();
|
availableLanguages.removeDuplicates();
|
||||||
availableLanguages.sort();
|
availableLanguages.sort();
|
||||||
|
|
||||||
for (const QString &lang : qAsConst(availableLanguages)) {
|
for (QString lang : availableLanguages)
|
||||||
|
{
|
||||||
// correcting Language Location if possible
|
// correcting Language Location if possible
|
||||||
QString aLang = lang;
|
QString aLang = lang;
|
||||||
if (QFile::exists(":/global/global." % lang % ".loc")) {
|
if (QFile::exists(":/global/global." % lang % ".loc"))
|
||||||
|
{
|
||||||
QFile locFile(":/global/global." % lang % ".loc");
|
QFile locFile(":/global/global." % lang % ".loc");
|
||||||
if (locFile.open(QFile::ReadOnly)) {
|
if (locFile.open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
aLang = QString::fromUtf8(locFile.readLine()).trimmed();
|
aLang = QString::fromUtf8(locFile.readLine()).trimmed();
|
||||||
locFile.close();
|
locFile.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QLocale langLocale(aLang);
|
QLocale langLocale(aLang);
|
||||||
const QString cbLangStr = langLocale.nativeLanguageName() % " (" % langLocale.nativeCountryName() % ") [" % aLang % "]";
|
QString cbLangStr = langLocale.nativeLanguageName() % " (" % langLocale.nativeCountryName() % ") [" % aLang % "]";
|
||||||
ui->cbAreaLanguage->addItem(cbLangStr, lang);
|
QString langIconStr = "flag-" % TranslationClass::getCountryCode(langLocale);
|
||||||
if (currentAreaLanguage == lang) {
|
|
||||||
|
ui->cbAreaLanguage->addItem(QIcon::fromTheme(langIconStr), cbLangStr, lang);
|
||||||
|
if (currentAreaLanguage == lang)
|
||||||
|
{
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
ui->cbAreaLanguage->setCurrentText(cbLangStr);
|
ui->cbAreaLanguage->setCurrentText(cbLangStr);
|
||||||
#else
|
#else
|
||||||
|
@ -258,10 +261,12 @@ void OptionsDialog::setupLanguageBox()
|
||||||
}
|
}
|
||||||
|
|
||||||
QString aCurrentAreaLanguage = Translator->getCurrentAreaLanguage();
|
QString aCurrentAreaLanguage = Translator->getCurrentAreaLanguage();
|
||||||
if (QFile::exists(":/global/global." % aCurrentAreaLanguage % ".loc")) {
|
if (QFile::exists(":/global/global." % aCurrentAreaLanguage % ".loc"))
|
||||||
|
{
|
||||||
qDebug() << "locFile found";
|
qDebug() << "locFile found";
|
||||||
QFile locFile(":/global/global." % aCurrentAreaLanguage % ".loc");
|
QFile locFile(":/global/global." % aCurrentAreaLanguage % ".loc");
|
||||||
if (locFile.open(QFile::ReadOnly)) {
|
if (locFile.open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
aCurrentAreaLanguage = QString::fromUtf8(locFile.readLine()).trimmed();
|
aCurrentAreaLanguage = QString::fromUtf8(locFile.readLine()).trimmed();
|
||||||
locFile.close();
|
locFile.close();
|
||||||
}
|
}
|
||||||
|
@ -277,12 +282,13 @@ void OptionsDialog::setupRadioButtons()
|
||||||
contentMode = settings->value("ContentMode", 0).toInt(&contentModeOk);
|
contentMode = settings->value("ContentMode", 0).toInt(&contentModeOk);
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
if (contentModeOk) {
|
if (contentModeOk)
|
||||||
switch (contentMode) {
|
{
|
||||||
|
switch (contentMode)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 20:
|
case 20:
|
||||||
ui->rbModern->setChecked(true);
|
ui->rbModern->setChecked(true);
|
||||||
ui->cbDoubleclick->setChecked(false);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -292,12 +298,11 @@ void OptionsDialog::setupRadioButtons()
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
ui->rbClassic->setChecked(true);
|
ui->rbClassic->setChecked(true);
|
||||||
ui->cbDoubleclick->setChecked(false);
|
#if QT_VERSION >= 0x050800
|
||||||
break;
|
Q_FALLTHROUGH();
|
||||||
|
#endif
|
||||||
case 11:
|
case 11:
|
||||||
ui->rbClassic->setChecked(true);
|
|
||||||
ui->cbDoubleclick->setChecked(true);
|
ui->cbDoubleclick->setChecked(true);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,7 +325,8 @@ void OptionsDialog::setupInterfaceSettings()
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
if (availableStyles.contains(currentStyle, Qt::CaseInsensitive)) {
|
if (availableStyles.contains(currentStyle, Qt::CaseInsensitive)) {
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
for (const QString ¤tStyleFF : availableStyles) {
|
for (const QString ¤tStyleFF : availableStyles) {
|
||||||
|
@ -369,13 +375,16 @@ void OptionsDialog::applySettings()
|
||||||
|
|
||||||
settings->beginGroup("Profile");
|
settings->beginGroup("Profile");
|
||||||
int newContentMode = 20;
|
int newContentMode = 20;
|
||||||
if (ui->rbModern->isChecked()) {
|
if (ui->rbModern->isChecked())
|
||||||
|
{
|
||||||
newContentMode = 20;
|
newContentMode = 20;
|
||||||
}
|
}
|
||||||
else if (ui->rbClassic->isChecked()) {
|
else if (ui->rbClassic->isChecked())
|
||||||
|
{
|
||||||
newContentMode = 10;
|
newContentMode = 10;
|
||||||
}
|
}
|
||||||
if (ui->cbDoubleclick->isChecked()) {
|
if (ui->cbDoubleclick->isChecked())
|
||||||
|
{
|
||||||
newContentMode++;
|
newContentMode++;
|
||||||
}
|
}
|
||||||
settings->setValue("ContentMode", newContentMode);
|
settings->setValue("ContentMode", newContentMode);
|
||||||
|
@ -387,15 +396,18 @@ void OptionsDialog::applySettings()
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
settings->beginGroup("Pictures");
|
settings->beginGroup("Pictures");
|
||||||
if (ui->cbPicCustomQuality->isChecked()) {
|
if (ui->cbPicCustomQuality->isChecked())
|
||||||
|
{
|
||||||
settings->setValue("CustomQuality", ui->hsPicQuality->value());
|
settings->setValue("CustomQuality", ui->hsPicQuality->value());
|
||||||
}
|
}
|
||||||
settings->setValue("CustomQualityEnabled", ui->cbPicCustomQuality->isChecked());
|
settings->setValue("CustomQualityEnabled", ui->cbPicCustomQuality->isChecked());
|
||||||
QString sizeMode = "Default";
|
QString sizeMode = "Default";
|
||||||
if (ui->rbPicDesktopRes->isChecked()) {
|
if (ui->rbPicDesktopRes->isChecked())
|
||||||
|
{
|
||||||
sizeMode = "Desktop";
|
sizeMode = "Desktop";
|
||||||
}
|
}
|
||||||
else if (ui->rbPicCustomRes->isChecked()) {
|
else if (ui->rbPicCustomRes->isChecked())
|
||||||
|
{
|
||||||
sizeMode = "Custom";
|
sizeMode = "Custom";
|
||||||
settings->setValue("CustomSize", QSize(ui->sbPicExportWidth->value(), ui->sbPicExportHeight->value()));
|
settings->setValue("CustomSize", QSize(ui->sbPicExportWidth->value(), ui->sbPicExportHeight->value()));
|
||||||
}
|
}
|
||||||
|
@ -440,15 +452,12 @@ void OptionsDialog::applySettings()
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
Telemetry->refresh();
|
Telemetry->refresh();
|
||||||
Telemetry->work();
|
Telemetry->work();
|
||||||
if (ui->cbUsageData->isChecked() && Telemetry->canPush()) {
|
if (ui->cbUsageData->isChecked() && Telemetry->canPush())
|
||||||
|
{
|
||||||
QJsonDocument jsonDocument;
|
QJsonDocument jsonDocument;
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "SettingsUpdated";
|
jsonObject["Type"] = "SettingsUpdated";
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["UpdateTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["UpdateTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["UpdateTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
|
@ -461,19 +470,22 @@ void OptionsDialog::applySettings()
|
||||||
bool languageChanged = ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentLanguage;
|
bool languageChanged = ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentLanguage;
|
||||||
bool languageAreaChanged = ui->cbAreaLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentAreaLanguage;
|
bool languageAreaChanged = ui->cbAreaLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentAreaLanguage;
|
||||||
#endif
|
#endif
|
||||||
if (languageChanged) {
|
if (languageChanged)
|
||||||
|
{
|
||||||
Translator->unloadTranslation(qApp);
|
Translator->unloadTranslation(qApp);
|
||||||
Translator->initUserLanguage();
|
Translator->initUserLanguage();
|
||||||
Translator->loadTranslation(qApp);
|
Translator->loadTranslation(qApp);
|
||||||
}
|
}
|
||||||
else if (languageAreaChanged) {
|
else if (languageAreaChanged)
|
||||||
|
{
|
||||||
Translator->initUserLanguage();
|
Translator->initUserLanguage();
|
||||||
}
|
}
|
||||||
|
|
||||||
settings->sync();
|
settings->sync();
|
||||||
emit settingsApplied(newContentMode, languageChanged);
|
emit settingsApplied(newContentMode, languageChanged);
|
||||||
|
|
||||||
if ((forceCustomFolder && ui->txtFolder->text() != currentCFolder) || (forceCustomFolder != currentFFolder && forceCustomFolder)) {
|
if ((forceCustomFolder && ui->txtFolder->text() != currentCFolder) || (forceCustomFolder != currentFFolder && forceCustomFolder))
|
||||||
|
{
|
||||||
QMessageBox::information(this, tr("%1", "%1").arg(GTA5SYNC_APPSTR), tr("The new Custom Folder will initialise after you restart %1.").arg(GTA5SYNC_APPSTR));
|
QMessageBox::information(this, tr("%1", "%1").arg(GTA5SYNC_APPSTR), tr("The new Custom Folder will initialise after you restart %1.").arg(GTA5SYNC_APPSTR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -490,9 +502,11 @@ void OptionsDialog::setupDefaultProfile()
|
||||||
|
|
||||||
void OptionsDialog::commitProfiles(const QStringList &profiles)
|
void OptionsDialog::commitProfiles(const QStringList &profiles)
|
||||||
{
|
{
|
||||||
for (const QString &profile : profiles) {
|
for (QString profile : profiles)
|
||||||
|
{
|
||||||
ui->cbProfiles->addItem(tr("Profile: %1").arg(profile), profile);
|
ui->cbProfiles->addItem(tr("Profile: %1").arg(profile), profile);
|
||||||
if (defaultProfile == profile) {
|
if (defaultProfile == profile)
|
||||||
|
{
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
ui->cbProfiles->setCurrentText(tr("Profile: %1").arg(profile));
|
ui->cbProfiles->setCurrentText(tr("Profile: %1").arg(profile));
|
||||||
#else
|
#else
|
||||||
|
@ -530,7 +544,8 @@ void OptionsDialog::setupPictureSettings()
|
||||||
|
|
||||||
// Quality Settings
|
// Quality Settings
|
||||||
customQuality = settings->value("CustomQuality", defaultQuality).toInt();
|
customQuality = settings->value("CustomQuality", defaultQuality).toInt();
|
||||||
if (customQuality < 1 || customQuality > 100) {
|
if (customQuality < 1 || customQuality > 100)
|
||||||
|
{
|
||||||
customQuality = 100;
|
customQuality = 100;
|
||||||
}
|
}
|
||||||
ui->hsPicQuality->setValue(customQuality);
|
ui->hsPicQuality->setValue(customQuality);
|
||||||
|
@ -538,34 +553,42 @@ void OptionsDialog::setupPictureSettings()
|
||||||
|
|
||||||
// Size Settings
|
// Size Settings
|
||||||
cusExportSize = settings->value("CustomSize", defExportSize).toSize();
|
cusExportSize = settings->value("CustomSize", defExportSize).toSize();
|
||||||
if (cusExportSize.width() > 3840) {
|
if (cusExportSize.width() > 3840)
|
||||||
|
{
|
||||||
cusExportSize.setWidth(3840);
|
cusExportSize.setWidth(3840);
|
||||||
}
|
}
|
||||||
else if (cusExportSize.height() > 2160) {
|
else if (cusExportSize.height() > 2160)
|
||||||
|
{
|
||||||
cusExportSize.setHeight(2160);
|
cusExportSize.setHeight(2160);
|
||||||
}
|
}
|
||||||
if (cusExportSize.width() < 1) {
|
if (cusExportSize.width() < 1)
|
||||||
|
{
|
||||||
cusExportSize.setWidth(1);
|
cusExportSize.setWidth(1);
|
||||||
}
|
}
|
||||||
else if (cusExportSize.height() < 1) {
|
else if (cusExportSize.height() < 1)
|
||||||
|
{
|
||||||
cusExportSize.setHeight(1);
|
cusExportSize.setHeight(1);
|
||||||
}
|
}
|
||||||
ui->sbPicExportWidth->setValue(cusExportSize.width());
|
ui->sbPicExportWidth->setValue(cusExportSize.width());
|
||||||
ui->sbPicExportHeight->setValue(cusExportSize.height());
|
ui->sbPicExportHeight->setValue(cusExportSize.height());
|
||||||
|
|
||||||
QString sizeMode = settings->value("ExportSizeMode", "Default").toString();
|
QString sizeMode = settings->value("ExportSizeMode", "Default").toString();
|
||||||
if (sizeMode == "Desktop") {
|
if (sizeMode == "Desktop")
|
||||||
|
{
|
||||||
ui->rbPicDesktopRes->setChecked(true);
|
ui->rbPicDesktopRes->setChecked(true);
|
||||||
}
|
}
|
||||||
else if (sizeMode == "Custom") {
|
else if (sizeMode == "Custom")
|
||||||
|
{
|
||||||
ui->rbPicCustomRes->setChecked(true);
|
ui->rbPicCustomRes->setChecked(true);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->rbPicDefaultRes->setChecked(true);
|
ui->rbPicDefaultRes->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
aspectRatio = (Qt::AspectRatioMode)settings->value("AspectRatio", Qt::KeepAspectRatio).toInt();
|
aspectRatio = (Qt::AspectRatioMode)settings->value("AspectRatio", Qt::KeepAspectRatio).toInt();
|
||||||
if (aspectRatio == Qt::IgnoreAspectRatio) {
|
if (aspectRatio == Qt::IgnoreAspectRatio)
|
||||||
|
{
|
||||||
ui->cbIgnoreAspectRatio->setChecked(true);
|
ui->cbIgnoreAspectRatio->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,14 +607,17 @@ void OptionsDialog::setupStatisticsSettings()
|
||||||
ui->cbUsageData->setChecked(settings->value("PushUsageData", false).toBool());
|
ui->cbUsageData->setChecked(settings->value("PushUsageData", false).toBool());
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
if (Telemetry->isStateForced()) {
|
if (Telemetry->isStateForced())
|
||||||
|
{
|
||||||
ui->cbParticipateStats->setEnabled(false);
|
ui->cbParticipateStats->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Telemetry->isRegistered()) {
|
if (Telemetry->isRegistered())
|
||||||
|
{
|
||||||
ui->labParticipationID->setText(tr("Participation ID: %1").arg(Telemetry->getRegisteredID()));
|
ui->labParticipationID->setText(tr("Participation ID: %1").arg(Telemetry->getRegisteredID()));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->labParticipationID->setText(tr("Participation ID: %1").arg(tr("Not registered")));
|
ui->labParticipationID->setText(tr("Participation ID: %1").arg(tr("Not registered")));
|
||||||
ui->cmdCopyStatsID->setVisible(false);
|
ui->cmdCopyStatsID->setVisible(false);
|
||||||
}
|
}
|
||||||
|
@ -605,49 +631,62 @@ void OptionsDialog::setupWindowsGameSettings()
|
||||||
#ifdef GTA5SYNC_GAME
|
#ifdef GTA5SYNC_GAME
|
||||||
GameVersion gameVersion = AppEnv::getGameVersion();
|
GameVersion gameVersion = AppEnv::getGameVersion();
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
if (gameVersion != GameVersion::NoVersion) {
|
if (gameVersion != GameVersion::NoVersion)
|
||||||
if (gameVersion == GameVersion::SocialClubVersion) {
|
{
|
||||||
|
if (gameVersion == GameVersion::SocialClubVersion)
|
||||||
|
{
|
||||||
ui->gbSteam->setDisabled(true);
|
ui->gbSteam->setDisabled(true);
|
||||||
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
||||||
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No"))));
|
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No"))));
|
||||||
if (AppEnv::getGameLanguage(GameVersion::SocialClubVersion) != GameLanguage::Undefined) {
|
if (AppEnv::getGameLanguage(GameVersion::SocialClubVersion) != GameLanguage::Undefined)
|
||||||
|
{
|
||||||
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SocialClubVersion))).nativeLanguageName()));
|
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SocialClubVersion))).nativeLanguageName()));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(tr("OS defined")));
|
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(tr("OS defined")));
|
||||||
}
|
}
|
||||||
ui->labSteamLanguage->setVisible(false);
|
ui->labSteamLanguage->setVisible(false);
|
||||||
}
|
}
|
||||||
else if (gameVersion == GameVersion::SteamVersion) {
|
else if (gameVersion == GameVersion::SteamVersion)
|
||||||
|
{
|
||||||
ui->gbSocialClub->setDisabled(true);
|
ui->gbSocialClub->setDisabled(true);
|
||||||
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No"))));
|
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No"))));
|
||||||
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
||||||
ui->labSocialClubLanguage->setVisible(false);
|
ui->labSocialClubLanguage->setVisible(false);
|
||||||
if (AppEnv::getGameLanguage(GameVersion::SteamVersion) != GameLanguage::Undefined) {
|
if (AppEnv::getGameLanguage(GameVersion::SteamVersion) != GameLanguage::Undefined)
|
||||||
|
{
|
||||||
ui->labSteamLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SteamVersion))).nativeLanguageName()));
|
ui->labSteamLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SteamVersion))).nativeLanguageName()));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->labSteamLanguage->setText(tr("Language: %1").arg(tr("Steam defined")));
|
ui->labSteamLanguage->setText(tr("Language: %1").arg(tr("Steam defined")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
||||||
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
|
||||||
if (AppEnv::getGameLanguage(GameVersion::SocialClubVersion) != GameLanguage::Undefined) {
|
if (AppEnv::getGameLanguage(GameVersion::SocialClubVersion) != GameLanguage::Undefined)
|
||||||
|
{
|
||||||
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SocialClubVersion))).nativeLanguageName()));
|
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SocialClubVersion))).nativeLanguageName()));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(tr("OS defined")));
|
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(tr("OS defined")));
|
||||||
}
|
}
|
||||||
if (AppEnv::getGameLanguage(GameVersion::SteamVersion) != GameLanguage::Undefined) {
|
if (AppEnv::getGameLanguage(GameVersion::SteamVersion) != GameLanguage::Undefined)
|
||||||
|
{
|
||||||
ui->labSteamLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SteamVersion))).nativeLanguageName()));
|
ui->labSteamLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SteamVersion))).nativeLanguageName()));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->labSteamLanguage->setText(tr("Language: %1").arg(tr("Steam defined")));
|
ui->labSteamLanguage->setText(tr("Language: %1").arg(tr("Steam defined")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabGame));
|
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabGame));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -660,10 +699,12 @@ void OptionsDialog::setupWindowsGameSettings()
|
||||||
|
|
||||||
void OptionsDialog::on_cbIgnoreAspectRatio_toggled(bool checked)
|
void OptionsDialog::on_cbIgnoreAspectRatio_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked)
|
||||||
|
{
|
||||||
aspectRatio = Qt::IgnoreAspectRatio;
|
aspectRatio = Qt::IgnoreAspectRatio;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
aspectRatio = Qt::KeepAspectRatio;
|
aspectRatio = Qt::KeepAspectRatio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -675,7 +716,8 @@ void OptionsDialog::setupCustomGTAFolder()
|
||||||
settings->beginGroup("dir");
|
settings->beginGroup("dir");
|
||||||
currentCFolder = settings->value("dir", "").toString();
|
currentCFolder = settings->value("dir", "").toString();
|
||||||
currentFFolder = settings->value("force", false).toBool();
|
currentFFolder = settings->value("force", false).toBool();
|
||||||
if (currentCFolder == "" && ok) {
|
if (currentCFolder == "" && ok)
|
||||||
|
{
|
||||||
currentCFolder = defaultGameFolder;
|
currentCFolder = defaultGameFolder;
|
||||||
}
|
}
|
||||||
ui->txtFolder->setText(currentCFolder);
|
ui->txtFolder->setText(currentCFolder);
|
||||||
|
@ -703,8 +745,9 @@ void OptionsDialog::setupSnapmaticPictureViewer()
|
||||||
|
|
||||||
void OptionsDialog::on_cmdExploreFolder_clicked()
|
void OptionsDialog::on_cmdExploreFolder_clicked()
|
||||||
{
|
{
|
||||||
const QString GTAV_Folder = QFileDialog::getExistingDirectory(this, UserInterface::tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly);
|
QString GTAV_Folder = QFileDialog::getExistingDirectory(this, UserInterface::tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly);
|
||||||
if (QDir(GTAV_Folder).exists()) {
|
if (QFileInfo(GTAV_Folder).exists())
|
||||||
|
{
|
||||||
ui->txtFolder->setText(GTAV_Folder);
|
ui->txtFolder->setText(GTAV_Folder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -38,15 +38,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050200
|
||||||
#include "dwmapi.h"
|
#include <QtWinExtras/QtWin>
|
||||||
|
#include <QtWinExtras/QWinEvent>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
#include <QStyleFactory>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
@ -66,7 +63,6 @@
|
||||||
#include <QPicture>
|
#include <QPicture>
|
||||||
#include <QBitmap>
|
#include <QBitmap>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QTimer>
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
@ -127,20 +123,10 @@ PictureDialog::PictureDialog(bool primaryWindow, ProfileDatabase *profileDB, Cre
|
||||||
void PictureDialog::setupPictureDialog()
|
void PictureDialog::setupPictureDialog()
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
// Set Window Flags
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
setWindowFlag(Qt::CustomizeWindowHint, true);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::CustomizeWindowHint);
|
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::CustomizeWindowHint);
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
// for stupid Window Manager like GNOME
|
// for stupid Window Manager (GNOME 3 should feel triggered)
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::Dialog, false);
|
|
||||||
setWindowFlag(Qt::Window, true);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::Dialog^Qt::Window);
|
setWindowFlags(windowFlags()^Qt::Dialog^Qt::Window);
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Setup User Interface
|
// Setup User Interface
|
||||||
|
@ -157,16 +143,18 @@ void PictureDialog::setupPictureDialog()
|
||||||
crewStr = "";
|
crewStr = "";
|
||||||
|
|
||||||
// Get Snapmatic Resolution
|
// Get Snapmatic Resolution
|
||||||
const QSize snapmaticResolution = SnapmaticPicture::getSnapmaticResolution();
|
QSize snapmaticResolution = SnapmaticPicture::getSnapmaticResolution();
|
||||||
|
|
||||||
// Avatar area
|
// Avatar area
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
qreal screenRatio = AppEnv::screenRatio();
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
qreal screenRatioPR = AppEnv::screenRatioPR();
|
||||||
if (screenRatio != 1 || screenRatioPR != 1) {
|
if (screenRatio != 1 || screenRatioPR != 1)
|
||||||
avatarAreaPicture = QImage(AppEnv::getImagesFolder() % "/avatararea.png").scaledToHeight(snapmaticResolution.height() * screenRatio * screenRatioPR, Qt::FastTransformation);
|
{
|
||||||
|
avatarAreaPicture = QImage(":/img/avatararea.png").scaledToHeight(snapmaticResolution.height() * screenRatio * screenRatioPR, Qt::FastTransformation);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
avatarAreaPicture = QImage(AppEnv::getImagesFolder() % "/avatararea.png");
|
{
|
||||||
|
avatarAreaPicture = QImage(":/img/avatararea.png");
|
||||||
}
|
}
|
||||||
avatarLocX = 145;
|
avatarLocX = 145;
|
||||||
avatarLocY = 66;
|
avatarLocY = 66;
|
||||||
|
@ -197,15 +185,21 @@ void PictureDialog::setupPictureDialog()
|
||||||
// Global map
|
// Global map
|
||||||
globalMap = GlobalString::getGlobalMap();
|
globalMap = GlobalString::getGlobalMap();
|
||||||
|
|
||||||
|
// Event connects
|
||||||
|
connect(ui->labJSON, SIGNAL(resized(QSize)), this, SLOT(adaptNewDialogSize(QSize)));
|
||||||
|
|
||||||
// Set Icon for Close Button
|
// Set Icon for Close Button
|
||||||
if (QIcon::hasThemeIcon("dialog-close")) {
|
if (QIcon::hasThemeIcon("dialog-close"))
|
||||||
|
{
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
|
ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-close")) {
|
else if (QIcon::hasThemeIcon("gtk-close"))
|
||||||
|
{
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
|
ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
|
||||||
}
|
}
|
||||||
|
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
|
// installEventFilter(ui->labPicture);
|
||||||
|
|
||||||
// DPI calculation
|
// DPI calculation
|
||||||
ui->hlButtons->setSpacing(6 * screenRatio);
|
ui->hlButtons->setSpacing(6 * screenRatio);
|
||||||
|
@ -214,13 +208,38 @@ void PictureDialog::setupPictureDialog()
|
||||||
ui->jsonLayout->setContentsMargins(4 * screenRatio, 10 * screenRatio, 4 * screenRatio, 4 * screenRatio);
|
ui->jsonLayout->setContentsMargins(4 * screenRatio, 10 * screenRatio, 4 * screenRatio, 4 * screenRatio);
|
||||||
|
|
||||||
// Pre-adapt window for DPI
|
// Pre-adapt window for DPI
|
||||||
const QSize windowSize(snapmaticResolution.width() * screenRatio, snapmaticResolution.height() * screenRatio);
|
setFixedWidth(snapmaticResolution.width() * screenRatio);
|
||||||
setMinimumSize(windowSize);
|
setFixedHeight(snapmaticResolution.height() * screenRatio);
|
||||||
setMaximumSize(windowSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PictureDialog::~PictureDialog()
|
PictureDialog::~PictureDialog()
|
||||||
{
|
{
|
||||||
|
//#ifdef Q_OS_WIN
|
||||||
|
//#if QT_VERSION >= 0x050200
|
||||||
|
// if (naviEnabled)
|
||||||
|
// {
|
||||||
|
// for (QObject *obj : layout()->menuBar()->children())
|
||||||
|
// {
|
||||||
|
// delete obj;
|
||||||
|
// }
|
||||||
|
// delete layout()->menuBar();
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
|
//#else
|
||||||
|
// if (naviEnabled)
|
||||||
|
// {
|
||||||
|
// for (QObject *obj : layout()->menuBar()->children())
|
||||||
|
// {
|
||||||
|
// delete obj;
|
||||||
|
// }
|
||||||
|
// delete layout()->menuBar();
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
|
// for (QObject *obj : manageMenu->children())
|
||||||
|
// {
|
||||||
|
// delete obj;
|
||||||
|
// }
|
||||||
|
// delete manageMenu;
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,11 +247,24 @@ void PictureDialog::closeEvent(QCloseEvent *ev)
|
||||||
{
|
{
|
||||||
Q_UNUSED(ev)
|
Q_UNUSED(ev)
|
||||||
if (primaryWindow)
|
if (primaryWindow)
|
||||||
|
{
|
||||||
emit endDatabaseThread();
|
emit endDatabaseThread();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PictureDialog::addPreviousNextButtons()
|
void PictureDialog::addPreviousNextButtons()
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#if QT_VERSION >= 0x050200
|
||||||
|
QToolBar *uiToolbar = new QToolBar("Picture Toolbar", this);
|
||||||
|
uiToolbar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
|
uiToolbar->setObjectName("UiToolbar");
|
||||||
|
uiToolbar->addAction(QIcon(":/img/back.svgz"), "", this, SLOT(previousPictureRequestedSlot()));
|
||||||
|
uiToolbar->addAction(QIcon(":/img/next.svgz"), "", this, SLOT(nextPictureRequestedSlot()));
|
||||||
|
layout()->setMenuBar(uiToolbar);
|
||||||
|
naviEnabled = true;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
QToolBar *uiToolbar = new QToolBar("Picture Toolbar", this);
|
QToolBar *uiToolbar = new QToolBar("Picture Toolbar", this);
|
||||||
#if QT_VERSION < 0x050600
|
#if QT_VERSION < 0x050600
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
qreal screenRatio = AppEnv::screenRatio();
|
||||||
|
@ -243,83 +275,60 @@ void PictureDialog::addPreviousNextButtons()
|
||||||
#endif
|
#endif
|
||||||
uiToolbar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
uiToolbar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
uiToolbar->setObjectName("UiToolbar");
|
uiToolbar->setObjectName("UiToolbar");
|
||||||
uiToolbar->addAction(QIcon(AppEnv::getImagesFolder() % "/back.svgz"), "", this, SLOT(previousPictureRequestedSlot()));
|
uiToolbar->addAction(QIcon(":/img/back.svgz"), "", this, SLOT(previousPictureRequestedSlot()));
|
||||||
uiToolbar->addAction(QIcon(AppEnv::getImagesFolder() % "/next.svgz"), "", this, SLOT(nextPictureRequestedSlot()));
|
uiToolbar->addAction(QIcon(":/img/next.svgz"), "", this, SLOT(nextPictureRequestedSlot()));
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
uiToolbar->setStyle(QStyleFactory::create("Fusion"));
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
layout()->setMenuBar(uiToolbar);
|
layout()->setMenuBar(uiToolbar);
|
||||||
naviEnabled = true;
|
naviEnabled = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PictureDialog::adaptDialogSize()
|
void PictureDialog::adaptNewDialogSize(QSize newLabelSize)
|
||||||
{
|
{
|
||||||
int newDialogHeight = (SnapmaticPicture::getSnapmaticResolution().height() * AppEnv::screenRatio()) + ui->jsonFrame->heightForWidth(width());
|
Q_UNUSED(newLabelSize)
|
||||||
if (naviEnabled)
|
int newDialogHeight = SnapmaticPicture::getSnapmaticResolution().height() * AppEnv::screenRatio();
|
||||||
newDialogHeight = newDialogHeight + layout()->menuBar()->height();
|
newDialogHeight = newDialogHeight + ui->jsonFrame->height();
|
||||||
const QSize windowSize(width(), newDialogHeight);
|
if (naviEnabled) newDialogHeight = newDialogHeight + layout()->menuBar()->height();
|
||||||
setMinimumSize(windowSize);
|
setMaximumSize(width(), newDialogHeight);
|
||||||
setMaximumSize(windowSize);
|
setMinimumSize(width(), newDialogHeight);
|
||||||
|
setFixedHeight(newDialogHeight);
|
||||||
|
ui->labPicture->updateGeometry();
|
||||||
|
ui->jsonFrame->updateGeometry();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PictureDialog::styliseDialog()
|
void PictureDialog::styliseDialog()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
BOOL isEnabled;
|
#if QT_VERSION >= 0x050200
|
||||||
DwmIsCompositionEnabled(&isEnabled);
|
if (QtWin::isCompositionEnabled()) {
|
||||||
if (isEnabled == TRUE) {
|
QPalette palette;
|
||||||
MARGINS margins = {0, 0, qRound(layout()->menuBar()->height() * AppEnv::screenRatioPR()), 0};
|
QtWin::extendFrameIntoClientArea(this, 0, qRound(layout()->menuBar()->height() * AppEnv::screenRatioPR()), 0, 0);
|
||||||
HRESULT hr = S_OK;
|
ui->jsonFrame->setStyleSheet(QString("QFrame{background:%1;}").arg(palette.window().color().name()));
|
||||||
hr = DwmExtendFrameIntoClientArea(reinterpret_cast<HWND>(winId()), &margins);
|
setStyleSheet("PictureDialog{background:transparent;}");
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
setStyleSheet("PictureDialog{background:transparent}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MARGINS margins = {0, 0, 0, 0};
|
QPalette palette;
|
||||||
DwmExtendFrameIntoClientArea(reinterpret_cast<HWND>(winId()), &margins);
|
QtWin::resetExtendedFrame(this);
|
||||||
bool colorOk = false;
|
ui->jsonFrame->setStyleSheet(QString("QFrame{background:%1;}").arg(palette.window().color().name()));
|
||||||
QSettings dwmRegistry("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\DWM", QSettings::NativeFormat);
|
setStyleSheet(QString("PictureDialog{background:%1;}").arg(QtWin::realColorizationColor().name()));
|
||||||
QRgb color = dwmRegistry.value("ColorizationColor").toUInt(&colorOk);
|
|
||||||
if (colorOk) {
|
|
||||||
setStyleSheet(QString("PictureDialog{background:%1}").arg(QColor::fromRgba(color).name()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
BOOL isOpaqueBlend;
|
|
||||||
DWORD colorization;
|
|
||||||
hr = DwmGetColorizationColor(&colorization, &isOpaqueBlend);
|
|
||||||
if (SUCCEEDED(hr) && isOpaqueBlend == FALSE) {
|
|
||||||
color = colorization;
|
|
||||||
setStyleSheet(QString("PictureDialog{background:%1}").arg(QColor::fromRgba(color).name()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setStyleSheet("PictureDialog{background:palette(window)}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ui->jsonFrame->setStyleSheet("QFrame{background:palette(window)}");
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
bool PictureDialog::event(QEvent *event)
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
bool PictureDialog::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
|
||||||
#else
|
|
||||||
bool PictureDialog::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
MSG *msg = reinterpret_cast<MSG*>(message);
|
#ifdef Q_OS_WIN
|
||||||
if (msg->message == 0x031e || msg->message == 0x0320) {
|
#if QT_VERSION >= 0x050200
|
||||||
styliseDialog();
|
if (naviEnabled) {
|
||||||
|
if (event->type() == QWinEvent::CompositionChange || event->type() == QWinEvent::ColorizationChange) {
|
||||||
|
styliseDialog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return QWidget::nativeEvent(eventType, message, result);
|
#endif
|
||||||
|
#endif
|
||||||
|
return QDialog::event(event);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PictureDialog::nextPictureRequestedSlot()
|
void PictureDialog::nextPictureRequestedSlot()
|
||||||
{
|
{
|
||||||
|
@ -334,10 +343,12 @@ void PictureDialog::previousPictureRequestedSlot()
|
||||||
bool PictureDialog::eventFilter(QObject *obj, QEvent *ev)
|
bool PictureDialog::eventFilter(QObject *obj, QEvent *ev)
|
||||||
{
|
{
|
||||||
bool returnValue = false;
|
bool returnValue = false;
|
||||||
if (obj == this || obj == ui->labPicture) {
|
if (obj == this || obj == ui->labPicture)
|
||||||
if (ev->type() == QEvent::KeyPress) {
|
{
|
||||||
|
if (ev->type() == QEvent::KeyPress)
|
||||||
|
{
|
||||||
QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(ev);
|
QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(ev);
|
||||||
switch (keyEvent->key()) {
|
switch (keyEvent->key()){
|
||||||
case Qt::Key_Left:
|
case Qt::Key_Left:
|
||||||
emit previousPictureRequested();
|
emit previousPictureRequested();
|
||||||
returnValue = true;
|
returnValue = true;
|
||||||
|
@ -347,21 +358,25 @@ bool PictureDialog::eventFilter(QObject *obj, QEvent *ev)
|
||||||
returnValue = true;
|
returnValue = true;
|
||||||
break;
|
break;
|
||||||
case Qt::Key_1:
|
case Qt::Key_1:
|
||||||
if (previewMode) {
|
if (previewMode)
|
||||||
|
{
|
||||||
previewMode = false;
|
previewMode = false;
|
||||||
renderPicture();
|
renderPicture();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
previewMode = true;
|
previewMode = true;
|
||||||
renderPicture();
|
renderPicture();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_2:
|
case Qt::Key_2:
|
||||||
if (overlayEnabled) {
|
if (overlayEnabled)
|
||||||
|
{
|
||||||
overlayEnabled = false;
|
overlayEnabled = false;
|
||||||
if (!previewMode) renderPicture();
|
if (!previewMode) renderPicture();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
overlayEnabled = true;
|
overlayEnabled = true;
|
||||||
if (!previewMode) renderPicture();
|
if (!previewMode) renderPicture();
|
||||||
}
|
}
|
||||||
|
@ -387,30 +402,40 @@ bool PictureDialog::eventFilter(QObject *obj, QEvent *ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050200
|
||||||
if (obj != ui->labPicture && naviEnabled) {
|
if (obj != ui->labPicture && naviEnabled)
|
||||||
if (ev->type() == QEvent::MouseButtonPress) {
|
{
|
||||||
|
if (ev->type() == QEvent::MouseButtonPress)
|
||||||
|
{
|
||||||
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(ev);
|
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(ev);
|
||||||
if (mouseEvent->pos().y() <= layout()->menuBar()->height()) {
|
if (mouseEvent->pos().y() <= layout()->menuBar()->height())
|
||||||
if (mouseEvent->button() == Qt::LeftButton) {
|
{
|
||||||
|
if (mouseEvent->button() == Qt::LeftButton)
|
||||||
|
{
|
||||||
dragPosition = mouseEvent->pos();
|
dragPosition = mouseEvent->pos();
|
||||||
dragStart = true;
|
dragStart = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ev->type() == QEvent::MouseButtonRelease) {
|
if (ev->type() == QEvent::MouseButtonRelease)
|
||||||
|
{
|
||||||
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(ev);
|
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(ev);
|
||||||
if (mouseEvent->pos().y() <= layout()->menuBar()->height()) {
|
if (mouseEvent->pos().y() <= layout()->menuBar()->height())
|
||||||
if (mouseEvent->button() == Qt::LeftButton) {
|
{
|
||||||
|
if (mouseEvent->button() == Qt::LeftButton)
|
||||||
|
{
|
||||||
dragStart = false;
|
dragStart = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dragStart && ev->type() == QEvent::MouseMove) {
|
if (ev->type() == QEvent::MouseMove && dragStart)
|
||||||
|
{
|
||||||
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(ev);
|
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(ev);
|
||||||
if (mouseEvent->pos().y() <= layout()->menuBar()->height()) {
|
if (mouseEvent->pos().y() <= layout()->menuBar()->height())
|
||||||
if (mouseEvent->buttons() & Qt::LeftButton) {
|
{
|
||||||
const QPoint diff = mouseEvent->pos() - dragPosition;
|
if (mouseEvent->buttons() & Qt::LeftButton)
|
||||||
|
{
|
||||||
|
QPoint diff = mouseEvent->pos() - dragPosition;
|
||||||
move(QPoint(pos() + diff));
|
move(QPoint(pos() + diff));
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
@ -468,12 +493,14 @@ void PictureDialog::renderOverlayPicture()
|
||||||
QRect overlaySpace = fontMetrics.boundingRect(preferedRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip | Qt::TextWordWrap, overlayText);
|
QRect overlaySpace = fontMetrics.boundingRect(preferedRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip | Qt::TextWordWrap, overlayText);
|
||||||
|
|
||||||
int hOverlay = Qt::AlignTop;
|
int hOverlay = Qt::AlignTop;
|
||||||
if (overlaySpace.height() < 74 * screenRatio * screenRatioPR) {
|
if (overlaySpace.height() < 74 * screenRatio * screenRatioPR)
|
||||||
|
{
|
||||||
hOverlay = Qt::AlignVCenter;
|
hOverlay = Qt::AlignVCenter;
|
||||||
preferedRect.setHeight(71 * screenRatio * screenRatioPR);
|
preferedRect.setHeight(71 * screenRatio * screenRatioPR);
|
||||||
overlaySpace.setHeight(80 * screenRatio * screenRatioPR);
|
overlaySpace.setHeight(80 * screenRatio * screenRatioPR);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
overlaySpace.setHeight(overlaySpace.height() + 6 * screenRatio * screenRatioPR);
|
overlaySpace.setHeight(overlaySpace.height() + 6 * screenRatio * screenRatioPR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,10 +513,12 @@ void PictureDialog::renderOverlayPicture()
|
||||||
overlayPainter.drawText(preferedRect, Qt::AlignLeft | hOverlay | Qt::TextDontClip | Qt::TextWordWrap, overlayText);
|
overlayPainter.drawText(preferedRect, Qt::AlignLeft | hOverlay | Qt::TextDontClip | Qt::TextWordWrap, overlayText);
|
||||||
overlayPainter.end();
|
overlayPainter.end();
|
||||||
|
|
||||||
if (overlaySpace.width() < 194 * screenRatio * screenRatioPR) {
|
if (overlaySpace.width() < 194 * screenRatio * screenRatioPR)
|
||||||
|
{
|
||||||
overlaySpace.setWidth(200 * screenRatio * screenRatioPR);
|
overlaySpace.setWidth(200 * screenRatio * screenRatioPR);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
overlaySpace.setWidth(overlaySpace.width() + 6 * screenRatio * screenRatioPR);
|
overlaySpace.setWidth(overlaySpace.width() + 6 * screenRatio * screenRatioPR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,11 +562,10 @@ void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, bool readOk,
|
||||||
}
|
}
|
||||||
setWindowTitle(windowTitleStr.arg(picTitl));
|
setWindowTitle(windowTitleStr.arg(picTitl));
|
||||||
ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created));
|
ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created));
|
||||||
QTimer::singleShot(0, this, SLOT(adaptDialogSize()));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ui->labJSON->setText(jsonDrawString.arg("0", "0", "0", tr("No Players"), tr("No Crew"), tr("Unknown Location")));
|
ui->labJSON->setText(jsonDrawString.arg("0", "0", "0", tr("No Players"), tr("No Crew"), tr("Unknown Location")));
|
||||||
QTimer::singleShot(0, this, SLOT(adaptDialogSize()));
|
// QMessageBox::warning(this, tr("Snapmatic Picture Viewer"), tr("Failed at %1").arg(picture->getLastStep()));
|
||||||
}
|
}
|
||||||
QObject::connect(smpic, SIGNAL(updated()), this, SLOT(updated()));
|
QObject::connect(smpic, SIGNAL(updated()), this, SLOT(updated()));
|
||||||
QObject::connect(smpic, SIGNAL(customSignal(QString)), this, SLOT(customSignal(QString)));
|
QObject::connect(smpic, SIGNAL(customSignal(QString)), this, SLOT(customSignal(QString)));
|
||||||
|
@ -605,19 +633,19 @@ void PictureDialog::crewNameUpdated()
|
||||||
{
|
{
|
||||||
SnapmaticPicture *picture = smpic; // used by macro
|
SnapmaticPicture *picture = smpic; // used by macro
|
||||||
QString crewIDStr = crewID;
|
QString crewIDStr = crewID;
|
||||||
if (crewIDStr == crewStr) {
|
if (crewIDStr == crewStr)
|
||||||
|
{
|
||||||
crewStr = crewDB->getCrewName(crewIDStr);
|
crewStr = crewDB->getCrewName(crewIDStr);
|
||||||
ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created));
|
ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created));
|
||||||
QTimer::singleShot(0, this, SLOT(adaptDialogSize()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PictureDialog::playerNameUpdated()
|
void PictureDialog::playerNameUpdated()
|
||||||
{
|
{
|
||||||
SnapmaticPicture *picture = smpic; // used by macro
|
SnapmaticPicture *picture = smpic; // used by macro
|
||||||
if (plyrsList.count() >= 1) {
|
if (plyrsList.count() >= 1)
|
||||||
|
{
|
||||||
ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created));
|
ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created));
|
||||||
QTimer::singleShot(0, this, SLOT(adaptDialogSize()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,7 +653,8 @@ QString PictureDialog::generateCrewString()
|
||||||
{
|
{
|
||||||
SnapmaticPicture *picture = smpic; // used by macro
|
SnapmaticPicture *picture = smpic; // used by macro
|
||||||
const QString crewIDStr = crewID; // save operation time
|
const QString crewIDStr = crewID; // save operation time
|
||||||
if (crewIDStr != "0" && !crewIDStr.isEmpty()) {
|
if (crewIDStr != "0" && !crewIDStr.isEmpty())
|
||||||
|
{
|
||||||
if (crewIDStr != crewStr) {
|
if (crewIDStr != crewStr) {
|
||||||
return QString("<a href=\"https://socialclub.rockstargames.com/crew/" % QString(crewStr).replace(" ", "_") % "/" % crewIDStr % "\">" % crewStr % "</a>");
|
return QString("<a href=\"https://socialclub.rockstargames.com/crew/" % QString(crewStr).replace(" ", "_") % "/" % crewIDStr % "\">" % crewStr % "</a>");
|
||||||
}
|
}
|
||||||
|
@ -689,10 +718,7 @@ void PictureDialog::on_labPicture_mouseDoubleClicked(Qt::MouseButton button)
|
||||||
#endif
|
#endif
|
||||||
PictureWidget *pictureWidget = new PictureWidget(this); // Work!
|
PictureWidget *pictureWidget = new PictureWidget(this); // Work!
|
||||||
pictureWidget->setObjectName("PictureWidget");
|
pictureWidget->setObjectName("PictureWidget");
|
||||||
#if QT_VERSION >= 0x050900
|
#if QT_VERSION >= 0x050600
|
||||||
pictureWidget->setWindowFlag(Qt::FramelessWindowHint, true);
|
|
||||||
pictureWidget->setWindowFlag(Qt::MaximizeUsingFullscreenGeometryHint, true);
|
|
||||||
#elif QT_VERSION >= 0x050600
|
|
||||||
pictureWidget->setWindowFlags(pictureWidget->windowFlags()^Qt::FramelessWindowHint^Qt::MaximizeUsingFullscreenGeometryHint);
|
pictureWidget->setWindowFlags(pictureWidget->windowFlags()^Qt::FramelessWindowHint^Qt::MaximizeUsingFullscreenGeometryHint);
|
||||||
#else
|
#else
|
||||||
pictureWidget->setWindowFlags(pictureWidget->windowFlags()^Qt::FramelessWindowHint);
|
pictureWidget->setWindowFlags(pictureWidget->windowFlags()^Qt::FramelessWindowHint);
|
||||||
|
@ -709,6 +735,11 @@ void PictureDialog::on_labPicture_mouseDoubleClicked(Qt::MouseButton button)
|
||||||
|
|
||||||
pictureWidget->move(desktopRect.x(), desktopRect.y());
|
pictureWidget->move(desktopRect.x(), desktopRect.y());
|
||||||
pictureWidget->resize(desktopRect.width(), desktopRect.height());
|
pictureWidget->resize(desktopRect.width(), desktopRect.height());
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#if QT_VERSION >= 0x050200
|
||||||
|
QtWin::markFullscreenWindow(pictureWidget, true);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
pictureWidget->showFullScreen();
|
pictureWidget->showFullScreen();
|
||||||
pictureWidget->setFocus();
|
pictureWidget->setFocus();
|
||||||
pictureWidget->raise();
|
pictureWidget->raise();
|
||||||
|
@ -737,15 +768,15 @@ int PictureDialog::getIndex()
|
||||||
void PictureDialog::openPreviewMap()
|
void PictureDialog::openPreviewMap()
|
||||||
{
|
{
|
||||||
SnapmaticPicture *picture = smpic;
|
SnapmaticPicture *picture = smpic;
|
||||||
SnapmaticProperties currentProperties = picture->getSnapmaticProperties();
|
|
||||||
MapLocationDialog *mapLocDialog;
|
MapLocationDialog *mapLocDialog;
|
||||||
if (rqFullscreen && fullscreenWidget != nullptr) {
|
if (rqFullscreen && fullscreenWidget != nullptr)
|
||||||
mapLocDialog = new MapLocationDialog(currentProperties.location.x, currentProperties.location.y, fullscreenWidget);
|
{
|
||||||
|
mapLocDialog = new MapLocationDialog(picture->getSnapmaticProperties().location.x, picture->getSnapmaticProperties().location.y, fullscreenWidget);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
mapLocDialog = new MapLocationDialog(currentProperties.location.x, currentProperties.location.y, this);
|
{
|
||||||
|
mapLocDialog = new MapLocationDialog(picture->getSnapmaticProperties().location.x, picture->getSnapmaticProperties().location.y, this);
|
||||||
}
|
}
|
||||||
mapLocDialog->setCayoPerico(currentProperties.location.isCayoPerico);
|
|
||||||
mapLocDialog->setWindowIcon(windowIcon());
|
mapLocDialog->setWindowIcon(windowIcon());
|
||||||
mapLocDialog->setModal(true);
|
mapLocDialog->setModal(true);
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
|
@ -754,43 +785,45 @@ void PictureDialog::openPreviewMap()
|
||||||
mapLocDialog->showMaximized();
|
mapLocDialog->showMaximized();
|
||||||
#endif
|
#endif
|
||||||
mapLocDialog->exec();
|
mapLocDialog->exec();
|
||||||
if (mapLocDialog->propUpdated()) {
|
if (mapLocDialog->propUpdated())
|
||||||
|
{
|
||||||
// Update Snapmatic Properties
|
// Update Snapmatic Properties
|
||||||
currentProperties.location.x = mapLocDialog->getXpos();
|
SnapmaticProperties localSpJson = picture->getSnapmaticProperties();
|
||||||
currentProperties.location.y = mapLocDialog->getYpos();
|
localSpJson.location.x = mapLocDialog->getXpos();
|
||||||
currentProperties.location.z = 0;
|
localSpJson.location.y = mapLocDialog->getYpos();
|
||||||
|
localSpJson.location.z = 0;
|
||||||
|
|
||||||
// Update Snapmatic Picture
|
// Update Snapmatic Picture
|
||||||
QString currentFilePath = picture->getPictureFilePath();
|
QString currentFilePath = picture->getPictureFilePath();
|
||||||
QString originalFilePath = picture->getOriginalPictureFilePath();
|
QString originalFilePath = picture->getOriginalPictureFilePath();
|
||||||
QString backupFileName = originalFilePath % ".bak";
|
QString backupFileName = originalFilePath % ".bak";
|
||||||
if (!QFile::exists(backupFileName)) {
|
if (!QFile::exists(backupFileName))
|
||||||
|
{
|
||||||
QFile::copy(currentFilePath, backupFileName);
|
QFile::copy(currentFilePath, backupFileName);
|
||||||
}
|
}
|
||||||
SnapmaticProperties fallbackProperties = picture->getSnapmaticProperties();
|
SnapmaticProperties fallbackProperties = picture->getSnapmaticProperties();
|
||||||
picture->setSnapmaticProperties(currentProperties);
|
picture->setSnapmaticProperties(localSpJson);
|
||||||
if (!picture->exportPicture(currentFilePath)) {
|
if (!picture->exportPicture(currentFilePath))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error"));
|
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error"));
|
||||||
picture->setSnapmaticProperties(fallbackProperties);
|
picture->setSnapmaticProperties(fallbackProperties);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
updated();
|
updated();
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
#ifdef GTA5SYNC_TELEMETRY
|
||||||
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
telemetrySettings.beginGroup("Telemetry");
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
||||||
telemetrySettings.endGroup();
|
telemetrySettings.endGroup();
|
||||||
if (pushUsageData && Telemetry->canPush()) {
|
if (pushUsageData && Telemetry->canPush())
|
||||||
|
{
|
||||||
QJsonDocument jsonDocument;
|
QJsonDocument jsonDocument;
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "LocationEdited";
|
jsonObject["Type"] = "LocationEdited";
|
||||||
jsonObject["ExtraFlags"] = "Viewer";
|
jsonObject["ExtraFlags"] = "Viewer";
|
||||||
jsonObject["EditedSize"] = QString::number(picture->getContentMaxLength());
|
jsonObject["EditedSize"] = QString::number(picture->getContentMaxLength());
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
|
@ -804,10 +837,12 @@ void PictureDialog::editSnapmaticProperties()
|
||||||
{
|
{
|
||||||
SnapmaticPicture *picture = smpic;
|
SnapmaticPicture *picture = smpic;
|
||||||
SnapmaticEditor *snapmaticEditor;
|
SnapmaticEditor *snapmaticEditor;
|
||||||
if (rqFullscreen && fullscreenWidget != nullptr) {
|
if (rqFullscreen && fullscreenWidget != nullptr)
|
||||||
|
{
|
||||||
snapmaticEditor = new SnapmaticEditor(crewDB, profileDB, fullscreenWidget);
|
snapmaticEditor = new SnapmaticEditor(crewDB, profileDB, fullscreenWidget);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
snapmaticEditor = new SnapmaticEditor(crewDB, profileDB, this);
|
snapmaticEditor = new SnapmaticEditor(crewDB, profileDB, this);
|
||||||
}
|
}
|
||||||
snapmaticEditor->setWindowIcon(windowIcon());
|
snapmaticEditor->setWindowIcon(windowIcon());
|
||||||
|
@ -826,10 +861,12 @@ void PictureDialog::editSnapmaticImage()
|
||||||
{
|
{
|
||||||
QImage *currentImage = new QImage(smpic->getImage());
|
QImage *currentImage = new QImage(smpic->getImage());
|
||||||
ImportDialog *importDialog;
|
ImportDialog *importDialog;
|
||||||
if (rqFullscreen && fullscreenWidget != nullptr) {
|
if (rqFullscreen && fullscreenWidget != nullptr)
|
||||||
|
{
|
||||||
importDialog = new ImportDialog(profileName, fullscreenWidget);
|
importDialog = new ImportDialog(profileName, fullscreenWidget);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
importDialog = new ImportDialog(profileName, this);
|
importDialog = new ImportDialog(profileName, this);
|
||||||
}
|
}
|
||||||
importDialog->setWindowIcon(windowIcon());
|
importDialog->setWindowIcon(windowIcon());
|
||||||
|
@ -837,17 +874,21 @@ void PictureDialog::editSnapmaticImage()
|
||||||
importDialog->enableOverwriteMode();
|
importDialog->enableOverwriteMode();
|
||||||
importDialog->setModal(true);
|
importDialog->setModal(true);
|
||||||
importDialog->exec();
|
importDialog->exec();
|
||||||
if (importDialog->isImportAgreed()) {
|
if (importDialog->isImportAgreed())
|
||||||
|
{
|
||||||
const QByteArray previousPicture = smpic->getPictureStream();
|
const QByteArray previousPicture = smpic->getPictureStream();
|
||||||
bool success = smpic->setImage(importDialog->image(), importDialog->isUnlimitedBuffer());
|
bool success = smpic->setImage(importDialog->image());
|
||||||
if (success) {
|
if (success)
|
||||||
|
{
|
||||||
QString currentFilePath = smpic->getPictureFilePath();
|
QString currentFilePath = smpic->getPictureFilePath();
|
||||||
QString originalFilePath = smpic->getOriginalPictureFilePath();
|
QString originalFilePath = smpic->getOriginalPictureFilePath();
|
||||||
QString backupFileName = originalFilePath % ".bak";
|
QString backupFileName = originalFilePath % ".bak";
|
||||||
if (!QFile::exists(backupFileName)) {
|
if (!QFile::exists(backupFileName))
|
||||||
|
{
|
||||||
QFile::copy(currentFilePath, backupFileName);
|
QFile::copy(currentFilePath, backupFileName);
|
||||||
}
|
}
|
||||||
if (!smpic->exportPicture(currentFilePath)) {
|
if (!smpic->exportPicture(currentFilePath))
|
||||||
|
{
|
||||||
smpic->setPictureStream(previousPicture);
|
smpic->setPictureStream(previousPicture);
|
||||||
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of I/O Error"));
|
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of I/O Error"));
|
||||||
return;
|
return;
|
||||||
|
@ -858,23 +899,21 @@ void PictureDialog::editSnapmaticImage()
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
telemetrySettings.beginGroup("Telemetry");
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
||||||
telemetrySettings.endGroup();
|
telemetrySettings.endGroup();
|
||||||
if (pushUsageData && Telemetry->canPush()) {
|
if (pushUsageData && Telemetry->canPush())
|
||||||
|
{
|
||||||
QJsonDocument jsonDocument;
|
QJsonDocument jsonDocument;
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "ImageEdited";
|
jsonObject["Type"] = "ImageEdited";
|
||||||
jsonObject["ExtraFlags"] = "Viewer";
|
jsonObject["ExtraFlags"] = "Viewer";
|
||||||
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
|
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of Image Error"));
|
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of Image Error"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -886,10 +925,12 @@ void PictureDialog::editSnapmaticRawJson()
|
||||||
{
|
{
|
||||||
SnapmaticPicture *picture = smpic;
|
SnapmaticPicture *picture = smpic;
|
||||||
JsonEditorDialog *jsonEditor;
|
JsonEditorDialog *jsonEditor;
|
||||||
if (rqFullscreen && fullscreenWidget != nullptr) {
|
if (rqFullscreen && fullscreenWidget != nullptr)
|
||||||
|
{
|
||||||
jsonEditor = new JsonEditorDialog(picture, fullscreenWidget);
|
jsonEditor = new JsonEditorDialog(picture, fullscreenWidget);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
jsonEditor = new JsonEditorDialog(picture, this);
|
jsonEditor = new JsonEditorDialog(picture, this);
|
||||||
}
|
}
|
||||||
jsonEditor->setWindowIcon(windowIcon());
|
jsonEditor->setWindowIcon(windowIcon());
|
||||||
|
@ -907,21 +948,23 @@ void PictureDialog::updated()
|
||||||
{
|
{
|
||||||
SnapmaticPicture *picture = smpic; // used by macro
|
SnapmaticPicture *picture = smpic; // used by macro
|
||||||
crewStr = crewDB->getCrewName(crewID);
|
crewStr = crewDB->getCrewName(crewID);
|
||||||
if (globalMap.contains(picArea)) {
|
if (globalMap.contains(picArea))
|
||||||
|
{
|
||||||
picAreaStr = globalMap[picArea];
|
picAreaStr = globalMap[picArea];
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
picAreaStr = picArea;
|
picAreaStr = picArea;
|
||||||
}
|
}
|
||||||
setWindowTitle(windowTitleStr.arg(picTitl));
|
setWindowTitle(windowTitleStr.arg(picTitl));
|
||||||
ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created));
|
ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created));
|
||||||
QTimer::singleShot(0, this, SLOT(adaptDialogSize()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PictureDialog::customSignal(QString signal)
|
void PictureDialog::customSignal(QString signal)
|
||||||
{
|
{
|
||||||
SnapmaticPicture *picture = smpic; // used by macro
|
SnapmaticPicture *picture = smpic; // used by macro
|
||||||
if (signal == "PictureUpdated") {
|
if (signal == "PictureUpdated")
|
||||||
|
{
|
||||||
snapmaticPicture = picture->getImage();
|
snapmaticPicture = picture->getImage();
|
||||||
renderPicture();
|
renderPicture();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -54,11 +54,11 @@ public:
|
||||||
~PictureDialog();
|
~PictureDialog();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void adaptDialogSize();
|
|
||||||
void crewNameUpdated();
|
void crewNameUpdated();
|
||||||
void playerNameUpdated();
|
void playerNameUpdated();
|
||||||
void dialogNextPictureRequested();
|
void dialogNextPictureRequested();
|
||||||
void dialogPreviousPictureRequested();
|
void dialogPreviousPictureRequested();
|
||||||
|
void adaptNewDialogSize(QSize newLabelSize);
|
||||||
void exportCustomContextMenuRequested(const QPoint &pos);
|
void exportCustomContextMenuRequested(const QPoint &pos);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -89,13 +89,7 @@ protected:
|
||||||
void closeEvent(QCloseEvent *ev);
|
void closeEvent(QCloseEvent *ev);
|
||||||
bool eventFilter(QObject *obj, QEvent *ev);
|
bool eventFilter(QObject *obj, QEvent *ev);
|
||||||
void mousePressEvent(QMouseEvent *ev);
|
void mousePressEvent(QMouseEvent *ev);
|
||||||
#ifdef Q_OS_WIN
|
bool event(QEvent *event);
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result);
|
|
||||||
#elif QT_VERSION >= 0x050000
|
|
||||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString generateCrewString();
|
QString generateCrewString();
|
||||||
|
@ -126,7 +120,7 @@ private:
|
||||||
int avatarSize;
|
int avatarSize;
|
||||||
QMenu *manageMenu;
|
QMenu *manageMenu;
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050200
|
||||||
QPoint dragPosition;
|
QPoint dragPosition;
|
||||||
bool dragStart;
|
bool dragStart;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,6 +48,19 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="vsJSONUpper">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="jsonFrame">
|
<widget class="QFrame" name="jsonFrame">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,9 +18,7 @@
|
||||||
|
|
||||||
#include "PlayerListDialog.h"
|
#include "PlayerListDialog.h"
|
||||||
#include "ui_PlayerListDialog.h"
|
#include "ui_PlayerListDialog.h"
|
||||||
#include "wrapper.h"
|
|
||||||
#include "AppEnv.h"
|
#include "AppEnv.h"
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QFontMetrics>
|
#include <QFontMetrics>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
@ -33,11 +31,7 @@ PlayerListDialog::PlayerListDialog(QStringList players, ProfileDatabase *profile
|
||||||
ui(new Ui::PlayerListDialog)
|
ui(new Ui::PlayerListDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
// Set Window Flags
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
#endif
|
|
||||||
|
|
||||||
listUpdated = false;
|
listUpdated = false;
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
@ -45,32 +39,40 @@ PlayerListDialog::PlayerListDialog(QStringList players, ProfileDatabase *profile
|
||||||
ui->cmdCancel->setFocus();
|
ui->cmdCancel->setFocus();
|
||||||
|
|
||||||
// Set Icon for Apply Button
|
// Set Icon for Apply Button
|
||||||
if (QIcon::hasThemeIcon("dialog-ok-apply")) {
|
if (QIcon::hasThemeIcon("dialog-ok-apply"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok-apply"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok-apply"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("dialog-apply")) {
|
else if (QIcon::hasThemeIcon("dialog-apply"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-apply"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-apply"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-apply")) {
|
else if (QIcon::hasThemeIcon("gtk-apply"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("gtk-apply"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("gtk-apply"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("dialog-ok")) {
|
else if (QIcon::hasThemeIcon("dialog-ok"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-ok")) {
|
else if (QIcon::hasThemeIcon("gtk-ok"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Cancel Button
|
// Set Icon for Cancel Button
|
||||||
if (QIcon::hasThemeIcon("dialog-cancel")) {
|
if (QIcon::hasThemeIcon("dialog-cancel"))
|
||||||
|
{
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-cancel")) {
|
else if (QIcon::hasThemeIcon("gtk-cancel"))
|
||||||
|
{
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Manage Buttons
|
// Set Icon for Manage Buttons
|
||||||
if (QIcon::hasThemeIcon("go-previous") && QIcon::hasThemeIcon("go-next") && QIcon::hasThemeIcon("list-add")) {
|
if (QIcon::hasThemeIcon("go-previous") && QIcon::hasThemeIcon("go-next") && QIcon::hasThemeIcon("list-add"))
|
||||||
|
{
|
||||||
#if QT_VERSION < 0x050600
|
#if QT_VERSION < 0x050600
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
qreal screenRatio = AppEnv::screenRatio();
|
||||||
if (screenRatio != 1) {
|
if (screenRatio != 1) {
|
||||||
|
@ -85,7 +87,8 @@ PlayerListDialog::PlayerListDialog(QStringList players, ProfileDatabase *profile
|
||||||
ui->cmdMakeSe->setIcon(QIcon::fromTheme("go-next"));
|
ui->cmdMakeSe->setIcon(QIcon::fromTheme("go-next"));
|
||||||
ui->cmdMakeAd->setIcon(QIcon::fromTheme("list-add"));
|
ui->cmdMakeAd->setIcon(QIcon::fromTheme("list-add"));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
#if QT_VERSION < 0x050600
|
#if QT_VERSION < 0x050600
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
qreal screenRatio = AppEnv::screenRatio();
|
||||||
if (screenRatio != 1) {
|
if (screenRatio != 1) {
|
||||||
|
@ -96,9 +99,9 @@ PlayerListDialog::PlayerListDialog(QStringList players, ProfileDatabase *profile
|
||||||
ui->cmdMakeAd->setIconSize(iconSize);
|
ui->cmdMakeAd->setIconSize(iconSize);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ui->cmdMakeAv->setIcon(QIcon(AppEnv::getImagesFolder() % "/back.svgz"));
|
ui->cmdMakeAv->setIcon(QIcon(":/img/back.svgz"));
|
||||||
ui->cmdMakeSe->setIcon(QIcon(AppEnv::getImagesFolder() % "/next.svgz"));
|
ui->cmdMakeSe->setIcon(QIcon(":/img/next.svgz"));
|
||||||
ui->cmdMakeAd->setIcon(QIcon(AppEnv::getImagesFolder() % "/add.svgz"));
|
ui->cmdMakeAd->setIcon(QIcon(":/img/add.svgz"));
|
||||||
}
|
}
|
||||||
buildInterface();
|
buildInterface();
|
||||||
|
|
||||||
|
@ -109,10 +112,12 @@ PlayerListDialog::PlayerListDialog(QStringList players, ProfileDatabase *profile
|
||||||
|
|
||||||
PlayerListDialog::~PlayerListDialog()
|
PlayerListDialog::~PlayerListDialog()
|
||||||
{
|
{
|
||||||
for (QObject *object : ui->listAvPlayers->children()) {
|
for (QObject *object : ui->listAvPlayers->children())
|
||||||
|
{
|
||||||
delete object;
|
delete object;
|
||||||
}
|
}
|
||||||
for (QObject *object : ui->listSePlayers->children()) {
|
for (QObject *object : ui->listSePlayers->children())
|
||||||
|
{
|
||||||
delete object;
|
delete object;
|
||||||
}
|
}
|
||||||
delete ui;
|
delete ui;
|
||||||
|
@ -126,13 +131,16 @@ void PlayerListDialog::on_cmdCancel_clicked()
|
||||||
void PlayerListDialog::buildInterface()
|
void PlayerListDialog::buildInterface()
|
||||||
{
|
{
|
||||||
const QStringList dbPlayers = profileDB->getPlayers();
|
const QStringList dbPlayers = profileDB->getPlayers();
|
||||||
for (const QString &sePlayer : qAsConst(players)) {
|
for (QString sePlayer : players)
|
||||||
|
{
|
||||||
QListWidgetItem *playerItem = new QListWidgetItem(profileDB->getPlayerName(sePlayer));
|
QListWidgetItem *playerItem = new QListWidgetItem(profileDB->getPlayerName(sePlayer));
|
||||||
playerItem->setData(Qt::UserRole, sePlayer);
|
playerItem->setData(Qt::UserRole, sePlayer);
|
||||||
ui->listSePlayers->addItem(playerItem);
|
ui->listSePlayers->addItem(playerItem);
|
||||||
}
|
}
|
||||||
for (const QString &dbPlayer : dbPlayers) {
|
for (QString dbPlayer : dbPlayers)
|
||||||
if (!players.contains(dbPlayer)) {
|
{
|
||||||
|
if (!players.contains(dbPlayer))
|
||||||
|
{
|
||||||
QListWidgetItem *playerItem = new QListWidgetItem(profileDB->getPlayerName(dbPlayer));
|
QListWidgetItem *playerItem = new QListWidgetItem(profileDB->getPlayerName(dbPlayer));
|
||||||
playerItem->setData(Qt::UserRole, dbPlayer);
|
playerItem->setData(Qt::UserRole, dbPlayer);
|
||||||
ui->listAvPlayers->addItem(playerItem);
|
ui->listAvPlayers->addItem(playerItem);
|
||||||
|
@ -143,7 +151,8 @@ void PlayerListDialog::buildInterface()
|
||||||
|
|
||||||
void PlayerListDialog::on_cmdMakeAv_clicked()
|
void PlayerListDialog::on_cmdMakeAv_clicked()
|
||||||
{
|
{
|
||||||
for (QListWidgetItem *item : ui->listSePlayers->selectedItems()) {
|
for (QListWidgetItem *item : ui->listSePlayers->selectedItems())
|
||||||
|
{
|
||||||
QString playerName = item->text();
|
QString playerName = item->text();
|
||||||
int playerID = item->data(Qt::UserRole).toInt();
|
int playerID = item->data(Qt::UserRole).toInt();
|
||||||
delete item;
|
delete item;
|
||||||
|
@ -157,11 +166,13 @@ void PlayerListDialog::on_cmdMakeAv_clicked()
|
||||||
void PlayerListDialog::on_cmdMakeSe_clicked()
|
void PlayerListDialog::on_cmdMakeSe_clicked()
|
||||||
{
|
{
|
||||||
int maxPlayers = 30;
|
int maxPlayers = 30;
|
||||||
if (maxPlayers < ui->listSePlayers->count() + ui->listAvPlayers->selectedItems().count()) {
|
if (maxPlayers < ui->listSePlayers->count() + ui->listAvPlayers->selectedItems().count())
|
||||||
|
{
|
||||||
QMessageBox::warning(this, tr("Add Players..."), tr("Failed to add more Players because the limit of Players are %1!").arg(QString::number(maxPlayers)));
|
QMessageBox::warning(this, tr("Add Players..."), tr("Failed to add more Players because the limit of Players are %1!").arg(QString::number(maxPlayers)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (QListWidgetItem *item : ui->listAvPlayers->selectedItems()) {
|
for (QListWidgetItem *item : ui->listAvPlayers->selectedItems())
|
||||||
|
{
|
||||||
QString playerName = item->text();
|
QString playerName = item->text();
|
||||||
int playerID = item->data(Qt::UserRole).toInt();
|
int playerID = item->data(Qt::UserRole).toInt();
|
||||||
delete item;
|
delete item;
|
||||||
|
@ -175,12 +186,15 @@ void PlayerListDialog::on_cmdMakeAd_clicked()
|
||||||
{
|
{
|
||||||
bool playerOk;
|
bool playerOk;
|
||||||
int playerID = QInputDialog::getInt(this, tr("Add Player..."), tr("Enter Social Club Player ID"), 1, 1, 214783647, 1, &playerOk, windowFlags());
|
int playerID = QInputDialog::getInt(this, tr("Add Player..."), tr("Enter Social Club Player ID"), 1, 1, 214783647, 1, &playerOk, windowFlags());
|
||||||
if (playerOk) {
|
if (playerOk)
|
||||||
for (int i = 0; i < ui->listAvPlayers->count(); ++i) {
|
{
|
||||||
|
for (int i = 0; i < ui->listAvPlayers->count(); ++i)
|
||||||
|
{
|
||||||
QListWidgetItem *item = ui->listAvPlayers->item(i);
|
QListWidgetItem *item = ui->listAvPlayers->item(i);
|
||||||
QString itemPlayerName = item->text();
|
QString itemPlayerName = item->text();
|
||||||
int itemPlayerID = item->data(Qt::UserRole).toInt();
|
int itemPlayerID = item->data(Qt::UserRole).toInt();
|
||||||
if (itemPlayerID == playerID) {
|
if (itemPlayerID == playerID)
|
||||||
|
{
|
||||||
delete item;
|
delete item;
|
||||||
QListWidgetItem *playerItem = new QListWidgetItem(itemPlayerName);
|
QListWidgetItem *playerItem = new QListWidgetItem(itemPlayerName);
|
||||||
playerItem->setData(Qt::UserRole, playerID);
|
playerItem->setData(Qt::UserRole, playerID);
|
||||||
|
@ -188,7 +202,8 @@ void PlayerListDialog::on_cmdMakeAd_clicked()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < ui->listSePlayers->count(); ++i) {
|
for (int i = 0; i < ui->listSePlayers->count(); ++i)
|
||||||
|
{
|
||||||
QListWidgetItem *item = ui->listSePlayers->item(i);
|
QListWidgetItem *item = ui->listSePlayers->item(i);
|
||||||
int itemPlayerID = item->data(Qt::UserRole).toInt();
|
int itemPlayerID = item->data(Qt::UserRole).toInt();
|
||||||
if (itemPlayerID == playerID)
|
if (itemPlayerID == playerID)
|
||||||
|
@ -206,7 +221,8 @@ void PlayerListDialog::on_cmdMakeAd_clicked()
|
||||||
void PlayerListDialog::on_cmdApply_clicked()
|
void PlayerListDialog::on_cmdApply_clicked()
|
||||||
{
|
{
|
||||||
players.clear();
|
players.clear();
|
||||||
for (int i = 0; i < ui->listSePlayers->count(); ++i) {
|
for (int i = 0; i < ui->listSePlayers->count(); ++i)
|
||||||
|
{
|
||||||
players += ui->listSePlayers->item(i)->data(Qt::UserRole).toString();
|
players += ui->listSePlayers->item(i)->data(Qt::UserRole).toString();
|
||||||
}
|
}
|
||||||
emit playerListUpdated(players);
|
emit playerListUpdated(players);
|
||||||
|
|
1189
ProfileInterface.cpp
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -30,7 +30,6 @@
|
||||||
#include "SavegameData.h"
|
#include "SavegameData.h"
|
||||||
#include "CrewDatabase.h"
|
#include "CrewDatabase.h"
|
||||||
#include "pcg_basic.h"
|
#include "pcg_basic.h"
|
||||||
#include <QFileSystemWatcher>
|
|
||||||
#include <QProgressDialog>
|
#include <QProgressDialog>
|
||||||
#include <QSpacerItem>
|
#include <QSpacerItem>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
@ -90,10 +89,6 @@ private slots:
|
||||||
void dialogNextPictureRequested(QWidget *dialog);
|
void dialogNextPictureRequested(QWidget *dialog);
|
||||||
void dialogPreviousPictureRequested(QWidget *dialog);
|
void dialogPreviousPictureRequested(QWidget *dialog);
|
||||||
void on_saProfileContent_dropped(const QMimeData *mimeData);
|
void on_saProfileContent_dropped(const QMimeData *mimeData);
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
void directoryChanged(const QString &path);
|
|
||||||
void directoryScanned(QVector<QString> savegameFiles, QVector<QString> snapmaticPics);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *watched, QEvent *event);
|
bool eventFilter(QObject *watched, QEvent *event);
|
||||||
|
@ -109,11 +104,6 @@ private:
|
||||||
QList<SavegameData*> savegames;
|
QList<SavegameData*> savegames;
|
||||||
QList<SnapmaticPicture*> pictures;
|
QList<SnapmaticPicture*> pictures;
|
||||||
QMap<ProfileWidget*,QString> widgets;
|
QMap<ProfileWidget*,QString> widgets;
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
QFileSystemWatcher fileSystemWatcher;
|
|
||||||
QVector<QString> savegameFiles;
|
|
||||||
QVector<QString> snapmaticPics;
|
|
||||||
#endif
|
|
||||||
QSpacerItem *saSpacerItem;
|
QSpacerItem *saSpacerItem;
|
||||||
QStringList fixedPictures;
|
QStringList fixedPictures;
|
||||||
QString enabledPicStr;
|
QString enabledPicStr;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,23 +16,17 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "SnapmaticPicture.h"
|
|
||||||
#include "ProfileLoader.h"
|
#include "ProfileLoader.h"
|
||||||
|
#include "SnapmaticPicture.h"
|
||||||
#include "SavegameData.h"
|
#include "SavegameData.h"
|
||||||
#include "CrewDatabase.h"
|
#include "CrewDatabase.h"
|
||||||
#include "wrapper.h"
|
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
#include <QVector>
|
#include <QStringList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QFile>
|
#include <QThread>
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
#include <QDir>
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#else
|
#include <QFile>
|
||||||
#include "sys/types.h"
|
#include <QDir>
|
||||||
#include "sys/stat.h"
|
|
||||||
#include "dirent.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ProfileLoader::ProfileLoader(QString profileFolder, CrewDatabase *crewDB, QObject *parent) : QThread(parent), profileFolder(profileFolder), crewDB(crewDB)
|
ProfileLoader::ProfileLoader(QString profileFolder, CrewDatabase *crewDB, QObject *parent) : QThread(parent), profileFolder(profileFolder), crewDB(crewDB)
|
||||||
{
|
{
|
||||||
|
@ -41,52 +35,30 @@ ProfileLoader::ProfileLoader(QString profileFolder, CrewDatabase *crewDB, QObjec
|
||||||
void ProfileLoader::run()
|
void ProfileLoader::run()
|
||||||
{
|
{
|
||||||
int curFile = 1;
|
int curFile = 1;
|
||||||
int maximumV = 0;
|
QDir profileDir;
|
||||||
QVector<int> crewList;
|
QList<int> crewList;
|
||||||
QVector<QString> savegameFiles;
|
profileDir.setPath(profileFolder);
|
||||||
QVector<QString> snapmaticPics;
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
// Seek pictures and savegames
|
||||||
QDir dir(profileFolder);
|
profileDir.setNameFilters(QStringList("SGTA5*"));
|
||||||
const QStringList files = dir.entryList(QDir::Files);
|
QStringList SavegameFiles = profileDir.entryList(QDir::Files | QDir::NoDot, QDir::NoSort);
|
||||||
for (const QString &fileName : files) {
|
QStringList BackupFiles = SavegameFiles.filter(".bak", Qt::CaseInsensitive);
|
||||||
if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) {
|
profileDir.setNameFilters(QStringList("PGTA5*"));
|
||||||
savegameFiles << fileName;
|
QStringList SnapmaticPics = profileDir.entryList(QDir::Files | QDir::NoDot, QDir::NoSort);
|
||||||
maximumV++;
|
BackupFiles += SnapmaticPics.filter(".bak", Qt::CaseInsensitive);
|
||||||
}
|
|
||||||
if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) {
|
|
||||||
snapmaticPics << fileName;
|
|
||||||
maximumV++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
DIR *dirp = opendir(profileFolder.toUtf8().constData());
|
|
||||||
struct dirent *dp;
|
|
||||||
while ((dp = readdir(dirp)) != 0) {
|
|
||||||
const QString fileName = QString::fromUtf8(dp->d_name);
|
|
||||||
const QString filePath = profileFolder % "/" % fileName;
|
|
||||||
struct stat fileStat;
|
|
||||||
stat(filePath.toUtf8().constData(), &fileStat);
|
|
||||||
if (S_ISREG(fileStat.st_mode) != 0) {
|
|
||||||
if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) {
|
|
||||||
savegameFiles << fileName;
|
|
||||||
maximumV++;
|
|
||||||
}
|
|
||||||
if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) {
|
|
||||||
snapmaticPics << fileName;
|
|
||||||
maximumV++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir(dirp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Directory successfully scanned
|
SavegameFiles.removeDuplicates();
|
||||||
emit directoryScanned(savegameFiles, snapmaticPics);
|
SnapmaticPics.removeDuplicates();
|
||||||
|
for (const QString &BackupFile : BackupFiles) {
|
||||||
|
SavegameFiles.removeAll(BackupFile);
|
||||||
|
SnapmaticPics.removeAll(BackupFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
int maximumV = SavegameFiles.length() + SnapmaticPics.length();
|
||||||
|
|
||||||
// Loading pictures and savegames
|
// Loading pictures and savegames
|
||||||
emit loadingProgress(curFile, maximumV);
|
emit loadingProgress(curFile, maximumV);
|
||||||
for (const QString &SavegameFile : qAsConst(savegameFiles)) {
|
for (const QString &SavegameFile : SavegameFiles) {
|
||||||
emit loadingProgress(curFile, maximumV);
|
emit loadingProgress(curFile, maximumV);
|
||||||
const QString sgdPath = profileFolder % "/" % SavegameFile;
|
const QString sgdPath = profileFolder % "/" % SavegameFile;
|
||||||
SavegameData *savegame = new SavegameData(sgdPath);
|
SavegameData *savegame = new SavegameData(sgdPath);
|
||||||
|
@ -95,7 +67,7 @@ void ProfileLoader::run()
|
||||||
}
|
}
|
||||||
curFile++;
|
curFile++;
|
||||||
}
|
}
|
||||||
for (const QString &SnapmaticPic : qAsConst(snapmaticPics)) {
|
for (const QString &SnapmaticPic : SnapmaticPics) {
|
||||||
emit loadingProgress(curFile, maximumV);
|
emit loadingProgress(curFile, maximumV);
|
||||||
const QString picturePath = profileFolder % "/" % SnapmaticPic;
|
const QString picturePath = profileFolder % "/" % SnapmaticPic;
|
||||||
SnapmaticPicture *picture = new SnapmaticPicture(picturePath);
|
SnapmaticPicture *picture = new SnapmaticPicture(picturePath);
|
||||||
|
@ -117,7 +89,7 @@ void ProfileLoader::run()
|
||||||
|
|
||||||
// adding found crews
|
// adding found crews
|
||||||
crewDB->setAddingCrews(true);
|
crewDB->setAddingCrews(true);
|
||||||
for (int crewID : qAsConst(crewList)) {
|
for (int crewID : crewList) {
|
||||||
crewDB->addCrew(crewID);
|
crewDB->addCrew(crewID);
|
||||||
}
|
}
|
||||||
crewDB->setAddingCrews(false);
|
crewDB->setAddingCrews(false);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -48,7 +48,6 @@ signals:
|
||||||
void pictureFixed(SnapmaticPicture *picture);
|
void pictureFixed(SnapmaticPicture *picture);
|
||||||
void savegameLoaded(SavegameData *savegame, QString savegamePath);
|
void savegameLoaded(SavegameData *savegame, QString savegamePath);
|
||||||
void loadingProgress(int value, int maximum);
|
void loadingProgress(int value, int maximum);
|
||||||
void directoryScanned(QVector<QString> savegameFiles, QVector<QString> snapmaticPics);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PROFILELOADER_H
|
#endif // PROFILELOADER_H
|
||||||
|
|
42
README.md
|
@ -1,5 +1,5 @@
|
||||||
## gta5view
|
## gta5view
|
||||||
Open Source Snapmatic and Savegame viewer/editor for GTA V
|
Grand Theft Auto V Savegame and Snapmatic viewer/editor
|
||||||
|
|
||||||
- View Snapmatics with the ability to disable them in-game
|
- View Snapmatics with the ability to disable them in-game
|
||||||
- Edit Snapmatic pictures and properties in multiple ways
|
- Edit Snapmatic pictures and properties in multiple ways
|
||||||
|
@ -14,32 +14,36 @@ Open Source Snapmatic and Savegame viewer/editor for GTA V
|
||||||
#### Build gta5view for Windows
|
#### Build gta5view for Windows
|
||||||
|
|
||||||
# Note: Install Docker Community Edition and Git before continuing
|
# Note: Install Docker Community Edition and Git before continuing
|
||||||
docker pull sypingauto/gta5view-build:1.10-static
|
git clone https://gitlab.com/Syping/gta5view && cd gta5view
|
||||||
git clone https://gitlab.com/Syping/gta5view
|
docker pull sypingauto/gta5view-build:1.9-static
|
||||||
docker run --rm -v "$PWD/gta5view:/gta5view" -it sypingauto/gta5view-build:1.10-static
|
docker run --rm -v ${PWD}:/gta5view -it sypingauto/gta5view-build:1.9-static
|
||||||
mingw64-qt-cmake -B /gta5view/build /gta5view
|
cd /gta5view && mkdir -p build && cd build
|
||||||
cmake --build /gta5view/build
|
mingw64-qt-cmake ../
|
||||||
|
make -j $(nproc --all)
|
||||||
|
|
||||||
#### Build gta5view for Debian/Ubuntu
|
#### Build gta5view for Debian/Ubuntu
|
||||||
|
|
||||||
sudo apt-get install cmake git gcc g++ libqt5svg5-dev make qtbase5-dev qttranslations5-l10n
|
sudo apt-get install cmake git gcc g++ libqt5svg5-dev make qtbase5-dev qttranslations5-l10n
|
||||||
git clone https://gitlab.com/Syping/gta5view
|
git clone https://gitlab.com/Syping/gta5view && cd gta5view
|
||||||
cmake -B gta5view-build gta5view
|
mkdir -p build && cd build
|
||||||
cmake --build gta5view-build
|
cmake ../
|
||||||
sudo cmake --install gta5view-build
|
make -j $(nproc --all)
|
||||||
|
sudo make install
|
||||||
|
|
||||||
#### Build gta5view for Arch/Manjaro
|
#### Build gta5view for Arch/Manjaro
|
||||||
|
|
||||||
sudo pacman -S cmake gcc git make qt5-base qt5-svg qt5-tools qt5-translations
|
sudo pacman -S cmake gcc git make qt5-base qt5-svg qt5-tools qt5-translations
|
||||||
git clone https://gitlab.com/Syping/gta5view
|
git clone https://gitlab.com/Syping/gta5view && cd gta5view
|
||||||
cmake -B gta5view-build gta5view
|
mkdir -p build && cd build
|
||||||
cmake --build gta5view-build
|
cmake ../
|
||||||
sudo cmake --install gta5view-build
|
make -j $(nproc --all)
|
||||||
|
sudo make install
|
||||||
|
|
||||||
#### Build gta5view for Fedora/RHEL
|
#### Build gta5view for Fedora
|
||||||
|
|
||||||
sudo dnf install cmake git gcc gcc-c++ make qt5-qtbase-devel qt5-qtsvg-devel qt5-qttranslations
|
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 https://gitlab.com/Syping/gta5view && cd gta5view
|
||||||
cmake -B gta5view-build gta5view
|
mkdir -p build && cd build
|
||||||
cmake --build gta5view-build
|
cmake ../
|
||||||
sudo cmake --install gta5view-build
|
make -j $(nproc --all)
|
||||||
|
sudo make install
|
||||||
|
|
203
RagePhoto.cpp
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2020-2022 Syping
|
* Copyright (C) 2020-2021 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -22,28 +22,7 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#if QT_VERSION < 0x060000
|
#if QT_VERSION < 0x060000
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#else
|
|
||||||
#include <QStringEncoder>
|
|
||||||
#include <QStringDecoder>
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef RAGEPHOTO_BENCHMARK
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <chrono>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline quint32 joaatFromSI(const char *data, size_t size)
|
|
||||||
{
|
|
||||||
quint32 val = 0xE47AB81CUL;
|
|
||||||
for (size_t i = 0; i != size; i++) {
|
|
||||||
val += data[i];
|
|
||||||
val += (val << 10);
|
|
||||||
val ^= (val >> 6);
|
|
||||||
}
|
|
||||||
val += (val << 3);
|
|
||||||
val ^= (val >> 11);
|
|
||||||
val += (val << 15);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
RagePhoto::RagePhoto()
|
RagePhoto::RagePhoto()
|
||||||
{
|
{
|
||||||
|
@ -104,10 +83,6 @@ bool RagePhoto::load()
|
||||||
QBuffer dataBuffer(&p_fileData);
|
QBuffer dataBuffer(&p_fileData);
|
||||||
dataBuffer.open(QIODevice::ReadOnly);
|
dataBuffer.open(QIODevice::ReadOnly);
|
||||||
|
|
||||||
#ifdef RAGEPHOTO_BENCHMARK
|
|
||||||
auto benchmark_parse_start = std::chrono::high_resolution_clock::now();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char uInt32Buffer[4];
|
char uInt32Buffer[4];
|
||||||
qint64 size = dataBuffer.read(uInt32Buffer, 4);
|
qint64 size = dataBuffer.read(uInt32Buffer, 4);
|
||||||
if (size != 4)
|
if (size != 4)
|
||||||
|
@ -115,9 +90,12 @@ bool RagePhoto::load()
|
||||||
quint32 format = charToUInt32LE(uInt32Buffer);
|
quint32 format = charToUInt32LE(uInt32Buffer);
|
||||||
|
|
||||||
if (format == static_cast<quint32>(PhotoFormat::GTA5)) {
|
if (format == static_cast<quint32>(PhotoFormat::GTA5)) {
|
||||||
char photoHeader[256];
|
char *photoHeader = static_cast<char*>(malloc(256));
|
||||||
|
if (!photoHeader)
|
||||||
|
return false;
|
||||||
size = dataBuffer.read(photoHeader, 256);
|
size = dataBuffer.read(photoHeader, 256);
|
||||||
if (size != 256) {
|
if (size != 256) {
|
||||||
|
free(photoHeader);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (const QChar &photoChar : utf16LEToString(photoHeader, 256)) {
|
for (const QChar &photoChar : utf16LEToString(photoHeader, 256)) {
|
||||||
|
@ -125,6 +103,7 @@ bool RagePhoto::load()
|
||||||
break;
|
break;
|
||||||
p_photoString += photoChar;
|
p_photoString += photoChar;
|
||||||
}
|
}
|
||||||
|
free(photoHeader);
|
||||||
|
|
||||||
size = dataBuffer.read(uInt32Buffer, 4);
|
size = dataBuffer.read(uInt32Buffer, 4);
|
||||||
if (size != 4)
|
if (size != 4)
|
||||||
|
@ -199,12 +178,11 @@ bool RagePhoto::load()
|
||||||
free(jsonBytes);
|
free(jsonBytes);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
quint32 i;
|
for (quint32 i = 0; i != p_jsonBuffer; i++) {
|
||||||
for (i = 0; i != p_jsonBuffer; i++) {
|
|
||||||
if (jsonBytes[i] == '\x00')
|
if (jsonBytes[i] == '\x00')
|
||||||
break;
|
break;
|
||||||
|
p_jsonData += jsonBytes[i];
|
||||||
}
|
}
|
||||||
p_jsonData = QByteArray(jsonBytes, i);
|
|
||||||
free(jsonBytes);
|
free(jsonBytes);
|
||||||
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData);
|
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData);
|
||||||
if (t_jsonDocument.isNull())
|
if (t_jsonDocument.isNull())
|
||||||
|
@ -231,11 +209,11 @@ bool RagePhoto::load()
|
||||||
free(titlBytes);
|
free(titlBytes);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (i = 0; i != p_titlBuffer; i++) {
|
for (const QChar &titlChar : QString::fromUtf8(titlBytes, p_titlBuffer)) {
|
||||||
if (titlBytes[i] == '\x00')
|
if (titlChar.isNull())
|
||||||
break;
|
break;
|
||||||
|
p_titleString += titlChar;
|
||||||
}
|
}
|
||||||
p_titleString = QString::fromUtf8(titlBytes, i);
|
|
||||||
free(titlBytes);
|
free(titlBytes);
|
||||||
|
|
||||||
dataBuffer.seek(p_descOffset + 264);
|
dataBuffer.seek(p_descOffset + 264);
|
||||||
|
@ -258,11 +236,11 @@ bool RagePhoto::load()
|
||||||
free(descBytes);
|
free(descBytes);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (i = 0; i != p_descBuffer; i++) {
|
for (const QChar &descChar : QString::fromUtf8(descBytes, p_descBuffer)) {
|
||||||
if (descBytes[i] == '\x00')
|
if (descChar.isNull())
|
||||||
break;
|
break;
|
||||||
|
p_descriptionString += descChar;
|
||||||
}
|
}
|
||||||
p_descriptionString = QString::fromUtf8(descBytes, i);
|
|
||||||
free(descBytes);
|
free(descBytes);
|
||||||
|
|
||||||
dataBuffer.seek(p_endOfFile + 260);
|
dataBuffer.seek(p_endOfFile + 260);
|
||||||
|
@ -272,17 +250,6 @@ bool RagePhoto::load()
|
||||||
if (strncmp(markerBuffer, "JEND", 4) != 0)
|
if (strncmp(markerBuffer, "JEND", 4) != 0)
|
||||||
return false;
|
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)
|
if (p_photoFormat != PhotoFormat::G5EX)
|
||||||
p_photoFormat = PhotoFormat::GTA5;
|
p_photoFormat = PhotoFormat::GTA5;
|
||||||
|
|
||||||
|
@ -437,17 +404,6 @@ bool RagePhoto::load()
|
||||||
return false;
|
return false;
|
||||||
p_endOfFile = charToUInt32LE(uInt32Buffer);
|
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_photoFormat = PhotoFormat::G5EX;
|
||||||
|
|
||||||
p_fileData.clear();
|
p_fileData.clear();
|
||||||
|
@ -465,12 +421,12 @@ bool RagePhoto::load()
|
||||||
else if (format == static_cast<quint32>(ExportFormat::G5E1P)) {
|
else if (format == static_cast<quint32>(ExportFormat::G5E1P)) {
|
||||||
#if QT_VERSION >= 0x050A00
|
#if QT_VERSION >= 0x050A00
|
||||||
size = dataBuffer.skip(1);
|
size = dataBuffer.skip(1);
|
||||||
|
#else
|
||||||
|
QByteArray skipData = dataBuffer.read(1);
|
||||||
|
size = skipData.size();
|
||||||
|
#endif
|
||||||
if (size != 1)
|
if (size != 1)
|
||||||
return false;
|
return false;
|
||||||
#else
|
|
||||||
if (!dataBuffer.seek(dataBuffer.pos() + 1))
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char length[1];
|
char length[1];
|
||||||
size = dataBuffer.read(length, 1);
|
size = dataBuffer.read(length, 1);
|
||||||
|
@ -480,12 +436,12 @@ bool RagePhoto::load()
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050A00
|
#if QT_VERSION >= 0x050A00
|
||||||
size = dataBuffer.skip(i_length);
|
size = dataBuffer.skip(i_length);
|
||||||
|
#else
|
||||||
|
skipData = dataBuffer.read(i_length);
|
||||||
|
size = skipData.size();
|
||||||
|
#endif
|
||||||
if (size != i_length)
|
if (size != i_length)
|
||||||
return false;
|
return false;
|
||||||
#else
|
|
||||||
if (!dataBuffer.seek(dataBuffer.pos() + i_length))
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
p_photoFormat = PhotoFormat::G5EX;
|
p_photoFormat = PhotoFormat::G5EX;
|
||||||
p_fileData = qUncompress(dataBuffer.readAll());
|
p_fileData = qUncompress(dataBuffer.readAll());
|
||||||
|
@ -544,15 +500,8 @@ bool RagePhoto::setJsonData(const QByteArray &data)
|
||||||
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(data);
|
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(data);
|
||||||
if (t_jsonDocument.isNull())
|
if (t_jsonDocument.isNull())
|
||||||
return false;
|
return false;
|
||||||
p_jsonObject = t_jsonDocument.object();
|
|
||||||
// serializer band-aid
|
|
||||||
QJsonObject t_jsonObject = p_jsonObject;
|
|
||||||
t_jsonObject["sign"] = "__gta5view.sign";
|
|
||||||
t_jsonDocument.setObject(t_jsonObject);
|
|
||||||
p_jsonData = t_jsonDocument.toJson(QJsonDocument::Compact);
|
p_jsonData = t_jsonDocument.toJson(QJsonDocument::Compact);
|
||||||
char sign_char[24];
|
p_jsonObject = t_jsonDocument.object();
|
||||||
sprintf(sign_char, "%llu", (0x100000000000000ULL | joaatFromSI(p_photoData.constData(), p_photoData.size())));
|
|
||||||
p_jsonData.replace("\"__gta5view.sign\"", sign_char);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,8 +525,6 @@ bool RagePhoto::setPhotoData(const QByteArray &data)
|
||||||
if (size > p_photoBuffer)
|
if (size > p_photoBuffer)
|
||||||
return false;
|
return false;
|
||||||
p_photoData = data;
|
p_photoData = data;
|
||||||
// serializer band-aid
|
|
||||||
setJsonData(p_jsonData);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,8 +533,6 @@ bool RagePhoto::setPhotoData(const char *data, int size)
|
||||||
if (static_cast<quint32>(size) > p_photoBuffer)
|
if (static_cast<quint32>(size) > p_photoBuffer)
|
||||||
return false;
|
return false;
|
||||||
p_photoData = QByteArray(data, size);
|
p_photoData = QByteArray(data, size);
|
||||||
// serializer band-aid
|
|
||||||
setJsonData(p_jsonData);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,83 +610,84 @@ QByteArray RagePhoto::save(PhotoFormat photoFormat)
|
||||||
|
|
||||||
void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
|
void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
|
||||||
{
|
{
|
||||||
// serializer band-aid
|
|
||||||
setJsonData(p_jsonData);
|
|
||||||
|
|
||||||
if (photoFormat == PhotoFormat::G5EX) {
|
if (photoFormat == PhotoFormat::G5EX) {
|
||||||
char uInt32Buffer[4];
|
char uInt32Buffer[4];
|
||||||
quint32 format = static_cast<quint32>(PhotoFormat::G5EX);
|
quint32 format = static_cast<quint32>(PhotoFormat::G5EX);
|
||||||
uInt32ToCharLE(format, uInt32Buffer);
|
uInt32ToCharLE(&format, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
format = static_cast<quint32>(ExportFormat::G5E3P);
|
format = static_cast<quint32>(ExportFormat::G5E3P);
|
||||||
uInt32ToCharLE(format, uInt32Buffer);
|
uInt32ToCharLE(&format, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
QByteArray compressedData = qCompress(p_photoString.toUtf8(), 9);
|
QByteArray compressedData = qCompress(p_photoString.toUtf8(), 9);
|
||||||
quint32 compressedSize = compressedData.size();
|
quint32 compressedSize = compressedData.size();
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
uInt32ToCharLE(&compressedSize, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
ioDevice->write(compressedData);
|
ioDevice->write(compressedData);
|
||||||
|
|
||||||
uInt32ToCharLE(p_headerSum, uInt32Buffer);
|
uInt32ToCharLE(&p_headerSum, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_photoBuffer, uInt32Buffer);
|
uInt32ToCharLE(&p_photoBuffer, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
compressedData = qCompress(p_photoData, 9);
|
compressedData = qCompress(p_photoData, 9);
|
||||||
compressedSize = compressedData.size();
|
compressedSize = compressedData.size();
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
uInt32ToCharLE(&compressedSize, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
ioDevice->write(compressedData);
|
ioDevice->write(compressedData);
|
||||||
|
|
||||||
uInt32ToCharLE(p_jsonOffset, uInt32Buffer);
|
uInt32ToCharLE(&p_jsonOffset, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_jsonBuffer, uInt32Buffer);
|
uInt32ToCharLE(&p_jsonBuffer, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
compressedData = qCompress(p_jsonData, 9);
|
compressedData = qCompress(p_jsonData, 9);
|
||||||
compressedSize = compressedData.size();
|
compressedSize = compressedData.size();
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
uInt32ToCharLE(&compressedSize, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
ioDevice->write(compressedData);
|
ioDevice->write(compressedData);
|
||||||
|
|
||||||
uInt32ToCharLE(p_titlOffset, uInt32Buffer);
|
uInt32ToCharLE(&p_titlOffset, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_titlBuffer, uInt32Buffer);
|
uInt32ToCharLE(&p_titlBuffer, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
compressedData = qCompress(p_titleString.toUtf8(), 9);
|
compressedData = qCompress(p_titleString.toUtf8(), 9);
|
||||||
compressedSize = compressedData.size();
|
compressedSize = compressedData.size();
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
uInt32ToCharLE(&compressedSize, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
ioDevice->write(compressedData);
|
ioDevice->write(compressedData);
|
||||||
|
|
||||||
uInt32ToCharLE(p_descOffset, uInt32Buffer);
|
uInt32ToCharLE(&p_descOffset, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_descBuffer, uInt32Buffer);
|
uInt32ToCharLE(&p_descBuffer, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
compressedData = qCompress(p_descriptionString.toUtf8(), 9);
|
compressedData = qCompress(p_descriptionString.toUtf8(), 9);
|
||||||
compressedSize = compressedData.size();
|
compressedSize = compressedData.size();
|
||||||
uInt32ToCharLE(compressedSize, uInt32Buffer);
|
uInt32ToCharLE(&compressedSize, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
ioDevice->write(compressedData);
|
ioDevice->write(compressedData);
|
||||||
|
|
||||||
uInt32ToCharLE(p_endOfFile, uInt32Buffer);
|
uInt32ToCharLE(&p_endOfFile, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x050000
|
||||||
|
ioDevice->aboutToClose();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (photoFormat == PhotoFormat::GTA5) {
|
else if (photoFormat == PhotoFormat::GTA5) {
|
||||||
char uInt32Buffer[4];
|
char uInt32Buffer[4];
|
||||||
quint32 format = static_cast<quint32>(PhotoFormat::GTA5);
|
quint32 format = static_cast<quint32>(PhotoFormat::GTA5);
|
||||||
uInt32ToCharLE(format, uInt32Buffer);
|
uInt32ToCharLE(&format, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
QByteArray photoHeader = stringToUtf16LE(p_photoString);
|
QByteArray photoHeader = stringToUtf16LE(p_photoString);
|
||||||
if (photoHeader.startsWith("\xFF\xFE")) {
|
if (photoHeader.left(2) == "\xFF\xFE") {
|
||||||
photoHeader.remove(0, 2);
|
photoHeader.remove(0, 2);
|
||||||
}
|
}
|
||||||
qint64 photoHeaderSize = photoHeader.size();
|
qint64 photoHeaderSize = photoHeader.size();
|
||||||
|
@ -754,28 +700,28 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
|
||||||
ioDevice->write("\x00", 1);
|
ioDevice->write("\x00", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32ToCharLE(p_headerSum, uInt32Buffer);
|
uInt32ToCharLE(&p_headerSum, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_endOfFile, uInt32Buffer);
|
uInt32ToCharLE(&p_endOfFile, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_jsonOffset, uInt32Buffer);
|
uInt32ToCharLE(&p_jsonOffset, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_titlOffset, uInt32Buffer);
|
uInt32ToCharLE(&p_titlOffset, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_descOffset, uInt32Buffer);
|
uInt32ToCharLE(&p_descOffset, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
ioDevice->write("JPEG", 4);
|
ioDevice->write("JPEG", 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_photoBuffer, uInt32Buffer);
|
uInt32ToCharLE(&p_photoBuffer, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
quint32 t_photoSize = p_photoData.size();
|
quint32 t_photoSize = p_photoData.size();
|
||||||
uInt32ToCharLE(t_photoSize, uInt32Buffer);
|
uInt32ToCharLE(&t_photoSize, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
ioDevice->write(p_photoData);
|
ioDevice->write(p_photoData);
|
||||||
|
@ -786,7 +732,7 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
|
||||||
ioDevice->seek(p_jsonOffset + 264);
|
ioDevice->seek(p_jsonOffset + 264);
|
||||||
ioDevice->write("JSON", 4);
|
ioDevice->write("JSON", 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_jsonBuffer, uInt32Buffer);
|
uInt32ToCharLE(&p_jsonBuffer, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
qint64 dataSize = p_jsonData.size();
|
qint64 dataSize = p_jsonData.size();
|
||||||
|
@ -798,7 +744,7 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
|
||||||
ioDevice->seek(p_titlOffset + 264);
|
ioDevice->seek(p_titlOffset + 264);
|
||||||
ioDevice->write("TITL", 4);
|
ioDevice->write("TITL", 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_titlBuffer, uInt32Buffer);
|
uInt32ToCharLE(&p_titlBuffer, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
QByteArray data = p_titleString.toUtf8();
|
QByteArray data = p_titleString.toUtf8();
|
||||||
|
@ -811,7 +757,7 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
|
||||||
ioDevice->seek(p_descOffset + 264);
|
ioDevice->seek(p_descOffset + 264);
|
||||||
ioDevice->write("DESC", 4);
|
ioDevice->write("DESC", 4);
|
||||||
|
|
||||||
uInt32ToCharLE(p_descBuffer, uInt32Buffer);
|
uInt32ToCharLE(&p_descBuffer, uInt32Buffer);
|
||||||
ioDevice->write(uInt32Buffer, 4);
|
ioDevice->write(uInt32Buffer, 4);
|
||||||
|
|
||||||
data = p_descriptionString.toUtf8();
|
data = p_descriptionString.toUtf8();
|
||||||
|
@ -823,6 +769,10 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
|
||||||
|
|
||||||
ioDevice->seek(p_endOfFile + 260);
|
ioDevice->seek(p_endOfFile + 260);
|
||||||
ioDevice->write("JEND", 4);
|
ioDevice->write("JEND", 4);
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x050000
|
||||||
|
ioDevice->aboutToClose();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,44 +799,47 @@ quint32 RagePhoto::charToUInt32LE(char *x)
|
||||||
static_cast<unsigned char>(x[0]));
|
static_cast<unsigned char>(x[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RagePhoto::uInt32ToCharBE(quint32 x, char *y)
|
void RagePhoto::uInt32ToCharBE(quint32 *x, char *y)
|
||||||
{
|
{
|
||||||
y[0] = x >> 24;
|
y[0] = (*x >> 24) & 0xFF;
|
||||||
y[1] = x >> 16;
|
y[1] = (*x >> 16) & 0xFF;
|
||||||
y[2] = x >> 8;
|
y[2] = (*x >> 8) & 0xFF;
|
||||||
y[3] = x;
|
y[3] = (*x) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RagePhoto::uInt32ToCharLE(quint32 x, char *y)
|
void RagePhoto::uInt32ToCharLE(quint32 *x, char *y)
|
||||||
{
|
{
|
||||||
y[0] = x;
|
y[0] = (*x) & 0xFF;
|
||||||
y[1] = x >> 8;
|
y[1] = (*x >> 8) & 0xFF;
|
||||||
y[2] = x >> 16;
|
y[2] = (*x >> 16) & 0xFF;
|
||||||
y[3] = x >> 24;
|
y[3] = (*x >> 24) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray RagePhoto::stringToUtf16LE(const QString &string)
|
QByteArray RagePhoto::stringToUtf16LE(const QString &string)
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x060000
|
||||||
return QStringEncoder(QStringEncoder::Utf16LE)(string);
|
QStringEncoder stringEncoder = QStringEncoder(QStringEncoder::Utf16LE);
|
||||||
|
return stringEncoder(string);
|
||||||
#else
|
#else
|
||||||
return QTextCodec::codecForName("UTF-16LE")->fromUnicode(string);
|
return QTextCodec::codecForName("UTF-16LE")->fromUnicode(string);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString RagePhoto::utf16LEToString(const QByteArray &data)
|
QString RagePhoto::utf16LEToString(const QByteArray &data)
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x060000
|
||||||
return QStringDecoder(QStringDecoder::Utf16LE)(data);
|
QStringDecoder stringDecoder = QStringDecoder(QStringDecoder::Utf16LE);
|
||||||
|
return stringDecoder(data);
|
||||||
#else
|
#else
|
||||||
return QTextCodec::codecForName("UTF-16LE")->toUnicode(data);
|
return QTextCodec::codecForName("UTF-16LE")->toUnicode(data);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString RagePhoto::utf16LEToString(const char *data, int size)
|
QString RagePhoto::utf16LEToString(const char *data, int size)
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x060000
|
||||||
return QStringDecoder(QStringDecoder::Utf16LE)(QByteArray::fromRawData(data, size));
|
QStringDecoder stringDecoder = QStringDecoder(QStringDecoder::Utf16LE);
|
||||||
|
return stringDecoder(QByteArray::fromRawData(data, size));
|
||||||
#else
|
#else
|
||||||
return QTextCodec::codecForName("UTF-16LE")->toUnicode(data, size);
|
return QTextCodec::codecForName("UTF-16LE")->toUnicode(data, size);
|
||||||
#endif
|
#endif
|
||||||
|
|
10
RagePhoto.h
|
@ -79,11 +79,11 @@ public:
|
||||||
private:
|
private:
|
||||||
inline quint32 charToUInt32BE(char *x);
|
inline quint32 charToUInt32BE(char *x);
|
||||||
inline quint32 charToUInt32LE(char *x);
|
inline quint32 charToUInt32LE(char *x);
|
||||||
inline void uInt32ToCharBE(quint32 x, char *y);
|
inline void uInt32ToCharBE(quint32 *x, char *y);
|
||||||
inline void uInt32ToCharLE(quint32 x, char *y);
|
inline void uInt32ToCharLE(quint32 *x, char *y);
|
||||||
inline const QByteArray stringToUtf16LE(const QString &string);
|
inline QByteArray stringToUtf16LE(const QString &string);
|
||||||
inline const QString utf16LEToString(const QByteArray &data);
|
inline QString utf16LEToString(const QByteArray &data);
|
||||||
inline const QString utf16LEToString(const char *data, int size);
|
inline QString utf16LEToString(const char *data, int size);
|
||||||
PhotoFormat p_photoFormat;
|
PhotoFormat p_photoFormat;
|
||||||
QJsonObject p_jsonObject;
|
QJsonObject p_jsonObject;
|
||||||
QByteArray p_fileData;
|
QByteArray p_fileData;
|
||||||
|
|
|
@ -28,11 +28,7 @@ SavegameDialog::SavegameDialog(QWidget *parent) :
|
||||||
ui(new Ui::SavegameDialog)
|
ui(new Ui::SavegameDialog)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
// Set Window Flags
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup User Interface
|
// Setup User Interface
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2018 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,7 +25,6 @@
|
||||||
#include "SavegameCopy.h"
|
#include "SavegameCopy.h"
|
||||||
#include "AppEnv.h"
|
#include "AppEnv.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
@ -60,7 +59,7 @@ SavegameWidget::SavegameWidget(QWidget *parent) :
|
||||||
ui->labSavegamePic->setFixedSize(48 * screenRatio, 27 * screenRatio);
|
ui->labSavegamePic->setFixedSize(48 * screenRatio, 27 * screenRatio);
|
||||||
|
|
||||||
ui->labSavegamePic->setScaledContents(true);
|
ui->labSavegamePic->setScaledContents(true);
|
||||||
ui->labSavegamePic->setPixmap(QPixmap(AppEnv::getImagesFolder() % "/savegame.svgz"));
|
ui->labSavegamePic->setPixmap(QPixmap(":/img/savegame.svgz"));
|
||||||
|
|
||||||
QString exportSavegameStr = tr("Export Savegame...");
|
QString exportSavegameStr = tr("Export Savegame...");
|
||||||
Q_UNUSED(exportSavegameStr)
|
Q_UNUSED(exportSavegameStr)
|
||||||
|
@ -153,11 +152,7 @@ void SavegameWidget::on_cmdDelete_clicked()
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "DeleteSuccess";
|
jsonObject["Type"] = "DeleteSuccess";
|
||||||
jsonObject["ExtraFlags"] = "Savegame";
|
jsonObject["ExtraFlags"] = "Savegame";
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
|
@ -176,11 +171,7 @@ void SavegameWidget::on_cmdDelete_clicked()
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "DeleteSuccess";
|
jsonObject["Type"] = "DeleteSuccess";
|
||||||
jsonObject["ExtraFlags"] = "Savegame";
|
jsonObject["ExtraFlags"] = "Savegame";
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2018 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -21,7 +21,6 @@
|
||||||
#include "SnapmaticPicture.h"
|
#include "SnapmaticPicture.h"
|
||||||
#include "PlayerListDialog.h"
|
#include "PlayerListDialog.h"
|
||||||
#include "StringParser.h"
|
#include "StringParser.h"
|
||||||
#include "wrapper.h"
|
|
||||||
#include "AppEnv.h"
|
#include "AppEnv.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
|
@ -42,38 +41,41 @@ SnapmaticEditor::SnapmaticEditor(CrewDatabase *crewDB, ProfileDatabase *profileD
|
||||||
ui(new Ui::SnapmaticEditor)
|
ui(new Ui::SnapmaticEditor)
|
||||||
{
|
{
|
||||||
// Set Window Flags
|
// Set Window Flags
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
#endif
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->cmdCancel->setDefault(true);
|
ui->cmdCancel->setDefault(true);
|
||||||
ui->cmdCancel->setFocus();
|
ui->cmdCancel->setFocus();
|
||||||
|
|
||||||
// Set Icon for Apply Button
|
// Set Icon for Apply Button
|
||||||
if (QIcon::hasThemeIcon("dialog-ok-apply")) {
|
if (QIcon::hasThemeIcon("dialog-ok-apply"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok-apply"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok-apply"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("dialog-apply")) {
|
else if (QIcon::hasThemeIcon("dialog-apply"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-apply"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-apply"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-apply")) {
|
else if (QIcon::hasThemeIcon("gtk-apply"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("gtk-apply"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("gtk-apply"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("dialog-ok")) {
|
else if (QIcon::hasThemeIcon("dialog-ok"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-ok")) {
|
else if (QIcon::hasThemeIcon("gtk-ok"))
|
||||||
|
{
|
||||||
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Cancel Button
|
// Set Icon for Cancel Button
|
||||||
if (QIcon::hasThemeIcon("dialog-cancel")) {
|
if (QIcon::hasThemeIcon("dialog-cancel"))
|
||||||
|
{
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-cancel")) {
|
else if (QIcon::hasThemeIcon("gtk-cancel"))
|
||||||
|
{
|
||||||
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,18 +96,27 @@ SnapmaticEditor::~SnapmaticEditor()
|
||||||
|
|
||||||
void SnapmaticEditor::selfie_toggled(bool checked)
|
void SnapmaticEditor::selfie_toggled(bool checked)
|
||||||
{
|
{
|
||||||
isSelfie = checked;
|
if (checked)
|
||||||
|
{
|
||||||
|
isSelfie = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isSelfie = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SnapmaticEditor::mugshot_toggled(bool checked)
|
void SnapmaticEditor::mugshot_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked)
|
||||||
|
{
|
||||||
isMugshot = true;
|
isMugshot = true;
|
||||||
ui->cbDirector->setEnabled(false);
|
ui->cbDirector->setEnabled(false);
|
||||||
ui->cbDirector->setChecked(false);
|
ui->cbDirector->setChecked(false);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
isMugshot = false;
|
isMugshot = false;
|
||||||
ui->cbDirector->setEnabled(true);
|
ui->cbDirector->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -113,12 +124,14 @@ void SnapmaticEditor::mugshot_toggled(bool checked)
|
||||||
|
|
||||||
void SnapmaticEditor::editor_toggled(bool checked)
|
void SnapmaticEditor::editor_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked)
|
||||||
|
{
|
||||||
isEditor = true;
|
isEditor = true;
|
||||||
ui->cbDirector->setEnabled(false);
|
ui->cbDirector->setEnabled(false);
|
||||||
ui->cbDirector->setChecked(false);
|
ui->cbDirector->setChecked(false);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
isEditor = false;
|
isEditor = false;
|
||||||
ui->cbDirector->setEnabled(true);
|
ui->cbDirector->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +139,8 @@ void SnapmaticEditor::editor_toggled(bool checked)
|
||||||
|
|
||||||
void SnapmaticEditor::on_rbSelfie_toggled(bool checked)
|
void SnapmaticEditor::on_rbSelfie_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked)
|
||||||
|
{
|
||||||
mugshot_toggled(false);
|
mugshot_toggled(false);
|
||||||
editor_toggled(false);
|
editor_toggled(false);
|
||||||
selfie_toggled(true);
|
selfie_toggled(true);
|
||||||
|
@ -135,7 +149,8 @@ void SnapmaticEditor::on_rbSelfie_toggled(bool checked)
|
||||||
|
|
||||||
void SnapmaticEditor::on_rbMugshot_toggled(bool checked)
|
void SnapmaticEditor::on_rbMugshot_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked)
|
||||||
|
{
|
||||||
selfie_toggled(false);
|
selfie_toggled(false);
|
||||||
editor_toggled(false);
|
editor_toggled(false);
|
||||||
mugshot_toggled(true);
|
mugshot_toggled(true);
|
||||||
|
@ -144,7 +159,8 @@ void SnapmaticEditor::on_rbMugshot_toggled(bool checked)
|
||||||
|
|
||||||
void SnapmaticEditor::on_rbEditor_toggled(bool checked)
|
void SnapmaticEditor::on_rbEditor_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked)
|
||||||
|
{
|
||||||
selfie_toggled(false);
|
selfie_toggled(false);
|
||||||
mugshot_toggled(false);
|
mugshot_toggled(false);
|
||||||
editor_toggled(true);
|
editor_toggled(true);
|
||||||
|
@ -153,7 +169,8 @@ void SnapmaticEditor::on_rbEditor_toggled(bool checked)
|
||||||
|
|
||||||
void SnapmaticEditor::on_rbCustom_toggled(bool checked)
|
void SnapmaticEditor::on_rbCustom_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked)
|
||||||
|
{
|
||||||
selfie_toggled(false);
|
selfie_toggled(false);
|
||||||
mugshot_toggled(false);
|
mugshot_toggled(false);
|
||||||
editor_toggled(false);
|
editor_toggled(false);
|
||||||
|
@ -172,16 +189,20 @@ void SnapmaticEditor::setSnapmaticPicture(SnapmaticPicture *picture)
|
||||||
playersList = snapmaticProperties.playersList;
|
playersList = snapmaticProperties.playersList;
|
||||||
ui->cbDirector->setChecked(snapmaticProperties.isFromDirector);
|
ui->cbDirector->setChecked(snapmaticProperties.isFromDirector);
|
||||||
ui->cbMeme->setChecked(snapmaticProperties.isMeme);
|
ui->cbMeme->setChecked(snapmaticProperties.isMeme);
|
||||||
if (isSelfie) {
|
if (isSelfie)
|
||||||
|
{
|
||||||
ui->rbSelfie->setChecked(true);
|
ui->rbSelfie->setChecked(true);
|
||||||
}
|
}
|
||||||
else if (isMugshot) {
|
else if (isMugshot)
|
||||||
|
{
|
||||||
ui->rbMugshot->setChecked(true);
|
ui->rbMugshot->setChecked(true);
|
||||||
}
|
}
|
||||||
else if (isEditor) {
|
else if (isEditor)
|
||||||
|
{
|
||||||
ui->rbEditor->setChecked(true);
|
ui->rbEditor->setChecked(true);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->rbCustom->setChecked(true);
|
ui->rbCustom->setChecked(true);
|
||||||
}
|
}
|
||||||
setSnapmaticCrew(returnCrewName(crewID));
|
setSnapmaticCrew(returnCrewName(crewID));
|
||||||
|
@ -191,7 +212,8 @@ void SnapmaticEditor::setSnapmaticPicture(SnapmaticPicture *picture)
|
||||||
|
|
||||||
void SnapmaticEditor::insertPlayerNames(QStringList *players)
|
void SnapmaticEditor::insertPlayerNames(QStringList *players)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < players->size(); ++i) {
|
for (int i = 0; i < players->size(); ++i)
|
||||||
|
{
|
||||||
players->replace(i, profileDB->getPlayerName(players->at(i)));
|
players->replace(i, profileDB->getPlayerName(players->at(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,48 +229,54 @@ void SnapmaticEditor::setSnapmaticPlayers(const QStringList &players)
|
||||||
{
|
{
|
||||||
QString editStr = QString("<a href=\"g5e://editplayers\" style=\"text-decoration: none;\">%1</a>").arg(tr("Edit"));
|
QString editStr = QString("<a href=\"g5e://editplayers\" style=\"text-decoration: none;\">%1</a>").arg(tr("Edit"));
|
||||||
QString playersStr;
|
QString playersStr;
|
||||||
if (players.length() != 1) {
|
if (players.length() != 1)
|
||||||
|
{
|
||||||
playersStr = tr("Players: %1 (%2)", "Multiple Player are inserted here");
|
playersStr = tr("Players: %1 (%2)", "Multiple Player are inserted here");
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
playersStr = tr("Player: %1 (%2)", "One Player is inserted here");
|
playersStr = tr("Player: %1 (%2)", "One Player is inserted here");
|
||||||
}
|
}
|
||||||
if (players.length() != 0) {
|
if (players.length() != 0)
|
||||||
|
{
|
||||||
ui->labPlayers->setText(playersStr.arg(players.join(", "), editStr));
|
ui->labPlayers->setText(playersStr.arg(players.join(", "), editStr));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->labPlayers->setText(playersStr.arg(QApplication::translate("PictureDialog", "No Players"), editStr));
|
ui->labPlayers->setText(playersStr.arg(QApplication::translate("PictureDialog", "No Players"), editStr));
|
||||||
}
|
}
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
ui->gbValues->resize(ui->gbValues->width(), ui->gbValues->heightForWidth(ui->gbValues->width()));
|
ui->gbValues->resize(ui->gbValues->width(), ui->gbValues->heightForWidth(ui->gbValues->width()));
|
||||||
ui->frameWidget->resize(ui->gbValues->width(), ui->frameWidget->heightForWidth(ui->frameWidget->width()));
|
ui->frameWidget->resize(ui->gbValues->width(), ui->frameWidget->heightForWidth(ui->frameWidget->width()));
|
||||||
if (heightForWidth(width()) > height())
|
if (heightForWidth(width()) > height()) { resize(width(), heightForWidth(width())); }
|
||||||
resize(width(), heightForWidth(width()));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnapmaticEditor::setSnapmaticTitle(const QString &title)
|
void SnapmaticEditor::setSnapmaticTitle(const QString &title)
|
||||||
{
|
{
|
||||||
if (title.length() > 39) {
|
if (title.length() > 39)
|
||||||
|
{
|
||||||
snapmaticTitle = title.left(39);
|
snapmaticTitle = title.left(39);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
snapmaticTitle = title;
|
snapmaticTitle = title;
|
||||||
}
|
}
|
||||||
QString editStr = QString("<a href=\"g5e://edittitle\" style=\"text-decoration: none;\">%1</a>").arg(tr("Edit"));
|
QString editStr = QString("<a href=\"g5e://edittitle\" style=\"text-decoration: none;\">%1</a>").arg(tr("Edit"));
|
||||||
QString titleStr = tr("Title: %1 (%2)").arg(StringParser::escapeString(snapmaticTitle), editStr);
|
QString titleStr = tr("Title: %1 (%2)").arg(StringParser::escapeString(snapmaticTitle), editStr);
|
||||||
ui->labTitle->setText(titleStr);
|
ui->labTitle->setText(titleStr);
|
||||||
if (SnapmaticPicture::verifyTitle(snapmaticTitle)) {
|
if (SnapmaticPicture::verifyTitle(snapmaticTitle))
|
||||||
|
{
|
||||||
ui->labAppropriate->setText(tr("Appropriate: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes", "Yes, should work fine"))));
|
ui->labAppropriate->setText(tr("Appropriate: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes", "Yes, should work fine"))));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->labAppropriate->setText(tr("Appropriate: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No", "No, could lead to issues"))));
|
ui->labAppropriate->setText(tr("Appropriate: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No", "No, could lead to issues"))));
|
||||||
}
|
}
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
ui->gbValues->resize(ui->gbValues->width(), ui->gbValues->heightForWidth(ui->gbValues->width()));
|
ui->gbValues->resize(ui->gbValues->width(), ui->gbValues->heightForWidth(ui->gbValues->width()));
|
||||||
ui->frameWidget->resize(ui->gbValues->width(), ui->frameWidget->heightForWidth(ui->frameWidget->width()));
|
ui->frameWidget->resize(ui->gbValues->width(), ui->frameWidget->heightForWidth(ui->frameWidget->width()));
|
||||||
if (heightForWidth(width()) > height())
|
if (heightForWidth(width()) > height()) { resize(width(), heightForWidth(width())); }
|
||||||
resize(width(), heightForWidth(width()));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,8 +288,7 @@ void SnapmaticEditor::setSnapmaticCrew(const QString &crew)
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
ui->gbValues->resize(ui->gbValues->width(), ui->gbValues->heightForWidth(ui->gbValues->width()));
|
ui->gbValues->resize(ui->gbValues->width(), ui->gbValues->heightForWidth(ui->gbValues->width()));
|
||||||
ui->frameWidget->resize(ui->gbValues->width(), ui->frameWidget->heightForWidth(ui->frameWidget->width()));
|
ui->frameWidget->resize(ui->gbValues->width(), ui->frameWidget->heightForWidth(ui->frameWidget->width()));
|
||||||
if (heightForWidth(width()) > height())
|
if (heightForWidth(width()) > height()) { resize(width(), heightForWidth(width())); }
|
||||||
resize(width(), heightForWidth(width()));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +304,8 @@ void SnapmaticEditor::on_cmdCancel_clicked()
|
||||||
|
|
||||||
void SnapmaticEditor::on_cmdApply_clicked()
|
void SnapmaticEditor::on_cmdApply_clicked()
|
||||||
{
|
{
|
||||||
if (ui->cbQualify->isChecked()) {
|
if (ui->cbQualify->isChecked())
|
||||||
|
{
|
||||||
qualifyAvatar();
|
qualifyAvatar();
|
||||||
}
|
}
|
||||||
snapmaticProperties.crewID = crewID;
|
snapmaticProperties.crewID = crewID;
|
||||||
|
@ -287,23 +315,27 @@ void SnapmaticEditor::on_cmdApply_clicked()
|
||||||
snapmaticProperties.isFromDirector = ui->cbDirector->isChecked();
|
snapmaticProperties.isFromDirector = ui->cbDirector->isChecked();
|
||||||
snapmaticProperties.isMeme = ui->cbMeme->isChecked();
|
snapmaticProperties.isMeme = ui->cbMeme->isChecked();
|
||||||
snapmaticProperties.playersList = playersList;
|
snapmaticProperties.playersList = playersList;
|
||||||
if (smpic) {
|
if (smpic)
|
||||||
|
{
|
||||||
QString currentFilePath = smpic->getPictureFilePath();
|
QString currentFilePath = smpic->getPictureFilePath();
|
||||||
QString originalFilePath = smpic->getOriginalPictureFilePath();
|
QString originalFilePath = smpic->getOriginalPictureFilePath();
|
||||||
QString backupFileName = originalFilePath % ".bak";
|
QString backupFileName = originalFilePath % ".bak";
|
||||||
if (!QFile::exists(backupFileName)) {
|
if (!QFile::exists(backupFileName))
|
||||||
|
{
|
||||||
QFile::copy(currentFilePath, backupFileName);
|
QFile::copy(currentFilePath, backupFileName);
|
||||||
}
|
}
|
||||||
SnapmaticProperties fallbackProperties = smpic->getSnapmaticProperties();
|
SnapmaticProperties fallbackProperties = smpic->getSnapmaticProperties();
|
||||||
QString fallbackTitle = smpic->getPictureTitle();
|
QString fallbackTitle = smpic->getPictureTitle();
|
||||||
smpic->setSnapmaticProperties(snapmaticProperties);
|
smpic->setSnapmaticProperties(snapmaticProperties);
|
||||||
smpic->setPictureTitle(snapmaticTitle);
|
smpic->setPictureTitle(snapmaticTitle);
|
||||||
if (!smpic->exportPicture(currentFilePath)) {
|
if (!smpic->exportPicture(currentFilePath))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, tr("Snapmatic Properties"), tr("Patching of Snapmatic Properties failed because of I/O Error"));
|
QMessageBox::warning(this, tr("Snapmatic Properties"), tr("Patching of Snapmatic Properties failed because of I/O Error"));
|
||||||
smpic->setSnapmaticProperties(fallbackProperties);
|
smpic->setSnapmaticProperties(fallbackProperties);
|
||||||
smpic->setPictureTitle(fallbackTitle);
|
smpic->setPictureTitle(fallbackTitle);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
smpic->updateStrings();
|
smpic->updateStrings();
|
||||||
smpic->emitUpdate();
|
smpic->emitUpdate();
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
#ifdef GTA5SYNC_TELEMETRY
|
||||||
|
@ -311,16 +343,13 @@ void SnapmaticEditor::on_cmdApply_clicked()
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
telemetrySettings.beginGroup("Telemetry");
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
||||||
telemetrySettings.endGroup();
|
telemetrySettings.endGroup();
|
||||||
if (pushUsageData && Telemetry->canPush()) {
|
if (pushUsageData && Telemetry->canPush())
|
||||||
|
{
|
||||||
QJsonDocument jsonDocument;
|
QJsonDocument jsonDocument;
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "PropertyEdited";
|
jsonObject["Type"] = "PropertyEdited";
|
||||||
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
|
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
|
@ -340,7 +369,8 @@ void SnapmaticEditor::qualifyAvatar()
|
||||||
|
|
||||||
void SnapmaticEditor::on_cbQualify_toggled(bool checked)
|
void SnapmaticEditor::on_cbQualify_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked)
|
||||||
|
{
|
||||||
ui->cbMeme->setEnabled(false);
|
ui->cbMeme->setEnabled(false);
|
||||||
ui->cbDirector->setEnabled(false);
|
ui->cbDirector->setEnabled(false);
|
||||||
ui->rbCustom->setEnabled(false);
|
ui->rbCustom->setEnabled(false);
|
||||||
|
@ -348,13 +378,15 @@ void SnapmaticEditor::on_cbQualify_toggled(bool checked)
|
||||||
ui->rbEditor->setEnabled(false);
|
ui->rbEditor->setEnabled(false);
|
||||||
ui->rbMugshot->setEnabled(false);
|
ui->rbMugshot->setEnabled(false);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->cbMeme->setEnabled(true);
|
ui->cbMeme->setEnabled(true);
|
||||||
ui->rbCustom->setEnabled(true);
|
ui->rbCustom->setEnabled(true);
|
||||||
ui->rbSelfie->setEnabled(true);
|
ui->rbSelfie->setEnabled(true);
|
||||||
ui->rbEditor->setEnabled(true);
|
ui->rbEditor->setEnabled(true);
|
||||||
ui->rbMugshot->setEnabled(true);
|
ui->rbMugshot->setEnabled(true);
|
||||||
if (ui->rbSelfie->isChecked() || ui->rbCustom->isChecked()) {
|
if (ui->rbSelfie->isChecked() || ui->rbCustom->isChecked())
|
||||||
|
{
|
||||||
ui->cbDirector->setEnabled(true);
|
ui->cbDirector->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +394,8 @@ void SnapmaticEditor::on_cbQualify_toggled(bool checked)
|
||||||
|
|
||||||
void SnapmaticEditor::on_labPlayers_linkActivated(const QString &link)
|
void SnapmaticEditor::on_labPlayers_linkActivated(const QString &link)
|
||||||
{
|
{
|
||||||
if (link == "g5e://editplayers") {
|
if (link == "g5e://editplayers")
|
||||||
|
{
|
||||||
PlayerListDialog *playerListDialog = new PlayerListDialog(playersList, profileDB, this);
|
PlayerListDialog *playerListDialog = new PlayerListDialog(playersList, profileDB, this);
|
||||||
connect(playerListDialog, SIGNAL(playerListUpdated(QStringList)), this, SLOT(playerListUpdated(QStringList)));
|
connect(playerListDialog, SIGNAL(playerListUpdated(QStringList)), this, SLOT(playerListUpdated(QStringList)));
|
||||||
playerListDialog->setModal(true);
|
playerListDialog->setModal(true);
|
||||||
|
@ -374,10 +407,12 @@ void SnapmaticEditor::on_labPlayers_linkActivated(const QString &link)
|
||||||
|
|
||||||
void SnapmaticEditor::on_labTitle_linkActivated(const QString &link)
|
void SnapmaticEditor::on_labTitle_linkActivated(const QString &link)
|
||||||
{
|
{
|
||||||
if (link == "g5e://edittitle") {
|
if (link == "g5e://edittitle")
|
||||||
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
QString newTitle = QInputDialog::getText(this, tr("Snapmatic Title"), tr("New Snapmatic title:"), QLineEdit::Normal, snapmaticTitle, &ok, windowFlags());
|
QString newTitle = QInputDialog::getText(this, tr("Snapmatic Title"), tr("New Snapmatic title:"), QLineEdit::Normal, snapmaticTitle, &ok, windowFlags());
|
||||||
if (ok && !newTitle.isEmpty()) {
|
if (ok && !newTitle.isEmpty())
|
||||||
|
{
|
||||||
setSnapmaticTitle(newTitle);
|
setSnapmaticTitle(newTitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,33 +420,39 @@ void SnapmaticEditor::on_labTitle_linkActivated(const QString &link)
|
||||||
|
|
||||||
void SnapmaticEditor::on_labCrew_linkActivated(const QString &link)
|
void SnapmaticEditor::on_labCrew_linkActivated(const QString &link)
|
||||||
{
|
{
|
||||||
if (link == "g5e://editcrew") {
|
if (link == "g5e://editcrew")
|
||||||
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
int indexNum = 0;
|
int indexNum = 0;
|
||||||
QStringList itemList;
|
QStringList itemList;
|
||||||
QStringList crewList = crewDB->getCrews();
|
QStringList crewList = crewDB->getCrews();
|
||||||
if (!crewList.contains(QLatin1String("0"))) {
|
if (!crewList.contains(QLatin1String("0")))
|
||||||
|
{
|
||||||
crewList += QLatin1String("0");
|
crewList += QLatin1String("0");
|
||||||
}
|
}
|
||||||
crewList.sort();
|
crewList.sort();
|
||||||
for (const QString &crew : crewList) {
|
for (QString crew : crewList)
|
||||||
|
{
|
||||||
itemList += QString("%1 (%2)").arg(crew, returnCrewName(crew.toInt()));
|
itemList += QString("%1 (%2)").arg(crew, returnCrewName(crew.toInt()));
|
||||||
}
|
}
|
||||||
if (crewList.contains(QString::number(crewID))) {
|
if (crewList.contains(QString::number(crewID)))
|
||||||
|
{
|
||||||
indexNum = crewList.indexOf(QString::number(crewID));
|
indexNum = crewList.indexOf(QString::number(crewID));
|
||||||
}
|
}
|
||||||
QString newCrew = QInputDialog::getItem(this, tr("Snapmatic Crew"), tr("New Snapmatic crew:"), itemList, indexNum, true, &ok, windowFlags());
|
QString newCrew = QInputDialog::getItem(this, tr("Snapmatic Crew"), tr("New Snapmatic crew:"), itemList, indexNum, true, &ok, windowFlags());
|
||||||
if (ok && !newCrew.isEmpty()) {
|
if (ok && !newCrew.isEmpty())
|
||||||
if (newCrew.contains(" "))
|
{
|
||||||
newCrew = newCrew.split(" ").at(0);
|
if (newCrew.contains(" ")) newCrew = newCrew.split(" ").at(0);
|
||||||
if (newCrew.length() > 10)
|
if (newCrew.length() > 10) return;
|
||||||
return;
|
for (QChar crewChar : newCrew)
|
||||||
for (const QChar &crewChar : qAsConst(newCrew)) {
|
{
|
||||||
if (!crewChar.isNumber()) {
|
if (!crewChar.isNumber())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!crewList.contains(newCrew)) {
|
if (!crewList.contains(newCrew))
|
||||||
|
{
|
||||||
crewDB->addCrew(crewID);
|
crewDB->addCrew(crewID);
|
||||||
}
|
}
|
||||||
crewID = newCrew.toInt();
|
crewID = newCrew.toInt();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5spv Grand Theft Auto Snapmatic Picture Viewer
|
* gta5spv Grand Theft Auto Snapmatic Picture Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -34,8 +34,6 @@
|
||||||
|
|
||||||
#if QT_VERSION < 0x060000
|
#if QT_VERSION < 0x060000
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#else
|
|
||||||
#include <QStringDecoder>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
|
@ -86,7 +84,8 @@ bool SnapmaticPicture::preloadFile()
|
||||||
|
|
||||||
isFormatSwitch = false;
|
isFormatSwitch = false;
|
||||||
|
|
||||||
if (!picFile->open(QFile::ReadOnly)) {
|
if (!picFile->open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
lastStep = "1;/1,OpenFile," % convertDrawStringForLog(picFilePath);
|
lastStep = "1;/1,OpenFile," % convertDrawStringForLog(picFilePath);
|
||||||
delete picFile;
|
delete picFile;
|
||||||
return false;
|
return false;
|
||||||
|
@ -99,7 +98,8 @@ bool SnapmaticPicture::preloadFile()
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (picFilePath.right(4) != QLatin1String(".g5e")) {
|
if (picFilePath.right(4) != QLatin1String(".g5e"))
|
||||||
|
{
|
||||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX)
|
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX)
|
||||||
isFormatSwitch = true;
|
isFormatSwitch = true;
|
||||||
}
|
}
|
||||||
|
@ -122,9 +122,9 @@ bool SnapmaticPicture::readingPicture(bool cacheEnabled_)
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (cacheEnabled)
|
if (cacheEnabled) picOk = cachePicture.loadFromData(p_ragePhoto.photoData(), "JPEG");
|
||||||
picOk = cachePicture.loadFromData(p_ragePhoto.photoData(), "JPEG");
|
if (!cacheEnabled)
|
||||||
if (!cacheEnabled) {
|
{
|
||||||
QImage tempPicture;
|
QImage tempPicture;
|
||||||
picOk = tempPicture.loadFromData(p_ragePhoto.photoData(), "JPEG");
|
picOk = tempPicture.loadFromData(p_ragePhoto.photoData(), "JPEG");
|
||||||
}
|
}
|
||||||
|
@ -154,29 +154,26 @@ void SnapmaticPicture::updateStrings()
|
||||||
pictureStr = tr("PHOTO - %1").arg(localProperties.createdDateTime.toString("MM/dd/yy HH:mm:ss"));
|
pictureStr = tr("PHOTO - %1").arg(localProperties.createdDateTime.toString("MM/dd/yy HH:mm:ss"));
|
||||||
sortStr = localProperties.createdDateTime.toString("yyMMddHHmmss") % QString::number(localProperties.uid);
|
sortStr = localProperties.createdDateTime.toString("yyMMddHHmmss") % QString::number(localProperties.uid);
|
||||||
QString exportStr = localProperties.createdDateTime.toString("yyyyMMdd") % "-" % QString::number(localProperties.uid);
|
QString exportStr = localProperties.createdDateTime.toString("yyyyMMdd") % "-" % QString::number(localProperties.uid);
|
||||||
if (getSnapmaticFormat() == SnapmaticFormat::G5E_Format)
|
if (getSnapmaticFormat() == SnapmaticFormat::G5E_Format) picFileName = "PGTA5" % QString::number(localProperties.uid);
|
||||||
picFileName = "PGTA5" % QString::number(localProperties.uid);
|
|
||||||
picExportFileName = exportStr % "_" % cmpPicTitl;
|
picExportFileName = exportStr % "_" % cmpPicTitl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SnapmaticPicture::readingPictureFromFile(const QString &fileName, bool cacheEnabled_)
|
bool SnapmaticPicture::readingPictureFromFile(const QString &fileName, bool cacheEnabled_)
|
||||||
{
|
{
|
||||||
if (!fileName.isEmpty()) {
|
if (!fileName.isEmpty())
|
||||||
|
{
|
||||||
picFilePath = fileName;
|
picFilePath = fileName;
|
||||||
return readingPicture(cacheEnabled_);
|
return readingPicture(cacheEnabled_);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SnapmaticPicture::setImage(const QImage &picture, bool eXtendMode)
|
bool SnapmaticPicture::setImage(const QImage &picture, bool eXtendMode)
|
||||||
{
|
{
|
||||||
#ifdef GTA5SYNC_DYNAMIC_PHOTOBUFFER
|
|
||||||
quint32 jpegPicStreamLength = p_ragePhoto.photoBuffer();
|
quint32 jpegPicStreamLength = p_ragePhoto.photoBuffer();
|
||||||
#else
|
|
||||||
quint32 jpegPicStreamLength = 524288U;
|
|
||||||
#endif
|
|
||||||
QByteArray picByteArray;
|
QByteArray picByteArray;
|
||||||
int comLvl = 100;
|
int comLvl = 100;
|
||||||
bool saveSuccess = false;
|
bool saveSuccess = false;
|
||||||
|
@ -199,11 +196,6 @@ bool SnapmaticPicture::setImage(const QImage &picture, bool eXtendMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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;
|
picByteArray = picByteArrayT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,10 +244,12 @@ QString SnapmaticPicture::getExportPictureFileName()
|
||||||
QString SnapmaticPicture::getOriginalPictureFileName()
|
QString SnapmaticPicture::getOriginalPictureFileName()
|
||||||
{
|
{
|
||||||
QString newPicFileName = picFileName;
|
QString newPicFileName = picFileName;
|
||||||
if (picFileName.right(4) == ".bak") {
|
if (picFileName.right(4) == ".bak")
|
||||||
|
{
|
||||||
newPicFileName = QString(picFileName).remove(picFileName.length() - 4, 4);
|
newPicFileName = QString(picFileName).remove(picFileName.length() - 4, 4);
|
||||||
}
|
}
|
||||||
if (picFileName.right(7) == ".hidden") {
|
if (picFileName.right(7) == ".hidden")
|
||||||
|
{
|
||||||
newPicFileName = QString(picFileName).remove(picFileName.length() - 7, 7);
|
newPicFileName = QString(picFileName).remove(picFileName.length() - 7, 7);
|
||||||
}
|
}
|
||||||
return newPicFileName;
|
return newPicFileName;
|
||||||
|
@ -264,10 +258,12 @@ QString SnapmaticPicture::getOriginalPictureFileName()
|
||||||
QString SnapmaticPicture::getOriginalPictureFilePath()
|
QString SnapmaticPicture::getOriginalPictureFilePath()
|
||||||
{
|
{
|
||||||
QString newPicFilePath = picFilePath;
|
QString newPicFilePath = picFilePath;
|
||||||
if (picFilePath.right(4) == ".bak") {
|
if (picFilePath.right(4) == ".bak")
|
||||||
|
{
|
||||||
newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 4, 4);
|
newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 4, 4);
|
||||||
}
|
}
|
||||||
if (picFilePath.right(7) == ".hidden") {
|
if (picFilePath.right(7) == ".hidden")
|
||||||
|
{
|
||||||
newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7);
|
newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7);
|
||||||
}
|
}
|
||||||
return newPicFilePath;
|
return newPicFilePath;
|
||||||
|
@ -300,65 +296,79 @@ QString SnapmaticPicture::getPictureStr()
|
||||||
|
|
||||||
QString SnapmaticPicture::getLastStep(bool readable)
|
QString SnapmaticPicture::getLastStep(bool readable)
|
||||||
{
|
{
|
||||||
if (readable) {
|
if (readable)
|
||||||
|
{
|
||||||
QStringList lastStepList = lastStep.split(";/");
|
QStringList lastStepList = lastStep.split(";/");
|
||||||
if (lastStepList.length() < 2)
|
if (lastStepList.length() < 2) { return lastStep; }
|
||||||
return lastStep;
|
|
||||||
bool intOk;
|
bool intOk;
|
||||||
QStringList descStepList = lastStepList.at(1).split(",");
|
QStringList descStepList = lastStepList.at(1).split(",");
|
||||||
if (descStepList.length() < 1)
|
if (descStepList.length() < 1) { return lastStep; }
|
||||||
return lastStep;
|
|
||||||
int argsCount = descStepList.at(0).toInt(&intOk);
|
int argsCount = descStepList.at(0).toInt(&intOk);
|
||||||
if (!intOk) { return lastStep; }
|
if (!intOk) { return lastStep; }
|
||||||
if (argsCount == 1) {
|
if (argsCount == 1)
|
||||||
|
{
|
||||||
QString currentAction = descStepList.at(1);
|
QString currentAction = descStepList.at(1);
|
||||||
QString actionFile = descStepList.at(2);
|
QString actionFile = descStepList.at(2);
|
||||||
if (currentAction == "OpenFile") {
|
if (currentAction == "OpenFile")
|
||||||
|
{
|
||||||
return tr("open file %1").arg(actionFile);
|
return tr("open file %1").arg(actionFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (argsCount == 3 || argsCount == 4) {
|
else if (argsCount == 3 || argsCount == 4)
|
||||||
|
{
|
||||||
QString currentAction = descStepList.at(1);
|
QString currentAction = descStepList.at(1);
|
||||||
QString actionFile = descStepList.at(2);
|
QString actionFile = descStepList.at(2);
|
||||||
QString actionError = descStepList.at(4);
|
QString actionError = descStepList.at(4);
|
||||||
QString actionError2;
|
QString actionError2;
|
||||||
if (argsCount == 4) { actionError2 = descStepList.at(5); }
|
if (argsCount == 4) { actionError2 = descStepList.at(5); }
|
||||||
if (currentAction == "ReadingFile") {
|
if (currentAction == "ReadingFile")
|
||||||
|
{
|
||||||
QString readableError = actionError;
|
QString readableError = actionError;
|
||||||
if (actionError == "NOHEADER") {
|
if (actionError == "NOHEADER")
|
||||||
|
{
|
||||||
readableError = tr("header not exists");
|
readableError = tr("header not exists");
|
||||||
}
|
}
|
||||||
else if (actionError == "MALFORMEDHEADER") {
|
else if (actionError == "MALFORMEDHEADER")
|
||||||
|
{
|
||||||
readableError = tr("header is malformed");
|
readableError = tr("header is malformed");
|
||||||
}
|
}
|
||||||
else if (actionError == "NOJPEG" || actionError == "NOPIC") {
|
else if (actionError == "NOJPEG" || actionError == "NOPIC")
|
||||||
|
{
|
||||||
readableError = tr("picture not exists (%1)").arg(actionError);
|
readableError = tr("picture not exists (%1)").arg(actionError);
|
||||||
}
|
}
|
||||||
else if (actionError == "NOJSON" || actionError == "CTJSON") {
|
else if (actionError == "NOJSON" || actionError == "CTJSON")
|
||||||
|
{
|
||||||
readableError = tr("JSON not exists (%1)").arg(actionError);
|
readableError = tr("JSON not exists (%1)").arg(actionError);
|
||||||
}
|
}
|
||||||
else if (actionError == "NOTITL" || actionError == "CTTITL") {
|
else if (actionError == "NOTITL" || actionError == "CTTITL")
|
||||||
|
{
|
||||||
readableError = tr("title not exists (%1)").arg(actionError);
|
readableError = tr("title not exists (%1)").arg(actionError);
|
||||||
}
|
}
|
||||||
else if (actionError == "NODESC" || actionError == "CTDESC") {
|
else if (actionError == "NODESC" || actionError == "CTDESC")
|
||||||
|
{
|
||||||
readableError = tr("description not exists (%1)").arg(actionError);
|
readableError = tr("description not exists (%1)").arg(actionError);
|
||||||
}
|
}
|
||||||
else if (actionError == "JSONINCOMPLETE" && actionError2 == "JSONERROR") {
|
else if (actionError == "JSONINCOMPLETE" && actionError2 == "JSONERROR")
|
||||||
|
{
|
||||||
readableError = tr("JSON is incomplete and malformed");
|
readableError = tr("JSON is incomplete and malformed");
|
||||||
}
|
}
|
||||||
else if (actionError == "JSONINCOMPLETE") {
|
else if (actionError == "JSONINCOMPLETE")
|
||||||
|
{
|
||||||
readableError = tr("JSON is incomplete");
|
readableError = tr("JSON is incomplete");
|
||||||
}
|
}
|
||||||
else if (actionError == "JSONERROR") {
|
else if (actionError == "JSONERROR")
|
||||||
|
{
|
||||||
readableError = tr("JSON is malformed");
|
readableError = tr("JSON is malformed");
|
||||||
}
|
}
|
||||||
return tr("reading file %1 because of %2", "Example for %2: JSON is malformed error").arg(actionFile, readableError);
|
return tr("reading file %1 because of %2", "Example for %2: JSON is malformed error").arg(actionFile, readableError);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
return lastStep;
|
return lastStep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
return lastStep;
|
return lastStep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,20 +437,25 @@ void SnapmaticPicture::parseJsonContent()
|
||||||
|
|
||||||
bool jsonIncomplete = false;
|
bool jsonIncomplete = false;
|
||||||
bool jsonError = false;
|
bool jsonError = false;
|
||||||
if (jsonObject.contains("loc")) {
|
if (jsonObject.contains("loc"))
|
||||||
if (jsonObject["loc"].isObject()) {
|
{
|
||||||
|
if (jsonObject["loc"].isObject())
|
||||||
|
{
|
||||||
QJsonObject locObject = jsonObject["loc"].toObject();
|
QJsonObject locObject = jsonObject["loc"].toObject();
|
||||||
if (locObject.contains("x")) {
|
if (locObject.contains("x"))
|
||||||
|
{
|
||||||
if (locObject["x"].isDouble()) { localProperties.location.x = locObject["x"].toDouble(); }
|
if (locObject["x"].isDouble()) { localProperties.location.x = locObject["x"].toDouble(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (locObject.contains("y")) {
|
if (locObject.contains("y"))
|
||||||
|
{
|
||||||
if (locObject["y"].isDouble()) { localProperties.location.y = locObject["y"].toDouble(); }
|
if (locObject["y"].isDouble()) { localProperties.location.y = locObject["y"].toDouble(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (locObject.contains("z")) {
|
if (locObject.contains("z"))
|
||||||
|
{
|
||||||
if (locObject["z"].isDouble()) { localProperties.location.z = locObject["z"].toDouble(); }
|
if (locObject["z"].isDouble()) { localProperties.location.z = locObject["z"].toDouble(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
|
@ -449,30 +464,35 @@ void SnapmaticPicture::parseJsonContent()
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("uid")) {
|
if (jsonObject.contains("uid"))
|
||||||
|
{
|
||||||
bool uidOk;
|
bool uidOk;
|
||||||
localProperties.uid = jsonMap["uid"].toInt(&uidOk);
|
localProperties.uid = jsonMap["uid"].toInt(&uidOk);
|
||||||
if (!uidOk) { jsonError = true; }
|
if (!uidOk) { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("area")) {
|
if (jsonObject.contains("area"))
|
||||||
|
{
|
||||||
if (jsonObject["area"].isString()) { localProperties.location.area = jsonObject["area"].toString(); }
|
if (jsonObject["area"].isString()) { localProperties.location.area = jsonObject["area"].toString(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("crewid")) {
|
if (jsonObject.contains("crewid"))
|
||||||
|
{
|
||||||
bool crewIDOk;
|
bool crewIDOk;
|
||||||
localProperties.crewID = jsonMap["crewid"].toInt(&crewIDOk);
|
localProperties.crewID = jsonMap["crewid"].toInt(&crewIDOk);
|
||||||
if (!crewIDOk) { jsonError = true; }
|
if (!crewIDOk) { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("street")) {
|
if (jsonObject.contains("street"))
|
||||||
|
{
|
||||||
bool streetIDOk;
|
bool streetIDOk;
|
||||||
localProperties.streetID = jsonMap["street"].toInt(&streetIDOk);
|
localProperties.streetID = jsonMap["street"].toInt(&streetIDOk);
|
||||||
if (!streetIDOk) { jsonError = true; }
|
if (!streetIDOk) { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("creat")) {
|
if (jsonObject.contains("creat"))
|
||||||
|
{
|
||||||
bool timestampOk;
|
bool timestampOk;
|
||||||
QDateTime createdTimestamp;
|
QDateTime createdTimestamp;
|
||||||
localProperties.createdTimestamp = jsonMap["creat"].toUInt(×tampOk);
|
localProperties.createdTimestamp = jsonMap["creat"].toUInt(×tampOk);
|
||||||
|
@ -485,53 +505,59 @@ void SnapmaticPicture::parseJsonContent()
|
||||||
if (!timestampOk) { jsonError = true; }
|
if (!timestampOk) { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("plyrs")) {
|
if (jsonObject.contains("plyrs"))
|
||||||
|
{
|
||||||
if (jsonObject["plyrs"].isArray()) { localProperties.playersList = jsonMap["plyrs"].toStringList(); }
|
if (jsonObject["plyrs"].isArray()) { localProperties.playersList = jsonMap["plyrs"].toStringList(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
// else { jsonIncomplete = true; } // 2016 Snapmatic pictures left out plyrs when none are captured, so don't force exists on that one
|
// 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.contains("meme"))
|
||||||
|
{
|
||||||
if (jsonObject["meme"].isBool()) { localProperties.isMeme = jsonObject["meme"].toBool(); }
|
if (jsonObject["meme"].isBool()) { localProperties.isMeme = jsonObject["meme"].toBool(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("mug")) {
|
if (jsonObject.contains("mug"))
|
||||||
|
{
|
||||||
if (jsonObject["mug"].isBool()) { localProperties.isMug = jsonObject["mug"].toBool(); }
|
if (jsonObject["mug"].isBool()) { localProperties.isMug = jsonObject["mug"].toBool(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("slf")) {
|
if (jsonObject.contains("slf"))
|
||||||
|
{
|
||||||
if (jsonObject["slf"].isBool()) { localProperties.isSelfie = jsonObject["slf"].toBool(); }
|
if (jsonObject["slf"].isBool()) { localProperties.isSelfie = jsonObject["slf"].toBool(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("drctr")) {
|
if (jsonObject.contains("drctr"))
|
||||||
|
{
|
||||||
if (jsonObject["drctr"].isBool()) { localProperties.isFromDirector = jsonObject["drctr"].toBool(); }
|
if (jsonObject["drctr"].isBool()) { localProperties.isFromDirector = jsonObject["drctr"].toBool(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { jsonIncomplete = true; }
|
else { jsonIncomplete = true; }
|
||||||
if (jsonObject.contains("rsedtr")) {
|
if (jsonObject.contains("rsedtr"))
|
||||||
|
{
|
||||||
if (jsonObject["rsedtr"].isBool()) { localProperties.isFromRSEditor = jsonObject["rsedtr"].toBool(); }
|
if (jsonObject["rsedtr"].isBool()) { localProperties.isFromRSEditor = jsonObject["rsedtr"].toBool(); }
|
||||||
else { jsonError = true; }
|
else { jsonError = true; }
|
||||||
}
|
}
|
||||||
else { localProperties.isFromRSEditor = false; }
|
// else { jsonIncomplete = true; } // Game release Snapmatic pictures prior May 2015 left out rsedtr, so don't force exists on that one
|
||||||
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) {
|
if (!jsonIncomplete && !jsonError)
|
||||||
|
{
|
||||||
jsonOk = true;
|
jsonOk = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (jsonIncomplete && jsonError) {
|
{
|
||||||
|
if (jsonIncomplete && jsonError)
|
||||||
|
{
|
||||||
lastStep = "2;/4,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE,JSONERROR";
|
lastStep = "2;/4,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE,JSONERROR";
|
||||||
}
|
}
|
||||||
else if (jsonIncomplete) {
|
else if (jsonIncomplete)
|
||||||
|
{
|
||||||
lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE";
|
lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE";
|
||||||
}
|
}
|
||||||
else if (jsonError) {
|
else if (jsonError)
|
||||||
|
{
|
||||||
lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONERROR";
|
lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONERROR";
|
||||||
}
|
}
|
||||||
jsonOk = false;
|
jsonOk = false;
|
||||||
|
@ -559,10 +585,10 @@ bool SnapmaticPicture::setSnapmaticProperties(SnapmaticProperties properties)
|
||||||
jsonObject["slf"] = properties.isSelfie;
|
jsonObject["slf"] = properties.isSelfie;
|
||||||
jsonObject["drctr"] = properties.isFromDirector;
|
jsonObject["drctr"] = properties.isFromDirector;
|
||||||
jsonObject["rsedtr"] = properties.isFromRSEditor;
|
jsonObject["rsedtr"] = properties.isFromRSEditor;
|
||||||
jsonObject["onislandx"] = properties.location.isCayoPerico;
|
|
||||||
|
|
||||||
QJsonDocument jsonDocument(jsonObject);
|
QJsonDocument jsonDocument(jsonObject);
|
||||||
if (setJsonStr(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Compact)))) {
|
if (setJsonStr(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Compact))))
|
||||||
|
{
|
||||||
localProperties = properties;
|
localProperties = properties;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -587,11 +613,14 @@ bool SnapmaticPicture::exportPicture(const QString &fileName, SnapmaticFormat fo
|
||||||
{
|
{
|
||||||
// Keep current format when Auto_Format is used
|
// Keep current format when Auto_Format is used
|
||||||
SnapmaticFormat format = format_;
|
SnapmaticFormat format = format_;
|
||||||
if (format_ == SnapmaticFormat::Auto_Format) {
|
if (format_ == SnapmaticFormat::Auto_Format)
|
||||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
|
{
|
||||||
|
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX)
|
||||||
|
{
|
||||||
format = SnapmaticFormat::G5E_Format;
|
format = SnapmaticFormat::G5E_Format;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
format = SnapmaticFormat::PGTA_Format;
|
format = SnapmaticFormat::PGTA_Format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -602,8 +631,10 @@ bool SnapmaticPicture::exportPicture(const QString &fileName, SnapmaticFormat fo
|
||||||
#else
|
#else
|
||||||
QFile *picFile = new QFile(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp");
|
QFile *picFile = new QFile(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp");
|
||||||
#endif
|
#endif
|
||||||
if (picFile->open(QIODevice::WriteOnly)) {
|
if (picFile->open(QIODevice::WriteOnly))
|
||||||
if (format == SnapmaticFormat::G5E_Format) {
|
{
|
||||||
|
if (format == SnapmaticFormat::G5E_Format)
|
||||||
|
{
|
||||||
p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::G5EX);
|
p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::G5EX);
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
saveSuccess = picFile->commit();
|
saveSuccess = picFile->commit();
|
||||||
|
@ -613,7 +644,8 @@ bool SnapmaticPicture::exportPicture(const QString &fileName, SnapmaticFormat fo
|
||||||
#endif
|
#endif
|
||||||
delete picFile;
|
delete picFile;
|
||||||
}
|
}
|
||||||
else if (format == SnapmaticFormat::JPEG_Format) {
|
else if (format == SnapmaticFormat::JPEG_Format)
|
||||||
|
{
|
||||||
picFile->write(p_ragePhoto.photoData());
|
picFile->write(p_ragePhoto.photoData());
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
saveSuccess = picFile->commit();
|
saveSuccess = picFile->commit();
|
||||||
|
@ -623,7 +655,8 @@ bool SnapmaticPicture::exportPicture(const QString &fileName, SnapmaticFormat fo
|
||||||
#endif
|
#endif
|
||||||
delete picFile;
|
delete picFile;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::GTA5);
|
p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::GTA5);
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
saveSuccess = picFile->commit();
|
saveSuccess = picFile->commit();
|
||||||
|
@ -655,7 +688,8 @@ bool SnapmaticPicture::exportPicture(const QString &fileName, SnapmaticFormat fo
|
||||||
#endif
|
#endif
|
||||||
return saveSuccess;
|
return saveSuccess;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
delete picFile;
|
delete picFile;
|
||||||
return saveSuccess;
|
return saveSuccess;
|
||||||
}
|
}
|
||||||
|
@ -674,13 +708,16 @@ void SnapmaticPicture::setPicFilePath(const QString &picFilePath_)
|
||||||
bool SnapmaticPicture::deletePicFile()
|
bool SnapmaticPicture::deletePicFile()
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (!QFile::exists(picFilePath)) {
|
if (!QFile::exists(picFilePath))
|
||||||
|
{
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
else if (QFile::remove(picFilePath)) {
|
else if (QFile::remove(picFilePath))
|
||||||
|
{
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
if (isHidden()) {
|
if (isHidden())
|
||||||
|
{
|
||||||
const QString picBakPath = QString(picFilePath).remove(picFilePath.length() - 7, 7) % ".bak";
|
const QString picBakPath = QString(picFilePath).remove(picFilePath.length() - 7, 7) % ".bak";
|
||||||
if (QFile::exists(picBakPath)) QFile::remove(picBakPath);
|
if (QFile::exists(picBakPath)) QFile::remove(picBakPath);
|
||||||
}
|
}
|
||||||
|
@ -695,7 +732,8 @@ bool SnapmaticPicture::deletePicFile()
|
||||||
|
|
||||||
bool SnapmaticPicture::isHidden()
|
bool SnapmaticPicture::isHidden()
|
||||||
{
|
{
|
||||||
if (picFilePath.right(7) == QLatin1String(".hidden")) {
|
if (picFilePath.right(7) == QLatin1String(".hidden"))
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -703,7 +741,8 @@ bool SnapmaticPicture::isHidden()
|
||||||
|
|
||||||
bool SnapmaticPicture::isVisible()
|
bool SnapmaticPicture::isVisible()
|
||||||
{
|
{
|
||||||
if (picFilePath.right(7) == QLatin1String(".hidden")) {
|
if (picFilePath.right(7) == QLatin1String(".hidden"))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -711,12 +750,15 @@ bool SnapmaticPicture::isVisible()
|
||||||
|
|
||||||
bool SnapmaticPicture::setPictureHidden()
|
bool SnapmaticPicture::setPictureHidden()
|
||||||
{
|
{
|
||||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
|
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!isHidden()) {
|
if (!isHidden())
|
||||||
|
{
|
||||||
QString newPicFilePath = QString(picFilePath % ".hidden");
|
QString newPicFilePath = QString(picFilePath % ".hidden");
|
||||||
if (QFile::rename(picFilePath, newPicFilePath)) {
|
if (QFile::rename(picFilePath, newPicFilePath))
|
||||||
|
{
|
||||||
picFilePath = newPicFilePath;
|
picFilePath = newPicFilePath;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -727,12 +769,15 @@ bool SnapmaticPicture::setPictureHidden()
|
||||||
|
|
||||||
bool SnapmaticPicture::setPictureVisible()
|
bool SnapmaticPicture::setPictureVisible()
|
||||||
{
|
{
|
||||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
|
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isHidden()) {
|
if (isHidden())
|
||||||
|
{
|
||||||
QString newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7);
|
QString newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7);
|
||||||
if (QFile::rename(picFilePath, newPicFilePath)) {
|
if (QFile::rename(picFilePath, newPicFilePath))
|
||||||
|
{
|
||||||
picFilePath = newPicFilePath;
|
picFilePath = newPicFilePath;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -752,7 +797,8 @@ QSize SnapmaticPicture::getSnapmaticResolution()
|
||||||
|
|
||||||
SnapmaticFormat SnapmaticPicture::getSnapmaticFormat()
|
SnapmaticFormat SnapmaticPicture::getSnapmaticFormat()
|
||||||
{
|
{
|
||||||
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
|
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX)
|
||||||
|
{
|
||||||
return SnapmaticFormat::G5E_Format;
|
return SnapmaticFormat::G5E_Format;
|
||||||
}
|
}
|
||||||
return SnapmaticFormat::PGTA_Format;
|
return SnapmaticFormat::PGTA_Format;
|
||||||
|
@ -760,11 +806,13 @@ SnapmaticFormat SnapmaticPicture::getSnapmaticFormat()
|
||||||
|
|
||||||
void SnapmaticPicture::setSnapmaticFormat(SnapmaticFormat format)
|
void SnapmaticPicture::setSnapmaticFormat(SnapmaticFormat format)
|
||||||
{
|
{
|
||||||
if (format == SnapmaticFormat::G5E_Format) {
|
if (format == SnapmaticFormat::G5E_Format)
|
||||||
|
{
|
||||||
p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::G5EX);
|
p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::G5EX);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (format == SnapmaticFormat::PGTA_Format) {
|
else if (format == SnapmaticFormat::PGTA_Format)
|
||||||
|
{
|
||||||
p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::GTA5);
|
p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::GTA5);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -781,8 +829,10 @@ bool SnapmaticPicture::isFormatSwitched()
|
||||||
bool SnapmaticPicture::verifyTitle(const QString &title)
|
bool SnapmaticPicture::verifyTitle(const QString &title)
|
||||||
{
|
{
|
||||||
// VERIFY TITLE FOR BE A VALID SNAPMATIC TITLE
|
// VERIFY TITLE FOR BE A VALID SNAPMATIC TITLE
|
||||||
if (title.length() <= 39 && title.length() > 0) {
|
if (title.length() <= 39 && title.length() > 0)
|
||||||
for (const QChar &titleChar : title) {
|
{
|
||||||
|
for (const QChar &titleChar : title)
|
||||||
|
{
|
||||||
if (!verifyTitleChar(titleChar)) return false;
|
if (!verifyTitleChar(titleChar)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -793,7 +843,8 @@ bool SnapmaticPicture::verifyTitle(const QString &title)
|
||||||
bool SnapmaticPicture::verifyTitleChar(const QChar &titleChar)
|
bool SnapmaticPicture::verifyTitleChar(const QChar &titleChar)
|
||||||
{
|
{
|
||||||
// VERIFY CHAR FOR BE A VALID SNAPMATIC CHARACTER
|
// VERIFY CHAR FOR BE A VALID SNAPMATIC CHARACTER
|
||||||
if (titleChar.isLetterOrNumber() || titleChar.isPrint()) {
|
if (titleChar.isLetterOrNumber() || titleChar.isPrint())
|
||||||
|
{
|
||||||
if (titleChar == '<' || titleChar == '>' || titleChar == '\\') return false;
|
if (titleChar == '<' || titleChar == '>' || titleChar == '\\') return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ struct SnapmaticProperties {
|
||||||
double x;
|
double x;
|
||||||
double y;
|
double y;
|
||||||
double z;
|
double z;
|
||||||
bool isCayoPerico;
|
|
||||||
};
|
};
|
||||||
int uid;
|
int uid;
|
||||||
int crewID;
|
int crewID;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -85,8 +85,7 @@ void SnapmaticWidget::setSnapmaticPicture(SnapmaticPicture *picture)
|
||||||
QPixmap renderPixmap(renderResolution);
|
QPixmap renderPixmap(renderResolution);
|
||||||
renderPixmap.fill(Qt::transparent);
|
renderPixmap.fill(Qt::transparent);
|
||||||
QPainter renderPainter(&renderPixmap);
|
QPainter renderPainter(&renderPixmap);
|
||||||
const QImage originalImage = picture->getImage();
|
const QImage renderImage = picture->getImage().scaled(renderResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
const QImage renderImage = originalImage.scaled(renderResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation); // Stack smash
|
|
||||||
if (renderImage.width() < renderResolution.width()) {
|
if (renderImage.width() < renderResolution.width()) {
|
||||||
renderPainter.drawImage((renderResolution.width() - renderImage.width()) / 2, 0, renderImage, Qt::AutoColor);
|
renderPainter.drawImage((renderResolution.width() - renderImage.width()) / 2, 0, renderImage, Qt::AutoColor);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +115,8 @@ void SnapmaticWidget::snapmaticUpdated()
|
||||||
|
|
||||||
void SnapmaticWidget::customSignal(QString signal)
|
void SnapmaticWidget::customSignal(QString signal)
|
||||||
{
|
{
|
||||||
if (signal == "PictureUpdated") {
|
if (signal == "PictureUpdated")
|
||||||
|
{
|
||||||
QPixmap SnapmaticPixmap = QPixmap::fromImage(smpic->getImage().scaled(ui->labPicture->width(), ui->labPicture->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::AutoColor);
|
QPixmap SnapmaticPixmap = QPixmap::fromImage(smpic->getImage().scaled(ui->labPicture->width(), ui->labPicture->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::AutoColor);
|
||||||
ui->labPicture->setPixmap(SnapmaticPixmap);
|
ui->labPicture->setPixmap(SnapmaticPixmap);
|
||||||
}
|
}
|
||||||
|
@ -146,8 +146,7 @@ void SnapmaticWidget::on_cmdView_clicked()
|
||||||
QObject::connect(picDialog, SIGNAL(previousPictureRequested()), this, SLOT(dialogPreviousPictureRequested()));
|
QObject::connect(picDialog, SIGNAL(previousPictureRequested()), this, SLOT(dialogPreviousPictureRequested()));
|
||||||
|
|
||||||
// add previous next buttons
|
// add previous next buttons
|
||||||
if (navigationBar)
|
if (navigationBar) picDialog->addPreviousNextButtons();
|
||||||
picDialog->addPreviousNextButtons();
|
|
||||||
|
|
||||||
// show picture dialog
|
// show picture dialog
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
|
@ -176,38 +175,37 @@ void SnapmaticWidget::on_cmdExport_clicked()
|
||||||
|
|
||||||
void SnapmaticWidget::on_cmdDelete_clicked()
|
void SnapmaticWidget::on_cmdDelete_clicked()
|
||||||
{
|
{
|
||||||
if (deletePicture())
|
if (deletePicture()) emit pictureDeleted();
|
||||||
emit pictureDeleted();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SnapmaticWidget::deletePicture()
|
bool SnapmaticWidget::deletePicture()
|
||||||
{
|
{
|
||||||
int uchoice = QMessageBox::question(this, tr("Delete picture"), tr("Are you sure to delete %1 from your Snapmatic pictures?").arg("\""+smpic->getPictureTitle()+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
int uchoice = QMessageBox::question(this, tr("Delete picture"), tr("Are you sure to delete %1 from your Snapmatic pictures?").arg("\""+smpic->getPictureTitle()+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||||
if (uchoice == QMessageBox::Yes) {
|
if (uchoice == QMessageBox::Yes)
|
||||||
if (smpic->deletePictureFile()) {
|
{
|
||||||
|
if (smpic->deletePictureFile())
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
#ifdef GTA5SYNC_TELEMETRY
|
||||||
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
telemetrySettings.beginGroup("Telemetry");
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
||||||
telemetrySettings.endGroup();
|
telemetrySettings.endGroup();
|
||||||
if (pushUsageData && Telemetry->canPush()) {
|
if (pushUsageData && Telemetry->canPush())
|
||||||
|
{
|
||||||
QJsonDocument jsonDocument;
|
QJsonDocument jsonDocument;
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "DeleteSuccess";
|
jsonObject["Type"] = "DeleteSuccess";
|
||||||
jsonObject["ExtraFlags"] = "Snapmatic";
|
jsonObject["ExtraFlags"] = "Snapmatic";
|
||||||
jsonObject["DeletedSize"] = QString::number(smpic->getContentMaxLength());
|
jsonObject["DeletedSize"] = QString::number(smpic->getContentMaxLength());
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
QMessageBox::warning(this, tr("Delete picture"), tr("Failed at deleting %1 from your Snapmatic pictures").arg("\""+smpic->getPictureTitle()+"\""));
|
QMessageBox::warning(this, tr("Delete picture"), tr("Failed at deleting %1 from your Snapmatic pictures").arg("\""+smpic->getPictureTitle()+"\""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,22 +220,29 @@ void SnapmaticWidget::mousePressEvent(QMouseEvent *ev)
|
||||||
void SnapmaticWidget::mouseReleaseEvent(QMouseEvent *ev)
|
void SnapmaticWidget::mouseReleaseEvent(QMouseEvent *ev)
|
||||||
{
|
{
|
||||||
ProfileWidget::mouseReleaseEvent(ev);
|
ProfileWidget::mouseReleaseEvent(ev);
|
||||||
if (ui->cbSelected->isVisible()) {
|
if (ui->cbSelected->isVisible())
|
||||||
if (rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) {
|
{
|
||||||
|
if (rect().contains(ev->pos()) && ev->button() == Qt::LeftButton)
|
||||||
|
{
|
||||||
ui->cbSelected->setChecked(!ui->cbSelected->isChecked());
|
ui->cbSelected->setChecked(!ui->cbSelected->isChecked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
const int contentMode = getContentMode();
|
const int contentMode = getContentMode();
|
||||||
if ((contentMode == 0 || contentMode == 10 || contentMode == 20) && rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) {
|
if ((contentMode == 0 || contentMode == 10 || contentMode == 20) && rect().contains(ev->pos()) && ev->button() == Qt::LeftButton)
|
||||||
if (ev->modifiers().testFlag(Qt::ShiftModifier)) {
|
{
|
||||||
|
if (ev->modifiers().testFlag(Qt::ShiftModifier))
|
||||||
|
{
|
||||||
ui->cbSelected->setChecked(!ui->cbSelected->isChecked());
|
ui->cbSelected->setChecked(!ui->cbSelected->isChecked());
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
on_cmdView_clicked();
|
on_cmdView_clicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton && ev->modifiers().testFlag(Qt::ShiftModifier)) {
|
else if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton && ev->modifiers().testFlag(Qt::ShiftModifier))
|
||||||
|
{
|
||||||
ui->cbSelected->setChecked(!ui->cbSelected->isChecked());
|
ui->cbSelected->setChecked(!ui->cbSelected->isChecked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +253,8 @@ void SnapmaticWidget::mouseDoubleClickEvent(QMouseEvent *ev)
|
||||||
ProfileWidget::mouseDoubleClickEvent(ev);
|
ProfileWidget::mouseDoubleClickEvent(ev);
|
||||||
|
|
||||||
const int contentMode = getContentMode();
|
const int contentMode = getContentMode();
|
||||||
if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton) {
|
if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton)
|
||||||
|
{
|
||||||
on_cmdView_clicked();
|
on_cmdView_clicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,27 +286,32 @@ void SnapmaticWidget::dialogPreviousPictureRequested()
|
||||||
|
|
||||||
void SnapmaticWidget::on_cbSelected_stateChanged(int arg1)
|
void SnapmaticWidget::on_cbSelected_stateChanged(int arg1)
|
||||||
{
|
{
|
||||||
if (arg1 == Qt::Checked) {
|
if (arg1 == Qt::Checked)
|
||||||
|
{
|
||||||
emit widgetSelected();
|
emit widgetSelected();
|
||||||
}
|
}
|
||||||
else if (arg1 == Qt::Unchecked) {
|
else if (arg1 == Qt::Unchecked)
|
||||||
|
{
|
||||||
emit widgetDeselected();
|
emit widgetDeselected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnapmaticWidget::adjustTextColor()
|
void SnapmaticWidget::adjustTextColor()
|
||||||
{
|
{
|
||||||
if (isHidden()) {
|
if (isHidden())
|
||||||
|
{
|
||||||
ui->labPicStr->setStyleSheet(QString("QLabel{color: rgb(%1, %2, %3);}").arg(QString::number(highlightHiddenColor.red()), QString::number(highlightHiddenColor.green()), QString::number(highlightHiddenColor.blue())));
|
ui->labPicStr->setStyleSheet(QString("QLabel{color: rgb(%1, %2, %3);}").arg(QString::number(highlightHiddenColor.red()), QString::number(highlightHiddenColor.green()), QString::number(highlightHiddenColor.blue())));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui->labPicStr->setStyleSheet("");
|
ui->labPicStr->setStyleSheet("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SnapmaticWidget::makePictureHidden()
|
bool SnapmaticWidget::makePictureHidden()
|
||||||
{
|
{
|
||||||
if (smpic->setPictureHidden()) {
|
if (smpic->setPictureHidden())
|
||||||
|
{
|
||||||
adjustTextColor();
|
adjustTextColor();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +320,8 @@ bool SnapmaticWidget::makePictureHidden()
|
||||||
|
|
||||||
bool SnapmaticWidget::makePictureVisible()
|
bool SnapmaticWidget::makePictureVisible()
|
||||||
{
|
{
|
||||||
if (smpic->setPictureVisible()) {
|
if (smpic->setPictureVisible())
|
||||||
|
{
|
||||||
adjustTextColor();
|
adjustTextColor();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -319,13 +331,17 @@ bool SnapmaticWidget::makePictureVisible()
|
||||||
void SnapmaticWidget::makePictureHiddenSlot()
|
void SnapmaticWidget::makePictureHiddenSlot()
|
||||||
{
|
{
|
||||||
if (!makePictureHidden())
|
if (!makePictureHidden())
|
||||||
|
{
|
||||||
QMessageBox::warning(this, QApplication::translate("UserInterface", "Hide In-game"), QApplication::translate("SnapmaticWidget", "Failed to hide %1 In-game from your Snapmatic pictures").arg("\""+smpic->getPictureTitle()+"\""));
|
QMessageBox::warning(this, QApplication::translate("UserInterface", "Hide In-game"), QApplication::translate("SnapmaticWidget", "Failed to hide %1 In-game from your Snapmatic pictures").arg("\""+smpic->getPictureTitle()+"\""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnapmaticWidget::makePictureVisibleSlot()
|
void SnapmaticWidget::makePictureVisibleSlot()
|
||||||
{
|
{
|
||||||
if (!makePictureVisible())
|
if (!makePictureVisible())
|
||||||
|
{
|
||||||
QMessageBox::warning(this, QApplication::translate("UserInterface", "Show In-game"), QApplication::translate("SnapmaticWidget", "Failed to show %1 In-game from your Snapmatic pictures").arg("\""+smpic->getPictureTitle()+"\""));
|
QMessageBox::warning(this, QApplication::translate("UserInterface", "Show In-game"), QApplication::translate("SnapmaticWidget", "Failed to show %1 In-game from your Snapmatic pictures").arg("\""+smpic->getPictureTitle()+"\""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnapmaticWidget::editSnapmaticProperties()
|
void SnapmaticWidget::editSnapmaticProperties()
|
||||||
|
@ -355,17 +371,21 @@ void SnapmaticWidget::editSnapmaticImage()
|
||||||
importDialog->enableOverwriteMode();
|
importDialog->enableOverwriteMode();
|
||||||
importDialog->setModal(true);
|
importDialog->setModal(true);
|
||||||
importDialog->exec();
|
importDialog->exec();
|
||||||
if (importDialog->isImportAgreed()) {
|
if (importDialog->isImportAgreed())
|
||||||
|
{
|
||||||
const QByteArray previousPicture = smpic->getPictureStream();
|
const QByteArray previousPicture = smpic->getPictureStream();
|
||||||
bool success = smpic->setImage(importDialog->image(), importDialog->isUnlimitedBuffer());
|
bool success = smpic->setImage(importDialog->image());
|
||||||
if (success) {
|
if (success)
|
||||||
|
{
|
||||||
QString currentFilePath = smpic->getPictureFilePath();
|
QString currentFilePath = smpic->getPictureFilePath();
|
||||||
QString originalFilePath = smpic->getOriginalPictureFilePath();
|
QString originalFilePath = smpic->getOriginalPictureFilePath();
|
||||||
QString backupFileName = originalFilePath % ".bak";
|
QString backupFileName = originalFilePath % ".bak";
|
||||||
if (!QFile::exists(backupFileName)) {
|
if (!QFile::exists(backupFileName))
|
||||||
|
{
|
||||||
QFile::copy(currentFilePath, backupFileName);
|
QFile::copy(currentFilePath, backupFileName);
|
||||||
}
|
}
|
||||||
if (!smpic->exportPicture(currentFilePath)) {
|
if (!smpic->exportPicture(currentFilePath))
|
||||||
|
{
|
||||||
smpic->setPictureStream(previousPicture);
|
smpic->setPictureStream(previousPicture);
|
||||||
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of I/O Error"));
|
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of I/O Error"));
|
||||||
return;
|
return;
|
||||||
|
@ -376,23 +396,21 @@ void SnapmaticWidget::editSnapmaticImage()
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
telemetrySettings.beginGroup("Telemetry");
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
||||||
telemetrySettings.endGroup();
|
telemetrySettings.endGroup();
|
||||||
if (pushUsageData && Telemetry->canPush()) {
|
if (pushUsageData && Telemetry->canPush())
|
||||||
|
{
|
||||||
QJsonDocument jsonDocument;
|
QJsonDocument jsonDocument;
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "ImageEdited";
|
jsonObject["Type"] = "ImageEdited";
|
||||||
jsonObject["ExtraFlags"] = "Interface";
|
jsonObject["ExtraFlags"] = "Interface";
|
||||||
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
|
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of Image Error"));
|
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of Image Error"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -403,48 +421,48 @@ void SnapmaticWidget::editSnapmaticImage()
|
||||||
void SnapmaticWidget::openMapViewer()
|
void SnapmaticWidget::openMapViewer()
|
||||||
{
|
{
|
||||||
SnapmaticPicture *picture = smpic;
|
SnapmaticPicture *picture = smpic;
|
||||||
SnapmaticProperties currentProperties = picture->getSnapmaticProperties();
|
MapLocationDialog *mapLocDialog = new MapLocationDialog(picture->getSnapmaticProperties().location.x, picture->getSnapmaticProperties().location.y, this);
|
||||||
MapLocationDialog *mapLocDialog = new MapLocationDialog(currentProperties.location.x, currentProperties.location.y, this);
|
|
||||||
mapLocDialog->setCayoPerico(currentProperties.location.isCayoPerico);
|
|
||||||
mapLocDialog->setModal(true);
|
mapLocDialog->setModal(true);
|
||||||
mapLocDialog->show();
|
mapLocDialog->show();
|
||||||
mapLocDialog->exec();
|
mapLocDialog->exec();
|
||||||
if (mapLocDialog->propUpdated()) {
|
if (mapLocDialog->propUpdated())
|
||||||
|
{
|
||||||
// Update Snapmatic Properties
|
// Update Snapmatic Properties
|
||||||
currentProperties.location.x = mapLocDialog->getXpos();
|
SnapmaticProperties localSpJson = picture->getSnapmaticProperties();
|
||||||
currentProperties.location.y = mapLocDialog->getYpos();
|
localSpJson.location.x = mapLocDialog->getXpos();
|
||||||
currentProperties.location.z = 0;
|
localSpJson.location.y = mapLocDialog->getYpos();
|
||||||
|
localSpJson.location.z = 0;
|
||||||
|
|
||||||
// Update Snapmatic Picture
|
// Update Snapmatic Picture
|
||||||
QString currentFilePath = picture->getPictureFilePath();
|
QString currentFilePath = picture->getPictureFilePath();
|
||||||
QString originalFilePath = picture->getOriginalPictureFilePath();
|
QString originalFilePath = picture->getOriginalPictureFilePath();
|
||||||
QString backupFileName = originalFilePath % ".bak";
|
QString backupFileName = originalFilePath % ".bak";
|
||||||
if (!QFile::exists(backupFileName)) {
|
if (!QFile::exists(backupFileName))
|
||||||
|
{
|
||||||
QFile::copy(currentFilePath, backupFileName);
|
QFile::copy(currentFilePath, backupFileName);
|
||||||
}
|
}
|
||||||
SnapmaticProperties fallbackProperties = picture->getSnapmaticProperties();
|
SnapmaticProperties fallbackProperties = picture->getSnapmaticProperties();
|
||||||
picture->setSnapmaticProperties(currentProperties);
|
picture->setSnapmaticProperties(localSpJson);
|
||||||
if (!picture->exportPicture(currentFilePath)) {
|
if (!picture->exportPicture(currentFilePath))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error"));
|
QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error"));
|
||||||
picture->setSnapmaticProperties(fallbackProperties);
|
picture->setSnapmaticProperties(fallbackProperties);
|
||||||
}
|
}
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
#ifdef GTA5SYNC_TELEMETRY
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
telemetrySettings.beginGroup("Telemetry");
|
||||||
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
|
||||||
telemetrySettings.endGroup();
|
telemetrySettings.endGroup();
|
||||||
if (pushUsageData && Telemetry->canPush()) {
|
if (pushUsageData && Telemetry->canPush())
|
||||||
|
{
|
||||||
QJsonDocument jsonDocument;
|
QJsonDocument jsonDocument;
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
jsonObject["Type"] = "LocationEdited";
|
jsonObject["Type"] = "LocationEdited";
|
||||||
jsonObject["ExtraFlags"] = "Interface";
|
jsonObject["ExtraFlags"] = "Interface";
|
||||||
jsonObject["EditedSize"] = QString::number(picture->getContentMaxLength());
|
jsonObject["EditedSize"] = QString::number(picture->getContentMaxLength());
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch());
|
|
||||||
#else
|
|
||||||
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
|
||||||
#endif
|
|
||||||
jsonDocument.setObject(jsonObject);
|
jsonDocument.setObject(jsonObject);
|
||||||
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -23,6 +23,11 @@
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
StandardPaths::StandardPaths()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QString StandardPaths::applicationsLocation()
|
QString StandardPaths::applicationsLocation()
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
class StandardPaths
|
class StandardPaths
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
StandardPaths();
|
||||||
static QString applicationsLocation();
|
static QString applicationsLocation();
|
||||||
static QString cacheLocation();
|
static QString cacheLocation();
|
||||||
static QString dataLocation();
|
static QString dataLocation();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -17,9 +17,7 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "StringParser.h"
|
#include "StringParser.h"
|
||||||
#include "config.h"
|
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
#include <QApplication>
|
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
@ -27,6 +25,16 @@
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
|
#ifdef GTA5SYNC_PROJECT
|
||||||
|
#include <QApplication>
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
StringParser::StringParser()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QString StringParser::escapeString(const QString &toEscape)
|
QString StringParser::escapeString(const QString &toEscape)
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
|
@ -36,6 +44,7 @@ QString StringParser::escapeString(const QString &toEscape)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GTA5SYNC_PROJECT
|
||||||
QString StringParser::convertBuildedString(const QString &buildedStr)
|
QString StringParser::convertBuildedString(const QString &buildedStr)
|
||||||
{
|
{
|
||||||
QString outputStr = buildedStr;
|
QString outputStr = buildedStr;
|
||||||
|
@ -52,3 +61,4 @@ QString StringParser::convertBuildedString(const QString &buildedStr)
|
||||||
outputStr.replace("SEPARATOR:", QDir::separator());
|
outputStr.replace("SEPARATOR:", QDir::separator());
|
||||||
return outputStr;
|
return outputStr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,8 +25,11 @@
|
||||||
class StringParser
|
class StringParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
StringParser();
|
||||||
static QString escapeString(const QString &toEscape);
|
static QString escapeString(const QString &toEscape);
|
||||||
|
#ifdef GTA5SYNC_PROJECT
|
||||||
static QString convertBuildedString(const QString &buildedStr);
|
static QString convertBuildedString(const QString &buildedStr);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STRINGPARSER_H
|
#endif // STRINGPARSER_H
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2017-2021 Syping
|
* Copyright (C) 2017 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -48,20 +48,19 @@ void TranslationClass::initUserLanguage()
|
||||||
|
|
||||||
void TranslationClass::loadTranslation(QApplication *app)
|
void TranslationClass::loadTranslation(QApplication *app)
|
||||||
{
|
{
|
||||||
if (isLangLoaded) {
|
if (isLangLoaded) { unloadTranslation(app); }
|
||||||
unloadTranslation(app);
|
else { currentLangIndex = 0; }
|
||||||
}
|
QString exLangPath = AppEnv::getExLangFolder();
|
||||||
else {
|
QString inLangPath = AppEnv::getInLangFolder();
|
||||||
currentLangIndex = 0;
|
if (userLanguage == "en" || userLanguage == "en_GB")
|
||||||
}
|
{
|
||||||
const QString exLangPath = AppEnv::getExLangFolder();
|
|
||||||
const QString inLangPath = AppEnv::getInLangFolder();
|
|
||||||
if (userLanguage == "en" || userLanguage == "en_GB") {
|
|
||||||
currentLanguage = "en_GB";
|
currentLanguage = "en_GB";
|
||||||
if (loadQtTranslation_p(exLangPath, &exQtTranslator)) {
|
if (loadQtTranslation_p(exLangPath, &exQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&exQtTranslator);
|
app->installTranslator(&exQtTranslator);
|
||||||
}
|
}
|
||||||
else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) {
|
else if (loadQtTranslation_p(inLangPath, &inQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&inQtTranslator);
|
app->installTranslator(&inQtTranslator);
|
||||||
}
|
}
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x060000
|
||||||
|
@ -78,28 +77,33 @@ void TranslationClass::loadTranslation(QApplication *app)
|
||||||
bool externalEnglishMode = false;
|
bool externalEnglishMode = false;
|
||||||
bool loadInternalLang = false;
|
bool loadInternalLang = false;
|
||||||
bool trLoadSuccess = false;
|
bool trLoadSuccess = false;
|
||||||
if (isUserLanguageSystem_p()) {
|
if (isUserLanguageSystem_p())
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadExSystemLanguage";
|
qDebug() << "loadExSystemLanguage";
|
||||||
#endif
|
#endif
|
||||||
trLoadSuccess = loadSystemTranslation_p(exLangPath, &exAppTranslator);
|
trLoadSuccess = loadSystemTranslation_p(exLangPath, &exAppTranslator);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadExUserLanguage";
|
qDebug() << "loadExUserLanguage";
|
||||||
#endif
|
#endif
|
||||||
trLoadSuccess = loadUserTranslation_p(exLangPath, &exAppTranslator);
|
trLoadSuccess = loadUserTranslation_p(exLangPath, &exAppTranslator);
|
||||||
if (!trLoadSuccess) {
|
if (!trLoadSuccess)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadInUserLanguage";
|
qDebug() << "loadInUserLanguage";
|
||||||
#endif
|
#endif
|
||||||
trLoadSuccess = loadUserTranslation_p(inLangPath, &inAppTranslator);
|
trLoadSuccess = loadUserTranslation_p(inLangPath, &inAppTranslator);
|
||||||
if (!trLoadSuccess) {
|
if (!trLoadSuccess)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadUserLanguageFailed";
|
qDebug() << "loadUserLanguageFailed";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadUserLanguageSuccess";
|
qDebug() << "loadUserLanguageSuccess";
|
||||||
#endif
|
#endif
|
||||||
|
@ -107,16 +111,18 @@ void TranslationClass::loadTranslation(QApplication *app)
|
||||||
isLangLoaded = true;
|
isLangLoaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadUserLanguageSuccess";
|
qDebug() << "loadUserLanguageSuccess";
|
||||||
#endif
|
#endif
|
||||||
isLangLoaded = true;
|
isLangLoaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (trLoadSuccess) {
|
if (trLoadSuccess)
|
||||||
// Don't install the language until we know we not have a better language for the user
|
{
|
||||||
if (currentLangIndex != 0 || isEnglishMode) {
|
if (currentLangIndex != 0 || isEnglishMode) // Don't install the language until we know we not have a better language for the user
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "externalLanguageReady" << currentLanguage;
|
qDebug() << "externalLanguageReady" << currentLanguage;
|
||||||
#endif
|
#endif
|
||||||
|
@ -124,20 +130,25 @@ void TranslationClass::loadTranslation(QApplication *app)
|
||||||
externalLanguageStr = currentLanguage;
|
externalLanguageStr = currentLanguage;
|
||||||
externalLanguageReady = true;
|
externalLanguageReady = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "installTranslation";
|
qDebug() << "installTranslation";
|
||||||
#endif
|
#endif
|
||||||
if (loadInternalLang) {
|
if (loadInternalLang)
|
||||||
|
{
|
||||||
app->installTranslator(&inAppTranslator);
|
app->installTranslator(&inAppTranslator);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
app->installTranslator(&exAppTranslator);
|
app->installTranslator(&exAppTranslator);
|
||||||
}
|
}
|
||||||
if (loadQtTranslation_p(exLangPath, &exQtTranslator)) {
|
if (loadQtTranslation_p(exLangPath, &exQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&exQtTranslator);
|
app->installTranslator(&exQtTranslator);
|
||||||
}
|
}
|
||||||
else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) {
|
else if (loadQtTranslation_p(inLangPath, &inQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&inQtTranslator);
|
app->installTranslator(&inQtTranslator);
|
||||||
}
|
}
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x060000
|
||||||
|
@ -148,7 +159,8 @@ void TranslationClass::loadTranslation(QApplication *app)
|
||||||
isLangLoaded = true;
|
isLangLoaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (externalLanguageReady) {
|
if (externalLanguageReady)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadInSystemLanguage";
|
qDebug() << "loadInSystemLanguage";
|
||||||
#endif
|
#endif
|
||||||
|
@ -158,15 +170,18 @@ void TranslationClass::loadTranslation(QApplication *app)
|
||||||
qDebug() << "externalLangIndex" << externalLangIndex << "internalLangIndex" << currentLangIndex;
|
qDebug() << "externalLangIndex" << externalLangIndex << "internalLangIndex" << currentLangIndex;
|
||||||
qDebug() << "externalEnglishMode" << externalEnglishMode << "internalEnglishMode" << isEnglishMode;
|
qDebug() << "externalEnglishMode" << externalEnglishMode << "internalEnglishMode" << isEnglishMode;
|
||||||
#endif
|
#endif
|
||||||
if ((trLoadSuccess && externalLangIndex > currentLangIndex) || (trLoadSuccess && externalEnglishMode && !isEnglishMode)) {
|
if ((trLoadSuccess && externalLangIndex > currentLangIndex) || (trLoadSuccess && externalEnglishMode && !isEnglishMode))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "installInternalTranslation";
|
qDebug() << "installInternalTranslation";
|
||||||
#endif
|
#endif
|
||||||
app->installTranslator(&inAppTranslator);
|
app->installTranslator(&inAppTranslator);
|
||||||
if (loadQtTranslation_p(exLangPath, &exQtTranslator)) {
|
if (loadQtTranslation_p(exLangPath, &exQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&exQtTranslator);
|
app->installTranslator(&exQtTranslator);
|
||||||
}
|
}
|
||||||
else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) {
|
else if (loadQtTranslation_p(inLangPath, &inQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&inQtTranslator);
|
app->installTranslator(&inQtTranslator);
|
||||||
}
|
}
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x060000
|
||||||
|
@ -176,17 +191,20 @@ void TranslationClass::loadTranslation(QApplication *app)
|
||||||
#endif
|
#endif
|
||||||
isLangLoaded = true;
|
isLangLoaded = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "installExternalTranslation";
|
qDebug() << "installExternalTranslation";
|
||||||
#endif
|
#endif
|
||||||
isEnglishMode = externalEnglishMode;
|
isEnglishMode = externalEnglishMode;
|
||||||
currentLanguage = externalLanguageStr;
|
currentLanguage = externalLanguageStr;
|
||||||
app->installTranslator(&exAppTranslator);
|
app->installTranslator(&exAppTranslator);
|
||||||
if (loadQtTranslation_p(exLangPath, &exQtTranslator)) {
|
if (loadQtTranslation_p(exLangPath, &exQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&exQtTranslator);
|
app->installTranslator(&exQtTranslator);
|
||||||
}
|
}
|
||||||
else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) {
|
else if (loadQtTranslation_p(inLangPath, &inQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&inQtTranslator);
|
app->installTranslator(&inQtTranslator);
|
||||||
}
|
}
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x060000
|
||||||
|
@ -197,20 +215,24 @@ void TranslationClass::loadTranslation(QApplication *app)
|
||||||
isLangLoaded = true;
|
isLangLoaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!isLangLoaded) {
|
else if (!isLangLoaded)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadInSystemLanguage";
|
qDebug() << "loadInSystemLanguage";
|
||||||
#endif
|
#endif
|
||||||
trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator);
|
trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator);
|
||||||
if (trLoadSuccess) {
|
if (trLoadSuccess)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "installInternalTranslation";
|
qDebug() << "installInternalTranslation";
|
||||||
#endif
|
#endif
|
||||||
app->installTranslator(&inAppTranslator);
|
app->installTranslator(&inAppTranslator);
|
||||||
if (loadQtTranslation_p(exLangPath, &exQtTranslator)) {
|
if (loadQtTranslation_p(exLangPath, &exQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&exQtTranslator);
|
app->installTranslator(&exQtTranslator);
|
||||||
}
|
}
|
||||||
else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) {
|
else if (loadQtTranslation_p(inLangPath, &inQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&inQtTranslator);
|
app->installTranslator(&inQtTranslator);
|
||||||
}
|
}
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x060000
|
||||||
|
@ -220,15 +242,18 @@ void TranslationClass::loadTranslation(QApplication *app)
|
||||||
#endif
|
#endif
|
||||||
isLangLoaded = true;
|
isLangLoaded = true;
|
||||||
}
|
}
|
||||||
else if (!trLoadSuccess) {
|
else if (!trLoadSuccess)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "fallbackToDefaultApplicationLanguage";
|
qDebug() << "fallbackToDefaultApplicationLanguage";
|
||||||
#endif
|
#endif
|
||||||
currentLanguage = "en_GB";
|
currentLanguage = "en_GB";
|
||||||
if (loadQtTranslation_p(exLangPath, &exQtTranslator)) {
|
if (loadQtTranslation_p(exLangPath, &exQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&exQtTranslator);
|
app->installTranslator(&exQtTranslator);
|
||||||
}
|
}
|
||||||
else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) {
|
else if (loadQtTranslation_p(inLangPath, &inQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&inQtTranslator);
|
app->installTranslator(&inQtTranslator);
|
||||||
}
|
}
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x060000
|
||||||
|
@ -241,31 +266,33 @@ void TranslationClass::loadTranslation(QApplication *app)
|
||||||
}
|
}
|
||||||
#else // New qconf loading method
|
#else // New qconf loading method
|
||||||
bool trLoadSuccess;
|
bool trLoadSuccess;
|
||||||
if (isUserLanguageSystem_p()) {
|
if (isUserLanguageSystem_p())
|
||||||
|
{
|
||||||
trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator);
|
trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
trLoadSuccess = loadUserTranslation_p(inLangPath, &inAppTranslator);
|
trLoadSuccess = loadUserTranslation_p(inLangPath, &inAppTranslator);
|
||||||
}
|
}
|
||||||
if (!trLoadSuccess && !isUserLanguageSystem_p()) {
|
if (!trLoadSuccess && !isUserLanguageSystem_p())
|
||||||
|
{
|
||||||
trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator);
|
trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator);
|
||||||
}
|
}
|
||||||
if (trLoadSuccess) {
|
if (trLoadSuccess)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "installTranslation" << currentLanguage;
|
qDebug() << "installTranslation" << currentLanguage;
|
||||||
#endif
|
#endif
|
||||||
app->installTranslator(&inAppTranslator);
|
app->installTranslator(&inAppTranslator);
|
||||||
if (loadQtTranslation_p(exLangPath, &exQtTranslator)) {
|
if (loadQtTranslation_p(exLangPath, &exQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&exQtTranslator);
|
app->installTranslator(&exQtTranslator);
|
||||||
}
|
}
|
||||||
else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) {
|
else if (loadQtTranslation_p(inLangPath, &inQtTranslator))
|
||||||
|
{
|
||||||
app->installTranslator(&inQtTranslator);
|
app->installTranslator(&inQtTranslator);
|
||||||
}
|
}
|
||||||
#if QT_VERSION >= 0x060000
|
|
||||||
QLocale::setDefault(QLocale(currentLanguage));
|
|
||||||
#else
|
|
||||||
QLocale::setDefault(currentLanguage);
|
QLocale::setDefault(currentLanguage);
|
||||||
#endif
|
|
||||||
isLangLoaded = true;
|
isLangLoaded = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -277,7 +304,8 @@ QStringList TranslationClass::listTranslations(const QString &langPath)
|
||||||
langDir.setNameFilters(QStringList("gta5sync_*.qm"));
|
langDir.setNameFilters(QStringList("gta5sync_*.qm"));
|
||||||
langDir.setPath(langPath);
|
langDir.setPath(langPath);
|
||||||
QStringList availableLanguages;
|
QStringList availableLanguages;
|
||||||
for (const QString &lang : langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort)) {
|
for (QString lang : langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort))
|
||||||
|
{
|
||||||
availableLanguages << QString(lang).remove("gta5sync_").remove(".qm");
|
availableLanguages << QString(lang).remove("gta5sync_").remove(".qm");
|
||||||
}
|
}
|
||||||
return availableLanguages;
|
return availableLanguages;
|
||||||
|
@ -289,7 +317,8 @@ QStringList TranslationClass::listAreaTranslations()
|
||||||
langDir.setNameFilters(QStringList("global.*.ini"));
|
langDir.setNameFilters(QStringList("global.*.ini"));
|
||||||
langDir.setPath(":/global");
|
langDir.setPath(":/global");
|
||||||
QStringList availableLanguages;
|
QStringList availableLanguages;
|
||||||
for (const QString &lang : langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort)) {
|
for (QString lang : langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort))
|
||||||
|
{
|
||||||
availableLanguages << QString(lang).remove("global.").remove(".ini");
|
availableLanguages << QString(lang).remove("global.").remove(".ini");
|
||||||
}
|
}
|
||||||
return availableLanguages;
|
return availableLanguages;
|
||||||
|
@ -301,17 +330,21 @@ bool TranslationClass::loadSystemTranslation_p(const QString &langPath, QTransla
|
||||||
qDebug() << "loadSystemTranslation_p";
|
qDebug() << "loadSystemTranslation_p";
|
||||||
#endif
|
#endif
|
||||||
int currentLangCounter = 0;
|
int currentLangCounter = 0;
|
||||||
for (const QString &languageName : QLocale::system().uiLanguages()) {
|
for (QString languageName : QLocale::system().uiLanguages())
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguage" << languageName;
|
qDebug() << "loadLanguage" << languageName;
|
||||||
#endif
|
#endif
|
||||||
const QStringList langList = QString(languageName).replace("-","_").split("_");
|
QStringList langList = QString(languageName).replace("-","_").split("_");
|
||||||
if (langList.length() == 2) {
|
if (langList.length() == 2)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm");
|
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm")) {
|
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm"))
|
||||||
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm")) {
|
{
|
||||||
|
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm"))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm");
|
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
|
@ -324,8 +357,10 @@ bool TranslationClass::loadSystemTranslation_p(const QString &langPath, QTransla
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm")) {
|
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm"))
|
||||||
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm")) {
|
{
|
||||||
|
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm"))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
|
@ -334,7 +369,8 @@ bool TranslationClass::loadSystemTranslation_p(const QString &langPath, QTransla
|
||||||
currentLangIndex = currentLangCounter;
|
currentLangIndex = currentLangCounter;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (langList.at(0) == "en") {
|
else if (langList.at(0) == "en")
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "languageEnglishMode index" << currentLangCounter;
|
qDebug() << "languageEnglishMode index" << currentLangCounter;
|
||||||
#endif
|
#endif
|
||||||
|
@ -344,7 +380,8 @@ bool TranslationClass::loadSystemTranslation_p(const QString &langPath, QTransla
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (langList.at(0) == "en") {
|
else if (langList.at(0) == "en")
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "languageEnglishMode index" << currentLangCounter;
|
qDebug() << "languageEnglishMode index" << currentLangCounter;
|
||||||
#endif
|
#endif
|
||||||
|
@ -354,12 +391,15 @@ bool TranslationClass::loadSystemTranslation_p(const QString &langPath, QTransla
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (langList.length() == 1) {
|
else if (langList.length() == 1)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm")) {
|
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm"))
|
||||||
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm")) {
|
{
|
||||||
|
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm"))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
|
@ -383,14 +423,17 @@ bool TranslationClass::loadUserTranslation_p(const QString &langPath, QTranslato
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadUserTranslation_p";
|
qDebug() << "loadUserTranslation_p";
|
||||||
#endif
|
#endif
|
||||||
const QString languageName = userLanguage;
|
QString languageName = userLanguage;
|
||||||
const QStringList langList = QString(languageName).replace("-","_").split("_");
|
QStringList langList = QString(languageName).replace("-","_").split("_");
|
||||||
if (langList.length() == 2) {
|
if (langList.length() == 2)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm");
|
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm")) {
|
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm"))
|
||||||
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm")) {
|
{
|
||||||
|
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm"))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm");
|
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
|
@ -401,8 +444,10 @@ bool TranslationClass::loadUserTranslation_p(const QString &langPath, QTranslato
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm")) {
|
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm"))
|
||||||
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm")) {
|
{
|
||||||
|
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm"))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
|
@ -411,12 +456,15 @@ bool TranslationClass::loadUserTranslation_p(const QString &langPath, QTranslato
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (langList.length() == 1) {
|
else if (langList.length() == 1)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm")) {
|
if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm"))
|
||||||
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm")) {
|
{
|
||||||
|
if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm"))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
|
@ -433,14 +481,17 @@ bool TranslationClass::loadQtTranslation_p(const QString &langPath, QTranslator
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadQtTranslation_p" << currentLanguage;
|
qDebug() << "loadQtTranslation_p" << currentLanguage;
|
||||||
#endif
|
#endif
|
||||||
const QString languageName = currentLanguage;
|
QString languageName = currentLanguage;
|
||||||
const QStringList langList = QString(languageName).replace("-","_").split("_");
|
QStringList langList = QString(languageName).replace("-","_").split("_");
|
||||||
if (langList.length() == 2) {
|
if (langList.length() == 2)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFile" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm");
|
qDebug() << "loadLanguageFile" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
if (QFile::exists(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm")) {
|
if (QFile::exists(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm"))
|
||||||
if (qtTranslator->load(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm")) {
|
{
|
||||||
|
if (qtTranslator->load(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm"))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFileSuccess" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm");
|
qDebug() << "loadLanguageFileSuccess" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
|
@ -450,8 +501,10 @@ bool TranslationClass::loadQtTranslation_p(const QString &langPath, QTranslator
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFile" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFile" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
if (QFile::exists(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm")) {
|
if (QFile::exists(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm"))
|
||||||
if (qtTranslator->load(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm")) {
|
{
|
||||||
|
if (qtTranslator->load(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm"))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFileSuccess" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFileSuccess" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
|
@ -459,12 +512,15 @@ bool TranslationClass::loadQtTranslation_p(const QString &langPath, QTranslator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (langList.length() == 1) {
|
else if (langList.length() == 1)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFile" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFile" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
if (QFile::exists(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm")) {
|
if (QFile::exists(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm"))
|
||||||
if (qtTranslator->load(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm")) {
|
{
|
||||||
|
if (qtTranslator->load(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm"))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "loadLanguageFileSuccess" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm");
|
qDebug() << "loadLanguageFileSuccess" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm");
|
||||||
#endif
|
#endif
|
||||||
|
@ -483,44 +539,49 @@ bool TranslationClass::isUserLanguageSystem_p()
|
||||||
QString TranslationClass::getCurrentAreaLanguage()
|
QString TranslationClass::getCurrentAreaLanguage()
|
||||||
{
|
{
|
||||||
const QStringList areaTranslations = listAreaTranslations();
|
const QStringList areaTranslations = listAreaTranslations();
|
||||||
if (userAreaLanguage == "Auto" || userAreaLanguage.trimmed().isEmpty()) {
|
if (userAreaLanguage == "Auto" || userAreaLanguage.trimmed().isEmpty())
|
||||||
const GameLanguage gameLanguage = AppEnv::getGameLanguage(AppEnv::getGameVersion());
|
{
|
||||||
if (gameLanguage == GameLanguage::Undefined) {
|
GameLanguage gameLanguage = AppEnv::getGameLanguage(AppEnv::getGameVersion());
|
||||||
|
if (gameLanguage == GameLanguage::Undefined)
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "autoAreaLanguageModeInterface";
|
qDebug() << "autoAreaLanguageModeInterface";
|
||||||
#endif
|
#endif
|
||||||
QString langCode = QString(currentLanguage).replace("-", "_");
|
QString langCode = QString(currentLanguage).replace("-", "_");
|
||||||
if (areaTranslations.contains(langCode)) {
|
if (areaTranslations.contains(langCode))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "autoAreaLanguageSelected" << langCode;
|
qDebug() << "autoAreaLanguageSelected" << langCode;
|
||||||
#endif
|
#endif
|
||||||
return langCode;
|
return langCode;
|
||||||
}
|
}
|
||||||
else if (langCode.contains("_")) {
|
else if (langCode.contains("_"))
|
||||||
|
{
|
||||||
langCode = langCode.split("_").at(0);
|
langCode = langCode.split("_").at(0);
|
||||||
if (!areaTranslations.contains(langCode))
|
if (!areaTranslations.contains(langCode)) goto outputDefaultLanguage;
|
||||||
goto outputDefaultLanguage;
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "autoAreaLanguageSelected" << langCode;
|
qDebug() << "autoAreaLanguageSelected" << langCode;
|
||||||
#endif
|
#endif
|
||||||
return langCode;
|
return langCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "autoAreaLanguageModeGame";
|
qDebug() << "autoAreaLanguageModeGame";
|
||||||
#endif
|
#endif
|
||||||
QString langCode = AppEnv::gameLanguageToString(gameLanguage).replace("-", "_");
|
QString langCode = AppEnv::gameLanguageToString(gameLanguage).replace("-", "_");
|
||||||
if (areaTranslations.contains(langCode)) {
|
if (areaTranslations.contains(langCode))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "autoAreaLanguageSelected" << langCode;
|
qDebug() << "autoAreaLanguageSelected" << langCode;
|
||||||
#endif
|
#endif
|
||||||
return langCode;
|
return langCode;
|
||||||
}
|
}
|
||||||
else if (langCode.contains("_")) {
|
else if (langCode.contains("_"))
|
||||||
|
{
|
||||||
langCode = langCode.split("_").at(0);
|
langCode = langCode.split("_").at(0);
|
||||||
if (!areaTranslations.contains(langCode))
|
if (!areaTranslations.contains(langCode)) goto outputDefaultLanguage;
|
||||||
goto outputDefaultLanguage;
|
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "autoAreaLanguageSelected" << langCode;
|
qDebug() << "autoAreaLanguageSelected" << langCode;
|
||||||
#endif
|
#endif
|
||||||
|
@ -528,16 +589,17 @@ QString TranslationClass::getCurrentAreaLanguage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (areaTranslations.contains(userAreaLanguage)) {
|
else if (areaTranslations.contains(userAreaLanguage))
|
||||||
|
{
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "userAreaLanguageSelected" << userAreaLanguage;
|
qDebug() << "userAreaLanguageSelected" << userAreaLanguage;
|
||||||
#endif
|
#endif
|
||||||
return userAreaLanguage;
|
return userAreaLanguage;
|
||||||
}
|
}
|
||||||
else if (userAreaLanguage.contains("_")) {
|
else if (userAreaLanguage.contains("_"))
|
||||||
const QString langCode = QString(userAreaLanguage).replace("-", "_").split("_").at(0);
|
{
|
||||||
if (!areaTranslations.contains(langCode))
|
QString langCode = QString(userAreaLanguage).replace("-", "_").split("_").at(0);
|
||||||
goto outputDefaultLanguage;
|
if (!areaTranslations.contains(langCode)) goto outputDefaultLanguage;
|
||||||
#ifdef GTA5SYNC_DEBUG
|
#ifdef GTA5SYNC_DEBUG
|
||||||
qDebug() << "userAreaLanguageSelected" << langCode;
|
qDebug() << "userAreaLanguageSelected" << langCode;
|
||||||
#endif
|
#endif
|
||||||
|
@ -562,7 +624,8 @@ bool TranslationClass::isLanguageLoaded()
|
||||||
|
|
||||||
void TranslationClass::unloadTranslation(QApplication *app)
|
void TranslationClass::unloadTranslation(QApplication *app)
|
||||||
{
|
{
|
||||||
if (isLangLoaded) {
|
if (isLangLoaded)
|
||||||
|
{
|
||||||
#ifndef GTA5SYNC_QCONF
|
#ifndef GTA5SYNC_QCONF
|
||||||
app->removeTranslator(&exAppTranslator);
|
app->removeTranslator(&exAppTranslator);
|
||||||
app->removeTranslator(&exQtTranslator);
|
app->removeTranslator(&exQtTranslator);
|
||||||
|
@ -585,21 +648,30 @@ void TranslationClass::unloadTranslation(QApplication *app)
|
||||||
|
|
||||||
QString TranslationClass::getCountryCode(QLocale::Country country)
|
QString TranslationClass::getCountryCode(QLocale::Country country)
|
||||||
{
|
{
|
||||||
const QList<QLocale> locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, country);
|
QList<QLocale> locales = QLocale::matchingLocales(QLocale::AnyLanguage,
|
||||||
if (!locales.isEmpty()) {
|
QLocale::AnyScript,
|
||||||
const QStringList localeStrList = locales.at(0).name().split("_");
|
country);
|
||||||
if (localeStrList.length() >= 2) {
|
if (locales.isEmpty()) return QString();
|
||||||
return localeStrList.at(1).toLower();
|
QStringList localeStrList = locales.at(0).name().split("_");
|
||||||
}
|
if (localeStrList.length() >= 2)
|
||||||
|
{
|
||||||
|
return localeStrList.at(1).toLower();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
}
|
}
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TranslationClass::getCountryCode(QLocale locale)
|
QString TranslationClass::getCountryCode(QLocale locale)
|
||||||
{
|
{
|
||||||
QStringList localeStrList = locale.name().split("_");
|
QStringList localeStrList = locale.name().split("_");
|
||||||
if (localeStrList.length() >= 2) {
|
if (localeStrList.length() >= 2)
|
||||||
|
{
|
||||||
return localeStrList.at(1).toLower();
|
return localeStrList.at(1).toLower();
|
||||||
}
|
}
|
||||||
return QString();
|
else
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2019 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -46,25 +46,15 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
||||||
#ifdef GTA5SYNC_DONATE
|
|
||||||
#ifdef GTA5SYNC_DONATE_ADDRESSES
|
|
||||||
#include <QSvgRenderer>
|
|
||||||
#include <QClipboard>
|
|
||||||
#include <QPainter>
|
|
||||||
#include "QrCode.h"
|
|
||||||
using namespace qrcodegen;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GTA5SYNC_MOTD
|
#ifdef GTA5SYNC_MOTD
|
||||||
UserInterface::UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, MessageThread *threadMessage, QWidget *parent) :
|
UserInterface::UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, MessageThread *threadMessage, QWidget *parent) :
|
||||||
QMainWindow(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), threadMessage(threadMessage),
|
QMainWindow(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), threadMessage(threadMessage),
|
||||||
ui(new Ui::UserInterface)
|
ui(new Ui::UserInterface)
|
||||||
#else
|
#else
|
||||||
UserInterface::UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent) :
|
UserInterface::UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent) :
|
||||||
QMainWindow(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB),
|
QMainWindow(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB),
|
||||||
ui(new Ui::UserInterface)
|
ui(new Ui::UserInterface)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
contentMode = 0;
|
contentMode = 0;
|
||||||
|
@ -73,244 +63,113 @@ UserInterface::UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, D
|
||||||
ui->menuProfile->setEnabled(false);
|
ui->menuProfile->setEnabled(false);
|
||||||
ui->actionSelect_profile->setEnabled(false);
|
ui->actionSelect_profile->setEnabled(false);
|
||||||
ui->actionAbout_gta5sync->setIcon(IconLoader::loadingAppIcon());
|
ui->actionAbout_gta5sync->setIcon(IconLoader::loadingAppIcon());
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
ui->actionAbout_gta5sync->setText(QApplication::translate("MAC_APPLICATION_MENU", "About %1").arg(GTA5SYNC_APPSTR));
|
|
||||||
ui->actionOptions->setText(QApplication::translate("MAC_APPLICATION_MENU", "Preferences..."));
|
|
||||||
#else
|
|
||||||
ui->actionAbout_gta5sync->setText(tr("&About %1").arg(GTA5SYNC_APPSTR));
|
ui->actionAbout_gta5sync->setText(tr("&About %1").arg(GTA5SYNC_APPSTR));
|
||||||
#endif
|
|
||||||
ui->cmdClose->setToolTip(ui->cmdClose->toolTip().arg(GTA5SYNC_APPSTR));
|
ui->cmdClose->setToolTip(ui->cmdClose->toolTip().arg(GTA5SYNC_APPSTR));
|
||||||
defaultWindowTitle = tr("%2 - %1").arg("%1", GTA5SYNC_APPSTR);
|
defaultWindowTitle = tr("%2 - %1").arg("%1", GTA5SYNC_APPSTR);
|
||||||
|
|
||||||
setWindowTitle(defaultWindowTitle.arg(tr("Select Profile")));
|
setWindowTitle(defaultWindowTitle.arg(tr("Select Profile")));
|
||||||
QString appVersion = QApplication::applicationVersion();
|
QString appVersion = GTA5SYNC_APPVER;
|
||||||
const char* literalBuildType = GTA5SYNC_BUILDTYPE;
|
#ifndef GTA5SYNC_BUILDTYPE_REL
|
||||||
#ifdef GTA5SYNC_COMMIT
|
#ifdef GTA5SYNC_COMMIT
|
||||||
if ((strcmp(literalBuildType, REL_BUILDTYPE) != 0) && !appVersion.contains("-"))
|
if (!appVersion.contains("-")) { appVersion = appVersion % "-" % GTA5SYNC_COMMIT; }
|
||||||
appVersion = appVersion % "-" % GTA5SYNC_COMMIT;
|
#endif
|
||||||
#endif
|
#endif
|
||||||
ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion));
|
ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion));
|
||||||
|
|
||||||
// Set Icon for Close Button
|
// Set Icon for Close Button
|
||||||
if (QIcon::hasThemeIcon("dialog-close")) {
|
if (QIcon::hasThemeIcon("dialog-close"))
|
||||||
|
{
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
|
ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-close")) {
|
else if (QIcon::hasThemeIcon("gtk-close"))
|
||||||
|
{
|
||||||
ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
|
ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Reload Button
|
// Set Icon for Reload Button
|
||||||
if (QIcon::hasThemeIcon("view-refresh")) {
|
if (QIcon::hasThemeIcon("view-refresh"))
|
||||||
|
{
|
||||||
ui->cmdReload->setIcon(QIcon::fromTheme("view-refresh"));
|
ui->cmdReload->setIcon(QIcon::fromTheme("view-refresh"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("reload")) {
|
else if (QIcon::hasThemeIcon("reload"))
|
||||||
|
{
|
||||||
ui->cmdReload->setIcon(QIcon::fromTheme("reload"));
|
ui->cmdReload->setIcon(QIcon::fromTheme("reload"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Choose GTA V Folder Menu Item
|
// Set Icon for Choose GTA V Folder Menu Item
|
||||||
if (QIcon::hasThemeIcon("document-open-folder")) {
|
if (QIcon::hasThemeIcon("document-open-folder"))
|
||||||
|
{
|
||||||
ui->actionSelect_GTA_Folder->setIcon(QIcon::fromTheme("document-open-folder"));
|
ui->actionSelect_GTA_Folder->setIcon(QIcon::fromTheme("document-open-folder"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-directory")) {
|
else if (QIcon::hasThemeIcon("gtk-directory"))
|
||||||
|
{
|
||||||
ui->actionSelect_GTA_Folder->setIcon(QIcon::fromTheme("gtk-directory"));
|
ui->actionSelect_GTA_Folder->setIcon(QIcon::fromTheme("gtk-directory"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Open File Menu Item
|
// Set Icon for Open File Menu Item
|
||||||
if (QIcon::hasThemeIcon("document-open")) {
|
if (QIcon::hasThemeIcon("document-open"))
|
||||||
|
{
|
||||||
ui->actionOpen_File->setIcon(QIcon::fromTheme("document-open"));
|
ui->actionOpen_File->setIcon(QIcon::fromTheme("document-open"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Close Profile Menu Item
|
// Set Icon for Close Profile Menu Item
|
||||||
if (QIcon::hasThemeIcon("dialog-close")) {
|
if (QIcon::hasThemeIcon("dialog-close"))
|
||||||
|
{
|
||||||
ui->actionSelect_profile->setIcon(QIcon::fromTheme("dialog-close"));
|
ui->actionSelect_profile->setIcon(QIcon::fromTheme("dialog-close"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("gtk-close")) {
|
else if (QIcon::hasThemeIcon("gtk-close"))
|
||||||
|
{
|
||||||
ui->actionSelect_profile->setIcon(QIcon::fromTheme("gtk-close"));
|
ui->actionSelect_profile->setIcon(QIcon::fromTheme("gtk-close"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Exit Menu Item
|
// Set Icon for Exit Menu Item
|
||||||
if (QIcon::hasThemeIcon("application-exit")) {
|
if (QIcon::hasThemeIcon("application-exit"))
|
||||||
|
{
|
||||||
#ifndef Q_OS_MACOS // Setting icon for exit/quit lead to a crash in Mac OS X
|
#ifndef Q_OS_MACOS // Setting icon for exit/quit lead to a crash in Mac OS X
|
||||||
ui->actionExit->setIcon(QIcon::fromTheme("application-exit"));
|
ui->actionExit->setIcon(QIcon::fromTheme("application-exit"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Preferences Menu Item
|
// Set Icon for Preferences Menu Item
|
||||||
if (QIcon::hasThemeIcon("preferences-system")) {
|
if (QIcon::hasThemeIcon("preferences-system"))
|
||||||
|
{
|
||||||
#ifndef Q_OS_MACOS // Setting icon for preferences/settings/options lead to a crash in Mac OS X
|
#ifndef Q_OS_MACOS // Setting icon for preferences/settings/options lead to a crash in Mac OS X
|
||||||
ui->actionOptions->setIcon(QIcon::fromTheme("preferences-system"));
|
ui->actionOptions->setIcon(QIcon::fromTheme("preferences-system"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("configure")) {
|
else if (QIcon::hasThemeIcon("configure"))
|
||||||
|
{
|
||||||
#ifndef Q_OS_MACOS // Setting icon for preferences/settings/options lead to a crash in Mac OS X
|
#ifndef Q_OS_MACOS // Setting icon for preferences/settings/options lead to a crash in Mac OS X
|
||||||
ui->actionOptions->setIcon(QIcon::fromTheme("configure"));
|
ui->actionOptions->setIcon(QIcon::fromTheme("configure"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Profile Import Menu Item
|
// Set Icon for Profile Import Menu Item
|
||||||
if (QIcon::hasThemeIcon("document-import")) {
|
if (QIcon::hasThemeIcon("document-import"))
|
||||||
|
{
|
||||||
ui->action_Import->setIcon(QIcon::fromTheme("document-import"));
|
ui->action_Import->setIcon(QIcon::fromTheme("document-import"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("document-open")) {
|
else if (QIcon::hasThemeIcon("document-open"))
|
||||||
|
{
|
||||||
ui->action_Import->setIcon(QIcon::fromTheme("document-open"));
|
ui->action_Import->setIcon(QIcon::fromTheme("document-open"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Profile Export Menu Item
|
// Set Icon for Profile Export Menu Item
|
||||||
if (QIcon::hasThemeIcon("document-export")) {
|
if (QIcon::hasThemeIcon("document-export"))
|
||||||
|
{
|
||||||
ui->actionExport_selected->setIcon(QIcon::fromTheme("document-export"));
|
ui->actionExport_selected->setIcon(QIcon::fromTheme("document-export"));
|
||||||
}
|
}
|
||||||
else if (QIcon::hasThemeIcon("document-save")) {
|
else if (QIcon::hasThemeIcon("document-save"))
|
||||||
|
{
|
||||||
ui->actionExport_selected->setIcon(QIcon::fromTheme("document-save"));
|
ui->actionExport_selected->setIcon(QIcon::fromTheme("document-save"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Icon for Profile Remove Menu Item
|
// Set Icon for Profile Remove Menu Item
|
||||||
if (QIcon::hasThemeIcon("remove")) {
|
if (QIcon::hasThemeIcon("remove"))
|
||||||
|
{
|
||||||
ui->actionDelete_selected->setIcon(QIcon::fromTheme("remove"));
|
ui->actionDelete_selected->setIcon(QIcon::fromTheme("remove"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GTA5SYNC_DONATE
|
|
||||||
#ifdef GTA5SYNC_DONATE_ADDRESSES
|
|
||||||
donateAction = new QAction(tr("&Donate"), this);
|
|
||||||
if (QIcon::hasThemeIcon("help-donate")) {
|
|
||||||
donateAction->setIcon(QIcon::fromTheme("help-donate"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("taxes-finances")) {
|
|
||||||
donateAction->setIcon(QIcon::fromTheme("taxes-finances"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
donateAction->setIcon(QIcon(":/img/donate.svgz"));
|
|
||||||
}
|
|
||||||
ui->menuHelp->insertAction(ui->actionAbout_gta5sync, donateAction);
|
|
||||||
QObject::connect(donateAction, &QAction::triggered, this, [=](){
|
|
||||||
QDialog *donateDialog = new QDialog(this);
|
|
||||||
donateDialog->setWindowTitle(QString("%1 - %2").arg(GTA5SYNC_APPSTR, tr("Donate")));
|
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
donateDialog->setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
donateDialog->setWindowFlags(donateDialog->windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
#endif
|
|
||||||
QVBoxLayout *donateLayout = new QVBoxLayout;
|
|
||||||
donateDialog->setLayout(donateLayout);
|
|
||||||
QLabel *methodsLabel = new QLabel(QString("<b>%1</b>").arg(tr("Donation methods").toHtmlEscaped()), donateDialog);
|
|
||||||
methodsLabel->setWordWrap(true);
|
|
||||||
donateLayout->addWidget(methodsLabel);
|
|
||||||
QHBoxLayout *currencyLayout = new QHBoxLayout;
|
|
||||||
donateLayout->addLayout(currencyLayout);
|
|
||||||
const QStringList addressList = QString::fromUtf8(GTA5SYNC_DONATE_ADDRESSES).split(',');
|
|
||||||
for (const QString &address : addressList) {
|
|
||||||
const QStringList addressList = address.split(':');
|
|
||||||
if (addressList.length() == 2) {
|
|
||||||
const QString currency = addressList.at(0);
|
|
||||||
const QString address = addressList.at(1);
|
|
||||||
QString currencyStr = currency;
|
|
||||||
const QString strPath = QString(":/donate/%1.str").arg(currency);
|
|
||||||
if (QFile::exists(strPath)) {
|
|
||||||
QFile strFile(strPath);
|
|
||||||
if (strFile.open(QIODevice::ReadOnly)) {
|
|
||||||
currencyStr = QString::fromUtf8(strFile.readAll());
|
|
||||||
strFile.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const QString iconPath = QString(":/donate/%1.svgz").arg(currency);
|
|
||||||
QPushButton *currencyButton = new QPushButton(currencyStr, donateDialog);
|
|
||||||
currencyButton->setToolTip(currencyStr);
|
|
||||||
if (QFile::exists(iconPath)) {
|
|
||||||
currencyButton->setIconSize(QSize(32, 32));
|
|
||||||
currencyButton->setIcon(QIcon(iconPath));
|
|
||||||
}
|
|
||||||
currencyLayout->addWidget(currencyButton);
|
|
||||||
QObject::connect(currencyButton, &QPushButton::pressed, donateDialog, [=](){
|
|
||||||
QDialog *addressDialog = new QDialog(donateDialog);
|
|
||||||
addressDialog->setWindowTitle(currencyStr);
|
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
addressDialog->setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
addressDialog->setWindowFlags(donateDialog->windowFlags()^Qt::WindowContextHelpButtonHint);
|
|
||||||
#endif
|
|
||||||
QVBoxLayout *addressLayout = new QVBoxLayout;
|
|
||||||
addressDialog->setLayout(addressLayout);
|
|
||||||
QLabel *addressLabel = new QLabel(address, addressDialog);
|
|
||||||
addressLabel->setAlignment(Qt::AlignCenter);
|
|
||||||
addressLabel->setTextFormat(Qt::PlainText);
|
|
||||||
addressLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
|
||||||
addressLayout->addWidget(addressLabel);
|
|
||||||
QHBoxLayout *qrLayout = new QHBoxLayout;
|
|
||||||
qrLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
|
||||||
QrCode qr = QrCode::encodeText(address.toUtf8().constData(), QrCode::Ecc::MEDIUM);
|
|
||||||
const std::string svgString = qr.toSvgString(0);
|
|
||||||
QSvgRenderer svgRenderer(QByteArray::fromRawData(svgString.c_str(), svgString.size()));
|
|
||||||
qreal screenRatioPR = AppEnv::screenRatioPR();
|
|
||||||
const QSize widgetSize = QSize(200, 200);
|
|
||||||
const QSize pixmapSize = widgetSize * screenRatioPR;
|
|
||||||
QPixmap qrPixmap(pixmapSize);
|
|
||||||
qrPixmap.fill(Qt::white);
|
|
||||||
QPainter qrPainter(&qrPixmap);
|
|
||||||
svgRenderer.render(&qrPainter, QRectF(QPointF(0, 0), pixmapSize));
|
|
||||||
qrPainter.end();
|
|
||||||
#if QT_VERSION >= 0x050600
|
|
||||||
qrPixmap.setDevicePixelRatio(screenRatioPR);
|
|
||||||
#endif
|
|
||||||
QLabel *qrLabel = new QLabel(addressDialog);
|
|
||||||
qrLabel->setFixedSize(widgetSize);
|
|
||||||
qrLabel->setPixmap(qrPixmap);
|
|
||||||
qrLayout->addWidget(qrLabel);
|
|
||||||
qrLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
|
||||||
addressLayout->addLayout(qrLayout);
|
|
||||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
|
||||||
buttonLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
|
||||||
QPushButton *copyAddressButton = new QPushButton(tr("&Copy"), addressDialog);
|
|
||||||
if (QIcon::hasThemeIcon("edit-copy")) {
|
|
||||||
copyAddressButton->setIcon(QIcon::fromTheme("edit-copy"));
|
|
||||||
}
|
|
||||||
QObject::connect(copyAddressButton, &QPushButton::pressed, addressDialog, [=](){
|
|
||||||
QApplication::clipboard()->setText(address);
|
|
||||||
});
|
|
||||||
buttonLayout->addWidget(copyAddressButton);
|
|
||||||
QPushButton *closeButton = new QPushButton(tr("&Close"), addressDialog);
|
|
||||||
if (QIcon::hasThemeIcon("dialog-close")) {
|
|
||||||
closeButton->setIcon(QIcon::fromTheme("dialog-close"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-close")) {
|
|
||||||
closeButton->setIcon(QIcon::fromTheme("gtk-close"));
|
|
||||||
}
|
|
||||||
closeButton->setDefault(true);
|
|
||||||
buttonLayout->addWidget(closeButton);
|
|
||||||
buttonLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
|
||||||
addressLayout->addLayout(buttonLayout);
|
|
||||||
QObject::connect(closeButton, &QPushButton::clicked, addressDialog, &QDialog::accept);
|
|
||||||
QObject::connect(addressDialog, &QDialog::finished, addressDialog, &QDialog::deleteLater);
|
|
||||||
QTimer::singleShot(0, addressDialog, [=](){
|
|
||||||
addressDialog->setFocus();
|
|
||||||
});
|
|
||||||
addressDialog->open();
|
|
||||||
addressDialog->setFixedSize(addressDialog->size());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
|
||||||
buttonLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
|
||||||
QPushButton *closeButton = new QPushButton(donateDialog);
|
|
||||||
closeButton->setText(tr("&Close"));
|
|
||||||
if (QIcon::hasThemeIcon("dialog-close")) {
|
|
||||||
closeButton->setIcon(QIcon::fromTheme("dialog-close"));
|
|
||||||
}
|
|
||||||
else if (QIcon::hasThemeIcon("gtk-close")) {
|
|
||||||
closeButton->setIcon(QIcon::fromTheme("gtk-close"));
|
|
||||||
}
|
|
||||||
closeButton->setDefault(true);
|
|
||||||
buttonLayout->addWidget(closeButton);
|
|
||||||
donateLayout->addLayout(buttonLayout);
|
|
||||||
QObject::connect(closeButton, &QPushButton::clicked, donateDialog, &QDialog::accept);
|
|
||||||
QObject::connect(donateDialog, &QDialog::finished, donateDialog, &QDialog::deleteLater);
|
|
||||||
QTimer::singleShot(0, donateDialog, [=](){
|
|
||||||
donateDialog->setFocus();
|
|
||||||
});
|
|
||||||
donateDialog->open();
|
|
||||||
donateDialog->setFixedSize(donateDialog->size());
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// DPI calculation
|
// DPI calculation
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
qreal screenRatio = AppEnv::screenRatio();
|
||||||
#ifndef Q_QS_ANDROID
|
#ifndef Q_QS_ANDROID
|
||||||
|
@ -330,19 +189,22 @@ void UserInterface::setupDirEnv(bool showFolderDialog)
|
||||||
if (folderExists) {
|
if (folderExists) {
|
||||||
QDir::setCurrent(GTAV_Folder);
|
QDir::setCurrent(GTAV_Folder);
|
||||||
}
|
}
|
||||||
else if (showFolderDialog) {
|
else {
|
||||||
GTAV_Folder = QFileDialog::getExistingDirectory(this, tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly);
|
if (showFolderDialog) {
|
||||||
if (QDir(GTAV_Folder).exists()) {
|
GTAV_Folder = QFileDialog::getExistingDirectory(this, tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly);
|
||||||
folderExists = true;
|
if (QFileInfo(GTAV_Folder).exists()) {
|
||||||
QDir::setCurrent(GTAV_Folder);
|
folderExists = true;
|
||||||
AppEnv::setGameFolder(GTAV_Folder);
|
QDir::setCurrent(GTAV_Folder);
|
||||||
|
AppEnv::setGameFolder(GTAV_Folder);
|
||||||
|
|
||||||
// First time folder selection save
|
// First time folder selection save
|
||||||
settings.beginGroup("dir");
|
settings.beginGroup("dir");
|
||||||
if (settings.value("dir", "").toString().isEmpty()) {
|
if (settings.value("dir", "").toString().isEmpty())
|
||||||
settings.setValue("dir", GTAV_Folder);
|
{
|
||||||
|
settings.setValue("dir", GTAV_Folder);
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
settings.endGroup();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,7 +245,8 @@ void UserInterface::setupDirEnv(bool showFolderDialog)
|
||||||
void UserInterface::setupProfileUi()
|
void UserInterface::setupProfileUi()
|
||||||
{
|
{
|
||||||
qreal screenRatio = AppEnv::screenRatio();
|
qreal screenRatio = AppEnv::screenRatio();
|
||||||
if (GTAV_Profiles.isEmpty()) {
|
if (GTAV_Profiles.isEmpty())
|
||||||
|
{
|
||||||
QPushButton *changeDirBtn = new QPushButton(tr("Select >A V Folder..."), ui->swSelection);
|
QPushButton *changeDirBtn = new QPushButton(tr("Select >A V Folder..."), ui->swSelection);
|
||||||
changeDirBtn->setObjectName("cmdChangeDir");
|
changeDirBtn->setObjectName("cmdChangeDir");
|
||||||
changeDirBtn->setMinimumSize(0, 40 * screenRatio);
|
changeDirBtn->setMinimumSize(0, 40 * screenRatio);
|
||||||
|
@ -393,7 +256,8 @@ void UserInterface::setupProfileUi()
|
||||||
|
|
||||||
QObject::connect(changeDirBtn, SIGNAL(clicked(bool)), this, SLOT(changeFolder_clicked()));
|
QObject::connect(changeDirBtn, SIGNAL(clicked(bool)), this, SLOT(changeFolder_clicked()));
|
||||||
}
|
}
|
||||||
else for (const QString >AV_Profile : GTAV_Profiles) {
|
else for (QString GTAV_Profile : GTAV_Profiles)
|
||||||
|
{
|
||||||
QPushButton *profileBtn = new QPushButton(GTAV_Profile, ui->swSelection);
|
QPushButton *profileBtn = new QPushButton(GTAV_Profile, ui->swSelection);
|
||||||
profileBtn->setObjectName(GTAV_Profile);
|
profileBtn->setObjectName(GTAV_Profile);
|
||||||
profileBtn->setMinimumSize(0, 40 * screenRatio);
|
profileBtn->setMinimumSize(0, 40 * screenRatio);
|
||||||
|
@ -413,7 +277,8 @@ void UserInterface::changeFolder_clicked()
|
||||||
|
|
||||||
void UserInterface::on_cmdReload_clicked()
|
void UserInterface::on_cmdReload_clicked()
|
||||||
{
|
{
|
||||||
for (QPushButton *profileBtn : profileBtns) {
|
for (QPushButton *profileBtn : profileBtns)
|
||||||
|
{
|
||||||
ui->vlButtons->removeWidget(profileBtn);
|
ui->vlButtons->removeWidget(profileBtn);
|
||||||
delete profileBtn;
|
delete profileBtn;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +309,8 @@ void UserInterface::openProfile(const QString &profileName_)
|
||||||
|
|
||||||
void UserInterface::closeProfile()
|
void UserInterface::closeProfile()
|
||||||
{
|
{
|
||||||
if (profileOpen) {
|
if (profileOpen)
|
||||||
|
{
|
||||||
closeProfile_p();
|
closeProfile_p();
|
||||||
}
|
}
|
||||||
setWindowTitle(defaultWindowTitle.arg(tr("Select Profile")));
|
setWindowTitle(defaultWindowTitle.arg(tr("Select Profile")));
|
||||||
|
@ -475,8 +341,11 @@ void UserInterface::closeEvent(QCloseEvent *ev)
|
||||||
UserInterface::~UserInterface()
|
UserInterface::~UserInterface()
|
||||||
{
|
{
|
||||||
if (profileOpen)
|
if (profileOpen)
|
||||||
|
{
|
||||||
closeProfile_p();
|
closeProfile_p();
|
||||||
for (QPushButton *profileBtn : profileBtns) {
|
}
|
||||||
|
for (QPushButton *profileBtn : profileBtns)
|
||||||
|
{
|
||||||
delete profileBtn;
|
delete profileBtn;
|
||||||
}
|
}
|
||||||
profileBtns.clear();
|
profileBtns.clear();
|
||||||
|
@ -523,25 +392,33 @@ void UserInterface::profileLoaded()
|
||||||
void UserInterface::on_actionSelect_all_triggered()
|
void UserInterface::on_actionSelect_all_triggered()
|
||||||
{
|
{
|
||||||
if (profileOpen)
|
if (profileOpen)
|
||||||
|
{
|
||||||
profileUI->selectAllWidgets();
|
profileUI->selectAllWidgets();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInterface::on_actionDeselect_all_triggered()
|
void UserInterface::on_actionDeselect_all_triggered()
|
||||||
{
|
{
|
||||||
if (profileOpen)
|
if (profileOpen)
|
||||||
|
{
|
||||||
profileUI->deselectAllWidgets();
|
profileUI->deselectAllWidgets();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInterface::on_actionExport_selected_triggered()
|
void UserInterface::on_actionExport_selected_triggered()
|
||||||
{
|
{
|
||||||
if (profileOpen)
|
if (profileOpen)
|
||||||
|
{
|
||||||
profileUI->exportSelected();
|
profileUI->exportSelected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInterface::on_actionDelete_selected_triggered()
|
void UserInterface::on_actionDelete_selected_triggered()
|
||||||
{
|
{
|
||||||
if (profileOpen)
|
if (profileOpen)
|
||||||
|
{
|
||||||
profileUI->deleteSelected();
|
profileUI->deleteSelected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInterface::on_actionOptions_triggered()
|
void UserInterface::on_actionOptions_triggered()
|
||||||
|
@ -566,7 +443,9 @@ void UserInterface::on_actionOptions_triggered()
|
||||||
void UserInterface::on_action_Import_triggered()
|
void UserInterface::on_action_Import_triggered()
|
||||||
{
|
{
|
||||||
if (profileOpen)
|
if (profileOpen)
|
||||||
|
{
|
||||||
profileUI->importFiles();
|
profileUI->importFiles();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInterface::on_actionOpen_File_triggered()
|
void UserInterface::on_actionOpen_File_triggered()
|
||||||
|
@ -580,11 +459,7 @@ fileDialogPreOpen:
|
||||||
fileDialog.setViewMode(QFileDialog::Detail);
|
fileDialog.setViewMode(QFileDialog::Detail);
|
||||||
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
|
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog, false);
|
fileDialog.setOption(QFileDialog::DontUseNativeDialog, false);
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
fileDialog.setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
#endif
|
|
||||||
fileDialog.setWindowTitle(tr("Open File..."));
|
fileDialog.setWindowTitle(tr("Open File..."));
|
||||||
|
|
||||||
QStringList filters;
|
QStringList filters;
|
||||||
|
@ -601,9 +476,11 @@ fileDialogPreOpen:
|
||||||
fileDialog.setDirectory(settings.value("OpenDialogDirectory", StandardPaths::documentsLocation()).toString());
|
fileDialog.setDirectory(settings.value("OpenDialogDirectory", StandardPaths::documentsLocation()).toString());
|
||||||
fileDialog.restoreGeometry(settings.value("OpenDialogGeometry","").toByteArray());
|
fileDialog.restoreGeometry(settings.value("OpenDialogGeometry","").toByteArray());
|
||||||
|
|
||||||
if (fileDialog.exec()) {
|
if (fileDialog.exec())
|
||||||
|
{
|
||||||
QStringList selectedFiles = fileDialog.selectedFiles();
|
QStringList selectedFiles = fileDialog.selectedFiles();
|
||||||
if (selectedFiles.length() == 1) {
|
if (selectedFiles.length() == 1)
|
||||||
|
{
|
||||||
QString selectedFile = selectedFiles.at(0);
|
QString selectedFile = selectedFiles.at(0);
|
||||||
if (!openFile(selectedFile, true)) goto fileDialogPreOpen;
|
if (!openFile(selectedFile, true)) goto fileDialogPreOpen;
|
||||||
}
|
}
|
||||||
|
@ -617,61 +494,68 @@ fileDialogPreOpen:
|
||||||
bool UserInterface::openFile(QString selectedFile, bool warn)
|
bool UserInterface::openFile(QString selectedFile, bool warn)
|
||||||
{
|
{
|
||||||
QString selectedFileName = QFileInfo(selectedFile).fileName();
|
QString selectedFileName = QFileInfo(selectedFile).fileName();
|
||||||
if (QFile::exists(selectedFile)) {
|
if (QFile::exists(selectedFile))
|
||||||
if (selectedFileName.left(4) == "PGTA" || selectedFileName.right(4) == ".g5e") {
|
{
|
||||||
|
if (selectedFileName.left(4) == "PGTA" || selectedFileName.right(4) == ".g5e")
|
||||||
|
{
|
||||||
SnapmaticPicture *picture = new SnapmaticPicture(selectedFile);
|
SnapmaticPicture *picture = new SnapmaticPicture(selectedFile);
|
||||||
if (picture->readingPicture()) {
|
if (picture->readingPicture())
|
||||||
|
{
|
||||||
openSnapmaticFile(picture);
|
openSnapmaticFile(picture);
|
||||||
delete picture;
|
delete picture;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (warn)
|
{
|
||||||
QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Snapmatic picture"));
|
if (warn) QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Snapmatic picture"));
|
||||||
delete picture;
|
delete picture;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (selectedFileName.left(4) == "SGTA") {
|
else if (selectedFileName.left(4) == "SGTA")
|
||||||
|
{
|
||||||
SavegameData *savegame = new SavegameData(selectedFile);
|
SavegameData *savegame = new SavegameData(selectedFile);
|
||||||
if (savegame->readingSavegame()) {
|
if (savegame->readingSavegame())
|
||||||
|
{
|
||||||
openSavegameFile(savegame);
|
openSavegameFile(savegame);
|
||||||
delete savegame;
|
delete savegame;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (warn)
|
{
|
||||||
QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Savegame file"));
|
if (warn) QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Savegame file"));
|
||||||
delete savegame;
|
delete savegame;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
SnapmaticPicture *picture = new SnapmaticPicture(selectedFile);
|
SnapmaticPicture *picture = new SnapmaticPicture(selectedFile);
|
||||||
SavegameData *savegame = new SavegameData(selectedFile);
|
SavegameData *savegame = new SavegameData(selectedFile);
|
||||||
if (picture->readingPicture()) {
|
if (picture->readingPicture())
|
||||||
|
{
|
||||||
delete savegame;
|
delete savegame;
|
||||||
openSnapmaticFile(picture);
|
openSnapmaticFile(picture);
|
||||||
delete picture;
|
delete picture;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (savegame->readingSavegame()) {
|
else if (savegame->readingSavegame())
|
||||||
|
{
|
||||||
delete picture;
|
delete picture;
|
||||||
openSavegameFile(savegame);
|
openSavegameFile(savegame);
|
||||||
delete savegame;
|
delete savegame;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
delete savegame;
|
delete savegame;
|
||||||
delete picture;
|
delete picture;
|
||||||
if (warn)
|
if (warn) QMessageBox::warning(this, tr("Open File"), tr("Can't open %1 because of not valid file format").arg("\""+selectedFileName+"\""));
|
||||||
QMessageBox::warning(this, tr("Open File"), tr("Can't open %1 because of not valid file format").arg("\""+selectedFileName+"\""));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (warn)
|
if (warn) QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("No valid file is selected"));
|
||||||
QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("No valid file is selected"));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,11 +600,13 @@ void UserInterface::openSavegameFile(SavegameData *savegame)
|
||||||
|
|
||||||
void UserInterface::settingsApplied(int _contentMode, bool languageChanged)
|
void UserInterface::settingsApplied(int _contentMode, bool languageChanged)
|
||||||
{
|
{
|
||||||
if (languageChanged) {
|
if (languageChanged)
|
||||||
|
{
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
}
|
}
|
||||||
contentMode = _contentMode;
|
contentMode = _contentMode;
|
||||||
if (profileOpen) {
|
if (profileOpen)
|
||||||
|
{
|
||||||
profileUI->settingsApplied(contentMode, languageChanged);
|
profileUI->settingsApplied(contentMode, languageChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -754,11 +640,7 @@ void UserInterface::showMessages(const QStringList messages)
|
||||||
{
|
{
|
||||||
QDialog *messageDialog = new QDialog(this);
|
QDialog *messageDialog = new QDialog(this);
|
||||||
messageDialog->setWindowTitle(tr("%1 - Messages").arg(GTA5SYNC_APPSTR));
|
messageDialog->setWindowTitle(tr("%1 - Messages").arg(GTA5SYNC_APPSTR));
|
||||||
#if QT_VERSION >= 0x050900
|
|
||||||
messageDialog->setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
|
||||||
#else
|
|
||||||
messageDialog->setWindowFlags(messageDialog->windowFlags()^Qt::WindowContextHelpButtonHint);
|
messageDialog->setWindowFlags(messageDialog->windowFlags()^Qt::WindowContextHelpButtonHint);
|
||||||
#endif
|
|
||||||
QVBoxLayout *messageLayout = new QVBoxLayout;
|
QVBoxLayout *messageLayout = new QVBoxLayout;
|
||||||
messageDialog->setLayout(messageLayout);
|
messageDialog->setLayout(messageLayout);
|
||||||
QStackedWidget *stackWidget = new QStackedWidget(messageDialog);
|
QStackedWidget *stackWidget = new QStackedWidget(messageDialog);
|
||||||
|
@ -777,8 +659,8 @@ void UserInterface::showMessages(const QStringList messages)
|
||||||
nextButton->setIcon(QIcon::fromTheme("go-next"));
|
nextButton->setIcon(QIcon::fromTheme("go-next"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
backButton->setIcon(QIcon(AppEnv::getImagesFolder() % "/back.svgz"));
|
backButton->setIcon(QIcon(":/img/back.svgz"));
|
||||||
nextButton->setIcon(QIcon(AppEnv::getImagesFolder() % "/next.svgz"));
|
nextButton->setIcon(QIcon(":/img/next.svgz"));
|
||||||
}
|
}
|
||||||
backButton->setEnabled(false);
|
backButton->setEnabled(false);
|
||||||
if (stackWidget->count() <= 1) {
|
if (stackWidget->count() <= 1) {
|
||||||
|
@ -829,9 +711,7 @@ void UserInterface::showMessages(const QStringList messages)
|
||||||
});
|
});
|
||||||
QObject::connect(closeButton, &QPushButton::clicked, messageDialog, &QDialog::accept);
|
QObject::connect(closeButton, &QPushButton::clicked, messageDialog, &QDialog::accept);
|
||||||
QObject::connect(messageDialog, &QDialog::finished, messageDialog, &QDialog::deleteLater);
|
QObject::connect(messageDialog, &QDialog::finished, messageDialog, &QDialog::deleteLater);
|
||||||
QTimer::singleShot(0, closeButton, [=](){
|
QTimer::singleShot(0, closeButton, SLOT(setFocus()));
|
||||||
closeButton->setFocus();
|
|
||||||
});
|
|
||||||
messageDialog->show();
|
messageDialog->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -847,8 +727,10 @@ void UserInterface::updateCacheId(uint cacheId)
|
||||||
void UserInterface::on_actionSelect_GTA_Folder_triggered()
|
void UserInterface::on_actionSelect_GTA_Folder_triggered()
|
||||||
{
|
{
|
||||||
QString GTAV_Folder_Temp = QFileDialog::getExistingDirectory(this, tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly);
|
QString GTAV_Folder_Temp = QFileDialog::getExistingDirectory(this, tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly);
|
||||||
if (QDir(GTAV_Folder_Temp).exists()) {
|
if (QFileInfo(GTAV_Folder_Temp).exists())
|
||||||
if (profileOpen) {
|
{
|
||||||
|
if (profileOpen)
|
||||||
|
{
|
||||||
closeProfile_p();
|
closeProfile_p();
|
||||||
}
|
}
|
||||||
GTAV_Folder = GTAV_Folder_Temp;
|
GTAV_Folder = GTAV_Folder_Temp;
|
||||||
|
@ -861,40 +743,36 @@ void UserInterface::on_actionSelect_GTA_Folder_triggered()
|
||||||
void UserInterface::on_action_Enable_In_game_triggered()
|
void UserInterface::on_action_Enable_In_game_triggered()
|
||||||
{
|
{
|
||||||
if (profileOpen)
|
if (profileOpen)
|
||||||
|
{
|
||||||
profileUI->enableSelected();
|
profileUI->enableSelected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInterface::on_action_Disable_In_game_triggered()
|
void UserInterface::on_action_Disable_In_game_triggered()
|
||||||
{
|
{
|
||||||
if (profileOpen)
|
if (profileOpen)
|
||||||
|
{
|
||||||
profileUI->disableSelected();
|
profileUI->disableSelected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInterface::retranslateUi()
|
void UserInterface::retranslateUi()
|
||||||
{
|
{
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
#ifdef GTA5SYNC_DONATE
|
|
||||||
#ifdef GTA5SYNC_DONATE_ADDRESSES
|
|
||||||
donateAction->setText(tr("&Donate"));
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
ui->actionAbout_gta5sync->setText(QApplication::translate("MAC_APPLICATION_MENU", "About %1").arg(GTA5SYNC_APPSTR));
|
|
||||||
ui->actionOptions->setText(QApplication::translate("MAC_APPLICATION_MENU", "Preferences..."));
|
|
||||||
#else
|
|
||||||
ui->actionAbout_gta5sync->setText(tr("&About %1").arg(GTA5SYNC_APPSTR));
|
ui->actionAbout_gta5sync->setText(tr("&About %1").arg(GTA5SYNC_APPSTR));
|
||||||
#endif
|
QString appVersion = GTA5SYNC_APPVER;
|
||||||
QString appVersion = QApplication::applicationVersion();
|
#ifndef GTA5SYNC_BUILDTYPE_REL
|
||||||
const char* literalBuildType = GTA5SYNC_BUILDTYPE;
|
|
||||||
#ifdef GTA5SYNC_COMMIT
|
#ifdef GTA5SYNC_COMMIT
|
||||||
if ((strcmp(literalBuildType, REL_BUILDTYPE) != 0) && !appVersion.contains("-"))
|
if (!appVersion.contains("-")) { appVersion = appVersion % "-" % GTA5SYNC_COMMIT; }
|
||||||
appVersion = appVersion % "-" % GTA5SYNC_COMMIT;
|
#endif
|
||||||
#endif
|
#endif
|
||||||
ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion));
|
ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion));
|
||||||
if (profileOpen) {
|
if (profileOpen)
|
||||||
|
{
|
||||||
setWindowTitle(defaultWindowTitle.arg(profileName));
|
setWindowTitle(defaultWindowTitle.arg(profileName));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
setWindowTitle(defaultWindowTitle.arg(tr("Select Profile")));
|
setWindowTitle(defaultWindowTitle.arg(tr("Select Profile")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,11 +90,6 @@ private:
|
||||||
DatabaseThread *threadDB;
|
DatabaseThread *threadDB;
|
||||||
#ifdef GTA5SYNC_MOTD
|
#ifdef GTA5SYNC_MOTD
|
||||||
MessageThread *threadMessage;
|
MessageThread *threadMessage;
|
||||||
#endif
|
|
||||||
#ifdef GTA5SYNC_DONATE
|
|
||||||
#ifdef GTA5SYNC_DONATE_ADDRESSES
|
|
||||||
QAction *donateAction;
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
Ui::UserInterface *ui;
|
Ui::UserInterface *ui;
|
||||||
ProfileInterface *profileUI;
|
ProfileInterface *profileUI;
|
||||||
|
|
862
anpro/QrCode.cpp
|
@ -1,862 +0,0 @@
|
||||||
/*
|
|
||||||
* QR Code generator library (C++)
|
|
||||||
*
|
|
||||||
* Copyright (c) Project Nayuki. (MIT License)
|
|
||||||
* https://www.nayuki.io/page/qr-code-generator-library
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
|
||||||
* the Software without restriction, including without limitation the rights to
|
|
||||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
* - The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
* - The Software is provided "as is", without warranty of any kind, express or
|
|
||||||
* implied, including but not limited to the warranties of merchantability,
|
|
||||||
* fitness for a particular purpose and noninfringement. In no event shall the
|
|
||||||
* authors or copyright holders be liable for any claim, damages or other
|
|
||||||
* liability, whether in an action of contract, tort or otherwise, arising from,
|
|
||||||
* out of or in connection with the Software or the use or other dealings in the
|
|
||||||
* Software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <climits>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <utility>
|
|
||||||
#include "QrCode.h"
|
|
||||||
|
|
||||||
using std::int8_t;
|
|
||||||
using std::uint8_t;
|
|
||||||
using std::size_t;
|
|
||||||
using std::vector;
|
|
||||||
|
|
||||||
|
|
||||||
namespace qrcodegen {
|
|
||||||
|
|
||||||
QrSegment::Mode::Mode(int mode, int cc0, int cc1, int cc2) :
|
|
||||||
modeBits(mode) {
|
|
||||||
numBitsCharCount[0] = cc0;
|
|
||||||
numBitsCharCount[1] = cc1;
|
|
||||||
numBitsCharCount[2] = cc2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrSegment::Mode::getModeBits() const {
|
|
||||||
return modeBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrSegment::Mode::numCharCountBits(int ver) const {
|
|
||||||
return numBitsCharCount[(ver + 7) / 17];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const QrSegment::Mode QrSegment::Mode::NUMERIC (0x1, 10, 12, 14);
|
|
||||||
const QrSegment::Mode QrSegment::Mode::ALPHANUMERIC(0x2, 9, 11, 13);
|
|
||||||
const QrSegment::Mode QrSegment::Mode::BYTE (0x4, 8, 16, 16);
|
|
||||||
const QrSegment::Mode QrSegment::Mode::KANJI (0x8, 8, 10, 12);
|
|
||||||
const QrSegment::Mode QrSegment::Mode::ECI (0x7, 0, 0, 0);
|
|
||||||
|
|
||||||
|
|
||||||
QrSegment QrSegment::makeBytes(const vector<uint8_t> &data) {
|
|
||||||
if (data.size() > static_cast<unsigned int>(INT_MAX))
|
|
||||||
throw std::length_error("Data too long");
|
|
||||||
BitBuffer bb;
|
|
||||||
for (uint8_t b : data)
|
|
||||||
bb.appendBits(b, 8);
|
|
||||||
return QrSegment(Mode::BYTE, static_cast<int>(data.size()), std::move(bb));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrSegment QrSegment::makeNumeric(const char *digits) {
|
|
||||||
BitBuffer bb;
|
|
||||||
int accumData = 0;
|
|
||||||
int accumCount = 0;
|
|
||||||
int charCount = 0;
|
|
||||||
for (; *digits != '\0'; digits++, charCount++) {
|
|
||||||
char c = *digits;
|
|
||||||
if (c < '0' || c > '9')
|
|
||||||
throw std::domain_error("String contains non-numeric characters");
|
|
||||||
accumData = accumData * 10 + (c - '0');
|
|
||||||
accumCount++;
|
|
||||||
if (accumCount == 3) {
|
|
||||||
bb.appendBits(static_cast<uint32_t>(accumData), 10);
|
|
||||||
accumData = 0;
|
|
||||||
accumCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (accumCount > 0) // 1 or 2 digits remaining
|
|
||||||
bb.appendBits(static_cast<uint32_t>(accumData), accumCount * 3 + 1);
|
|
||||||
return QrSegment(Mode::NUMERIC, charCount, std::move(bb));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrSegment QrSegment::makeAlphanumeric(const char *text) {
|
|
||||||
BitBuffer bb;
|
|
||||||
int accumData = 0;
|
|
||||||
int accumCount = 0;
|
|
||||||
int charCount = 0;
|
|
||||||
for (; *text != '\0'; text++, charCount++) {
|
|
||||||
const char *temp = std::strchr(ALPHANUMERIC_CHARSET, *text);
|
|
||||||
if (temp == nullptr)
|
|
||||||
throw std::domain_error("String contains unencodable characters in alphanumeric mode");
|
|
||||||
accumData = accumData * 45 + static_cast<int>(temp - ALPHANUMERIC_CHARSET);
|
|
||||||
accumCount++;
|
|
||||||
if (accumCount == 2) {
|
|
||||||
bb.appendBits(static_cast<uint32_t>(accumData), 11);
|
|
||||||
accumData = 0;
|
|
||||||
accumCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (accumCount > 0) // 1 character remaining
|
|
||||||
bb.appendBits(static_cast<uint32_t>(accumData), 6);
|
|
||||||
return QrSegment(Mode::ALPHANUMERIC, charCount, std::move(bb));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vector<QrSegment> QrSegment::makeSegments(const char *text) {
|
|
||||||
// Select the most efficient segment encoding automatically
|
|
||||||
vector<QrSegment> result;
|
|
||||||
if (*text == '\0'); // Leave result empty
|
|
||||||
else if (isNumeric(text))
|
|
||||||
result.push_back(makeNumeric(text));
|
|
||||||
else if (isAlphanumeric(text))
|
|
||||||
result.push_back(makeAlphanumeric(text));
|
|
||||||
else {
|
|
||||||
vector<uint8_t> bytes;
|
|
||||||
for (; *text != '\0'; text++)
|
|
||||||
bytes.push_back(static_cast<uint8_t>(*text));
|
|
||||||
result.push_back(makeBytes(bytes));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrSegment QrSegment::makeEci(long assignVal) {
|
|
||||||
BitBuffer bb;
|
|
||||||
if (assignVal < 0)
|
|
||||||
throw std::domain_error("ECI assignment value out of range");
|
|
||||||
else if (assignVal < (1 << 7))
|
|
||||||
bb.appendBits(static_cast<uint32_t>(assignVal), 8);
|
|
||||||
else if (assignVal < (1 << 14)) {
|
|
||||||
bb.appendBits(2, 2);
|
|
||||||
bb.appendBits(static_cast<uint32_t>(assignVal), 14);
|
|
||||||
} else if (assignVal < 1000000L) {
|
|
||||||
bb.appendBits(6, 3);
|
|
||||||
bb.appendBits(static_cast<uint32_t>(assignVal), 21);
|
|
||||||
} else
|
|
||||||
throw std::domain_error("ECI assignment value out of range");
|
|
||||||
return QrSegment(Mode::ECI, 0, std::move(bb));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrSegment::QrSegment(Mode md, int numCh, const std::vector<bool> &dt) :
|
|
||||||
mode(md),
|
|
||||||
numChars(numCh),
|
|
||||||
data(dt) {
|
|
||||||
if (numCh < 0)
|
|
||||||
throw std::domain_error("Invalid value");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrSegment::QrSegment(Mode md, int numCh, std::vector<bool> &&dt) :
|
|
||||||
mode(md),
|
|
||||||
numChars(numCh),
|
|
||||||
data(std::move(dt)) {
|
|
||||||
if (numCh < 0)
|
|
||||||
throw std::domain_error("Invalid value");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrSegment::getTotalBits(const vector<QrSegment> &segs, int version) {
|
|
||||||
int result = 0;
|
|
||||||
for (const QrSegment &seg : segs) {
|
|
||||||
int ccbits = seg.mode.numCharCountBits(version);
|
|
||||||
if (seg.numChars >= (1L << ccbits))
|
|
||||||
return -1; // The segment's length doesn't fit the field's bit width
|
|
||||||
if (4 + ccbits > INT_MAX - result)
|
|
||||||
return -1; // The sum will overflow an int type
|
|
||||||
result += 4 + ccbits;
|
|
||||||
if (seg.data.size() > static_cast<unsigned int>(INT_MAX - result))
|
|
||||||
return -1; // The sum will overflow an int type
|
|
||||||
result += static_cast<int>(seg.data.size());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool QrSegment::isAlphanumeric(const char *text) {
|
|
||||||
for (; *text != '\0'; text++) {
|
|
||||||
if (std::strchr(ALPHANUMERIC_CHARSET, *text) == nullptr)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool QrSegment::isNumeric(const char *text) {
|
|
||||||
for (; *text != '\0'; text++) {
|
|
||||||
char c = *text;
|
|
||||||
if (c < '0' || c > '9')
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrSegment::Mode QrSegment::getMode() const {
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrSegment::getNumChars() const {
|
|
||||||
return numChars;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const std::vector<bool> &QrSegment::getData() const {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *QrSegment::ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int QrCode::getFormatBits(Ecc ecl) {
|
|
||||||
switch (ecl) {
|
|
||||||
case Ecc::LOW : return 1;
|
|
||||||
case Ecc::MEDIUM : return 0;
|
|
||||||
case Ecc::QUARTILE: return 3;
|
|
||||||
case Ecc::HIGH : return 2;
|
|
||||||
default: throw std::logic_error("Assertion error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrCode QrCode::encodeText(const char *text, Ecc ecl) {
|
|
||||||
vector<QrSegment> segs = QrSegment::makeSegments(text);
|
|
||||||
return encodeSegments(segs, ecl);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrCode QrCode::encodeBinary(const vector<uint8_t> &data, Ecc ecl) {
|
|
||||||
vector<QrSegment> segs{QrSegment::makeBytes(data)};
|
|
||||||
return encodeSegments(segs, ecl);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
|
|
||||||
int minVersion, int maxVersion, int mask, bool boostEcl) {
|
|
||||||
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
|
|
||||||
throw std::invalid_argument("Invalid value");
|
|
||||||
|
|
||||||
// Find the minimal version number to use
|
|
||||||
int version, dataUsedBits;
|
|
||||||
for (version = minVersion; ; version++) {
|
|
||||||
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available
|
|
||||||
dataUsedBits = QrSegment::getTotalBits(segs, version);
|
|
||||||
if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits)
|
|
||||||
break; // This version number is found to be suitable
|
|
||||||
if (version >= maxVersion) { // All versions in the range could not fit the given data
|
|
||||||
std::ostringstream sb;
|
|
||||||
if (dataUsedBits == -1)
|
|
||||||
sb << "Segment too long";
|
|
||||||
else {
|
|
||||||
sb << "Data length = " << dataUsedBits << " bits, ";
|
|
||||||
sb << "Max capacity = " << dataCapacityBits << " bits";
|
|
||||||
}
|
|
||||||
throw data_too_long(sb.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dataUsedBits == -1)
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
|
|
||||||
// Increase the error correction level while the data still fits in the current version number
|
|
||||||
for (Ecc newEcl : vector<Ecc>{Ecc::MEDIUM, Ecc::QUARTILE, Ecc::HIGH}) { // From low to high
|
|
||||||
if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8)
|
|
||||||
ecl = newEcl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Concatenate all segments to create the data bit string
|
|
||||||
BitBuffer bb;
|
|
||||||
for (const QrSegment &seg : segs) {
|
|
||||||
bb.appendBits(static_cast<uint32_t>(seg.getMode().getModeBits()), 4);
|
|
||||||
bb.appendBits(static_cast<uint32_t>(seg.getNumChars()), seg.getMode().numCharCountBits(version));
|
|
||||||
bb.insert(bb.end(), seg.getData().begin(), seg.getData().end());
|
|
||||||
}
|
|
||||||
if (bb.size() != static_cast<unsigned int>(dataUsedBits))
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
|
|
||||||
// Add terminator and pad up to a byte if applicable
|
|
||||||
size_t dataCapacityBits = static_cast<size_t>(getNumDataCodewords(version, ecl)) * 8;
|
|
||||||
if (bb.size() > dataCapacityBits)
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
bb.appendBits(0, std::min(4, static_cast<int>(dataCapacityBits - bb.size())));
|
|
||||||
bb.appendBits(0, (8 - static_cast<int>(bb.size() % 8)) % 8);
|
|
||||||
if (bb.size() % 8 != 0)
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
|
|
||||||
// Pad with alternating bytes until data capacity is reached
|
|
||||||
for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
|
||||||
bb.appendBits(padByte, 8);
|
|
||||||
|
|
||||||
// Pack bits into bytes in big endian
|
|
||||||
vector<uint8_t> dataCodewords(bb.size() / 8);
|
|
||||||
for (size_t i = 0; i < bb.size(); i++)
|
|
||||||
dataCodewords[i >> 3] |= (bb.at(i) ? 1 : 0) << (7 - (i & 7));
|
|
||||||
|
|
||||||
// Create the QR Code object
|
|
||||||
return QrCode(version, ecl, dataCodewords, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrCode::QrCode(int ver, Ecc ecl, const vector<uint8_t> &dataCodewords, int msk) :
|
|
||||||
// Initialize fields and check arguments
|
|
||||||
version(ver),
|
|
||||||
errorCorrectionLevel(ecl) {
|
|
||||||
if (ver < MIN_VERSION || ver > MAX_VERSION)
|
|
||||||
throw std::domain_error("Version value out of range");
|
|
||||||
if (msk < -1 || msk > 7)
|
|
||||||
throw std::domain_error("Mask value out of range");
|
|
||||||
size = ver * 4 + 17;
|
|
||||||
size_t sz = static_cast<size_t>(size);
|
|
||||||
modules = vector<vector<bool> >(sz, vector<bool>(sz)); // Initially all white
|
|
||||||
isFunction = vector<vector<bool> >(sz, vector<bool>(sz));
|
|
||||||
|
|
||||||
// Compute ECC, draw modules
|
|
||||||
drawFunctionPatterns();
|
|
||||||
const vector<uint8_t> allCodewords = addEccAndInterleave(dataCodewords);
|
|
||||||
drawCodewords(allCodewords);
|
|
||||||
|
|
||||||
// Do masking
|
|
||||||
if (msk == -1) { // Automatically choose best mask
|
|
||||||
long minPenalty = LONG_MAX;
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
applyMask(i);
|
|
||||||
drawFormatBits(i);
|
|
||||||
long penalty = getPenaltyScore();
|
|
||||||
if (penalty < minPenalty) {
|
|
||||||
msk = i;
|
|
||||||
minPenalty = penalty;
|
|
||||||
}
|
|
||||||
applyMask(i); // Undoes the mask due to XOR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msk < 0 || msk > 7)
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
this->mask = msk;
|
|
||||||
applyMask(msk); // Apply the final choice of mask
|
|
||||||
drawFormatBits(msk); // Overwrite old format bits
|
|
||||||
|
|
||||||
isFunction.clear();
|
|
||||||
isFunction.shrink_to_fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrCode::getVersion() const {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrCode::getSize() const {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QrCode::Ecc QrCode::getErrorCorrectionLevel() const {
|
|
||||||
return errorCorrectionLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrCode::getMask() const {
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool QrCode::getModule(int x, int y) const {
|
|
||||||
return 0 <= x && x < size && 0 <= y && y < size && module(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string QrCode::toSvgString(int border) const {
|
|
||||||
if (border < 0)
|
|
||||||
throw std::domain_error("Border must be non-negative");
|
|
||||||
if (border > INT_MAX / 2 || border * 2 > INT_MAX - size)
|
|
||||||
throw std::overflow_error("Border too large");
|
|
||||||
|
|
||||||
std::ostringstream sb;
|
|
||||||
sb << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
|
||||||
sb << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
|
|
||||||
sb << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 ";
|
|
||||||
sb << (size + border * 2) << " " << (size + border * 2) << "\" stroke=\"none\">\n";
|
|
||||||
sb << "\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n";
|
|
||||||
sb << "\t<path d=\"";
|
|
||||||
for (int y = 0; y < size; y++) {
|
|
||||||
for (int x = 0; x < size; x++) {
|
|
||||||
if (getModule(x, y)) {
|
|
||||||
if (x != 0 || y != 0)
|
|
||||||
sb << " ";
|
|
||||||
sb << "M" << (x + border) << "," << (y + border) << "h1v1h-1z";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb << "\" fill=\"#000000\"/>\n";
|
|
||||||
sb << "</svg>\n";
|
|
||||||
return sb.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QrCode::drawFunctionPatterns() {
|
|
||||||
// Draw horizontal and vertical timing patterns
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
setFunctionModule(6, i, i % 2 == 0);
|
|
||||||
setFunctionModule(i, 6, i % 2 == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
|
|
||||||
drawFinderPattern(3, 3);
|
|
||||||
drawFinderPattern(size - 4, 3);
|
|
||||||
drawFinderPattern(3, size - 4);
|
|
||||||
|
|
||||||
// Draw numerous alignment patterns
|
|
||||||
const vector<int> alignPatPos = getAlignmentPatternPositions();
|
|
||||||
size_t numAlign = alignPatPos.size();
|
|
||||||
for (size_t i = 0; i < numAlign; i++) {
|
|
||||||
for (size_t j = 0; j < numAlign; j++) {
|
|
||||||
// Don't draw on the three finder corners
|
|
||||||
if (!((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0)))
|
|
||||||
drawAlignmentPattern(alignPatPos.at(i), alignPatPos.at(j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw configuration data
|
|
||||||
drawFormatBits(0); // Dummy mask value; overwritten later in the constructor
|
|
||||||
drawVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QrCode::drawFormatBits(int msk) {
|
|
||||||
// Calculate error correction code and pack bits
|
|
||||||
int data = getFormatBits(errorCorrectionLevel) << 3 | msk; // errCorrLvl is uint2, msk is uint3
|
|
||||||
int rem = data;
|
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
rem = (rem << 1) ^ ((rem >> 9) * 0x537);
|
|
||||||
int bits = (data << 10 | rem) ^ 0x5412; // uint15
|
|
||||||
if (bits >> 15 != 0)
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
|
|
||||||
// Draw first copy
|
|
||||||
for (int i = 0; i <= 5; i++)
|
|
||||||
setFunctionModule(8, i, getBit(bits, i));
|
|
||||||
setFunctionModule(8, 7, getBit(bits, 6));
|
|
||||||
setFunctionModule(8, 8, getBit(bits, 7));
|
|
||||||
setFunctionModule(7, 8, getBit(bits, 8));
|
|
||||||
for (int i = 9; i < 15; i++)
|
|
||||||
setFunctionModule(14 - i, 8, getBit(bits, i));
|
|
||||||
|
|
||||||
// Draw second copy
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
setFunctionModule(size - 1 - i, 8, getBit(bits, i));
|
|
||||||
for (int i = 8; i < 15; i++)
|
|
||||||
setFunctionModule(8, size - 15 + i, getBit(bits, i));
|
|
||||||
setFunctionModule(8, size - 8, true); // Always black
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QrCode::drawVersion() {
|
|
||||||
if (version < 7)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Calculate error correction code and pack bits
|
|
||||||
int rem = version; // version is uint6, in the range [7, 40]
|
|
||||||
for (int i = 0; i < 12; i++)
|
|
||||||
rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
|
|
||||||
long bits = static_cast<long>(version) << 12 | rem; // uint18
|
|
||||||
if (bits >> 18 != 0)
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
|
|
||||||
// Draw two copies
|
|
||||||
for (int i = 0; i < 18; i++) {
|
|
||||||
bool bit = getBit(bits, i);
|
|
||||||
int a = size - 11 + i % 3;
|
|
||||||
int b = i / 3;
|
|
||||||
setFunctionModule(a, b, bit);
|
|
||||||
setFunctionModule(b, a, bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QrCode::drawFinderPattern(int x, int y) {
|
|
||||||
for (int dy = -4; dy <= 4; dy++) {
|
|
||||||
for (int dx = -4; dx <= 4; dx++) {
|
|
||||||
int dist = std::max(std::abs(dx), std::abs(dy)); // Chebyshev/infinity norm
|
|
||||||
int xx = x + dx, yy = y + dy;
|
|
||||||
if (0 <= xx && xx < size && 0 <= yy && yy < size)
|
|
||||||
setFunctionModule(xx, yy, dist != 2 && dist != 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QrCode::drawAlignmentPattern(int x, int y) {
|
|
||||||
for (int dy = -2; dy <= 2; dy++) {
|
|
||||||
for (int dx = -2; dx <= 2; dx++)
|
|
||||||
setFunctionModule(x + dx, y + dy, std::max(std::abs(dx), std::abs(dy)) != 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QrCode::setFunctionModule(int x, int y, bool isBlack) {
|
|
||||||
size_t ux = static_cast<size_t>(x);
|
|
||||||
size_t uy = static_cast<size_t>(y);
|
|
||||||
modules .at(uy).at(ux) = isBlack;
|
|
||||||
isFunction.at(uy).at(ux) = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool QrCode::module(int x, int y) const {
|
|
||||||
return modules.at(static_cast<size_t>(y)).at(static_cast<size_t>(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vector<uint8_t> QrCode::addEccAndInterleave(const vector<uint8_t> &data) const {
|
|
||||||
if (data.size() != static_cast<unsigned int>(getNumDataCodewords(version, errorCorrectionLevel)))
|
|
||||||
throw std::invalid_argument("Invalid argument");
|
|
||||||
|
|
||||||
// Calculate parameter numbers
|
|
||||||
int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[static_cast<int>(errorCorrectionLevel)][version];
|
|
||||||
int blockEccLen = ECC_CODEWORDS_PER_BLOCK [static_cast<int>(errorCorrectionLevel)][version];
|
|
||||||
int rawCodewords = getNumRawDataModules(version) / 8;
|
|
||||||
int numShortBlocks = numBlocks - rawCodewords % numBlocks;
|
|
||||||
int shortBlockLen = rawCodewords / numBlocks;
|
|
||||||
|
|
||||||
// Split data into blocks and append ECC to each block
|
|
||||||
vector<vector<uint8_t> > blocks;
|
|
||||||
const vector<uint8_t> rsDiv = reedSolomonComputeDivisor(blockEccLen);
|
|
||||||
for (int i = 0, k = 0; i < numBlocks; i++) {
|
|
||||||
vector<uint8_t> dat(data.cbegin() + k, data.cbegin() + (k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1)));
|
|
||||||
k += static_cast<int>(dat.size());
|
|
||||||
const vector<uint8_t> ecc = reedSolomonComputeRemainder(dat, rsDiv);
|
|
||||||
if (i < numShortBlocks)
|
|
||||||
dat.push_back(0);
|
|
||||||
dat.insert(dat.end(), ecc.cbegin(), ecc.cend());
|
|
||||||
blocks.push_back(std::move(dat));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interleave (not concatenate) the bytes from every block into a single sequence
|
|
||||||
vector<uint8_t> result;
|
|
||||||
for (size_t i = 0; i < blocks.at(0).size(); i++) {
|
|
||||||
for (size_t j = 0; j < blocks.size(); j++) {
|
|
||||||
// Skip the padding byte in short blocks
|
|
||||||
if (i != static_cast<unsigned int>(shortBlockLen - blockEccLen) || j >= static_cast<unsigned int>(numShortBlocks))
|
|
||||||
result.push_back(blocks.at(j).at(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result.size() != static_cast<unsigned int>(rawCodewords))
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QrCode::drawCodewords(const vector<uint8_t> &data) {
|
|
||||||
if (data.size() != static_cast<unsigned int>(getNumRawDataModules(version) / 8))
|
|
||||||
throw std::invalid_argument("Invalid argument");
|
|
||||||
|
|
||||||
size_t i = 0; // Bit index into the data
|
|
||||||
// Do the funny zigzag scan
|
|
||||||
for (int right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair
|
|
||||||
if (right == 6)
|
|
||||||
right = 5;
|
|
||||||
for (int vert = 0; vert < size; vert++) { // Vertical counter
|
|
||||||
for (int j = 0; j < 2; j++) {
|
|
||||||
size_t x = static_cast<size_t>(right - j); // Actual x coordinate
|
|
||||||
bool upward = ((right + 1) & 2) == 0;
|
|
||||||
size_t y = static_cast<size_t>(upward ? size - 1 - vert : vert); // Actual y coordinate
|
|
||||||
if (!isFunction.at(y).at(x) && i < data.size() * 8) {
|
|
||||||
modules.at(y).at(x) = getBit(data.at(i >> 3), 7 - static_cast<int>(i & 7));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
// If this QR Code has any remainder bits (0 to 7), they were assigned as
|
|
||||||
// 0/false/white by the constructor and are left unchanged by this method
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i != data.size() * 8)
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QrCode::applyMask(int msk) {
|
|
||||||
if (msk < 0 || msk > 7)
|
|
||||||
throw std::domain_error("Mask value out of range");
|
|
||||||
size_t sz = static_cast<size_t>(size);
|
|
||||||
for (size_t y = 0; y < sz; y++) {
|
|
||||||
for (size_t x = 0; x < sz; x++) {
|
|
||||||
bool invert;
|
|
||||||
switch (msk) {
|
|
||||||
case 0: invert = (x + y) % 2 == 0; break;
|
|
||||||
case 1: invert = y % 2 == 0; break;
|
|
||||||
case 2: invert = x % 3 == 0; break;
|
|
||||||
case 3: invert = (x + y) % 3 == 0; break;
|
|
||||||
case 4: invert = (x / 3 + y / 2) % 2 == 0; break;
|
|
||||||
case 5: invert = x * y % 2 + x * y % 3 == 0; break;
|
|
||||||
case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break;
|
|
||||||
case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break;
|
|
||||||
default: throw std::logic_error("Assertion error");
|
|
||||||
}
|
|
||||||
modules.at(y).at(x) = modules.at(y).at(x) ^ (invert & !isFunction.at(y).at(x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
long QrCode::getPenaltyScore() const {
|
|
||||||
long result = 0;
|
|
||||||
|
|
||||||
// Adjacent modules in row having same color, and finder-like patterns
|
|
||||||
for (int y = 0; y < size; y++) {
|
|
||||||
bool runColor = false;
|
|
||||||
int runX = 0;
|
|
||||||
std::array<int,7> runHistory = {};
|
|
||||||
for (int x = 0; x < size; x++) {
|
|
||||||
if (module(x, y) == runColor) {
|
|
||||||
runX++;
|
|
||||||
if (runX == 5)
|
|
||||||
result += PENALTY_N1;
|
|
||||||
else if (runX > 5)
|
|
||||||
result++;
|
|
||||||
} else {
|
|
||||||
finderPenaltyAddHistory(runX, runHistory);
|
|
||||||
if (!runColor)
|
|
||||||
result += finderPenaltyCountPatterns(runHistory) * PENALTY_N3;
|
|
||||||
runColor = module(x, y);
|
|
||||||
runX = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result += finderPenaltyTerminateAndCount(runColor, runX, runHistory) * PENALTY_N3;
|
|
||||||
}
|
|
||||||
// Adjacent modules in column having same color, and finder-like patterns
|
|
||||||
for (int x = 0; x < size; x++) {
|
|
||||||
bool runColor = false;
|
|
||||||
int runY = 0;
|
|
||||||
std::array<int,7> runHistory = {};
|
|
||||||
for (int y = 0; y < size; y++) {
|
|
||||||
if (module(x, y) == runColor) {
|
|
||||||
runY++;
|
|
||||||
if (runY == 5)
|
|
||||||
result += PENALTY_N1;
|
|
||||||
else if (runY > 5)
|
|
||||||
result++;
|
|
||||||
} else {
|
|
||||||
finderPenaltyAddHistory(runY, runHistory);
|
|
||||||
if (!runColor)
|
|
||||||
result += finderPenaltyCountPatterns(runHistory) * PENALTY_N3;
|
|
||||||
runColor = module(x, y);
|
|
||||||
runY = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result += finderPenaltyTerminateAndCount(runColor, runY, runHistory) * PENALTY_N3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2*2 blocks of modules having same color
|
|
||||||
for (int y = 0; y < size - 1; y++) {
|
|
||||||
for (int x = 0; x < size - 1; x++) {
|
|
||||||
bool color = module(x, y);
|
|
||||||
if ( color == module(x + 1, y) &&
|
|
||||||
color == module(x, y + 1) &&
|
|
||||||
color == module(x + 1, y + 1))
|
|
||||||
result += PENALTY_N2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Balance of black and white modules
|
|
||||||
int black = 0;
|
|
||||||
for (const vector<bool> &row : modules) {
|
|
||||||
for (bool color : row) {
|
|
||||||
if (color)
|
|
||||||
black++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int total = size * size; // Note that size is odd, so black/total != 1/2
|
|
||||||
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
|
|
||||||
int k = static_cast<int>((std::abs(black * 20L - total * 10L) + total - 1) / total) - 1;
|
|
||||||
result += k * PENALTY_N4;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vector<int> QrCode::getAlignmentPatternPositions() const {
|
|
||||||
if (version == 1)
|
|
||||||
return vector<int>();
|
|
||||||
else {
|
|
||||||
int numAlign = version / 7 + 2;
|
|
||||||
int step = (version == 32) ? 26 :
|
|
||||||
(version*4 + numAlign*2 + 1) / (numAlign*2 - 2) * 2;
|
|
||||||
vector<int> result;
|
|
||||||
for (int i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step)
|
|
||||||
result.insert(result.begin(), pos);
|
|
||||||
result.insert(result.begin(), 6);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrCode::getNumRawDataModules(int ver) {
|
|
||||||
if (ver < MIN_VERSION || ver > MAX_VERSION)
|
|
||||||
throw std::domain_error("Version number out of range");
|
|
||||||
int result = (16 * ver + 128) * ver + 64;
|
|
||||||
if (ver >= 2) {
|
|
||||||
int numAlign = ver / 7 + 2;
|
|
||||||
result -= (25 * numAlign - 10) * numAlign - 55;
|
|
||||||
if (ver >= 7)
|
|
||||||
result -= 36;
|
|
||||||
}
|
|
||||||
if (!(208 <= result && result <= 29648))
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrCode::getNumDataCodewords(int ver, Ecc ecl) {
|
|
||||||
return getNumRawDataModules(ver) / 8
|
|
||||||
- ECC_CODEWORDS_PER_BLOCK [static_cast<int>(ecl)][ver]
|
|
||||||
* NUM_ERROR_CORRECTION_BLOCKS[static_cast<int>(ecl)][ver];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vector<uint8_t> QrCode::reedSolomonComputeDivisor(int degree) {
|
|
||||||
if (degree < 1 || degree > 255)
|
|
||||||
throw std::domain_error("Degree out of range");
|
|
||||||
// Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1.
|
|
||||||
// For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
|
|
||||||
vector<uint8_t> result(static_cast<size_t>(degree));
|
|
||||||
result.at(result.size() - 1) = 1; // Start off with the monomial x^0
|
|
||||||
|
|
||||||
// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
|
|
||||||
// and drop the highest monomial term which is always 1x^degree.
|
|
||||||
// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
|
|
||||||
uint8_t root = 1;
|
|
||||||
for (int i = 0; i < degree; i++) {
|
|
||||||
// Multiply the current product by (x - r^i)
|
|
||||||
for (size_t j = 0; j < result.size(); j++) {
|
|
||||||
result.at(j) = reedSolomonMultiply(result.at(j), root);
|
|
||||||
if (j + 1 < result.size())
|
|
||||||
result.at(j) ^= result.at(j + 1);
|
|
||||||
}
|
|
||||||
root = reedSolomonMultiply(root, 0x02);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vector<uint8_t> QrCode::reedSolomonComputeRemainder(const vector<uint8_t> &data, const vector<uint8_t> &divisor) {
|
|
||||||
vector<uint8_t> result(divisor.size());
|
|
||||||
for (uint8_t b : data) { // Polynomial division
|
|
||||||
uint8_t factor = b ^ result.at(0);
|
|
||||||
result.erase(result.begin());
|
|
||||||
result.push_back(0);
|
|
||||||
for (size_t i = 0; i < result.size(); i++)
|
|
||||||
result.at(i) ^= reedSolomonMultiply(divisor.at(i), factor);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t QrCode::reedSolomonMultiply(uint8_t x, uint8_t y) {
|
|
||||||
// Russian peasant multiplication
|
|
||||||
int z = 0;
|
|
||||||
for (int i = 7; i >= 0; i--) {
|
|
||||||
z = (z << 1) ^ ((z >> 7) * 0x11D);
|
|
||||||
z ^= ((y >> i) & 1) * x;
|
|
||||||
}
|
|
||||||
if (z >> 8 != 0)
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
return static_cast<uint8_t>(z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrCode::finderPenaltyCountPatterns(const std::array<int,7> &runHistory) const {
|
|
||||||
int n = runHistory.at(1);
|
|
||||||
if (n > size * 3)
|
|
||||||
throw std::logic_error("Assertion error");
|
|
||||||
bool core = n > 0 && runHistory.at(2) == n && runHistory.at(3) == n * 3 && runHistory.at(4) == n && runHistory.at(5) == n;
|
|
||||||
return (core && runHistory.at(0) >= n * 4 && runHistory.at(6) >= n ? 1 : 0)
|
|
||||||
+ (core && runHistory.at(6) >= n * 4 && runHistory.at(0) >= n ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int QrCode::finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, std::array<int,7> &runHistory) const {
|
|
||||||
if (currentRunColor) { // Terminate black run
|
|
||||||
finderPenaltyAddHistory(currentRunLength, runHistory);
|
|
||||||
currentRunLength = 0;
|
|
||||||
}
|
|
||||||
currentRunLength += size; // Add white border to final run
|
|
||||||
finderPenaltyAddHistory(currentRunLength, runHistory);
|
|
||||||
return finderPenaltyCountPatterns(runHistory);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QrCode::finderPenaltyAddHistory(int currentRunLength, std::array<int,7> &runHistory) const {
|
|
||||||
if (runHistory.at(0) == 0)
|
|
||||||
currentRunLength += size; // Add white border to initial run
|
|
||||||
std::copy_backward(runHistory.cbegin(), runHistory.cend() - 1, runHistory.end());
|
|
||||||
runHistory.at(0) = currentRunLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool QrCode::getBit(long x, int i) {
|
|
||||||
return ((x >> i) & 1) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Tables of constants ----*/
|
|
||||||
|
|
||||||
const int QrCode::PENALTY_N1 = 3;
|
|
||||||
const int QrCode::PENALTY_N2 = 3;
|
|
||||||
const int QrCode::PENALTY_N3 = 40;
|
|
||||||
const int QrCode::PENALTY_N4 = 10;
|
|
||||||
|
|
||||||
|
|
||||||
const int8_t QrCode::ECC_CODEWORDS_PER_BLOCK[4][41] = {
|
|
||||||
// Version: (note that index 0 is for padding, and is set to an illegal value)
|
|
||||||
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
|
||||||
{-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Low
|
|
||||||
{-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, // Medium
|
|
||||||
{-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Quartile
|
|
||||||
{-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // High
|
|
||||||
};
|
|
||||||
|
|
||||||
const int8_t QrCode::NUM_ERROR_CORRECTION_BLOCKS[4][41] = {
|
|
||||||
// Version: (note that index 0 is for padding, and is set to an illegal value)
|
|
||||||
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
|
||||||
{-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low
|
|
||||||
{-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium
|
|
||||||
{-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile
|
|
||||||
{-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
data_too_long::data_too_long(const std::string &msg) :
|
|
||||||
std::length_error(msg) {}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BitBuffer::BitBuffer()
|
|
||||||
: std::vector<bool>() {}
|
|
||||||
|
|
||||||
|
|
||||||
void BitBuffer::appendBits(std::uint32_t val, int len) {
|
|
||||||
if (len < 0 || len > 31 || val >> len != 0)
|
|
||||||
throw std::domain_error("Value out of range");
|
|
||||||
for (int i = len - 1; i >= 0; i--) // Append bit by bit
|
|
||||||
this->push_back(((val >> i) & 1) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
556
anpro/QrCode.h
|
@ -1,556 +0,0 @@
|
||||||
/*
|
|
||||||
* QR Code generator library (C++)
|
|
||||||
*
|
|
||||||
* Copyright (c) Project Nayuki. (MIT License)
|
|
||||||
* https://www.nayuki.io/page/qr-code-generator-library
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
|
||||||
* the Software without restriction, including without limitation the rights to
|
|
||||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
* - The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
* - The Software is provided "as is", without warranty of any kind, express or
|
|
||||||
* implied, including but not limited to the warranties of merchantability,
|
|
||||||
* fitness for a particular purpose and noninfringement. In no event shall the
|
|
||||||
* authors or copyright holders be liable for any claim, damages or other
|
|
||||||
* liability, whether in an action of contract, tort or otherwise, arising from,
|
|
||||||
* out of or in connection with the Software or the use or other dealings in the
|
|
||||||
* Software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
namespace qrcodegen {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A segment of character/binary/control data in a QR Code symbol.
|
|
||||||
* Instances of this class are immutable.
|
|
||||||
* The mid-level way to create a segment is to take the payload data
|
|
||||||
* and call a static factory function such as QrSegment::makeNumeric().
|
|
||||||
* The low-level way to create a segment is to custom-make the bit buffer
|
|
||||||
* and call the QrSegment() constructor with appropriate values.
|
|
||||||
* This segment class imposes no length restrictions, but QR Codes have restrictions.
|
|
||||||
* Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
|
|
||||||
* Any segment longer than this is meaningless for the purpose of generating QR Codes.
|
|
||||||
*/
|
|
||||||
class QrSegment final {
|
|
||||||
|
|
||||||
/*---- Public helper enumeration ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Describes how a segment's data bits are interpreted. Immutable.
|
|
||||||
*/
|
|
||||||
public: class Mode final {
|
|
||||||
|
|
||||||
/*-- Constants --*/
|
|
||||||
|
|
||||||
public: static const Mode NUMERIC;
|
|
||||||
public: static const Mode ALPHANUMERIC;
|
|
||||||
public: static const Mode BYTE;
|
|
||||||
public: static const Mode KANJI;
|
|
||||||
public: static const Mode ECI;
|
|
||||||
|
|
||||||
|
|
||||||
/*-- Fields --*/
|
|
||||||
|
|
||||||
// The mode indicator bits, which is a uint4 value (range 0 to 15).
|
|
||||||
private: int modeBits;
|
|
||||||
|
|
||||||
// Number of character count bits for three different version ranges.
|
|
||||||
private: int numBitsCharCount[3];
|
|
||||||
|
|
||||||
|
|
||||||
/*-- Constructor --*/
|
|
||||||
|
|
||||||
private: Mode(int mode, int cc0, int cc1, int cc2);
|
|
||||||
|
|
||||||
|
|
||||||
/*-- Methods --*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (Package-private) Returns the mode indicator bits, which is an unsigned 4-bit value (range 0 to 15).
|
|
||||||
*/
|
|
||||||
public: int getModeBits() const;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (Package-private) Returns the bit width of the character count field for a segment in
|
|
||||||
* this mode in a QR Code at the given version number. The result is in the range [0, 16].
|
|
||||||
*/
|
|
||||||
public: int numCharCountBits(int ver) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Static factory functions (mid level) ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a segment representing the given binary data encoded in
|
|
||||||
* byte mode. All input byte vectors are acceptable. Any text string
|
|
||||||
* can be converted to UTF-8 bytes and encoded as a byte mode segment.
|
|
||||||
*/
|
|
||||||
public: static QrSegment makeBytes(const std::vector<std::uint8_t> &data);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a segment representing the given string of decimal digits encoded in numeric mode.
|
|
||||||
*/
|
|
||||||
public: static QrSegment makeNumeric(const char *digits);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a segment representing the given text string encoded in alphanumeric mode.
|
|
||||||
* The characters allowed are: 0 to 9, A to Z (uppercase only), space,
|
|
||||||
* dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
|
||||||
*/
|
|
||||||
public: static QrSegment makeAlphanumeric(const char *text);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a list of zero or more segments to represent the given text string. The result
|
|
||||||
* may use various segment modes and switch modes to optimize the length of the bit stream.
|
|
||||||
*/
|
|
||||||
public: static std::vector<QrSegment> makeSegments(const char *text);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a segment representing an Extended Channel Interpretation
|
|
||||||
* (ECI) designator with the given assignment value.
|
|
||||||
*/
|
|
||||||
public: static QrSegment makeEci(long assignVal);
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Public static helper functions ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tests whether the given string can be encoded as a segment in alphanumeric mode.
|
|
||||||
* A string is encodable iff each character is in the following set: 0 to 9, A to Z
|
|
||||||
* (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
|
||||||
*/
|
|
||||||
public: static bool isAlphanumeric(const char *text);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tests whether the given string can be encoded as a segment in numeric mode.
|
|
||||||
* A string is encodable iff each character is in the range 0 to 9.
|
|
||||||
*/
|
|
||||||
public: static bool isNumeric(const char *text);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Instance fields ----*/
|
|
||||||
|
|
||||||
/* The mode indicator of this segment. Accessed through getMode(). */
|
|
||||||
private: Mode mode;
|
|
||||||
|
|
||||||
/* The length of this segment's unencoded data. Measured in characters for
|
|
||||||
* numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode.
|
|
||||||
* Always zero or positive. Not the same as the data's bit length.
|
|
||||||
* Accessed through getNumChars(). */
|
|
||||||
private: int numChars;
|
|
||||||
|
|
||||||
/* The data bits of this segment. Accessed through getData(). */
|
|
||||||
private: std::vector<bool> data;
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Constructors (low level) ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Creates a new QR Code segment with the given attributes and data.
|
|
||||||
* The character count (numCh) must agree with the mode and the bit buffer length,
|
|
||||||
* but the constraint isn't checked. The given bit buffer is copied and stored.
|
|
||||||
*/
|
|
||||||
public: QrSegment(Mode md, int numCh, const std::vector<bool> &dt);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Creates a new QR Code segment with the given parameters and data.
|
|
||||||
* The character count (numCh) must agree with the mode and the bit buffer length,
|
|
||||||
* but the constraint isn't checked. The given bit buffer is moved and stored.
|
|
||||||
*/
|
|
||||||
public: QrSegment(Mode md, int numCh, std::vector<bool> &&dt);
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Methods ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the mode field of this segment.
|
|
||||||
*/
|
|
||||||
public: Mode getMode() const;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the character count field of this segment.
|
|
||||||
*/
|
|
||||||
public: int getNumChars() const;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the data bits of this segment.
|
|
||||||
*/
|
|
||||||
public: const std::vector<bool> &getData() const;
|
|
||||||
|
|
||||||
|
|
||||||
// (Package-private) Calculates the number of bits needed to encode the given segments at
|
|
||||||
// the given version. Returns a non-negative number if successful. Otherwise returns -1 if a
|
|
||||||
// segment has too many characters to fit its length field, or the total bits exceeds INT_MAX.
|
|
||||||
public: static int getTotalBits(const std::vector<QrSegment> &segs, int version);
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Private constant ----*/
|
|
||||||
|
|
||||||
/* The set of all legal characters in alphanumeric mode, where
|
|
||||||
* each character value maps to the index in the string. */
|
|
||||||
private: static const char *ALPHANUMERIC_CHARSET;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A QR Code symbol, which is a type of two-dimension barcode.
|
|
||||||
* Invented by Denso Wave and described in the ISO/IEC 18004 standard.
|
|
||||||
* Instances of this class represent an immutable square grid of black and white cells.
|
|
||||||
* The class provides static factory functions to create a QR Code from text or binary data.
|
|
||||||
* The class covers the QR Code Model 2 specification, supporting all versions (sizes)
|
|
||||||
* from 1 to 40, all 4 error correction levels, and 4 character encoding modes.
|
|
||||||
*
|
|
||||||
* Ways to create a QR Code object:
|
|
||||||
* - High level: Take the payload data and call QrCode::encodeText() or QrCode::encodeBinary().
|
|
||||||
* - Mid level: Custom-make the list of segments and call QrCode::encodeSegments().
|
|
||||||
* - Low level: Custom-make the array of data codeword bytes (including
|
|
||||||
* segment headers and final padding, excluding error correction codewords),
|
|
||||||
* supply the appropriate version number, and call the QrCode() constructor.
|
|
||||||
* (Note that all ways require supplying the desired error correction level.)
|
|
||||||
*/
|
|
||||||
class QrCode final {
|
|
||||||
|
|
||||||
/*---- Public helper enumeration ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The error correction level in a QR Code symbol.
|
|
||||||
*/
|
|
||||||
public: enum class Ecc {
|
|
||||||
LOW = 0 , // The QR Code can tolerate about 7% erroneous codewords
|
|
||||||
MEDIUM , // The QR Code can tolerate about 15% erroneous codewords
|
|
||||||
QUARTILE, // The QR Code can tolerate about 25% erroneous codewords
|
|
||||||
HIGH , // The QR Code can tolerate about 30% erroneous codewords
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Returns a value in the range 0 to 3 (unsigned 2-bit integer).
|
|
||||||
private: static int getFormatBits(Ecc ecl);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Static factory functions (high level) ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a QR Code representing the given Unicode text string at the given error correction level.
|
|
||||||
* As a conservative upper bound, this function is guaranteed to succeed for strings that have 2953 or fewer
|
|
||||||
* UTF-8 code units (not Unicode code points) if the low error correction level is used. The smallest possible
|
|
||||||
* QR Code version is automatically chosen for the output. The ECC level of the result may be higher than
|
|
||||||
* the ecl argument if it can be done without increasing the version.
|
|
||||||
*/
|
|
||||||
public: static QrCode encodeText(const char *text, Ecc ecl);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a QR Code representing the given binary data at the given error correction level.
|
|
||||||
* This function always encodes using the binary segment mode, not any text mode. The maximum number of
|
|
||||||
* bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
|
|
||||||
* The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
|
|
||||||
*/
|
|
||||||
public: static QrCode encodeBinary(const std::vector<std::uint8_t> &data, Ecc ecl);
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Static factory functions (mid level) ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a QR Code representing the given segments with the given encoding parameters.
|
|
||||||
* The smallest possible QR Code version within the given range is automatically
|
|
||||||
* chosen for the output. Iff boostEcl is true, then the ECC level of the result
|
|
||||||
* may be higher than the ecl argument if it can be done without increasing the
|
|
||||||
* version. The mask number is either between 0 to 7 (inclusive) to force that
|
|
||||||
* mask, or -1 to automatically choose an appropriate mask (which may be slow).
|
|
||||||
* This function allows the user to create a custom sequence of segments that switches
|
|
||||||
* between modes (such as alphanumeric and byte) to encode text in less space.
|
|
||||||
* This is a mid-level API; the high-level API is encodeText() and encodeBinary().
|
|
||||||
*/
|
|
||||||
public: static QrCode encodeSegments(const std::vector<QrSegment> &segs, Ecc ecl,
|
|
||||||
int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true); // All optional parameters
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Instance fields ----*/
|
|
||||||
|
|
||||||
// Immutable scalar parameters:
|
|
||||||
|
|
||||||
/* The version number of this QR Code, which is between 1 and 40 (inclusive).
|
|
||||||
* This determines the size of this barcode. */
|
|
||||||
private: int version;
|
|
||||||
|
|
||||||
/* The width and height of this QR Code, measured in modules, between
|
|
||||||
* 21 and 177 (inclusive). This is equal to version * 4 + 17. */
|
|
||||||
private: int size;
|
|
||||||
|
|
||||||
/* The error correction level used in this QR Code. */
|
|
||||||
private: Ecc errorCorrectionLevel;
|
|
||||||
|
|
||||||
/* The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).
|
|
||||||
* Even if a QR Code is created with automatic masking requested (mask = -1),
|
|
||||||
* the resulting object still has a mask value between 0 and 7. */
|
|
||||||
private: int mask;
|
|
||||||
|
|
||||||
// Private grids of modules/pixels, with dimensions of size*size:
|
|
||||||
|
|
||||||
// The modules of this QR Code (false = white, true = black).
|
|
||||||
// Immutable after constructor finishes. Accessed through getModule().
|
|
||||||
private: std::vector<std::vector<bool> > modules;
|
|
||||||
|
|
||||||
// Indicates function modules that are not subjected to masking. Discarded when constructor finishes.
|
|
||||||
private: std::vector<std::vector<bool> > isFunction;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Constructor (low level) ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Creates a new QR Code with the given version number,
|
|
||||||
* error correction level, data codeword bytes, and mask number.
|
|
||||||
* This is a low-level API that most users should not use directly.
|
|
||||||
* A mid-level API is the encodeSegments() function.
|
|
||||||
*/
|
|
||||||
public: QrCode(int ver, Ecc ecl, const std::vector<std::uint8_t> &dataCodewords, int msk);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Public instance methods ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns this QR Code's version, in the range [1, 40].
|
|
||||||
*/
|
|
||||||
public: int getVersion() const;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns this QR Code's size, in the range [21, 177].
|
|
||||||
*/
|
|
||||||
public: int getSize() const;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns this QR Code's error correction level.
|
|
||||||
*/
|
|
||||||
public: Ecc getErrorCorrectionLevel() const;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns this QR Code's mask, in the range [0, 7].
|
|
||||||
*/
|
|
||||||
public: int getMask() const;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the color of the module (pixel) at the given coordinates, which is false
|
|
||||||
* for white or true for black. The top left corner has the coordinates (x=0, y=0).
|
|
||||||
* If the given coordinates are out of bounds, then false (white) is returned.
|
|
||||||
*/
|
|
||||||
public: bool getModule(int x, int y) const;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a string of SVG code for an image depicting this QR Code, with the given number
|
|
||||||
* of border modules. The string always uses Unix newlines (\n), regardless of the platform.
|
|
||||||
*/
|
|
||||||
public: std::string toSvgString(int border) const;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Private helper methods for constructor: Drawing function modules ----*/
|
|
||||||
|
|
||||||
// Reads this object's version field, and draws and marks all function modules.
|
|
||||||
private: void drawFunctionPatterns();
|
|
||||||
|
|
||||||
|
|
||||||
// Draws two copies of the format bits (with its own error correction code)
|
|
||||||
// based on the given mask and this object's error correction level field.
|
|
||||||
private: void drawFormatBits(int msk);
|
|
||||||
|
|
||||||
|
|
||||||
// Draws two copies of the version bits (with its own error correction code),
|
|
||||||
// based on this object's version field, iff 7 <= version <= 40.
|
|
||||||
private: void drawVersion();
|
|
||||||
|
|
||||||
|
|
||||||
// Draws a 9*9 finder pattern including the border separator,
|
|
||||||
// with the center module at (x, y). Modules can be out of bounds.
|
|
||||||
private: void drawFinderPattern(int x, int y);
|
|
||||||
|
|
||||||
|
|
||||||
// Draws a 5*5 alignment pattern, with the center module
|
|
||||||
// at (x, y). All modules must be in bounds.
|
|
||||||
private: void drawAlignmentPattern(int x, int y);
|
|
||||||
|
|
||||||
|
|
||||||
// Sets the color of a module and marks it as a function module.
|
|
||||||
// Only used by the constructor. Coordinates must be in bounds.
|
|
||||||
private: void setFunctionModule(int x, int y, bool isBlack);
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the color of the module at the given coordinates, which must be in range.
|
|
||||||
private: bool module(int x, int y) const;
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Private helper methods for constructor: Codewords and masking ----*/
|
|
||||||
|
|
||||||
// Returns a new byte string representing the given data with the appropriate error correction
|
|
||||||
// codewords appended to it, based on this object's version and error correction level.
|
|
||||||
private: std::vector<std::uint8_t> addEccAndInterleave(const std::vector<std::uint8_t> &data) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
|
|
||||||
// data area of this QR Code. Function modules need to be marked off before this is called.
|
|
||||||
private: void drawCodewords(const std::vector<std::uint8_t> &data);
|
|
||||||
|
|
||||||
|
|
||||||
// XORs the codeword modules in this QR Code with the given mask pattern.
|
|
||||||
// The function modules must be marked and the codeword bits must be drawn
|
|
||||||
// before masking. Due to the arithmetic of XOR, calling applyMask() with
|
|
||||||
// the same mask value a second time will undo the mask. A final well-formed
|
|
||||||
// QR Code needs exactly one (not zero, two, etc.) mask applied.
|
|
||||||
private: void applyMask(int msk);
|
|
||||||
|
|
||||||
|
|
||||||
// Calculates and returns the penalty score based on state of this QR Code's current modules.
|
|
||||||
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
|
|
||||||
private: long getPenaltyScore() const;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Private helper functions ----*/
|
|
||||||
|
|
||||||
// Returns an ascending list of positions of alignment patterns for this version number.
|
|
||||||
// Each position is in the range [0,177), and are used on both the x and y axes.
|
|
||||||
// This could be implemented as lookup table of 40 variable-length lists of unsigned bytes.
|
|
||||||
private: std::vector<int> getAlignmentPatternPositions() const;
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the number of data bits that can be stored in a QR Code of the given version number, after
|
|
||||||
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
|
|
||||||
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
|
|
||||||
private: static int getNumRawDataModules(int ver);
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
|
|
||||||
// QR Code of the given version number and error correction level, with remainder bits discarded.
|
|
||||||
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
|
|
||||||
private: static int getNumDataCodewords(int ver, Ecc ecl);
|
|
||||||
|
|
||||||
|
|
||||||
// Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be
|
|
||||||
// implemented as a lookup table over all possible parameter values, instead of as an algorithm.
|
|
||||||
private: static std::vector<std::uint8_t> reedSolomonComputeDivisor(int degree);
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.
|
|
||||||
private: static std::vector<std::uint8_t> reedSolomonComputeRemainder(const std::vector<std::uint8_t> &data, const std::vector<std::uint8_t> &divisor);
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the product of the two given field elements modulo GF(2^8/0x11D).
|
|
||||||
// All inputs are valid. This could be implemented as a 256*256 lookup table.
|
|
||||||
private: static std::uint8_t reedSolomonMultiply(std::uint8_t x, std::uint8_t y);
|
|
||||||
|
|
||||||
|
|
||||||
// Can only be called immediately after a white run is added, and
|
|
||||||
// returns either 0, 1, or 2. A helper function for getPenaltyScore().
|
|
||||||
private: int finderPenaltyCountPatterns(const std::array<int,7> &runHistory) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().
|
|
||||||
private: int finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, std::array<int,7> &runHistory) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().
|
|
||||||
private: void finderPenaltyAddHistory(int currentRunLength, std::array<int,7> &runHistory) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Returns true iff the i'th bit of x is set to 1.
|
|
||||||
private: static bool getBit(long x, int i);
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Constants and tables ----*/
|
|
||||||
|
|
||||||
// The minimum version number supported in the QR Code Model 2 standard.
|
|
||||||
public: static constexpr int MIN_VERSION = 1;
|
|
||||||
|
|
||||||
// The maximum version number supported in the QR Code Model 2 standard.
|
|
||||||
public: static constexpr int MAX_VERSION = 40;
|
|
||||||
|
|
||||||
|
|
||||||
// For use in getPenaltyScore(), when evaluating which mask is best.
|
|
||||||
private: static const int PENALTY_N1;
|
|
||||||
private: static const int PENALTY_N2;
|
|
||||||
private: static const int PENALTY_N3;
|
|
||||||
private: static const int PENALTY_N4;
|
|
||||||
|
|
||||||
|
|
||||||
private: static const std::int8_t ECC_CODEWORDS_PER_BLOCK[4][41];
|
|
||||||
private: static const std::int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Public exception class ----*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Thrown when the supplied data does not fit any QR Code version. Ways to handle this exception include:
|
|
||||||
* - Decrease the error correction level if it was greater than Ecc::LOW.
|
|
||||||
* - If the encodeSegments() function was called with a maxVersion argument, then increase
|
|
||||||
* it if it was less than QrCode::MAX_VERSION. (This advice does not apply to the other
|
|
||||||
* factory functions because they search all versions up to QrCode::MAX_VERSION.)
|
|
||||||
* - Split the text data into better or optimal segments in order to reduce the number of bits required.
|
|
||||||
* - Change the text or binary data to be shorter.
|
|
||||||
* - Change the text to fit the character set of a particular segment mode (e.g. alphanumeric).
|
|
||||||
* - Propagate the error upward to the caller/user.
|
|
||||||
*/
|
|
||||||
class data_too_long : public std::length_error {
|
|
||||||
|
|
||||||
public: explicit data_too_long(const std::string &msg);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* An appendable sequence of bits (0s and 1s). Mainly used by QrSegment.
|
|
||||||
*/
|
|
||||||
class BitBuffer final : public std::vector<bool> {
|
|
||||||
|
|
||||||
/*---- Constructor ----*/
|
|
||||||
|
|
||||||
// Creates an empty bit buffer (length 0).
|
|
||||||
public: BitBuffer();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Method ----*/
|
|
||||||
|
|
||||||
// Appends the given number of low-order bits of the given value
|
|
||||||
// to this buffer. Requires 0 <= len <= 31 and val < 2^len.
|
|
||||||
public: void appendBits(std::uint32_t val, int len);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
59
config.h
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2020 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -21,13 +21,6 @@
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#define REL_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Release")
|
|
||||||
#define RC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Release Candidate")
|
|
||||||
#define BETA_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Beta")
|
|
||||||
#define ALPHA_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Alpha")
|
|
||||||
#define DEV_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Developer")
|
|
||||||
#define DAILY_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Daily Build")
|
|
||||||
#define CUSTOM_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Custom")
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GTA5SYNC_APPVENDOR
|
#ifndef GTA5SYNC_APPVENDOR
|
||||||
|
@ -47,14 +40,50 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GTA5SYNC_COPYRIGHT
|
#ifndef GTA5SYNC_COPYRIGHT
|
||||||
#define GTA5SYNC_COPYRIGHT "2016-2023"
|
#define GTA5SYNC_COPYRIGHT "2016-2021"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GTA5SYNC_APPVER
|
#ifndef GTA5SYNC_APPVER
|
||||||
#define GTA5SYNC_APPVER "1.10.2"
|
#define GTA5SYNC_APPVER "1.9.2"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
#ifdef GTA5SYNC_BUILDTYPE_REL
|
||||||
|
#ifndef GTA5SYNC_BUILDTYPE
|
||||||
|
#define GTA5SYNC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Release")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GTA5SYNC_BUILDTYPE_RC
|
||||||
|
#ifndef GTA5SYNC_BUILDTYPE
|
||||||
|
#define GTA5SYNC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Release Candidate")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GTA5SYNC_BUILDTYPE_DAILY
|
||||||
|
#ifndef GTA5SYNC_BUILDTYPE
|
||||||
|
#define GTA5SYNC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Daily Build")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GTA5SYNC_BUILDTYPE_DEV
|
||||||
|
#ifndef GTA5SYNC_BUILDTYPE
|
||||||
|
#define GTA5SYNC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Developer")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GTA5SYNC_BUILDTYPE_BETA
|
||||||
|
#ifndef GTA5SYNC_BUILDTYPE
|
||||||
|
#define GTA5SYNC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Beta")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GTA5SYNC_BUILDTYPE_ALPHA
|
||||||
|
#ifndef GTA5SYNC_BUILDTYPE
|
||||||
|
#define GTA5SYNC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Alpha")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef GTA5SYNC_BUILDTYPE
|
#ifndef GTA5SYNC_BUILDTYPE
|
||||||
#define GTA5SYNC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Custom")
|
#define GTA5SYNC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Custom")
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,11 +94,7 @@
|
||||||
|
|
||||||
#ifdef GTA5SYNC_QCONF
|
#ifdef GTA5SYNC_QCONF
|
||||||
#ifndef GTA5SYNC_SHARE
|
#ifndef GTA5SYNC_SHARE
|
||||||
#ifdef Q_OS_WIN
|
#define GTA5SYNC_SHARE "RUNDIR:SEPARATOR:..SEPARATOR:share"
|
||||||
#define GTA5SYNC_SHARE "RUNDIR:"
|
|
||||||
#else
|
|
||||||
#define GTA5SYNC_SHARE "RUNDIR:/../share"
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef GTA5SYNC_LANG
|
#ifndef GTA5SYNC_LANG
|
||||||
#define GTA5SYNC_LANG "QCONFLANG:"
|
#define GTA5SYNC_LANG "QCONFLANG:"
|
||||||
|
@ -87,10 +112,10 @@
|
||||||
#define GTA5SYNC_SHARE "RUNDIR:"
|
#define GTA5SYNC_SHARE "RUNDIR:"
|
||||||
#endif
|
#endif
|
||||||
#ifndef GTA5SYNC_LANG
|
#ifndef GTA5SYNC_LANG
|
||||||
#define GTA5SYNC_LANG "SHAREDDIR:/lang"
|
#define GTA5SYNC_LANG "SHAREDDIR:SEPARATOR:lang"
|
||||||
#endif
|
#endif
|
||||||
#ifndef GTA5SYNC_PLUG
|
#ifndef GTA5SYNC_PLUG
|
||||||
#define GTA5SYNC_PLUG "RUNDIR:/plugins"
|
#define GTA5SYNC_PLUG "RUNDIR:SEPARATOR:plugins"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
13
gta5view.pro
|
@ -1,6 +1,6 @@
|
||||||
#/*****************************************************************************
|
#/*****************************************************************************
|
||||||
#* gta5view Grand Theft Auto V Profile Viewer
|
#* gta5view Grand Theft Auto V Profile Viewer
|
||||||
#* Copyright (C) 2015-2021 Syping
|
#* Copyright (C) 2015-2020 Syping
|
||||||
#*
|
#*
|
||||||
#* This program is free software: you can redistribute it and/or modify
|
#* This program is free software: you can redistribute it and/or modify
|
||||||
#* it under the terms of the GNU General Public License as published by
|
#* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,14 +19,13 @@
|
||||||
QT += core gui network svg
|
QT += core gui network svg
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): win32: LIBS += -ldwmapi
|
greaterThan(QT_MAJOR_VERSION, 4): greaterThan(QT_MINOR_VERSION, 1): win32: QT += winextras
|
||||||
|
|
||||||
DEPLOYMENT.display_name = gta5view
|
DEPLOYMENT.display_name = gta5view
|
||||||
TARGET = gta5view
|
TARGET = gta5view
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|
||||||
HEADERS += config.h \
|
HEADERS += config.h
|
||||||
wrapper.h
|
|
||||||
PRECOMPILED_HEADER += config.h
|
PRECOMPILED_HEADER += config.h
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
|
@ -144,8 +143,7 @@ TRANSLATIONS += \
|
||||||
res/gta5sync_zh_TW.ts
|
res/gta5sync_zh_TW.ts
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
res/img.qrc \
|
res/app.qrc \
|
||||||
res/template.qrc \
|
|
||||||
res/tr_g5p.qrc
|
res/tr_g5p.qrc
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
|
@ -179,6 +177,7 @@ INCLUDEPATH += ./anpro ./pcg ./tmext ./uimod
|
||||||
|
|
||||||
DEFINES += GTA5SYNC_QMAKE # We using qmake do we?
|
DEFINES += GTA5SYNC_QMAKE # We using qmake do we?
|
||||||
DEFINES += GTA5SYNC_PROJECT # Enable exclusive gta5sync/gta5view functions
|
DEFINES += GTA5SYNC_PROJECT # Enable exclusive gta5sync/gta5view functions
|
||||||
|
DEFINES += SNAPMATIC_NODEFAULT # Not assisting at proper usage of SnapmaticPicture class
|
||||||
|
|
||||||
# WINDOWS ONLY
|
# WINDOWS ONLY
|
||||||
|
|
||||||
|
@ -187,7 +186,7 @@ win32: CONFIG -= embed_manifest_exe
|
||||||
contains(DEFINES, GTA5SYNC_TELEMETRY): win32: LIBS += -ld3d9 # Required for getting information about GPU
|
contains(DEFINES, GTA5SYNC_TELEMETRY): win32: LIBS += -ld3d9 # Required for getting information about GPU
|
||||||
|
|
||||||
# MAC OS X ONLY
|
# MAC OS X ONLY
|
||||||
macx: ICON = res/gta5view.icns
|
macx: ICON = res/5sync.icns
|
||||||
|
|
||||||
# QT4 ONLY STUFF
|
# QT4 ONLY STUFF
|
||||||
|
|
||||||
|
|
74
main.cpp
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* gta5view Grand Theft Auto V Profile Viewer
|
* gta5view Grand Theft Auto V Profile Viewer
|
||||||
* Copyright (C) 2016-2021 Syping
|
* Copyright (C) 2016-2019 Syping
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -49,6 +49,7 @@
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QDebug>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
|
@ -93,6 +94,7 @@ int main(int argc, char *argv[])
|
||||||
settings.sync();
|
settings.sync();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool isFirstStart = settings.value("IsFirstStart", true).toBool();
|
||||||
bool customStyle = settings.value("CustomStyle", false).toBool();
|
bool customStyle = settings.value("CustomStyle", false).toBool();
|
||||||
if (customStyle) {
|
if (customStyle) {
|
||||||
const QString appStyle = settings.value("AppStyle", "Default").toString();
|
const QString appStyle = settings.value("AppStyle", "Default").toString();
|
||||||
|
@ -102,9 +104,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#if QT_VERSION >= 0x060000
|
#if QT_VERSION >= 0x050400
|
||||||
a.setFont(QApplication::font("QMenu"));
|
|
||||||
#elif QT_VERSION >= 0x050400
|
|
||||||
if (QSysInfo::windowsVersion() >= 0x0080) {
|
if (QSysInfo::windowsVersion() >= 0x0080) {
|
||||||
a.setFont(QApplication::font("QMenu"));
|
a.setFont(QApplication::font("QMenu"));
|
||||||
}
|
}
|
||||||
|
@ -130,10 +130,28 @@ int main(int argc, char *argv[])
|
||||||
Telemetry->work();
|
Telemetry->work();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!applicationArgs.contains("--skip-firststart"))
|
||||||
|
{
|
||||||
|
if (isFirstStart)
|
||||||
|
{
|
||||||
|
QMessageBox::StandardButton button = QMessageBox::information(nullptr, QString("%1 %2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER), QApplication::tr("<h4>Welcome to %1!</h4>You want to configure %1 before you start using it?").arg(GTA5SYNC_APPSTR), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||||
|
if (button == QMessageBox::Yes)
|
||||||
|
{
|
||||||
|
ProfileDatabase profileDB;
|
||||||
|
OptionsDialog optionsDialog(&profileDB);
|
||||||
|
optionsDialog.setWindowIcon(IconLoader::loadingAppIcon());
|
||||||
|
optionsDialog.show();
|
||||||
|
optionsDialog.exec();
|
||||||
|
}
|
||||||
|
settings.setValue("IsFirstStart", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef GTA5SYNC_TELEMETRY
|
#ifdef GTA5SYNC_TELEMETRY
|
||||||
bool telemetryWindowLaunched = settings.value("PersonalUsageDataWindowLaunched", false).toBool();
|
bool telemetryWindowLaunched = settings.value("PersonalUsageDataWindowLaunched", false).toBool();
|
||||||
bool pushUsageData = settings.value("PushUsageData", false).toBool();
|
bool pushUsageData = settings.value("PushUsageData", false).toBool();
|
||||||
if (!telemetryWindowLaunched && !pushUsageData) {
|
if (!telemetryWindowLaunched && !pushUsageData)
|
||||||
|
{
|
||||||
QDialog *telemetryDialog = new QDialog();
|
QDialog *telemetryDialog = new QDialog();
|
||||||
telemetryDialog->setObjectName(QStringLiteral("TelemetryDialog"));
|
telemetryDialog->setObjectName(QStringLiteral("TelemetryDialog"));
|
||||||
telemetryDialog->setWindowTitle(QString("%1 %2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER));
|
telemetryDialog->setWindowTitle(QString("%1 %2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER));
|
||||||
|
@ -165,7 +183,8 @@ int main(int argc, char *argv[])
|
||||||
telemetryDialog->setFixedSize(telemetryDialog->sizeHint());
|
telemetryDialog->setFixedSize(telemetryDialog->sizeHint());
|
||||||
telemetryDialog->exec();
|
telemetryDialog->exec();
|
||||||
QObject::disconnect(telemetryButton, SIGNAL(clicked(bool)), telemetryDialog, SLOT(close()));
|
QObject::disconnect(telemetryButton, SIGNAL(clicked(bool)), telemetryDialog, SLOT(close()));
|
||||||
if (telemetryCheckBox->isChecked()) {
|
if (telemetryCheckBox->isChecked())
|
||||||
|
{
|
||||||
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
|
||||||
telemetrySettings.beginGroup("Telemetry");
|
telemetrySettings.beginGroup("Telemetry");
|
||||||
telemetrySettings.setValue("PushUsageData", true);
|
telemetrySettings.setValue("PushUsageData", true);
|
||||||
|
@ -181,35 +200,43 @@ int main(int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
for (const QString ¤tArg : applicationArgs) {
|
for (QString currentArg : applicationArgs)
|
||||||
|
{
|
||||||
QString reworkedArg;
|
QString reworkedArg;
|
||||||
if (currentArg.left(9) == "-showpic=" && selectedAction == "") {
|
if (currentArg.left(9) == "-showpic=" && selectedAction == "")
|
||||||
reworkedArg = QString(currentArg).remove(0,9);
|
{
|
||||||
|
reworkedArg = currentArg.remove(0,9);
|
||||||
arg1 = reworkedArg;
|
arg1 = reworkedArg;
|
||||||
selectedAction = "showpic";
|
selectedAction = "showpic";
|
||||||
}
|
}
|
||||||
else if (currentArg.left(9) == "-showsgd=" && selectedAction == "") {
|
else if (currentArg.left(9) == "-showsgd=" && selectedAction == "")
|
||||||
reworkedArg = QString(currentArg).remove(0,9);
|
{
|
||||||
|
reworkedArg = currentArg.remove(0,9);
|
||||||
arg1 = reworkedArg;
|
arg1 = reworkedArg;
|
||||||
selectedAction = "showsgd";
|
selectedAction = "showsgd";
|
||||||
}
|
}
|
||||||
else if (selectedAction == "") {
|
else if (selectedAction == "")
|
||||||
|
{
|
||||||
QFile argumentFile(currentArg);
|
QFile argumentFile(currentArg);
|
||||||
QFileInfo argumentFileInfo(argumentFile);
|
QFileInfo argumentFileInfo(argumentFile);
|
||||||
if (argumentFile.exists()) {
|
if (argumentFile.exists())
|
||||||
|
{
|
||||||
QString argumentFileName = argumentFileInfo.fileName();
|
QString argumentFileName = argumentFileInfo.fileName();
|
||||||
QString argumentFileType = argumentFileName.left(4);
|
QString argumentFileType = argumentFileName.left(4);
|
||||||
QString argumentFileExt = argumentFileName.right(4);
|
QString argumentFileExt = argumentFileName.right(4);
|
||||||
|
|
||||||
if (argumentFileType == "PGTA" || argumentFileExt == ".g5e") {
|
if (argumentFileType == "PGTA" || argumentFileExt == ".g5e")
|
||||||
|
{
|
||||||
arg1 = currentArg;
|
arg1 = currentArg;
|
||||||
selectedAction = "showpic";
|
selectedAction = "showpic";
|
||||||
}
|
}
|
||||||
else if (argumentFileType == "SGTA") {
|
else if (argumentFileType == "SGTA")
|
||||||
|
{
|
||||||
arg1 = currentArg;
|
arg1 = currentArg;
|
||||||
selectedAction = "showsgd";
|
selectedAction = "showsgd";
|
||||||
}
|
}
|
||||||
else if (argumentFileType == "MISR") {
|
else if (argumentFileType == "MISR")
|
||||||
|
{
|
||||||
arg1 = currentArg;
|
arg1 = currentArg;
|
||||||
selectedAction = "showsgd";
|
selectedAction = "showsgd";
|
||||||
}
|
}
|
||||||
|
@ -217,7 +244,8 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedAction == "showpic") {
|
if (selectedAction == "showpic")
|
||||||
|
{
|
||||||
CrewDatabase crewDB;
|
CrewDatabase crewDB;
|
||||||
ProfileDatabase profileDB;
|
ProfileDatabase profileDB;
|
||||||
DatabaseThread threadDB(&crewDB);
|
DatabaseThread threadDB(&crewDB);
|
||||||
|
@ -230,10 +258,8 @@ int main(int argc, char *argv[])
|
||||||
picDialog.setWindowFlags(picDialog.windowFlags()^Qt::Dialog^Qt::Window);
|
picDialog.setWindowFlags(picDialog.windowFlags()^Qt::Dialog^Qt::Window);
|
||||||
|
|
||||||
int crewID = picture.getSnapmaticProperties().crewID;
|
int crewID = picture.getSnapmaticProperties().crewID;
|
||||||
if (crewID != 0)
|
if (crewID != 0) { crewDB.addCrew(crewID); }
|
||||||
crewDB.addCrew(crewID);
|
if (!readOk) { return 1; }
|
||||||
if (!readOk)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
QObject::connect(&threadDB, SIGNAL(crewNameFound(int, QString)), &crewDB, SLOT(setCrewName(int, QString)));
|
QObject::connect(&threadDB, SIGNAL(crewNameFound(int, QString)), &crewDB, SLOT(setCrewName(int, QString)));
|
||||||
QObject::connect(&threadDB, SIGNAL(crewNameUpdated()), &picDialog, SLOT(crewNameUpdated()));
|
QObject::connect(&threadDB, SIGNAL(crewNameUpdated()), &picDialog, SLOT(crewNameUpdated()));
|
||||||
|
@ -247,7 +273,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
else if (selectedAction == "showsgd") {
|
else if (selectedAction == "showsgd")
|
||||||
|
{
|
||||||
SavegameDialog savegameDialog;
|
SavegameDialog savegameDialog;
|
||||||
SavegameData savegame;
|
SavegameData savegame;
|
||||||
|
|
||||||
|
@ -256,8 +283,7 @@ int main(int argc, char *argv[])
|
||||||
savegameDialog.setSavegameData(&savegame, arg1, readOk);
|
savegameDialog.setSavegameData(&savegame, arg1, readOk);
|
||||||
savegameDialog.setWindowFlags(savegameDialog.windowFlags()^Qt::Dialog^Qt::Window);
|
savegameDialog.setWindowFlags(savegameDialog.windowFlags()^Qt::Dialog^Qt::Window);
|
||||||
|
|
||||||
if (!readOk)
|
if (!readOk) { return 1; }
|
||||||
return 1;
|
|
||||||
|
|
||||||
a.setQuitOnLastWindowClosed(true);
|
a.setQuitOnLastWindowClosed(true);
|
||||||
savegameDialog.show();
|
savegameDialog.show();
|
||||||
|
|
BIN
res/add.svgz
|
@ -4,14 +4,7 @@
|
||||||
<file>avatararea.png</file>
|
<file>avatararea.png</file>
|
||||||
<file>avatarareaimport.png</file>
|
<file>avatarareaimport.png</file>
|
||||||
<file>back.svgz</file>
|
<file>back.svgz</file>
|
||||||
<file>flag-de.png</file>
|
<file>empty1x16.png</file>
|
||||||
<file>flag-fr.png</file>
|
|
||||||
<file>flag-gb.png</file>
|
|
||||||
<file>flag-kr.png</file>
|
|
||||||
<file>flag-ru.png</file>
|
|
||||||
<file>flag-tw.png</file>
|
|
||||||
<file>flag-ua.png</file>
|
|
||||||
<file>flag-us.png</file>
|
|
||||||
<file>gta5view-16.png</file>
|
<file>gta5view-16.png</file>
|
||||||
<file>gta5view-24.png</file>
|
<file>gta5view-24.png</file>
|
||||||
<file>gta5view-32.png</file>
|
<file>gta5view-32.png</file>
|
||||||
|
@ -21,7 +14,6 @@
|
||||||
<file>gta5view-96.png</file>
|
<file>gta5view-96.png</file>
|
||||||
<file>gta5view-128.png</file>
|
<file>gta5view-128.png</file>
|
||||||
<file>gta5view-256.png</file>
|
<file>gta5view-256.png</file>
|
||||||
<file>mapcayoperico.jpg</file>
|
|
||||||
<file>mappreview.jpg</file>
|
<file>mappreview.jpg</file>
|
||||||
<file>next.svgz</file>
|
<file>next.svgz</file>
|
||||||
<file>pointmaker-8.png</file>
|
<file>pointmaker-8.png</file>
|
||||||
|
@ -33,4 +25,7 @@
|
||||||
<file>watermark_2b.png</file>
|
<file>watermark_2b.png</file>
|
||||||
<file>watermark_2r.png</file>
|
<file>watermark_2r.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
<qresource prefix="/template">
|
||||||
|
<file>template.g5e</file>
|
||||||
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
10
res/app.rc
|
@ -4,8 +4,8 @@ IDI_ICON1 ICON DISCARDABLE "5sync.ico"
|
||||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "gta5view.exe.manifest"
|
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "gta5view.exe.manifest"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1, 10, 2, 0
|
FILEVERSION 1, 9, 2, 0
|
||||||
PRODUCTVERSION 1, 10, 2, 0
|
PRODUCTVERSION 1, 9, 2, 0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
FILEFLAGS 0
|
FILEFLAGS 0
|
||||||
FILEOS VOS_NT_WINDOWS32
|
FILEOS VOS_NT_WINDOWS32
|
||||||
|
@ -22,12 +22,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Syping"
|
VALUE "CompanyName", "Syping"
|
||||||
VALUE "FileDescription", "gta5view"
|
VALUE "FileDescription", "gta5view"
|
||||||
VALUE "FileVersion", "1.10.2"
|
VALUE "FileVersion", "1.9.2"
|
||||||
VALUE "InternalName", "gta5view"
|
VALUE "InternalName", "gta5view"
|
||||||
VALUE "LegalCopyright", "Copyright © 2016-2023 Syping"
|
VALUE "LegalCopyright", "Copyright © 2016-2021 Syping"
|
||||||
VALUE "OriginalFilename", "gta5view.exe"
|
VALUE "OriginalFilename", "gta5view.exe"
|
||||||
VALUE "ProductName", "gta5view"
|
VALUE "ProductName", "gta5view"
|
||||||
VALUE "ProductVersion", "1.10.2"
|
VALUE "ProductVersion", "1.9.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
BIN
res/back.svgz
|
@ -1 +0,0 @@
|
||||||
Bitcoin
|
|
BIN
res/btc.svgz
|
@ -3,11 +3,9 @@ Type=Application
|
||||||
Name=gta5view
|
Name=gta5view
|
||||||
Comment=Open and edit GTA V profiles
|
Comment=Open and edit GTA V profiles
|
||||||
Comment[de]=GTA V Profile öffnen und bearbeiten
|
Comment[de]=GTA V Profile öffnen und bearbeiten
|
||||||
Comment[ko]=GTA V 프로필을 열고 편집
|
|
||||||
Comment[ru]=Просмотрщик и редактор профилей GTA V
|
Comment[ru]=Просмотрщик и редактор профилей GTA V
|
||||||
Comment[zh_TW]=打開與編輯 GTA V 個人檔案
|
Categories=Qt;Utility;FileTools
|
||||||
Categories=Qt;Utility;FileTools;
|
Exec=gta5view
|
||||||
TryExec=gta5view
|
|
||||||
Exec=gta5view %f
|
|
||||||
Icon=de.syping.gta5view
|
Icon=de.syping.gta5view
|
||||||
MimeType=application/x-gta5view-export;
|
Terminal=false
|
||||||
|
StartupNotify=false
|
||||||
|
|
|
@ -10,14 +10,12 @@
|
||||||
|
|
||||||
<summary>Open and edit GTA V profiles</summary>
|
<summary>Open and edit GTA V profiles</summary>
|
||||||
<summary xml:lang="de">GTA V Profile öffnen und bearbeiten</summary>
|
<summary xml:lang="de">GTA V Profile öffnen und bearbeiten</summary>
|
||||||
<summary xml:lang="ko">GTA V 프로필을 열고 편집</summary>
|
|
||||||
<summary xml:lang="ru">Просмотрщик и редактор профилей GTA V</summary>
|
<summary xml:lang="ru">Просмотрщик и редактор профилей GTA V</summary>
|
||||||
<summary xml:lang="zh-TW">打開與編輯 GTA V 個人檔案</summary>
|
|
||||||
|
|
||||||
<icon type="remote">https://img.syping.de/gta5view/gta5view.png</icon>
|
<icon type="remote">https://img.syping.de/gta5view/gta5view.png</icon>
|
||||||
|
|
||||||
<description>
|
<description>
|
||||||
<p>Open Source Snapmatic and Savegame viewer/editor for GTA V</p>
|
<p>Open Source Snapmatic picture and Savegame viewer/editor for GTA V</p>
|
||||||
<p>Features</p>
|
<p>Features</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>View Snapmatics with the ability to disable them in-game</li>
|
<li>View Snapmatics with the ability to disable them in-game</li>
|
||||||
|
@ -34,9 +32,6 @@
|
||||||
<developer_name>Syping</developer_name>
|
<developer_name>Syping</developer_name>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
<release date="2023-03-15" version="1.10.2"/>
|
|
||||||
<release date="2021-06-17" version="1.10.1"/>
|
|
||||||
<release date="2021-05-27" version="1.10.0"/>
|
|
||||||
<release date="2021-03-22" version="1.9.2"/>
|
<release date="2021-03-22" version="1.9.2"/>
|
||||||
<release date="2020-12-16" version="1.9.1"/>
|
<release date="2020-12-16" version="1.9.1"/>
|
||||||
<release date="2020-11-30" version="1.9.0"/>
|
<release date="2020-11-30" version="1.9.0"/>
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
|
||||||
<mime-type type="application/x-gta5view-export">
|
|
||||||
<comment>gta5view Export</comment>
|
|
||||||
<glob pattern="*.g5e"/>
|
|
||||||
<generic-icon name="de.syping.gta5view"/>
|
|
||||||
</mime-type>
|
|
||||||
</mime-info>
|
|
|
@ -1,15 +0,0 @@
|
||||||
<RCC>
|
|
||||||
<qresource prefix="/donate">
|
|
||||||
<file>btc.str</file>
|
|
||||||
<file>btc.svgz</file>
|
|
||||||
<file>eth.str</file>
|
|
||||||
<file>eth.svgz</file>
|
|
||||||
<file>ltc.str</file>
|
|
||||||
<file>ltc.svgz</file>
|
|
||||||
<file>xmr.str</file>
|
|
||||||
<file>xmr.svgz</file>
|
|
||||||
</qresource>
|
|
||||||
<qresource prefix="/img">
|
|
||||||
<file>donate.svgz</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
BIN
res/donate.svgz
After Width: | Height: | Size: 87 B |
|
@ -1 +0,0 @@
|
||||||
Ethereum
|
|
BIN
res/eth.svgz
BIN
res/flag-de.png
Before Width: | Height: | Size: 1.1 KiB |
BIN
res/flag-fr.png
Before Width: | Height: | Size: 1.3 KiB |
BIN
res/flag-gb.png
Before Width: | Height: | Size: 2.8 KiB |
BIN
res/flag-kr.png
Before Width: | Height: | Size: 1.8 KiB |
BIN
res/flag-ru.png
Before Width: | Height: | Size: 1.4 KiB |
BIN
res/flag-tw.png
Before Width: | Height: | Size: 1.3 KiB |
BIN
res/flag-ua.png
Before Width: | Height: | Size: 1.2 KiB |
BIN
res/flag-us.png
Before Width: | Height: | Size: 2.8 KiB |