Compare commits

...

130 commits
1.5.x ... 1.7.x

Author SHA1 Message Date
Syping 8732b9d64d 1.7.1 release, fix installation
Some checks failed
continuous-integration/drone/push Build is failing
2019-08-04 15:56:16 +02:00
Syping bb4a9b484c 1.7.1 release, korean translation added 2019-08-04 15:49:32 +02:00
Syping c79c8dbe6e 1.7.0 release 2019-07-24 20:23:40 +02:00
Syping 4e31d159fa 1.7.0 release 2019-07-24 20:16:48 +02:00
Syping 0633d14d6b install Lua, change buildtype to Release 2019-07-24 20:12:26 +02:00
Syping c6b39546ba remove function to click numbers (don't work anymore) 2019-07-24 20:05:34 +02:00
Syping eac9caa2c6 fix compatibility issue 2019-07-24 19:47:08 +02:00
Syping a80b5843a7 fix build script 2019-07-24 19:10:14 +02:00
Syping 07797f6e60 remove upx compression step 2019-07-24 18:57:00 +02:00
Syping 55186e8b88 improve MapLocationDialog 2019-07-24 18:35:32 +02:00
Syping eee9100d8b remove OpenSSL changes 2019-04-22 20:39:18 +02:00
Syping b73719ed4e add WindowsVista style 2019-04-22 05:25:28 +02:00
Syping a143b43d15 fix uninstallation 2019-04-22 05:10:39 +02:00
Syping 032475ddfd remove audio 2019-04-22 05:07:04 +02:00
Syping bdde72573b gta5view.nsi now UTF-8 2019-04-22 05:05:12 +02:00
Syping 827676768a update Qt to 5.12.3 2019-04-22 04:59:26 +02:00
Syping 0c02c3ce98 use icons for PlayerListDialog buttons 2019-01-16 02:11:42 +01:00
Syping 6063803d5e improve PlayerListDialog 2019-01-13 14:56:35 +01:00
Syping 1f3c036b47 navigation bar fixed 2019-01-13 14:40:16 +01:00
Syping ea0526ae9d massive DPI improvements 2019-01-13 14:32:12 +01:00
Syping aeae6c9311 fix DPI scaling in PictureDialog 2018-12-25 21:05:09 +01:00
Syping c39c3a3e9f always scale savegame graphic 2018-12-02 18:10:34 +01:00
Syping 9989d9d869 replace savegame.png with scaleable savegame.svgz 2018-12-01 17:47:28 +01:00
Syping fa86e8f8a7 fix Windows installer build 2018-11-22 21:54:16 +01:00
Syping f9880fff70 update toolchain 2018-11-22 21:50:53 +01:00
Syping 7ba5322643 fix CI script SVG module installation 2018-11-18 20:39:32 +01:00
Syping 1f409b0f25 Scaleable navigation bar icons 2018-11-18 18:08:18 +01:00
Syping dea33f8ab0 1.7 development 2018-09-09 19:25:28 +02:00
Syping 6b54b2e6ae 1.6.0 release 2018-08-27 19:40:44 +02:00
VADemon 38f2877ea3 Russian translation updated 2018-08-27 17:19:18 +02:00
Syping c67a0a0fc9 add new crews to list 2018-08-25 03:11:37 +02:00
Syping 7a15c3e56b fix ProfileInterface hover bug 2018-08-17 16:35:14 +02:00
Syping feabaac48e fix warning & readme update 2018-08-05 15:29:30 +02:00
Jean 6ab75420ec
Update french translation 2018-08-05 15:05:38 +02:00
Syping cda974d5df update resources 2018-08-01 20:32:24 +02:00
VenJam1n 36677ed07a Ukrainian translation updated 2018-08-01 20:31:51 +02:00
Syping 17014925c5 fix retranslateUi 2018-07-30 02:54:51 +02:00
Syping f151035574 updated chinese translation 2018-07-30 02:17:47 +02:00
Syping 53ef2bdb54 1.6.0 RC 2018-07-28 05:18:01 +02:00
Syping 2606cd8965 fix some submit code 2018-07-28 05:06:46 +02:00
Syping 973fb58a5d don't spam telemetry 2018-07-28 05:00:57 +02:00
Syping 39f20aca9d added ability to read GTA V game language 2018-07-28 04:55:55 +02:00
Syping c29cc44717 added the ability to import duplicates 2018-07-27 04:26:10 +02:00
Syping 9ced2253fc update for travis ci 2018-07-27 03:09:40 +02:00
Syping 778abdd36a update for travis ci 2018-07-27 03:00:18 +02:00
Syping 30a6b55c9e ci update 2018-07-27 02:56:22 +02:00
Syping b02f06ae97 ImportDialog improved 2018-07-25 20:52:30 +02:00
Syping 193bb60caa image overwriter improved 2018-07-21 18:33:08 +02:00
Syping 414867f13e imge cropping added 2018-07-20 15:58:51 +02:00
Syping 7b68bb10b5 add ability to change picture while import process 2018-07-17 16:41:38 +02:00
Syping 2487a188d5 [ci skip] translation updated 2018-07-13 12:08:57 +02:00
Syping c34d3331fb remove unneccessary Capacity view, add Commit tag on version 2018-07-13 12:07:13 +02:00
Syping afeab6120d added GPUs to telemetry data 2018-07-13 09:06:53 +02:00
Syping 4c6962ab23 increase Snapmatic Max Capacity to 512 KB, support for pre May 2015
Snapmatic added
2018-07-12 10:52:33 +02:00
Syping 08ecd5ca61 delete crowdin because i can't afford it 2018-07-10 04:40:57 +02:00
Syping 5f35428cd0 add watermark 2018-07-09 20:39:27 +02:00
Syping 714be43280 fix crowdin file name 2018-07-06 03:12:31 +02:00
Syping 1165c3b536 Update Crowdin configuration file 2018-07-06 01:00:08 +00:00
Syping 06eb2e4277 update translations for crowdin 2018-07-06 02:59:11 +02:00
Syping 00db9ecab2 Update Crowdin configuration file 2018-07-06 00:48:32 +00:00
Syping dc101a66da fix remote import 2018-06-29 09:57:06 +02:00
Syping 541a7d18bd improve CPU string + GitLab CI 2018-06-29 09:36:25 +02:00
Syping f932a8d5ee GitLab artifacts updated 2018-06-29 09:27:54 +02:00
Syping 81ea0490cf add ability to drop images 2018-06-29 08:52:43 +02:00
Syping a8db3985a2 importUrls added 2018-06-29 08:20:01 +02:00
Syping 0127bc61e6 improve clipboard processing 2018-06-29 08:02:28 +02:00
Syping 25c64b7f5d improving player parser 2018-06-29 02:50:00 +02:00
Syping c3d684436b GitLab builds Windows Installer and Portable only now 2018-06-28 03:31:57 +02:00
Syping 4135b1f588 minor changes 2018-06-24 02:25:34 +02:00
Syping 7c08e1486e add Debian build to GitLab CI 2018-06-22 20:00:18 +02:00
Syping d61cbd4743 add Telemetry to GitLab build 2018-06-22 19:00:36 +02:00
Syping efa88cc46e add artifacts in .gitlab-ci.yml 2018-06-22 18:23:38 +02:00
Syping f1cfbbf573 change GitLab Lua to 5.2 2018-06-22 18:11:16 +02:00
Syping ca8003c2e8 fix .gitlab-ci.yml 2018-06-22 18:08:09 +02:00
Syping 69a7ec8dbe add .gitlab-ci.yml 2018-06-22 18:03:22 +02:00
Syping 0321d79136 rename some CI scripts and add GitLab main script 2018-06-22 17:25:27 +02:00
Syping e2b7062e26 update CI scripts 2018-06-22 17:11:18 +02:00
Syping 99f3c22ab0 update telemetry blob 2018-06-22 14:59:39 +02:00
Syping 9b5cb46c35 single selection hotkeys improved 2018-06-17 22:02:41 +02:00
Syping c909e20178 improve configure script 2018-06-17 10:52:50 +02:00
Syping 0e337b4dec fix Qt4 compilation 2018-06-17 09:51:46 +02:00
Syping 3b305fb809 add clipboard import 2018-06-17 09:27:10 +02:00
Syping 06a8657423 fixed mass import 2018-06-16 05:28:56 +02:00
Syping caffd9f246 update readme 2018-06-16 04:58:51 +02:00
Syping caaa6a1d85 making config.h C compatible 2018-06-15 05:04:20 +02:00
Syping 196cb8bc55 stop precompile config.h because it's not C compatible 2018-06-15 04:52:29 +02:00
Syping 2d62bbb97e random generator now based on pcg-random 2018-06-15 04:43:13 +02:00
Syping c3e030e827 G5E 2.0 implemented 2018-06-14 12:28:12 +02:00
Syping 291236ff2c better and more efficient uid generation 2018-06-14 11:36:01 +02:00
Syping c7ec038e26 don't do make depend automatically 2018-06-12 06:37:05 +02:00
Syping cde4b380f8 update configure to accept arguments 2018-06-12 06:30:08 +02:00
Syping bcd7e3cd15 update readme 2018-06-10 02:19:11 +02:00
Syping 1f1025787e fix QT_SELECT 2018-06-10 02:11:49 +02:00
Syping fd5ce958bd remove .gitlab folder 2018-06-10 02:00:20 +02:00
Syping 681e76737e fix indentation 2018-06-10 01:56:55 +02:00
Syping 24ca667537 add basic configure script 2018-06-10 01:53:08 +02:00
Syping e6c8a48e12 use RCC path 2018-06-09 21:53:28 +02:00
Syping 867281f80a deliver precompiled Resource again 2018-06-09 21:25:05 +02:00
Syping a33bc8145b make depend for resource generation 2018-06-09 21:16:33 +02:00
Syping e3a8edae2d compress global files 2018-06-09 20:38:12 +02:00
Syping 609efb7fba update README, Qt translation 2018-06-09 19:18:51 +02:00
Syping 29f883555d fixed UI issues, Personal Usage data check box added 2018-06-07 17:07:30 +02:00
Syping 8fc3dc6c7c Update to Qt 5.9.6 build 2018-06-06 22:13:59 +02:00
Syping 72377e49eb delete audio folder now at uninstall 2018-06-05 17:55:38 +02:00
Syping 5840d8e8e9 fix copy paste mistake with removing cd 2018-06-03 16:20:55 +02:00
Syping d0e157bf1c update Windows Qt to 5.9.5 2018-06-03 16:10:20 +02:00
Syping 9b41d80d9a change SPV screenshot format to .png 2018-06-02 07:17:29 +02:00
Syping 06ada3d770 updated README pictures 2018-06-02 07:15:07 +02:00
Syping cd20e0b512 Telemetry system updated 2018-05-31 06:12:47 +02:00
Syping bd97ee86ba update community translation files 2018-05-31 04:49:17 +02:00
Syping 7b98e75f8d clean up resources 2018-05-31 04:45:19 +02:00
Syping 99ffbf4178 update en_US translation 2018-05-31 04:41:34 +02:00
Syping 108f1725f6 remove unused strings 2018-05-31 04:40:03 +02:00
Syping 5c7cb24c36 update travis script 2018-05-30 11:00:27 +02:00
Syping 6e335638a3 fix dropbox 2018-05-30 10:42:27 +02:00
Syping 5a4b2f1d67 add dropbox_uploader to docker 2018-05-30 10:27:40 +02:00
Syping d91b9f5f43 install curl for Dropbox build 2018-05-30 10:05:04 +02:00
Syping 3dfc2e001b fix dropbox build 2018-05-30 09:51:27 +02:00
Syping 1b54c8c456 add dropbox_uploader 2018-05-30 09:39:10 +02:00
Syping 979747b8f5 update scripts to dev build 2018-05-30 09:31:47 +02:00
Syping e74b19fed0 update travis scripts with PACKAGE_CODE var 2018-05-30 09:09:15 +02:00
Syping d94a3712be add git head if not tagged 2018-05-30 08:53:27 +02:00
Syping e765511614 fix release labels 2018-05-30 08:29:46 +02:00
Syping 61864c65eb rename installer after packaging 2018-05-30 08:27:21 +02:00
Syping bf81aea0c9 fix OS build, add deployment label 2018-05-30 08:17:12 +02:00
Syping 48650633a5 fix OS X build 2018-05-30 07:57:51 +02:00
Syping 2b3a22b893 fix OS X build 2018-05-30 07:49:33 +02:00
Syping 9b373669b2 add future watermark to resources 2018-05-27 11:13:13 +02:00
Syping 55a01e7fe4 readme updated 2018-05-24 23:33:01 +02:00
Syping fdf07dd681 SnapmaticPicture now stay alone, gta5sync references reduced 2018-05-24 22:32:00 +02:00
210 changed files with 16247 additions and 4784 deletions

44
.ci/ci.sh Executable file
View file

@ -0,0 +1,44 @@
#!/bin/bash
if [ $(git name-rev --tags --name-only $(git rev-parse HEAD)) == "undefined" ]; then
export APPLICATION_VERSION=$(lua -e 'for line in io.lines("config.h") do local m = string.match(line, "#define GTA5SYNC_APPVER \"(.+)\"$"); if m then print(m); os.exit(0) end end')
else
export APPLICATION_VERSION=$(git name-rev --tags --name-only $(git rev-parse HEAD))
fi
export PACKAGE_VERSION=$(grep -oE '^[^\-]*' <<< $APPLICATION_VERSION)
export PACKAGE_BUILD=$(grep -oP '\-\K.+' <<< $APPLICATION_VERSION)
export EXECUTABLE_VERSION=${PACKAGE_VERSION}${PACKAGE_BUILD}${EXECUTABLE_TAG}
if [ "${PACKAGE_BUILD}" == "" ]; then
export PACKAGE_BUILD=1;
fi
if [ "${BUILD_TYPE}" == "ALPHA" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_ALPHA"
elif [ "${BUILD_TYPE}" == "Alpha" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_ALPHA"
elif [ "${BUILD_TYPE}" == "BETA" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_BETA"
elif [ "${BUILD_TYPE}" == "Beta" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_BETA"
elif [ "${BUILD_TYPE}" == "DEV" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_DEV"
elif [ "${BUILD_TYPE}" == "Development" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_DEV"
elif [ "${BUILD_TYPE}" == "DAILY" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_DAILY"
elif [ "${BUILD_TYPE}" == "Daily" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_DAILY"
elif [ "${BUILD_TYPE}" == "RC" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_RC"
elif [ "${BUILD_TYPE}" == "Release Candidate" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_RC"
elif [ "${BUILD_TYPE}" == "REL" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_REL"
elif [ "${BUILD_TYPE}" == "Release" ]; then
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE_REL"
fi
export PROJECT_DIR=$(pwd)
.ci/${BUILD_SCRIPT}

33
.ci/debian_build.sh Executable file
View file

@ -0,0 +1,33 @@
#!/bin/bash
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
mkdir -p build && \
mkdir -p assets && \
chmod -x res/gta5sync_*.qm res/gta5view.desktop res/gta5view.png && \
cd build && \
mkdir -p qt4 && \
cd qt4 && \
echo "Grand Theft Auto V Snapmatic and Savegame viewer/editor" > ./description-pak && \
cd .. && \
mkdir -p qt5 && \
cd qt5 && \
echo "Grand Theft Auto V Snapmatic and Savegame viewer/editor" > ./description-pak && \
cd .. && \
# Prepare checkinstall step
mkdir -p /usr/share/gta5view && \
# Starting build
cd qt5 && \
qmake -qt=5 -spec linux-clang GTA5SYNC_PREFIX=/usr QMAKE_CXXFLAGS+=-std=gnu++11 ${QMAKE_FLAGS_QT5} ${QMAKE_BUILD_TYPE} "DEFINES+=GTA5SYNC_BUILDCODE=\\\\\\\"${PACKAGE_CODE}\\\\\\\"" "DEFINES+=GTA5SYNC_APPVER=\\\\\\\"${APPLICATION_VERSION}\\\\\\\"" "DEFINES+=GTA5SYNC_COMMIT=\\\\\\\"${APPLICATION_COMMIT}\\\\\\\"" DEFINES+=GTA5SYNC_QCONF DEFINES+=GTA5SYNC_TELEMETRY "DEFINES+=GTA5SYNC_TELEMETRY_WEBURL=\\\\\\\"https://dev.syping.de/gta5view-userstats/\\\\\\\"" DEFINES+=GTA5SYNC_DONATION "DEFINES+=GTA5SYNC_DONATION_EMAIL=\\\\\\\"paypal/at/syping.de\\\\\\\"" ../../gta5view.pro && \
make depend && \
make -j 4 && \
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 depend && \
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

View file

@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
# Install packages # Install packages
.travis/osx_install.sh && \ .ci/debian_install.sh && \
# Build gta5view # Build gta5view
.travis/osx_build.sh && \ .ci/debian_build.sh && \
cd ${PROJECT_DIR} cd ${PROJECT_DIR}

15
.ci/debian_docker.sh Executable file
View file

@ -0,0 +1,15 @@
#!/bin/bash
if [ "${DOCKER_USER}" != "" ]; then
DOCKER_IMAGE=${DOCKER_USER}/debian:${DEBIAN_VERSION}
else
DOCKER_IMAGE=debian:${DEBIAN_VERSION}
fi
PROJECT_DIR_DOCKER=/gta5view
cd ${PROJECT_DIR} && \
docker pull ${DOCKER_IMAGE} && \
docker run --rm \
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
${DOCKER_IMAGE} \
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export APT_INSTALL=${APT_INSTALL} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export 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"

View file

@ -2,4 +2,4 @@
# Install packages # Install packages
apt-get update -qq && \ apt-get update -qq && \
apt-get install -qq ${APT_INSTALL} checkinstall dpkg-dev fakeroot g++ gcc qtbase5-dev qt5-qmake qttranslations5-l10n libqt4-dev apt-get install -qq ${APT_INSTALL} checkinstall dpkg-dev fakeroot g++ gcc qtbase5-dev qt5-qmake qttranslations5-l10n libqt4-dev libqt5svg5-dev

1763
.ci/dropbox_uploader.sh Executable file

File diff suppressed because it is too large Load diff

View file

@ -3,8 +3,8 @@
!define APP_NAME "gta5view" !define APP_NAME "gta5view"
!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.5.4.0" !define VERSION "1.7.1.0"
!define COPYRIGHT "Copyright © 2016-2018 Syping" !define COPYRIGHT "Copyright © 2016-2019 Syping"
!define DESCRIPTION "Grand Theft Auto V Savegame and Snapmatic Viewer/Editor" !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"
@ -33,6 +33,7 @@ Caption "${APP_NAME}"
OutFile "${INSTALLER_NAME}" OutFile "${INSTALLER_NAME}"
#BrandingText "${APP_NAME}" #BrandingText "${APP_NAME}"
XPStyle on XPStyle on
Unicode true
InstallDirRegKey "${REG_ROOT}" "${REG_APP_PATH}" "" InstallDirRegKey "${REG_ROOT}" "${REG_APP_PATH}" ""
InstallDir "$PROGRAMFILES64\Syping\gta5view" InstallDir "$PROGRAMFILES64\Syping\gta5view"
@ -78,7 +79,9 @@ InstallDir "$PROGRAMFILES64\Syping\gta5view"
!insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "French" !insertmacro MUI_LANGUAGE "French"
!insertmacro MUI_LANGUAGE "German" !insertmacro MUI_LANGUAGE "German"
!insertmacro MUI_LANGUAGE "Korean"
!insertmacro MUI_LANGUAGE "Russian" !insertmacro MUI_LANGUAGE "Russian"
!insertmacro MUI_LANGUAGE "Ukrainian"
!insertmacro MUI_LANGUAGE "TradChinese" !insertmacro MUI_LANGUAGE "TradChinese"
!insertmacro MUI_RESERVEFILE_LANGDLL !insertmacro MUI_RESERVEFILE_LANGDLL
@ -88,7 +91,7 @@ InstallDir "$PROGRAMFILES64\Syping\gta5view"
Function .onInit Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY !insertmacro MUI_LANGDLL_DISPLAY
!ifdef WIN32 !ifdef WIN32
MessageBox MB_OK|MB_ICONSTOP "Can't install the 64bit version on a 32bit system, please download the 32bit version!" MessageBox MB_OK|MB_ICONSTOP "Windows 32-Bit is not supported anymore!"
Quit Quit
!endif !endif
SetRegView 64 SetRegView 64
@ -101,10 +104,10 @@ ${INSTALL_TYPE}
SetOverwrite ifnewer SetOverwrite ifnewer
SetOutPath "$INSTDIR" SetOutPath "$INSTDIR"
File "../build/release/gta5view.exe" File "../build/release/gta5view.exe"
File "/usr/lib/gcc/x86_64-w64-mingw32/6.3-win32/libgcc_s_seh-1.dll" File "/usr/lib/gcc/x86_64-w64-mingw32/8.3-win32/libgcc_s_seh-1.dll"
File "/usr/lib/gcc/x86_64-w64-mingw32/6.3-win32/libstdc++-6.dll" File "/usr/lib/gcc/x86_64-w64-mingw32/8.3-win32/libstdc++-6.dll"
File "/opt/windev/libressl-latest_qt64d/bin/libcrypto-43.dll" File "/opt/windev/openssl-latest_qt64d/bin/libcrypto-1_1-x64.dll"
File "/opt/windev/libressl-latest_qt64d/bin/libssl-45.dll" File "/opt/windev/openssl-latest_qt64d/bin/libssl-1_1-x64.dll"
File "/opt/windev/libjpeg-turbo-latest_qt64d/bin/libjpeg-62.dll" File "/opt/windev/libjpeg-turbo-latest_qt64d/bin/libjpeg-62.dll"
File "/opt/windev/qt64d-latest/bin/Qt5Core.dll" File "/opt/windev/qt64d-latest/bin/Qt5Core.dll"
File "/opt/windev/qt64d-latest/bin/Qt5Gui.dll" File "/opt/windev/qt64d-latest/bin/Qt5Gui.dll"
@ -116,17 +119,17 @@ SetOutPath "$INSTDIR\lang"
File "../res/gta5sync_en_US.qm" File "../res/gta5sync_en_US.qm"
File "../res/gta5sync_de.qm" File "../res/gta5sync_de.qm"
File "../res/gta5sync_fr.qm" File "../res/gta5sync_fr.qm"
File "../res/gta5sync_ko.qm"
File "../res/gta5sync_ru.qm" File "../res/gta5sync_ru.qm"
File "../res/gta5sync_uk.qm" File "../res/gta5sync_uk.qm"
File "../res/gta5sync_zh_TW.qm" File "../res/gta5sync_zh_TW.qm"
File "../res/qtbase_en_GB.qm" File "../res/qtbase_en_GB.qm"
File "../res/qtbase_de.qm" File "../res/qtbase_de.qm"
File "../res/qtbase_fr.qm" File "../res/qtbase_fr.qm"
File "../res/qtbase_ko.qm"
File "../res/qtbase_ru.qm" File "../res/qtbase_ru.qm"
File "../res/qtbase_uk.qm" File "../res/qtbase_uk.qm"
File "../res/qtbase_zh_TW.qm" File "../res/qtbase_zh_TW.qm"
SetOutPath "$INSTDIR\audio"
File "/opt/windev/qt64d-latest/plugins/audio/qtaudio_windows.dll"
SetOutPath "$INSTDIR\imageformats" SetOutPath "$INSTDIR\imageformats"
File "/opt/windev/qt64d-latest/plugins/imageformats/qgif.dll" File "/opt/windev/qt64d-latest/plugins/imageformats/qgif.dll"
File "/opt/windev/qt64d-latest/plugins/imageformats/qicns.dll" File "/opt/windev/qt64d-latest/plugins/imageformats/qicns.dll"
@ -139,6 +142,10 @@ File "/opt/windev/qt64d-latest/plugins/imageformats/qwbmp.dll"
File "/opt/windev/qt64d-latest/plugins/imageformats/qwebp.dll" File "/opt/windev/qt64d-latest/plugins/imageformats/qwebp.dll"
SetOutPath "$INSTDIR\platforms" SetOutPath "$INSTDIR\platforms"
File "/opt/windev/qt64d-latest/plugins/platforms/qwindows.dll" File "/opt/windev/qt64d-latest/plugins/platforms/qwindows.dll"
SetOutPath "$INSTDIR\styles"
File "/opt/windev/qt64d-latest/plugins/styles/qcleanlooksstyle.dll"
File "/opt/windev/qt64d-latest/plugins/styles/qplastiquestyle.dll"
File "/opt/windev/qt64d-latest/plugins/styles/qwindowsvistastyle.dll"
SectionEnd SectionEnd
###################################################################### ######################################################################
@ -190,8 +197,8 @@ ${INSTALL_TYPE}
Delete "$INSTDIR\gta5view.exe" Delete "$INSTDIR\gta5view.exe"
Delete "$INSTDIR\libgcc_s_seh-1.dll" Delete "$INSTDIR\libgcc_s_seh-1.dll"
Delete "$INSTDIR\libstdc++-6.dll" Delete "$INSTDIR\libstdc++-6.dll"
Delete "$INSTDIR\libcrypto-43.dll" Delete "$INSTDIR\libcrypto-1_1-x64.dll"
Delete "$INSTDIR\libssl-45.dll" Delete "$INSTDIR\libssl-1_1-x64.dll"
Delete "$INSTDIR\libjpeg-62.dll" Delete "$INSTDIR\libjpeg-62.dll"
Delete "$INSTDIR\Qt5Core.dll" Delete "$INSTDIR\Qt5Core.dll"
Delete "$INSTDIR\Qt5Gui.dll" Delete "$INSTDIR\Qt5Gui.dll"
@ -202,16 +209,17 @@ 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"
Delete "$INSTDIR\lang\gta5sync_ko.qm"
Delete "$INSTDIR\lang\gta5sync_ru.qm" Delete "$INSTDIR\lang\gta5sync_ru.qm"
Delete "$INSTDIR\lang\gta5sync_uk.qm" Delete "$INSTDIR\lang\gta5sync_uk.qm"
Delete "$INSTDIR\lang\gta5sync_zh_TW.qm" Delete "$INSTDIR\lang\gta5sync_zh_TW.qm"
Delete "$INSTDIR\lang\qtbase_en_GB.qm" Delete "$INSTDIR\lang\qtbase_en_GB.qm"
Delete "$INSTDIR\lang\qtbase_de.qm" Delete "$INSTDIR\lang\qtbase_de.qm"
Delete "$INSTDIR\lang\qtbase_fr.qm" Delete "$INSTDIR\lang\qtbase_fr.qm"
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\audio\qtaudio_windows.dll"
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"
@ -222,10 +230,13 @@ Delete "$INSTDIR\imageformats\qtiff.dll"
Delete "$INSTDIR\imageformats\qwbmp.dll" Delete "$INSTDIR\imageformats\qwbmp.dll"
Delete "$INSTDIR\imageformats\qwebp.dll" Delete "$INSTDIR\imageformats\qwebp.dll"
Delete "$INSTDIR\platforms\qwindows.dll" Delete "$INSTDIR\platforms\qwindows.dll"
Delete "$INSTDIR\styles\qcleanlooksstyle.dll"
Delete "$INSTDIR\styles\qplastiquestyle.dll"
Delete "$INSTDIR\styles\qwindowsvistastyle.dll"
RmDir "$INSTDIR\lang" RmDir "$INSTDIR\lang"
RmDir "$INSTDIR\platforms"
RmDir "$INSTDIR\imageformats" RmDir "$INSTDIR\imageformats"
RmDir "$INSTDIR\platforms"
RmDir "$INSTDIR\styles"
Delete "$INSTDIR\uninstall.exe" Delete "$INSTDIR\uninstall.exe"
!ifdef WEB_SITE !ifdef WEB_SITE

15
.ci/osx_build.sh Executable file
View file

@ -0,0 +1,15 @@
#!/bin/bash
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
echo "gta5view image name is gta5view-osx_${APPLICATION_VERSION}.dmg" && \
mkdir -p build && \
mkdir -p assets && \
cd build && \
/usr/local/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 && \
make depend && \
make -j 4 && \
/usr/local/opt/qt/bin/macdeployqt gta5view.app -dmg && \
cp -Rf gta5view.dmg ../assets/gta5view-osx_${APPLICATION_VERSION}.dmg

8
.ci/osx_ci.sh Executable file
View file

@ -0,0 +1,8 @@
#!/bin/bash
# Install packages
.ci/osx_install.sh && \
# Build gta5view
.ci/osx_build.sh && \
cd ${PROJECT_DIR}

19
.ci/windows_build.sh Executable file
View file

@ -0,0 +1,19 @@
#!/bin/bash
# Prepare environment variable
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
echo "gta5view executable is ${GTA5VIEW_EXECUTABLE}" && \
mkdir -p build && \
mkdir -p assets && \
# Starting build
cd build && \
qmake-static ${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/\\\\\\\"" DEFINES+=GTA5SYNC_DONATION "DEFINES+=GTA5SYNC_DONATION_EMAIL=\\\\\\\"paypal/at/syping.de\\\\\\\"" ../gta5view.pro && \
make depend && \
make -j 4 && \
cp -Rf release/*.exe ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} && \
cd ${PROJECT_DIR}/assets

21
.ci/windows_docker.sh Executable file
View file

@ -0,0 +1,21 @@
#!/bin/bash
DOCKER_IMAGE=sypingauto/gta5view-build:1.7-static
PROJECT_DIR_DOCKER=/gta5view
cd ${PROJECT_DIR} && \
docker pull ${DOCKER_IMAGE} && \
docker run --rm \
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
${DOCKER_IMAGE} \
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/windows_build.sh" && \
# Prepare environment variable
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
# Upload Assets to Dropbox
if [ "${PACKAGE_CODE}" == "gta5-mods" ]; then
${PROJECT_DIR}/.ci/dropbox_uploader.sh mkdir gta5-mods/${PACKAGE_VERSION}
${PROJECT_DIR}/.ci/dropbox_uploader.sh upload ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} gta5-mods/${PACKAGE_VERSION}/${GTA5VIEW_EXECUTABLE} && \
rm -rf ${GTA5VIEW_EXECUTABLE}
fi

20
.ci/wininstall_build.sh Executable file
View file

@ -0,0 +1,20 @@
#!/bin/bash
# Install nsis
apt-get update -qq && \
apt-get install -qq nsis && \
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
mkdir -p build && \
mkdir -p assets && \
# Starting build
cd build && \
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/\\\\\\\"" DEFINES+=GTA5SYNC_DONATION "DEFINES+=GTA5SYNC_DONATION_EMAIL=\\\\\\\"paypal/at/syping.de\\\\\\\"" DEFINES+=GTA5SYNC_QCONF DEFINES+=GTA5SYNC_INLANG='\\\"RUNDIR:SEPARATOR:lang\\\"' DEFINES+=GTA5SYNC_LANG='\\\"RUNDIR:SEPARATOR:lang\\\"' DEFINES+=GTA5SYNC_PLUG='\\\"RUNDIR:SEPARATOR:plugins\\\"' "LIBS+=-ljpeg" ../gta5view.pro && \
make depend && \
make -j 4 && \
cd ${PROJECT_DIR}/assets && \
makensis -NOCD ${PROJECT_DIR}/.ci/gta5view.nsi && \
mv -f gta5view_setup.exe gta5view-${EXECUTABLE_VERSION}_setup.exe

11
.ci/wininstall_docker.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
DOCKER_IMAGE=sypingauto/gta5view-build:1.7-shared
PROJECT_DIR_DOCKER=/gta5view
cd ${PROJECT_DIR} && \
docker pull ${DOCKER_IMAGE} && \
docker run --rm \
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
${DOCKER_IMAGE} \
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export 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"

4
.gitignore vendored
View file

@ -29,3 +29,7 @@
# Qt project user file # Qt project user file
*.pro.user *.pro.user
# Gettext translation files
*.po
*.pot

31
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,31 @@
stages:
- build
variables:
BUILD_TYPE: "REL"
Windows Installer:
stage: build
image: sypingauto/gta5view-build:1.7-shared
variables:
BUILD_SCRIPT: "wininstall_build.sh"
QT_SELECT: "qt5-x86_64-w64-mingw32"
script:
- .gitlab/gitlab.sh
artifacts:
name: "gta5view-$CI_COMMIT_REF_NAME-${CI_COMMIT_SHA:0:8}_setup"
paths:
- "gta5view-*.exe"
Windows Portable:
stage: build
image: sypingauto/gta5view-build:1.7-static
variables:
BUILD_SCRIPT: "windows_build.sh"
QT_SELECT: "qt5-x86_64-w64-mingw32"
script:
- .gitlab/gitlab.sh
artifacts:
name: "gta5view-$CI_COMMIT_REF_NAME-${CI_COMMIT_SHA:0:8}_portable"
paths:
- "gta5view-*.exe"

Binary file not shown.

24
.gitlab/gitlab.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/bash
# Decrypt Telemetry Authenticator
rm -rf tmext/TelemetryClassAuthenticator.cpp && \
openssl aes-256-cbc -k $tca_pass -in .gitlab/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d
# Check if build is not tagged
if [ "${CI_COMMIT_TAG}" == "" ]; then
export EXECUTABLE_TAG=-$(git rev-parse --short HEAD)
else
export EXECUTABLE_TAG=
fi
# Check if package code is not set
if [ "${PACKAGE_CODE}" == "" ]; then
export PACKAGE_CODE=GitLab
fi
# Init Application Commit Hash
export APPLICATION_COMMIT=$(git rev-parse --short HEAD)
# Start CI script and copying assets into base directory
.ci/ci.sh && \
cp -Rf assets/* ./

View file

@ -5,35 +5,40 @@ language: cpp
service: service:
- docker - docker
env:
global:
- BUILD_TYPE=REL
matrix: matrix:
include: include:
- env: - env:
- BUILD_SCRIPT=debian_travis.sh - BUILD_SCRIPT=debian_docker.sh
- QMAKE_FLAGS_QT4=QMAKE_CXXFLAGS+=-Wno-missing-field-initializers - RELEASE_LABEL="Debian 64-Bit Package"
- DEBIAN_VERSION=jessie - DEBIAN_VERSION=stretch
- DOCKER_USER=i386
- APT_INSTALL=clang
- env:
- BUILD_SCRIPT=debian_travis.sh
- QMAKE_FLAGS_QT4=QMAKE_CXXFLAGS+=-Wno-missing-field-initializers
- DEBIAN_VERSION=jessie
- DOCKER_USER=amd64 - DOCKER_USER=amd64
- APT_INSTALL=clang - APT_INSTALL=clang
- env: - env:
- BUILD_SCRIPT=windows_travis.sh - BUILD_SCRIPT=windows_docker.sh
- QT_SELECT=qt5-i686-w64-mingw32
- env:
- BUILD_SCRIPT=windows_travis.sh
- QT_SELECT=qt5-x86_64-w64-mingw32 - QT_SELECT=qt5-x86_64-w64-mingw32
- EXECUTABLE_ARCH=_x64 - RELEASE_LABEL="Windows 64-Bit Portable"
- env: - env:
- BUILD_SCRIPT=wininstall_travis.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 for gta5-mods"
- PACKAGE_CODE=gta5-mods
- env:
- BUILD_SCRIPT=wininstall_docker.sh
- QT_SELECT=qt5-x86_64-w64-mingw32
- RELEASE_LABEL="Windows 64-Bit Installer"
- os: osx
env:
- BUILD_SCRIPT=osx_ci.sh
- RELEASE_LABEL="Mac OS X 64-Bit Disk Image"
before_install: before_install:
- ".travis/source.sh" - ".travis/source.sh"
script: script:
- ".travis/travis.sh" - ".travis/travis.sh"
@ -41,6 +46,7 @@ deploy:
provider: releases provider: releases
api_key: api_key:
secure: o7VneEz1aHfdVwZvOZLfopf6uJWNrFsZaBvunTmXFzpmNFhlNS1qwqgMUkIA2yBRbZ3wIzVs4vfwIHv7W9yE/PqK+AYL+R8+AwKGrwlgT4HqJNuk6VM/LNJ6GwT/qkQuaoOVw29bUjmzzgIRdHmw53SlJv6Hh1VE8HphlTT//aex6nCfcFhUZ0BETdZDWz5FSHwL3NalUoqfKfQrJeky5RXzCyCANQC2tKt0bV46GaWIgWrDo2KCTNqPtRWWf5GDmnkXE5IYRMQ3mXvO9iYh0v5Y2jo4PiXGUiFUU6Z3aAWFAiPdGclrBO697cf3lCTzDMhuCETR153qFYsLShUlFf61ITAmCeHAWETjZDri0lmPONo3GoNB6alGfYEA51qw14kXakrTpICtTJj7gw/gtUYOabW6hrzmieNzMBIy62RikDPjyakFnuwW2qNHRlD65e0jYv+6nCpb6E+OV16Ysh1zhV2vTfpfzVmSuyu2J+ELqXD3OZCXRSPpDIih9UQ8335p8FBji6jHORcgym/TRgdgRmENibh8tLzWp+UjpWHuWfcpvZgOskjfwU0iDMCayMJ7tDpOhXHcAhDRnd6XRIiOJ5YZCzflj2nEwmt3YUd7DwXS/AU+WHOmcNQBjXBxF/FJa35XXcy3HKJM5TTKqtph3medo30us5yXHeG6NNg= secure: o7VneEz1aHfdVwZvOZLfopf6uJWNrFsZaBvunTmXFzpmNFhlNS1qwqgMUkIA2yBRbZ3wIzVs4vfwIHv7W9yE/PqK+AYL+R8+AwKGrwlgT4HqJNuk6VM/LNJ6GwT/qkQuaoOVw29bUjmzzgIRdHmw53SlJv6Hh1VE8HphlTT//aex6nCfcFhUZ0BETdZDWz5FSHwL3NalUoqfKfQrJeky5RXzCyCANQC2tKt0bV46GaWIgWrDo2KCTNqPtRWWf5GDmnkXE5IYRMQ3mXvO9iYh0v5Y2jo4PiXGUiFUU6Z3aAWFAiPdGclrBO697cf3lCTzDMhuCETR153qFYsLShUlFf61ITAmCeHAWETjZDri0lmPONo3GoNB6alGfYEA51qw14kXakrTpICtTJj7gw/gtUYOabW6hrzmieNzMBIy62RikDPjyakFnuwW2qNHRlD65e0jYv+6nCpb6E+OV16Ysh1zhV2vTfpfzVmSuyu2J+ELqXD3OZCXRSPpDIih9UQ8335p8FBji6jHORcgym/TRgdgRmENibh8tLzWp+UjpWHuWfcpvZgOskjfwU0iDMCayMJ7tDpOhXHcAhDRnd6XRIiOJ5YZCzflj2nEwmt3YUd7DwXS/AU+WHOmcNQBjXBxF/FJa35XXcy3HKJM5TTKqtph3medo30us5yXHeG6NNg=
label: ${RELEASE_LABEL}
file_glob: true file_glob: true
file: assets/* file: assets/*
skip_cleanup: true skip_cleanup: true

Binary file not shown.

View file

@ -1,31 +0,0 @@
#!/bin/bash
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
mkdir -p build && \
mkdir -p assets && \
chmod -x res/gta5sync_*.qm res/gta5view.desktop res/gta5view.png && \
cd build && \
mkdir -p qt4 && \
cd qt4 && \
echo "Grand Theft Auto V Snapmatic and Savegame viewer/manager" > ./description-pak && \
cd .. && \
mkdir -p qt5 && \
cd qt5 && \
echo "Grand Theft Auto V Snapmatic and Savegame viewer/manager" > ./description-pak && \
cd .. && \
# Prepare checkinstall step
mkdir -p /usr/share/gta5view && \
# Starting build
cd qt5 && \
qmake -qt=5 -spec linux-clang GTA5SYNC_PREFIX=/usr QMAKE_CXXFLAGS+=-std=gnu++11 ${QMAKE_FLAGS_QT5} DEFINES+=GTA5SYNC_BUILDTYPE_REL "DEFINES+=GTA5SYNC_BUILDCODE=\\\\\\\"GitHub\\\\\\\"" "DEFINES+=GTA5SYNC_APPVER=\\\\\\\"${APPLICATION_VERSION}\\\\\\\"" DEFINES+=GTA5SYNC_QCONF DEFINES+=GTA5SYNC_TELEMETRY "DEFINES+=GTA5SYNC_TELEMETRY_WEBURL=\\\\\\\"https://dev.syping.de/gta5view-userstats/\\\\\\\"" ../../gta5view.pro && \
make -j 4 && \
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,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} DEFINES+=GTA5SYNC_BUILDTYPE_REL "DEFINES+=GTA5SYNC_BUILDCODE=\\\\\\\"GitHub\\\\\\\"" "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,qtcore4-l10n --conflicts=gta5view,gta5view-qt5 --replaces=gta5view,gta5view-qt5 --pakdir=${PROJECT_DIR}/assets

View file

@ -1,15 +0,0 @@
#!/bin/bash
if [[ ${DOCKER_USER} ]]; then
DOCKER_IMAGE=${DOCKER_USER}/debian:${DEBIAN_VERSION}
else
DOCKER_IMAGE=debian:${DEBIAN_VERSION}
fi
PROJECT_DIR_DOCKER=/gta5view
cd ${PROJECT_DIR} && \
docker pull ${DOCKER_IMAGE} && \
docker run --rm \
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
${DOCKER_IMAGE} \
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APT_INSTALL=${APT_INSTALL} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .travis/debian_install.sh && .travis/debian_build.sh"

View file

@ -0,0 +1 @@
Poァ鏖<EFBFBD>劾ラ<作1x」%几<>ャネw|RtZv<>kホ銓顴Z肄2チ廁湮ォ`<1A>,4vヨマ・@€<>ヲeハ・~U$+<2B><>€<EFBFBD><1A><牾&蓬熙

View file

@ -1,14 +0,0 @@
#!/bin/bash
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
echo "gta5view image name is gta5view-osx_${APPLICATION_VERSION}.dmg" && \
mkdir -p build && \
mkdir -p assets && \
cd build && \
/usr/local/opt/qt/bin/qmake ${QMAKE_FLAGS_QT5} DEFINES+=GTA5SYNC_BUILDTYPE_REL "DEFINES+=GTA5SYNC_BUILDCODE=\\\\\\\"GitHub\\\\\\\"" "DEFINES+=GTA5SYNC_APPVER=\\\\\\\"${APPLICATION_VERSION}\\\\\\\"" DEFINES+=GTA5SYNC_TELEMETRY "DEFINES+=GTA5SYNC_TELEMETRY_WEBURL=\\\\\\\"https://dev.syping.de/gta5view-userstats/\\\\\\\"" ../gta5view.pro && \
make -j 4 && \
/usr/local/opt/qt/bin/macdeployqt gta5view.app -dmg && \
cp -Rf gta5view.dmg ../assets/gta5view-osx_${APPLICATION_VERSION}.dmg

View file

@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
rm -rf tmext/TelemetryClassAuthenticator.cpp && \ rm -rf tmext/TelemetryClassAuthenticator.cpp && \
openssl aes-256-cbc -K $encrypted_55502862a724_key -iv $encrypted_55502862a724_iv -in tmext/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d openssl aes-256-cbc -K $encrypted_db000a5d87d6_key -iv $encrypted_db000a5d87d6_iv -in .travis/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d && \
openssl aes-256-cbc -K $encrypted_d57e7d2f8877_key -iv $encrypted_d57e7d2f8877_iv -in .travis/dropbox_uploader.enc -out ~/.dropbox_uploader -d

View file

@ -1,18 +1,27 @@
#!/bin/bash #!/bin/bash
# Install lua # Install lua
if [ "${TRAVIS_OS_NAME}" == "linux" ]; then if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
brew install lua
else
sudo apt-get update -qq && \ sudo apt-get update -qq && \
sudo apt-get install -qq lua5.2 sudo apt-get install -qq lua5.2
elif [ "${TRAVIS_OS_NAME}" == "osx" ]; then
brew install lua
fi fi
if [ `git name-rev --tags --name-only $(git rev-parse HEAD)` == "undefined" ]; then export APPLICATION_VERSION=`lua -e 'for line in io.lines("config.h") do local m = string.match(line, "#define GTA5SYNC_APPVER \"(.+)\"$"); if m then print(m); os.exit(0) end end'`; else export APPLICATION_VERSION=`git name-rev --tags --name-only $(git rev-parse HEAD)`; fi # Check if build is not tagged
export PACKAGE_VERSION=$(grep -oE '^[^\-]*' <<< $APPLICATION_VERSION) if [ "${TRAVIS_TAG}" == "" ]; then
export PACKAGE_BUILD=$(grep -oP '\-\K.+' <<< $APPLICATION_VERSION) export EXECUTABLE_TAG=-$(git rev-parse --short HEAD)
export EXECUTABLE_VERSION=${PACKAGE_VERSION}${PACKAGE_BUILD} else
if [[ ! ${PACKAGE_BUILD} ]]; then export PACKAGE_BUILD=1; fi export EXECUTABLE_TAG=
export PROJECT_DIR=$(pwd) fi
.travis/${BUILD_SCRIPT} # Check if package code is not set
if [ "${PACKAGE_CODE}" == "" ]; then
export PACKAGE_CODE=GitHub
fi
# Init Application Commit Hash
export APPLICATION_COMMIT=$(git rev-parse --short HEAD)
# Start CI script
.ci/ci.sh

View file

@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
# Install packages # Install packages
sudo .travis/debian_install.sh && \ sudo .ci/debian_install.sh && \
# Build gta5view # Build gta5view
sudo .travis/debian_build.sh && \ sudo .ci/debian_build.sh && \
cd ${PROJECT_DIR} cd ${PROJECT_DIR}

View file

@ -1,18 +0,0 @@
#!/bin/bash
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
echo "gta5view executable is ${GTA5VIEW_EXECUTABLE}" && \
mkdir -p build && \
mkdir -p assets && \
# Starting build
cd build && \
qmake-static ${QMAKE_FLAGS} DEFINES+=GTA5SYNC_BUILDTYPE_REL "DEFINES+=GTA5SYNC_BUILDCODE=\\\\\\\"GitHub\\\\\\\"" "DEFINES+=GTA5SYNC_APPVER=\\\\\\\"${APPLICATION_VERSION}\\\\\\\"" DEFINES+=GTA5SYNC_TELEMETRY "DEFINES+=GTA5SYNC_TELEMETRY_WEBURL=\\\\\\\"https://dev.syping.de/gta5view-userstats/\\\\\\\"" ../gta5view.pro && \
make -j 4 && \
cp -Rf release/*.exe ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} && \
cd ${PROJECT_DIR}/assets && \
upx --best ${GTA5VIEW_EXECUTABLE}

View file

@ -1,12 +0,0 @@
#!/bin/bash
QT_VERSION=5.6.3
DOCKER_IMAGE=syping/qt5-static-mingw:${QT_VERSION}
PROJECT_DIR_DOCKER=/gta5view
cd ${PROJECT_DIR} && \
docker pull ${DOCKER_IMAGE} && \
docker run --rm \
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
${DOCKER_IMAGE} \
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .travis/windows_build.sh"

View file

@ -1,17 +0,0 @@
#!/bin/bash
apt-get update -qq && \
apt-get install -qq nsis && \
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
mkdir -p build && \
mkdir -p assets && \
# Starting build
cd build && \
qmake ${QMAKE_FLAGS} DEFINES+=GTA5SYNC_BUILDTYPE_REL "DEFINES+=GTA5SYNC_BUILDCODE=\\\\\\\"GitHub\\\\\\\"" "DEFINES+=GTA5SYNC_APPVER=\\\\\\\"${APPLICATION_VERSION}\\\\\\\"" DEFINES+=GTA5SYNC_TELEMETRY "DEFINES+=GTA5SYNC_TELEMETRY_WEBURL=\\\\\\\"https://dev.syping.de/gta5view-userstats/\\\\\\\"" DEFINES+=GTA5SYNC_QCONF DEFINES+=GTA5SYNC_INLANG='\\\"RUNDIR:SEPARATOR:lang\\\"' DEFINES+=GTA5SYNC_LANG='\\\"RUNDIR:SEPARATOR:lang\\\"' DEFINES+=GTA5SYNC_PLUG='\\\"RUNDIR:SEPARATOR:plugins\\\"' ../gta5view.pro && \
make -j 4 && \
cd ${PROJECT_DIR}/assets && \
makensis -NOCD ${PROJECT_DIR}/.travis/gta5view.nsi

View file

@ -1,12 +0,0 @@
#!/bin/bash
QT_VERSION=5.6.3
DOCKER_IMAGE=syping/qt5-shared-mingw:${QT_VERSION}
PROJECT_DIR_DOCKER=/gta5view
cd ${PROJECT_DIR} && \
docker pull ${DOCKER_IMAGE} && \
docker run --rm \
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
${DOCKER_IMAGE} \
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .travis/wininstall_build.sh"

View file

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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
@ -37,6 +37,11 @@ AboutDialog::AboutDialog(QWidget *parent) :
buildType.replace("_", " "); buildType.replace("_", " ");
QString projectBuild = AppEnv::getBuildDateTime(); QString projectBuild = AppEnv::getBuildDateTime();
QString buildStr = GTA5SYNC_BUILDSTRING; QString buildStr = GTA5SYNC_BUILDSTRING;
#ifndef GTA5SYNC_BUILDTYPE_REL
#ifdef GTA5SYNC_COMMIT
if (!appVersion.contains("-")) { appVersion = appVersion % "-" % GTA5SYNC_COMMIT; }
#endif
#endif
// Translator Comments // Translator Comments
//: Translated by translator, example Translated by Syping //: Translated by translator, example Translated by Syping
@ -65,11 +70,7 @@ AboutDialog::AboutDialog(QWidget *parent) :
} }
// Project Description // Project Description
#ifdef GTA5SYNC_ENABLED
QString projectDes = tr("A project for viewing and sync Grand Theft Auto V Snapmatic<br/>\nPictures and Savegames");
#else
QString projectDes = tr("A project for viewing Grand Theft Auto V Snapmatic<br/>\nPictures and Savegames"); QString projectDes = tr("A project for viewing Grand Theft Auto V Snapmatic<br/>\nPictures and Savegames");
#endif
// Copyright Description // Copyright Description
QString copyrightDes1 = tr("Copyright &copy; <a href=\"%1\">%2</a> %3"); QString copyrightDes1 = tr("Copyright &copy; <a href=\"%1\">%2</a> %3");

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -152,7 +152,38 @@ QString AppEnv::getPluginsFolder()
QByteArray AppEnv::getUserAgent() QByteArray AppEnv::getUserAgent()
{ {
return QString("Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 %1/%2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8(); #if QT_VERSION >= 0x050400
#ifdef GTA5SYNC_WIN
QString kernelVersion = QSysInfo::kernelVersion();
const QStringList &kernelVersionList = kernelVersion.split(".");
if (kernelVersionList.length() > 2)
{
kernelVersion = kernelVersionList.at(0) % "." % kernelVersionList.at(1);
}
QString runArch = QSysInfo::buildCpuArchitecture();
if (runArch == "x86_64")
{
runArch = "Win64; x64";
}
else if (runArch == "i686")
{
const QString &curArch = QSysInfo::currentCpuArchitecture();
if (curArch == "x86_64")
{
runArch = "WOW64";
}
else if (curArch == "i686")
{
runArch = "Win32; x86";
}
}
return QString("Mozilla/5.0 (Windows NT %1; %2) %3/%4").arg(kernelVersion, runArch, GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
#else
return QString("Mozilla/5.0 (%1; %2) %3/%4").arg(QSysInfo::kernelType(), QSysInfo::kernelVersion(), GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
#endif
#else
return QString("Mozilla/5.0 %1/%2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
#endif
} }
// QUrl AppEnv::getCrewFetchingUrl(QString crewID) // QUrl AppEnv::getCrewFetchingUrl(QString crewID)
@ -167,7 +198,7 @@ QUrl AppEnv::getCrewFetchingUrl(QString crewID)
QUrl AppEnv::getPlayerFetchingUrl(QString crewID, QString pageNumber) QUrl AppEnv::getPlayerFetchingUrl(QString crewID, QString pageNumber)
{ {
return QUrl(QString("https://socialclub.rockstargames.com/crewsapi/GetMembersList?crewId=%1&pageNumber=%2").arg(crewID, pageNumber)); return QUrl(QString("https://socialclub.rockstargames.com/crewsapi/GetMembersList?crewId=%1&pageNumber=%2&pageSize=5000").arg(crewID, pageNumber));
} }
QUrl AppEnv::getPlayerFetchingUrl(QString crewID, int pageNumber) QUrl AppEnv::getPlayerFetchingUrl(QString crewID, int pageNumber)
@ -175,6 +206,296 @@ QUrl AppEnv::getPlayerFetchingUrl(QString crewID, int pageNumber)
return getPlayerFetchingUrl(crewID, QString::number(pageNumber)); return getPlayerFetchingUrl(crewID, QString::number(pageNumber));
} }
// Game Stuff
GameVersion AppEnv::getGameVersion()
{
#ifdef GTA5SYNC_WIN
QString argumentValue;
#ifdef _WIN64
argumentValue = "\\WOW6432Node";
#endif
QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat);
QString installFolderSc = registrySettingsSc.value("InstallFolder", "").toString();
QDir installFolderScDir(installFolderSc);
bool scVersionInstalled = false;
if (!installFolderSc.isEmpty() && installFolderScDir.exists())
{
#ifdef GTA5SYNC_DEBUG
qDebug() << "gameVersionFoundSocialClubVersion";
#endif
scVersionInstalled = true;
}
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\GTAV").arg(argumentValue), QSettings::NativeFormat);
QString installFolderSteam = registrySettingsSteam.value("installfoldersteam", "").toString();
if (installFolderSteam.right(5) == "\\GTAV")
{
installFolderSteam = installFolderSteam.remove(installFolderSteam.length() - 5, 5);
}
QDir installFolderSteamDir(installFolderSteam);
bool steamVersionInstalled = false;
if (!installFolderSteam.isEmpty() && installFolderSteamDir.exists())
{
#ifdef GTA5SYNC_DEBUG
qDebug() << "gameVersionFoundSteamVersion";
#endif
steamVersionInstalled = true;
}
if (scVersionInstalled && steamVersionInstalled)
{
return GameVersion::BothVersions;
}
else if (scVersionInstalled)
{
return GameVersion::SocialClubVersion;
}
else if (steamVersionInstalled)
{
return GameVersion::SteamVersion;
}
else
{
return GameVersion::NoVersion;
}
#else
return GameVersion::NoVersion;
#endif
}
GameLanguage AppEnv::getGameLanguage(GameVersion gameVersion)
{
if (gameVersion == GameVersion::SocialClubVersion)
{
#ifdef GTA5SYNC_WIN
QString argumentValue;
#ifdef _WIN64
argumentValue = "\\WOW6432Node";
#endif
QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat);
QString languageSc = registrySettingsSc.value("Language", "").toString();
return gameLanguageFromString(languageSc);
#else
return GameLanguage::Undefined;
#endif
}
else if (gameVersion == GameVersion::SteamVersion)
{
#ifdef GTA5SYNC_WIN
QString argumentValue;
#ifdef _WIN64
argumentValue = "\\WOW6432Node";
#endif
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V Steam").arg(argumentValue), QSettings::NativeFormat);
QString languageSteam = registrySettingsSteam.value("Language", "").toString();
return gameLanguageFromString(languageSteam);
#else
return GameLanguage::Undefined;
#endif
}
else
{
return GameLanguage::Undefined;
}
}
GameLanguage AppEnv::gameLanguageFromString(QString gameLanguage)
{
if (gameLanguage == "en-US")
{
return GameLanguage::English;
}
else if (gameLanguage == "fr-FR")
{
return GameLanguage::French;
}
else if (gameLanguage == "it-IT")
{
return GameLanguage::Italian;
}
else if (gameLanguage == "de-DE")
{
return GameLanguage::German;
}
else if (gameLanguage == "es-ES")
{
return GameLanguage::Spanish;
}
else if (gameLanguage == "es-MX")
{
return GameLanguage::Mexican;
}
else if (gameLanguage == "pt-BR")
{
return GameLanguage::Brasilian;
}
else if (gameLanguage == "ru-RU")
{
return GameLanguage::Russian;
}
else if (gameLanguage == "pl-PL")
{
return GameLanguage::Polish;
}
else if (gameLanguage == "ja-JP")
{
return GameLanguage::Japanese;
}
else if (gameLanguage == "zh-CHS")
{
return GameLanguage::SChinese;
}
else if (gameLanguage == "zh-CHT")
{
return GameLanguage::TChinese;
}
else if (gameLanguage == "ko-KR")
{
return GameLanguage::Koreana;
}
else
{
return GameLanguage::Undefined;
}
}
QString AppEnv::gameLanguageToString(GameLanguage gameLanguage)
{
if (gameLanguage == GameLanguage::English)
{
return "en-US";
}
else if (gameLanguage == GameLanguage::French)
{
return "fr-FR";
}
else if (gameLanguage == GameLanguage::Italian)
{
return "it-IT";
}
else if (gameLanguage == GameLanguage::German)
{
return "de-DE";
}
else if (gameLanguage == GameLanguage::Spanish)
{
return "es-ES";
}
else if (gameLanguage == GameLanguage::Mexican)
{
return "es-MX";
}
else if (gameLanguage == GameLanguage::Brasilian)
{
return "pt-BR";
}
else if (gameLanguage == GameLanguage::Russian)
{
return "ru-RU";
}
else if (gameLanguage == GameLanguage::Polish)
{
return "pl-PL";
}
else if (gameLanguage == GameLanguage::Japanese)
{
return "ja-JP";
}
else if (gameLanguage == GameLanguage::SChinese)
{
return "zh-CHS";
}
else if (gameLanguage == GameLanguage::TChinese)
{
return "zh-CHT";
}
else if (gameLanguage == GameLanguage::Koreana)
{
return "ko-KR";
}
else
{
return "Undefinied";
}
}
bool AppEnv::setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage)
{
bool socialClubVersion = false;
bool steamVersion = false;
if (gameVersion == GameVersion::SocialClubVersion)
{
socialClubVersion = true;
}
else if (gameVersion == GameVersion::SteamVersion)
{
steamVersion = true;
}
else if (gameVersion == GameVersion::BothVersions)
{
socialClubVersion = true;
steamVersion = true;
}
else
{
return false;
}
if (socialClubVersion)
{
#ifdef GTA5SYNC_WIN
QString argumentValue;
#ifdef _WIN64
argumentValue = "\\WOW6432Node";
#endif
QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat);
if (gameLanguage != GameLanguage::Undefined)
{
registrySettingsSc.setValue("Language", gameLanguageToString(gameLanguage));
}
else
{
registrySettingsSc.remove("Language");
}
registrySettingsSc.sync();
if (registrySettingsSc.status() != QSettings::NoError)
{
return false;
}
#else
Q_UNUSED(gameLanguage)
#endif
}
if (steamVersion)
{
#ifdef GTA5SYNC_WIN
QString argumentValue;
#ifdef _WIN64
argumentValue = "\\WOW6432Node";
#endif
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V Steam").arg(argumentValue), QSettings::NativeFormat);
if (gameLanguage != GameLanguage::Undefined)
{
registrySettingsSteam.setValue("Language", gameLanguageToString(gameLanguage));
}
else
{
registrySettingsSteam.remove("Language");
}
registrySettingsSteam.sync();
if (registrySettingsSteam.status() != QSettings::NoError)
{
return false;
}
#else
Q_UNUSED(gameLanguage)
#endif
}
return true;
}
// Screen Stuff
qreal AppEnv::screenRatio() qreal AppEnv::screenRatio()
{ {
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
@ -188,3 +509,12 @@ qreal AppEnv::screenRatio()
return (dpi / 96); return (dpi / 96);
#endif #endif
} }
qreal AppEnv::screenRatioPR()
{
#if QT_VERSION >= 0x050600
return QGuiApplication::primaryScreen()->devicePixelRatio();
#else
return 1;
#endif
}

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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
@ -22,6 +22,9 @@
#include <QString> #include <QString>
#include <QUrl> #include <QUrl>
enum class GameVersion : int { NoVersion = 0, SocialClubVersion = 1, SteamVersion = 2, BothVersions = 3 };
enum class GameLanguage : int { Undefined = 0, English = 1, French = 2, Italian = 3, German = 4, Spanish = 5, Mexican = 6, Brasilian = 7, Russian = 8, Polish = 9, Japanese = 10, SChinese = 11, TChinese = 12, Koreana = 13 };
class AppEnv class AppEnv
{ {
public: public:
@ -44,8 +47,16 @@ public:
static QUrl getPlayerFetchingUrl(QString crewID, QString pageNumber); static QUrl getPlayerFetchingUrl(QString crewID, QString pageNumber);
static QUrl getPlayerFetchingUrl(QString crewID, int pageNumber); static QUrl getPlayerFetchingUrl(QString crewID, int pageNumber);
// Game Stuff
static GameVersion getGameVersion();
static GameLanguage getGameLanguage(GameVersion gameVersion);
static GameLanguage gameLanguageFromString(QString gameLanguage);
static QString gameLanguageToString(GameLanguage gameLanguage);
static bool setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage);
// Screen Stuff // Screen Stuff
static qreal screenRatio(); static qreal screenRatio();
static qreal screenRatioPR();
}; };
#endif // APPENV_H #endif // APPENV_H

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -44,79 +44,10 @@ void DatabaseThread::run()
{ {
QEventLoop threadLoop; QEventLoop threadLoop;
QStringList crewList;
QStringList crewListR;
// Register thread loop end signal
QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit())); QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit()));
// Setup crewList for Quick time scan
crewList = crewDB->getCrews();
if (!crewList.isEmpty())
{
crewListR = deleteCompatibleCrews(crewList);
}
else
{
while (crewList.isEmpty() && threadRunning)
{
QTimer::singleShot(1000, &threadLoop, SLOT(quit()));
threadLoop.exec();
if (!crewDB->isAddingCrews())
{
crewList = crewDB->getCrews();
}
}
if (threadRunning)
{
crewListR = deleteCompatibleCrews(crewList);
}
}
// Only do QTS when Thread should be run
if (threadRunning)
{
// Quick time scan
#ifdef GTA5SYNC_DEBUG
qDebug() << "Start QTS";
#endif
if (crewListR.length() <= 5)
{
scanCrewReference(crewListR, 2500);
emit crewNameUpdated();
}
if (crewList.length() <= 3)
{
scanCrewMembersList(crewList, 3, 2500);
emit playerNameUpdated();
}
else if (crewList.length() <= 5)
{
scanCrewMembersList(crewList, 2, 2500);
emit playerNameUpdated();
}
if (threadRunning)
{
QTimer::singleShot(10000, &threadLoop, SLOT(quit()));
threadLoop.exec();
}
}
while (threadRunning) while (threadRunning)
{ {
crewList = crewDB->getCrews();
crewListR = deleteCompatibleCrews(crewList);
// Long time scan
#ifdef GTA5SYNC_DEBUG
qDebug() << "Start LTS";
#endif
scanCrewReference(crewListR, 10000);
emit crewNameUpdated();
scanCrewMembersList(crewList, crewMaxPages, 10000);
emit playerNameUpdated();
if (threadRunning) if (threadRunning)
{ {
QTimer::singleShot(300000, &threadLoop, SLOT(quit())); QTimer::singleShot(300000, &threadLoop, SLOT(quit()));
@ -137,8 +68,9 @@ void DatabaseThread::scanCrewReference(const QStringList &crewList, const int &r
netRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); netRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
#endif #endif
netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent()); netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent());
netRequest.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); netRequest.setRawHeader("Accept", "text/html");
netRequest.setRawHeader("Accept-Language", "en-US;q=0.5,en;q=0.3"); netRequest.setRawHeader("Accept-Charset", "utf-8");
netRequest.setRawHeader("Accept-Language", "en-US,en;q=0.9");
netRequest.setRawHeader("Connection", "keep-alive"); netRequest.setRawHeader("Connection", "keep-alive");
QNetworkReply *netReply = netManager->get(netRequest); QNetworkReply *netReply = netManager->get(netRequest);
@ -169,6 +101,10 @@ void DatabaseThread::scanCrewReference(const QStringList &crewList, const int &r
emit crewNameFound(crewID.toInt(), crewName); emit crewNameFound(crewID.toInt(), crewName);
} }
} }
else
{
netReply->abort();
}
if (threadRunning) if (threadRunning)
{ {
@ -205,8 +141,9 @@ void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int
netRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); netRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
#endif #endif
netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent()); netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent());
netRequest.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); netRequest.setRawHeader("Accept", "application/json");
netRequest.setRawHeader("Accept-Language", "en-US;q=0.5,en;q=0.3"); netRequest.setRawHeader("Accept-Charset", "utf-8");
netRequest.setRawHeader("Accept-Language", "en-US,en;q=0.9");
netRequest.setRawHeader("Connection", "keep-alive"); netRequest.setRawHeader("Connection", "keep-alive");
QNetworkReply *netReply = netManager->get(netRequest); QNetworkReply *netReply = netManager->get(netRequest);

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2017-2018 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
@ -37,6 +37,7 @@ ImageEditorDialog::ImageEditorDialog(SnapmaticPicture *picture, QString profileN
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
ui->setupUi(this); ui->setupUi(this);
ui->cmdClose->setDefault(true);
ui->cmdClose->setFocus(); ui->cmdClose->setFocus();
// Set Icon for Close Button // Set Icon for Close Button
@ -71,7 +72,6 @@ ImageEditorDialog::ImageEditorDialog(SnapmaticPicture *picture, QString profileN
snapmaticResolutionLW = 516 * screenRatio; // 430 snapmaticResolutionLW = 516 * screenRatio; // 430
snapmaticResolutionLH = 288 * screenRatio; // 240 snapmaticResolutionLH = 288 * screenRatio; // 240
ui->labPicture->setMinimumSize(snapmaticResolutionLW, snapmaticResolutionLH); ui->labPicture->setMinimumSize(snapmaticResolutionLW, snapmaticResolutionLH);
ui->labCapacity->setText(tr("Capacity: %1").arg(QString::number(qRound((double)picture->getContentMaxLength() / 1024)) % " KB"));
imageIsChanged = false; imageIsChanged = false;
pictureCache = picture->getImage(); pictureCache = picture->getImage();
@ -151,7 +151,7 @@ fileDialogPreOpen: //Work?
delete importImage; delete importImage;
goto fileDialogPreOpen; goto fileDialogPreOpen;
} }
ImportDialog *importDialog = new ImportDialog(this); ImportDialog *importDialog = new ImportDialog(profileName, this);
importDialog->setImage(importImage); importDialog->setImage(importImage);
importDialog->setModal(true); importDialog->setModal(true);
importDialog->show(); importDialog->show();
@ -203,9 +203,3 @@ void ImageEditorDialog::on_cmdSave_clicked()
} }
close(); close();
} }
void ImageEditorDialog::on_cmdQuestion_clicked()
{
QMessageBox::information(this, tr("Snapmatic Image Editor"), tr("Every taken Snapmatic have a different Capacity, a Snapmatic with higher Capacity can store a picture with better quality."));
}

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -38,7 +38,6 @@ private slots:
void on_cmdClose_clicked(); void on_cmdClose_clicked();
void on_cmdReplace_clicked(); void on_cmdReplace_clicked();
void on_cmdSave_clicked(); void on_cmdSave_clicked();
void on_cmdQuestion_clicked();
private: private:
SnapmaticPicture *smpic; SnapmaticPicture *smpic;

View file

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>516</width> <width>516</width>
<height>335</height> <height>337</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -51,41 +51,13 @@
<number>0</number> <number>0</number>
</property> </property>
<layout class="QVBoxLayout" name="vlButtons"> <layout class="QVBoxLayout" name="vlButtons">
<item>
<layout class="QHBoxLayout" name="hlCapacity">
<item>
<widget class="QLabel" name="labCapacity">
<property name="text">
<string>Capacity: %1</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="cmdQuestion">
<property name="text">
<string>?</string>
</property>
</widget>
</item>
<item>
<spacer name="hsCapacity">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="hlButtons"> <layout class="QHBoxLayout" name="hlButtons">
<item> <item>
<widget class="QPushButton" name="cmdReplace"> <widget class="QPushButton" name="cmdReplace">
<property name="toolTip">
<string>Import picture</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Import...</string> <string>&amp;Import...</string>
</property> </property>
@ -106,6 +78,9 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="cmdSave"> <widget class="QPushButton" name="cmdSave">
<property name="toolTip">
<string>Apply changes</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Overwrite</string> <string>&amp;Overwrite</string>
</property> </property>
@ -113,6 +88,9 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="cmdClose"> <widget class="QPushButton" name="cmdClose">
<property name="toolTip">
<string>Discard changes</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Close</string> <string>&amp;Close</string>
</property> </property>

View file

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2017-2018 Syping * Copyright (C) 2017-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
@ -20,9 +20,11 @@
#include "ui_ImportDialog.h" #include "ui_ImportDialog.h"
#include "SidebarGenerator.h" #include "SidebarGenerator.h"
#include "StandardPaths.h" #include "StandardPaths.h"
#include "imagecropper.h"
#include "AppEnv.h" #include "AppEnv.h"
#include "config.h" #include "config.h"
#include <QStringBuilder> #include <QStringBuilder>
#include <QInputDialog>
#include <QImageReader> #include <QImageReader>
#include <QColorDialog> #include <QColorDialog>
#include <QFileDialog> #include <QFileDialog>
@ -32,6 +34,7 @@
#include <QPixmap> #include <QPixmap>
#include <QImage> #include <QImage>
#include <QDebug> #include <QDebug>
#include <QStyle>
#include <QFile> #include <QFile>
#include <QRgb> #include <QRgb>
@ -42,15 +45,20 @@
#define snapmaticAvatarPlacementW 145 #define snapmaticAvatarPlacementW 145
#define snapmaticAvatarPlacementH 66 #define snapmaticAvatarPlacementH 66
ImportDialog::ImportDialog(QWidget *parent) : ImportDialog::ImportDialog(QString profileName, QWidget *parent) :
QDialog(parent), QDialog(parent), profileName(profileName),
ui(new Ui::ImportDialog) ui(new Ui::ImportDialog)
{ {
// Set Window Flags // Set Window Flags
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
ui->setupUi(this); ui->setupUi(this);
ui->cmdOK->setDefault(true);
ui->cmdOK->setFocus();
importAgreed = false; importAgreed = false;
settingsLocked = false;
watermarkAvatar = true;
watermarkPicture = false;
insideAvatarZone = false; insideAvatarZone = false;
avatarAreaImage = QImage(":/img/avatarareaimport.png"); avatarAreaImage = QImage(":/img/avatarareaimport.png");
selectedColour = QColor::fromRgb(0, 0, 0, 255); selectedColour = QColor::fromRgb(0, 0, 0, 255);
@ -80,6 +88,13 @@ ImportDialog::ImportDialog(QWidget *parent) :
ui->labBackgroundImage->setText(tr("Background Image:")); ui->labBackgroundImage->setText(tr("Background Image:"));
ui->cmdBackgroundWipe->setVisible(false); ui->cmdBackgroundWipe->setVisible(false);
// Set Import Settings
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
settings.beginGroup("Import");
QString currentProfile = settings.value("Profile", "Default").toString();
settings.endGroup();
processSettings(currentProfile);
// DPI calculation // DPI calculation
qreal screenRatio = AppEnv::screenRatio(); qreal screenRatio = AppEnv::screenRatio();
snapmaticResolutionLW = 516 * screenRatio; // 430 snapmaticResolutionLW = 516 * screenRatio; // 430
@ -100,6 +115,15 @@ ImportDialog::ImportDialog(QWidget *parent) :
} }
#endif #endif
// Options menu
optionsMenu = new QMenu(this);
optionsMenu->addAction(tr("&Import new Picture..."), this, SLOT(importNewPicture()));
optionsMenu->addAction(tr("&Crop Picture..."), this, SLOT(cropPicture()));
optionsMenu->addSeparator();
optionsMenu->addAction(tr("&Load Settings..."), this, SLOT(loadImportSettings()));
optionsMenu->addAction(tr("&Save Settings..."), this, SLOT(saveImportSettings()));
ui->cmdOptions->setMenu(optionsMenu);
setMaximumSize(sizeHint()); setMaximumSize(sizeHint());
setMinimumSize(sizeHint()); setMinimumSize(sizeHint());
setFixedSize(sizeHint()); setFixedSize(sizeHint());
@ -107,6 +131,7 @@ ImportDialog::ImportDialog(QWidget *parent) :
ImportDialog::~ImportDialog() ImportDialog::~ImportDialog()
{ {
delete optionsMenu;
delete ui; delete ui;
} }
@ -117,6 +142,7 @@ void ImportDialog::processImage()
QPixmap snapmaticPixmap(snapmaticResolutionW, snapmaticResolutionH); QPixmap snapmaticPixmap(snapmaticResolutionW, snapmaticResolutionH);
snapmaticPixmap.fill(selectedColour); snapmaticPixmap.fill(selectedColour);
QPainter snapmaticPainter(&snapmaticPixmap); QPainter snapmaticPainter(&snapmaticPixmap);
qreal screenRatioPR = AppEnv::screenRatioPR();
if (!backImage.isNull()) if (!backImage.isNull())
{ {
if (!ui->cbStretch->isChecked()) if (!ui->cbStretch->isChecked())
@ -168,6 +194,7 @@ void ImportDialog::processImage()
snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 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()) { processWatermark(&snapmaticPainter); }
imageTitle = tr("Custom Avatar", "Custom Avatar Description in SC, don't use Special Character!"); imageTitle = tr("Custom Avatar", "Custom Avatar Description in SC, don't use Special Character!");
} }
else else
@ -194,11 +221,351 @@ void ImportDialog::processImage()
snapmaticImage = snapmaticImage.scaled(snapmaticResolutionW, snapmaticResolutionH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); snapmaticImage = snapmaticImage.scaled(snapmaticResolutionW, snapmaticResolutionH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
} }
snapmaticPainter.drawImage(0 + diffWidth, 0 + diffHeight, snapmaticImage); snapmaticPainter.drawImage(0 + diffWidth, 0 + diffHeight, snapmaticImage);
if (ui->cbWatermark->isChecked()) { processWatermark(&snapmaticPainter); }
imageTitle = tr("Custom Picture", "Custom Picture Description in SC, don't use Special Character!"); imageTitle = tr("Custom Picture", "Custom Picture Description in SC, don't use Special Character!");
} }
snapmaticPainter.end(); snapmaticPainter.end();
newImage = snapmaticPixmap.toImage(); newImage = snapmaticPixmap.toImage();
ui->labPicture->setPixmap(snapmaticPixmap.scaled(snapmaticResolutionLW, snapmaticResolutionLH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); #if QT_VERSION >= 0x050600
snapmaticPixmap.setDevicePixelRatio(screenRatioPR);
#endif
ui->labPicture->setPixmap(snapmaticPixmap.scaled(snapmaticResolutionLW * screenRatioPR, snapmaticResolutionLH * screenRatioPR, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}
void ImportDialog::processWatermark(QPainter *snapmaticPainter)
{
bool blackWatermark = false;
bool redWatermark = false;
if (selectedColour.red() > 127)
{
if (selectedColour.green() > 127 || selectedColour.blue() > 127)
{
redWatermark = true;
}
}
else
{
redWatermark = true;
}
if (selectedColour.lightness() > 127)
{
blackWatermark = true;
}
// draw watermark
if (redWatermark)
{
snapmaticPainter->drawImage(0, 0, QImage(":/img/watermark_2r.png"));
}
else
{
QImage viewWatermark = QImage(":/img/watermark_2b.png");
if (!blackWatermark)
{
viewWatermark.invertPixels(QImage::InvertRgb);
}
snapmaticPainter->drawImage(0, 0, viewWatermark);
}
QImage textWatermark = QImage(":/img/watermark_1b.png");
if (!blackWatermark)
{
textWatermark.invertPixels(QImage::InvertRgb);
}
snapmaticPainter->drawImage(0, 0, textWatermark);
}
void ImportDialog::processSettings(QString settingsProfile, bool setDefault)
{
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
settings.beginGroup("Import");
if (setDefault)
{
settings.setValue("Profile", settingsProfile);
}
if (settingsProfile == "Default")
{
watermarkAvatar = true;
watermarkPicture = false;
selectedColour = QColor::fromRgb(0, 0, 0, 255);
backImage = QImage();
ui->cbStretch->setChecked(false);
ui->cbForceAvatarColour->setChecked(false);
}
else
{
settings.beginGroup(settingsProfile);
watermarkAvatar = settings.value("WatermarkAvatar", true).toBool();
watermarkPicture = settings.value("WatermarkPicture", false).toBool();
backImage = qvariant_cast<QImage>(settings.value("BackgroundImage", QImage()));
selectedColour = qvariant_cast<QColor>(settings.value("SelectedColour", QColor::fromRgb(0, 0, 0, 255)));
ui->cbStretch->setChecked(settings.value("BackgroundStretch", false).toBool());
ui->cbForceAvatarColour->setChecked(settings.value("ForceAvatarColour", false).toBool());
settings.endGroup();
}
if (!workImage.isNull())
{
if (ui->cbAvatar->isChecked())
{
ui->cbWatermark->setChecked(watermarkAvatar);
}
else
{
ui->cbWatermark->setChecked(watermarkPicture);
}
}
ui->labColour->setText(tr("Background Colour: <span style=\"color: %1\">%1</span>").arg(selectedColour.name()));
if (!backImage.isNull())
{
ui->labBackgroundImage->setText(tr("Background Image: %1").arg(tr("Storage", "Background Image: Storage")));
ui->cmdBackgroundWipe->setVisible(true);
}
else
{
ui->labBackgroundImage->setText(tr("Background Image:"));
ui->cmdBackgroundWipe->setVisible(false);
}
settings.endGroup();
}
void ImportDialog::saveSettings(QString settingsProfile)
{
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
settings.beginGroup("Import");
settings.beginGroup(settingsProfile);
settings.setValue("WatermarkAvatar", watermarkAvatar);
settings.setValue("WatermarkPicture", watermarkPicture);
settings.setValue("BackgroundImage", backImage);
settings.setValue("SelectedColour", selectedColour);
settings.setValue("BackgroundStretch", ui->cbStretch->isChecked());
settings.setValue("ForceAvatarColour", ui->cbForceAvatarColour->isChecked());
settings.endGroup();
settings.setValue("Profile", settingsProfile);
settings.endGroup();
}
void ImportDialog::cropPicture()
{
qreal screenRatio = AppEnv::screenRatio();
QDialog cropDialog(this);
#if QT_VERSION >= 0x050000
cropDialog.setObjectName(QStringLiteral("CropDialog"));
#else
cropDialog.setObjectName(QString::fromUtf8("CropDialog"));
#endif
cropDialog.setWindowTitle(tr("Crop Picture..."));
cropDialog.setWindowFlags(cropDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
cropDialog.setModal(true);
QVBoxLayout cropLayout;
#if QT_VERSION >= 0x050000
cropLayout.setObjectName(QStringLiteral("CropLayout"));
#else
cropLayout.setObjectName(QString::fromUtf8("CropLayout"));
#endif
cropLayout.setContentsMargins(0, 0, 0, 0);
cropLayout.setSpacing(0);
cropDialog.setLayout(&cropLayout);
ImageCropper imageCropper(&cropDialog);
#if QT_VERSION >= 0x050000
imageCropper.setObjectName(QStringLiteral("ImageCropper"));
#else
imageCropper.setObjectName(QString::fromUtf8("ImageCropper"));
#endif
imageCropper.setBackgroundColor(Qt::black);
imageCropper.setCroppingRectBorderColor(QColor(255, 255, 255, 127));
imageCropper.setImage(QPixmap::fromImage(workImage, Qt::AutoColor));
imageCropper.setProportion(QSize(1, 1));
imageCropper.setFixedSize(workImage.size());
cropLayout.addWidget(&imageCropper);
QHBoxLayout buttonLayout;
#if QT_VERSION >= 0x050000
cropLayout.setObjectName(QStringLiteral("ButtonLayout"));
#else
cropLayout.setObjectName(QString::fromUtf8("ButtonLayout"));
#endif
cropLayout.addLayout(&buttonLayout);
QPushButton cropButton(&cropDialog);
#if QT_VERSION >= 0x050000
cropButton.setObjectName(QStringLiteral("CropButton"));
#else
cropButton.setObjectName(QString::fromUtf8("CropButton"));
#endif
cropButton.setMinimumSize(0, 40 * screenRatio);
cropButton.setText(tr("&Crop"));
cropButton.setToolTip(tr("Crop Picture"));
QObject::connect(&cropButton, SIGNAL(clicked(bool)), &cropDialog, SLOT(accept()));
buttonLayout.addWidget(&cropButton);
cropDialog.show();
cropDialog.setFixedSize(cropDialog.sizeHint());
if (cropDialog.exec() == QDialog::Accepted)
{
QImage *croppedImage = new QImage(imageCropper.cropImage().toImage());
setImage(croppedImage);
}
}
void ImportDialog::importNewPicture()
{
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
settings.beginGroup("FileDialogs");
bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool();
settings.beginGroup("ImportCopy");
fileDialogPreOpen: //Work?
QFileDialog fileDialog(this);
fileDialog.setFileMode(QFileDialog::ExistingFile);
fileDialog.setViewMode(QFileDialog::Detail);
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
fileDialog.setWindowTitle(QApplication::translate("ProfileInterface", "Import..."));
fileDialog.setLabelText(QFileDialog::Accept, QApplication::translate("ProfileInterface", "Import"));
// Getting readable Image formats
QString imageFormatsStr = " ";
for (QByteArray imageFormat : QImageReader::supportedImageFormats())
{
imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " ";
}
QStringList filters;
filters << QApplication::translate("ProfileInterface", "All image files (%1)").arg(imageFormatsStr.trimmed());
filters << QApplication::translate("ProfileInterface", "All files (**)");
fileDialog.setNameFilters(filters);
QList<QUrl> sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls());
fileDialog.setSidebarUrls(sidebarUrls);
fileDialog.setDirectory(settings.value(profileName % "+Directory", StandardPaths::documentsLocation()).toString());
fileDialog.restoreGeometry(settings.value(profileName % "+Geometry", "").toByteArray());
if (fileDialog.exec())
{
QStringList selectedFiles = fileDialog.selectedFiles();
if (selectedFiles.length() == 1)
{
QString selectedFile = selectedFiles.at(0);
QString selectedFileName = QFileInfo(selectedFile).fileName();
QFile snapmaticFile(selectedFile);
if (!snapmaticFile.open(QFile::ReadOnly))
{
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be open").arg("\""+selectedFileName+"\""));
goto fileDialogPreOpen;
}
QImage *importImage = new QImage();
QImageReader snapmaticImageReader;
snapmaticImageReader.setDecideFormatFromContent(true);
snapmaticImageReader.setDevice(&snapmaticFile);
if (!snapmaticImageReader.read(importImage))
{
QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\""));
delete importImage;
goto fileDialogPreOpen;
}
setImage(importImage);
}
}
settings.setValue(profileName % "+Geometry", fileDialog.saveGeometry());
settings.setValue(profileName % "+Directory", fileDialog.directory().absolutePath());
settings.endGroup();
settings.endGroup();
}
void ImportDialog::loadImportSettings()
{
if (settingsLocked)
{
QMessageBox::information(this, tr("Load Settings..."), tr("Please import a new picture first"));
return;
}
bool ok;
QStringList profileList;
profileList << tr("Default", "Default as Default Profile")
<< tr("Profile %1", "Profile %1 as Profile 1").arg("1")
<< tr("Profile %1", "Profile %1 as Profile 1").arg("2")
<< tr("Profile %1", "Profile %1 as Profile 1").arg("3")
<< tr("Profile %1", "Profile %1 as Profile 1").arg("4")
<< tr("Profile %1", "Profile %1 as Profile 1").arg("5");
QString sProfile = QInputDialog::getItem(this, tr("Load Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags());
if (ok)
{
QString pProfile;
if (sProfile == tr("Default", "Default as Default Profile"))
{
pProfile = "Default";
}
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1"))
{
pProfile = "Profile 1";
}
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2"))
{
pProfile = "Profile 2";
}
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3"))
{
pProfile = "Profile 3";
}
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4"))
{
pProfile = "Profile 4";
}
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5"))
{
pProfile = "Profile 5";
}
processSettings(pProfile, true);
processImage();
}
}
void ImportDialog::saveImportSettings()
{
if (settingsLocked)
{
QMessageBox::information(this, tr("Save Settings..."), tr("Please import a new picture first"));
return;
}
bool ok;
QStringList profileList;
profileList << tr("Profile %1", "Profile %1 as Profile 1").arg("1")
<< tr("Profile %1", "Profile %1 as Profile 1").arg("2")
<< tr("Profile %1", "Profile %1 as Profile 1").arg("3")
<< tr("Profile %1", "Profile %1 as Profile 1").arg("4")
<< tr("Profile %1", "Profile %1 as Profile 1").arg("5");
QString sProfile = QInputDialog::getItem(this, tr("Save Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags());
if (ok)
{
QString pProfile;
if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1"))
{
pProfile = "Profile 1";
}
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2"))
{
pProfile = "Profile 2";
}
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3"))
{
pProfile = "Profile 3";
}
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4"))
{
pProfile = "Profile 4";
}
else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5"))
{
pProfile = "Profile 5";
}
saveSettings(pProfile);
}
} }
QImage ImportDialog::image() QImage ImportDialog::image()
@ -226,20 +593,57 @@ void ImportDialog::setImage(QImage *image_)
} }
else if (image_->width() > snapmaticResolutionW && image_->width() > image_->height()) else if (image_->width() > snapmaticResolutionW && image_->width() > image_->height())
{ {
insideAvatarZone = false;
ui->cbAvatar->setChecked(false);
workImage = image_->scaledToWidth(snapmaticResolutionW, Qt::SmoothTransformation); workImage = image_->scaledToWidth(snapmaticResolutionW, Qt::SmoothTransformation);
delete image_; delete image_;
} }
else if (image_->height() > snapmaticResolutionH && image_->height() > image_->width()) else if (image_->height() > snapmaticResolutionH && image_->height() > image_->width())
{ {
insideAvatarZone = false;
ui->cbAvatar->setChecked(false);
workImage = image_->scaledToHeight(snapmaticResolutionH, Qt::SmoothTransformation); workImage = image_->scaledToHeight(snapmaticResolutionH, Qt::SmoothTransformation);
delete image_; delete image_;
} }
else else
{ {
insideAvatarZone = false;
ui->cbAvatar->setChecked(false);
workImage = *image_; workImage = *image_;
delete image_; delete image_;
} }
processImage(); processImage();
lockSettings(false);
}
void ImportDialog::lockSettings(bool lock)
{
ui->cbAvatar->setDisabled(lock);
ui->cbForceAvatarColour->setDisabled(lock);
ui->cbIgnore->setDisabled(lock);
ui->cbStretch->setDisabled(lock);
ui->cbWatermark->setDisabled(lock);
ui->cmdBackgroundChange->setDisabled(lock);
ui->cmdBackgroundWipe->setDisabled(lock);
ui->cmdColourChange->setDisabled(lock);
ui->labBackgroundImage->setDisabled(lock);
ui->labColour->setDisabled(lock);
ui->gbSettings->setDisabled(lock);
ui->gbBackground->setDisabled(lock);
ui->cmdOK->setDisabled(lock);
settingsLocked = lock;
}
void ImportDialog::enableOverwriteMode()
{
setWindowTitle(QApplication::translate("ImageEditorDialog", "Overwrite Image..."));
ui->cmdOK->setText(QApplication::translate("ImageEditorDialog", "&Overwrite"));
ui->cmdOK->setToolTip(QApplication::translate("ImageEditorDialog", "Apply changes"));
ui->cmdCancel->setText(QApplication::translate("ImageEditorDialog", "&Close"));
ui->cmdCancel->setToolTip(QApplication::translate("ImageEditorDialog", "Discard changes"));
ui->cmdCancel->setDefault(true);
ui->cmdCancel->setFocus();
lockSettings(true);
} }
bool ImportDialog::isImportAgreed() bool ImportDialog::isImportAgreed()
@ -247,6 +651,11 @@ bool ImportDialog::isImportAgreed()
return importAgreed; return importAgreed;
} }
bool ImportDialog::areSettingsLocked()
{
return settingsLocked;
}
QString ImportDialog::getImageTitle() QString ImportDialog::getImageTitle()
{ {
return imageTitle; return imageTitle;
@ -260,7 +669,7 @@ void ImportDialog::on_cbIgnore_toggled(bool checked)
void ImportDialog::on_cbAvatar_toggled(bool checked) void ImportDialog::on_cbAvatar_toggled(bool checked)
{ {
if (workImage.width() == workImage.height() && !checked) if (!workImage.isNull() && workImage.width() == workImage.height() && !checked)
{ {
if (QMessageBox::No == QMessageBox::warning(this, tr("Snapmatic Avatar Zone"), tr("Are you sure to use a square image outside of the Avatar Zone?\nWhen you want to use it as Avatar the image will be detached!"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) if (QMessageBox::No == QMessageBox::warning(this, tr("Snapmatic Avatar Zone"), tr("Are you sure to use a square image outside of the Avatar Zone?\nWhen you want to use it as Avatar the image will be detached!"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No))
{ {
@ -270,6 +679,16 @@ void ImportDialog::on_cbAvatar_toggled(bool checked)
} }
} }
insideAvatarZone = ui->cbAvatar->isChecked(); insideAvatarZone = ui->cbAvatar->isChecked();
watermarkBlock = true;
if (insideAvatarZone)
{
ui->cbWatermark->setChecked(watermarkAvatar);
}
else
{
ui->cbWatermark->setChecked(watermarkPicture);
}
watermarkBlock = false;
processImage(); processImage();
} }
@ -401,3 +820,19 @@ void ImportDialog::on_cbForceAvatarColour_toggled(bool checked)
Q_UNUSED(checked) Q_UNUSED(checked)
processImage(); processImage();
} }
void ImportDialog::on_cbWatermark_toggled(bool checked)
{
if (!watermarkBlock)
{
if (insideAvatarZone)
{
watermarkAvatar = checked;
}
else
{
watermarkPicture = checked;
}
processImage();
}
}

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2017 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
@ -20,6 +20,7 @@
#define IMPORTDIALOG_H #define IMPORTDIALOG_H
#include <QDialog> #include <QDialog>
#include <QMenu>
namespace Ui { namespace Ui {
class ImportDialog; class ImportDialog;
@ -30,15 +31,22 @@ class ImportDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit ImportDialog(QWidget *parent = 0); explicit ImportDialog(QString profileName, QWidget *parent = 0);
~ImportDialog(); ~ImportDialog();
QImage image(); QImage image();
QString getImageTitle(); QString getImageTitle();
void setImage(QImage *image); void setImage(QImage *image);
void lockSettings(bool lock);
void enableOverwriteMode();
bool isImportAgreed(); bool isImportAgreed();
bool areSettingsLocked();
private slots: private slots:
void processImage(); void processImage();
void cropPicture();
void importNewPicture();
void loadImportSettings();
void saveImportSettings();
void on_cbIgnore_toggled(bool checked); void on_cbIgnore_toggled(bool checked);
void on_cbAvatar_toggled(bool checked); void on_cbAvatar_toggled(bool checked);
void on_cmdCancel_clicked(); void on_cmdCancel_clicked();
@ -49,8 +57,10 @@ private slots:
void on_cmdBackgroundWipe_clicked(); void on_cmdBackgroundWipe_clicked();
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);
private: private:
QString profileName;
Ui::ImportDialog *ui; Ui::ImportDialog *ui;
QImage avatarAreaImage; QImage avatarAreaImage;
QString backgroundPath; QString backgroundPath;
@ -59,10 +69,18 @@ private:
QImage workImage; QImage workImage;
QImage newImage; QImage newImage;
QColor selectedColour; QColor selectedColour;
QMenu *optionsMenu;
bool insideAvatarZone; bool insideAvatarZone;
bool watermarkPicture;
bool watermarkAvatar;
bool watermarkBlock;
bool settingsLocked;
bool importAgreed; bool importAgreed;
int snapmaticResolutionLW; int snapmaticResolutionLW;
int snapmaticResolutionLH; int snapmaticResolutionLH;
void processWatermark(QPainter *snapmaticPainter);
void processSettings(QString settingsProfile, bool setDefault = false);
void saveSettings(QString settingsProfile);
}; };
#endif // IMPORTDIALOG_H #endif // IMPORTDIALOG_H

View file

@ -7,13 +7,13 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>516</width> <width>516</width>
<height>425</height> <height>512</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>516</width> <width>516</width>
<height>425</height> <height>512</height>
</size> </size>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -85,7 +85,7 @@
</property> </property>
<layout class="QVBoxLayout" name="vlSettings"> <layout class="QVBoxLayout" name="vlSettings">
<item> <item>
<layout class="QHBoxLayout" name="hlCheckboxes"> <layout class="QHBoxLayout" name="hlCheckboxesTop">
<item> <item>
<widget class="QCheckBox" name="cbAvatar"> <widget class="QCheckBox" name="cbAvatar">
<property name="sizePolicy"> <property name="sizePolicy">
@ -114,6 +114,23 @@
</item> </item>
</layout> </layout>
</item> </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">
<string>Watermark</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -124,7 +141,7 @@
</property> </property>
<layout class="QVBoxLayout" name="vlBackground"> <layout class="QVBoxLayout" name="vlBackground">
<item> <item>
<layout class="QHBoxLayout" name="hlColor"> <layout class="QHBoxLayout" name="hlColour">
<item> <item>
<layout class="QHBoxLayout" name="hlColourManage"> <layout class="QHBoxLayout" name="hlColourManage">
<item> <item>
@ -153,6 +170,9 @@
</property> </property>
<item> <item>
<widget class="QToolButton" name="cmdColourChange"> <widget class="QToolButton" name="cmdColourChange">
<property name="toolTip">
<string>Select background colour</string>
</property>
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
@ -203,6 +223,9 @@
</property> </property>
<item> <item>
<widget class="QToolButton" name="cmdBackgroundChange"> <widget class="QToolButton" name="cmdBackgroundChange">
<property name="toolTip">
<string>Select background image</string>
</property>
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
@ -210,6 +233,9 @@
</item> </item>
<item> <item>
<widget class="QToolButton" name="cmdBackgroundWipe"> <widget class="QToolButton" name="cmdBackgroundWipe">
<property name="toolTip">
<string>Remove background image</string>
</property>
<property name="text"> <property name="text">
<string>X</string> <string>X</string>
</property> </property>
@ -273,6 +299,19 @@
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="hlButtons"> <layout class="QHBoxLayout" name="hlButtons">
<item>
<widget class="QPushButton" name="cmdOptions">
<property name="toolTip">
<string>Import options</string>
</property>
<property name="text">
<string>&amp;Options</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item> <item>
<spacer name="hsButtons"> <spacer name="hsButtons">
<property name="orientation"> <property name="orientation">

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2017-2018 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
@ -20,8 +20,10 @@
#include "ui_JsonEditorDialog.h" #include "ui_JsonEditorDialog.h"
#include "SnapmaticEditor.h" #include "SnapmaticEditor.h"
#include "AppEnv.h" #include "AppEnv.h"
#include "config.h"
#include <QStringBuilder> #include <QStringBuilder>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox> #include <QMessageBox>
#if QT_VERSION >= 0x050200 #if QT_VERSION >= 0x050200
@ -29,6 +31,10 @@
#include <QDebug> #include <QDebug>
#endif #endif
#ifdef GTA5SYNC_TELEMETRY
#include "TelemetryClass.h"
#endif
JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) : JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) :
QDialog(parent), smpic(picture), QDialog(parent), smpic(picture),
ui(new Ui::JsonEditorDialog) ui(new Ui::JsonEditorDialog)
@ -37,6 +43,7 @@ JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) :
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowMinMaxButtonsHint); setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowMinMaxButtonsHint);
ui->setupUi(this); ui->setupUi(this);
ui->cmdClose->setDefault(true);
ui->cmdClose->setFocus(); ui->cmdClose->setFocus();
// Set Icon for Close Button // Set Icon for Close Button
@ -87,6 +94,7 @@ JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) :
{ {
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));
} }
resize(450 * screenRatio, 550 * screenRatio); resize(450 * screenRatio, 550 * screenRatio);
} }
@ -182,7 +190,24 @@ bool JsonEditorDialog::saveJsonContent()
return false; return false;
} }
jsonCode = newCode; jsonCode = newCode;
smpic->updateStrings();
smpic->emitUpdate(); smpic->emitUpdate();
#ifdef GTA5SYNC_TELEMETRY
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "JSONEdited";
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
#endif
return true; return true;
} }
return true; return true;
@ -196,13 +221,13 @@ bool JsonEditorDialog::saveJsonContent()
void JsonEditorDialog::on_cmdClose_clicked() void JsonEditorDialog::on_cmdClose_clicked()
{ {
this->close(); close();
} }
void JsonEditorDialog::on_cmdSave_clicked() void JsonEditorDialog::on_cmdSave_clicked()
{ {
if (saveJsonContent()) if (saveJsonContent())
{ {
this->close(); close();
} }
} }

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2017 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

View file

@ -112,6 +112,9 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip">
<string>Apply changes</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Save</string> <string>&amp;Save</string>
</property> </property>
@ -125,6 +128,9 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip">
<string>Discard changes</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Close</string> <string>&amp;Close</string>
</property> </property>

View file

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2017 Syping * Copyright (C) 2017-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
@ -22,6 +22,7 @@
#include "AppEnv.h" #include "AppEnv.h"
#include <QPainter> #include <QPainter>
#include <QDebug> #include <QDebug>
#include <QStyle>
MapLocationDialog::MapLocationDialog(double x, double y, QWidget *parent) : MapLocationDialog::MapLocationDialog(double x, double y, QWidget *parent) :
QDialog(parent), xpos_old(x), ypos_old(y), QDialog(parent), xpos_old(x), ypos_old(y),
@ -60,9 +61,10 @@ MapLocationDialog::~MapLocationDialog()
void MapLocationDialog::drawPointOnMap(double xpos_d, double ypos_d) void MapLocationDialog::drawPointOnMap(double xpos_d, double ypos_d)
{ {
qreal screenRatio = AppEnv::screenRatio(); qreal screenRatio = AppEnv::screenRatio();
int pointMakerSize = 8 * screenRatio; qreal screenRatioPR = AppEnv::screenRatioPR();
int pointMakerSize = 8 * screenRatio * screenRatioPR;
QPixmap pointMakerPixmap = IconLoader::loadingPointmakerIcon().pixmap(QSize(pointMakerSize, pointMakerSize)); QPixmap pointMakerPixmap = IconLoader::loadingPointmakerIcon().pixmap(QSize(pointMakerSize, pointMakerSize));
QSize mapPixelSize = size(); QSize mapPixelSize = QSize(width() * screenRatioPR, height() * screenRatioPR);
int pointMakerHalfSize = pointMakerSize / 2; int pointMakerHalfSize = pointMakerSize / 2;
long xpos_ms = qRound(xpos_d); long xpos_ms = qRound(xpos_d);
@ -81,6 +83,9 @@ void MapLocationDialog::drawPointOnMap(double xpos_d, double ypos_d)
mapPainter.drawPixmap(0, 0, mapPixelSize.width(), mapPixelSize.height(), QPixmap(":/img/mappreview.jpg").scaled(mapPixelSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); mapPainter.drawPixmap(0, 0, mapPixelSize.width(), mapPixelSize.height(), QPixmap(":/img/mappreview.jpg").scaled(mapPixelSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
mapPainter.drawPixmap(xpos_pr, mapPixelSize.height() - ypos_pr, pointMakerSize, pointMakerSize, pointMakerPixmap); mapPainter.drawPixmap(xpos_pr, mapPixelSize.height() - ypos_pr, pointMakerSize, pointMakerSize, pointMakerPixmap);
mapPainter.end(); mapPainter.end();
#if QT_VERSION >= 0x050600
mapPixmap.setDevicePixelRatio(screenRatioPR);
#endif
QPalette backgroundPalette; QPalette backgroundPalette;
backgroundPalette.setBrush(backgroundRole(), QBrush(mapPixmap)); backgroundPalette.setBrush(backgroundRole(), QBrush(mapPixmap));

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2017 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

View file

@ -134,6 +134,9 @@ color: rgb(255, 255, 255);
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip">
<string>Close viewer</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Close</string> <string>&amp;Close</string>
</property> </property>
@ -160,6 +163,9 @@ color: rgb(255, 255, 255);
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip">
<string>Apply new position</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Apply</string> <string>&amp;Apply</string>
</property> </property>
@ -173,6 +179,9 @@ color: rgb(255, 255, 255);
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip">
<string>Revert old position</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Revert</string> <string>&amp;Revert</string>
</property> </property>
@ -186,8 +195,11 @@ color: rgb(255, 255, 255);
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip">
<string>Select new position</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Set</string> <string>&amp;Select</string>
</property> </property>
<property name="autoDefault"> <property name="autoDefault">
<bool>false</bool> <bool>false</bool>
@ -199,6 +211,9 @@ color: rgb(255, 255, 255);
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip">
<string>Quit select position</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Done</string> <string>&amp;Done</string>
</property> </property>

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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
@ -55,6 +55,7 @@ OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) :
ui->setupUi(this); ui->setupUi(this);
ui->tabWidget->setCurrentIndex(0); ui->tabWidget->setCurrentIndex(0);
ui->labPicCustomRes->setVisible(false); ui->labPicCustomRes->setVisible(false);
ui->cmdCancel->setDefault(true);
ui->cmdCancel->setFocus(); ui->cmdCancel->setFocus();
QRect desktopResolution = QApplication::desktop()->screenGeometry(this); QRect desktopResolution = QApplication::desktop()->screenGeometry(this);
@ -102,6 +103,7 @@ OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) :
setupInterfaceSettings(); setupInterfaceSettings();
setupStatisticsSettings(); setupStatisticsSettings();
setupSnapmaticPictureViewer(); setupSnapmaticPictureViewer();
setupWindowsGameSettings();
#ifndef Q_QS_ANDROID #ifndef Q_QS_ANDROID
// DPI calculation // DPI calculation
@ -109,11 +111,7 @@ OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) :
resize(435 * screenRatio, 405 * screenRatio); resize(435 * screenRatio, 405 * screenRatio);
#endif #endif
#ifdef GTA5SYNC_DISABLED setWindowTitle(windowTitle().arg(GTA5SYNC_APPSTR));
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabSync));
#endif
this->setWindowTitle(windowTitle().arg(GTA5SYNC_APPSTR));
} }
OptionsDialog::~OptionsDialog() OptionsDialog::~OptionsDialog()
@ -153,9 +151,21 @@ void OptionsDialog::setupLanguageBox()
currentAreaLanguage = settings->value("AreaLanguage", "Auto").toString(); currentAreaLanguage = settings->value("AreaLanguage", "Auto").toString();
settings->endGroup(); settings->endGroup();
QString cbSysStr = tr("%1 (Next Closest Language)", "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 GTA5SYNC_WIN
QString cbAutoStr;
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."));
}
else
{
cbAutoStr = tr("%1 (Closest to Interface)", "Next closest language compared to the Interface").arg(tr("Auto", "Automatic language choice."));
}
#else
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
ui->cbLanguage->addItem(cbSysStr, "System"); ui->cbLanguage->addItem(cbSysStr, "System");
ui->cbAreaLanguage->addItem(cbAutoStr, "Auto"); ui->cbAreaLanguage->addItem(cbAutoStr, "Auto");
@ -410,10 +420,20 @@ void OptionsDialog::applySettings()
#ifdef GTA5SYNC_TELEMETRY #ifdef GTA5SYNC_TELEMETRY
settings->beginGroup("Telemetry"); settings->beginGroup("Telemetry");
settings->setValue("PushAppConf", ui->cbAppConfigStats->isChecked()); settings->setValue("PushAppConf", ui->cbAppConfigStats->isChecked());
settings->setValue("PushUsageData", ui->cbUsageData->isChecked());
if (!Telemetry->isStateForced()) { settings->setValue("IsEnabled", ui->cbParticipateStats->isChecked()); } if (!Telemetry->isStateForced()) { settings->setValue("IsEnabled", ui->cbParticipateStats->isChecked()); }
settings->endGroup(); settings->endGroup();
Telemetry->refresh(); Telemetry->refresh();
Telemetry->work(); Telemetry->work();
if (ui->cbUsageData->isChecked() && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "SettingsUpdated";
jsonObject["UpdateTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
#endif #endif
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
@ -434,6 +454,7 @@ void OptionsDialog::applySettings()
Translator->initUserLanguage(); Translator->initUserLanguage();
} }
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))
@ -553,17 +574,10 @@ void OptionsDialog::setupStatisticsSettings()
ui->cbParticipateStats->setText(tr("Participate in %1 User Statistics").arg(GTA5SYNC_APPSTR)); ui->cbParticipateStats->setText(tr("Participate in %1 User Statistics").arg(GTA5SYNC_APPSTR));
ui->labUserStats->setText(QString("<a href=\"%2\">%1</a>").arg(tr("View %1 User Statistics Online").arg(GTA5SYNC_APPSTR), TelemetryClass::getWebURL().toString())); ui->labUserStats->setText(QString("<a href=\"%2\">%1</a>").arg(tr("View %1 User Statistics Online").arg(GTA5SYNC_APPSTR), TelemetryClass::getWebURL().toString()));
ui->gbUserFeedback->setVisible(false);
// settings->beginGroup("Startup");
// if (settings->value("IsFirstStart", true).toBool() == true)
// {
// ui->gbUserFeedback->setVisible(false);
// }
// settings->endGroup();
settings->beginGroup("Telemetry"); settings->beginGroup("Telemetry");
ui->cbParticipateStats->setChecked(Telemetry->isEnabled()); ui->cbParticipateStats->setChecked(Telemetry->isEnabled());
ui->cbAppConfigStats->setChecked(settings->value("PushAppConf", false).toBool()); ui->cbAppConfigStats->setChecked(settings->value("PushAppConf", false).toBool());
ui->cbUsageData->setChecked(settings->value("PushUsageData", false).toBool());
settings->endGroup(); settings->endGroup();
if (Telemetry->isStateForced()) if (Telemetry->isStateForced())
@ -585,6 +599,77 @@ void OptionsDialog::setupStatisticsSettings()
#endif #endif
} }
void OptionsDialog::setupWindowsGameSettings()
{
#ifdef GTA5SYNC_GAME
GameVersion gameVersion = AppEnv::getGameVersion();
#ifdef GTA5SYNC_WIN
if (gameVersion != GameVersion::NoVersion)
{
if (gameVersion == GameVersion::SocialClubVersion)
{
ui->gbSteam->setDisabled(true);
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No"))));
if (AppEnv::getGameLanguage(GameVersion::SocialClubVersion) != GameLanguage::Undefined)
{
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SocialClubVersion))).nativeLanguageName()));
}
else
{
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(tr("OS defined")));
}
ui->labSteamLanguage->setVisible(false);
}
else if (gameVersion == GameVersion::SteamVersion)
{
ui->gbSocialClub->setDisabled(true);
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: red\">%1</span>").arg(tr("No"))));
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
ui->labSocialClubLanguage->setVisible(false);
if (AppEnv::getGameLanguage(GameVersion::SteamVersion) != GameLanguage::Undefined)
{
ui->labSteamLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SteamVersion))).nativeLanguageName()));
}
else
{
ui->labSteamLanguage->setText(tr("Language: %1").arg(tr("Steam defined")));
}
}
else
{
ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
ui->labSteamFound->setText(tr("Found: %1").arg(QString("<span style=\"color: green\">%1</span>").arg(tr("Yes"))));
if (AppEnv::getGameLanguage(GameVersion::SocialClubVersion) != GameLanguage::Undefined)
{
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SocialClubVersion))).nativeLanguageName()));
}
else
{
ui->labSocialClubLanguage->setText(tr("Language: %1").arg(tr("OS defined")));
}
if (AppEnv::getGameLanguage(GameVersion::SteamVersion) != GameLanguage::Undefined)
{
ui->labSteamLanguage->setText(tr("Language: %1").arg(QLocale(AppEnv::gameLanguageToString(AppEnv::getGameLanguage(GameVersion::SteamVersion))).nativeLanguageName()));
}
else
{
ui->labSteamLanguage->setText(tr("Language: %1").arg(tr("Steam defined")));
}
}
}
else
{
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabGame));
}
#else
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabGame));
#endif
#else
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabGame));
#endif
}
void OptionsDialog::on_cbIgnoreAspectRatio_toggled(bool checked) void OptionsDialog::on_cbIgnoreAspectRatio_toggled(bool checked)
{ {
if (checked) if (checked)
@ -618,7 +703,7 @@ void OptionsDialog::setupSnapmaticPictureViewer()
#ifdef GTA5SYNC_WIN #ifdef GTA5SYNC_WIN
#if QT_VERSION >= 0x050200 #if QT_VERSION >= 0x050200
settings->beginGroup("Interface"); settings->beginGroup("Interface");
ui->cbSnapmaticNavigationBar->setChecked(settings->value("NavigationBar", false).toBool()); ui->cbSnapmaticNavigationBar->setChecked(settings->value("NavigationBar", true).toBool());
settings->endGroup(); settings->endGroup();
#else #else
ui->cbSnapmaticNavigationBar->setVisible(false); ui->cbSnapmaticNavigationBar->setVisible(false);
@ -644,25 +729,6 @@ void OptionsDialog::on_cbDefaultStyle_toggled(bool checked)
ui->cbStyleList->setDisabled(checked); ui->cbStyleList->setDisabled(checked);
} }
void OptionsDialog::on_cmdUserFeedbackSend_clicked()
{
#ifdef GTA5SYNC_TELEMETRY
if (ui->txtUserFeedback->toPlainText().length() < 1024 && ui->txtUserFeedback->toPlainText().length() >= 3)
{
QJsonDocument feedback;
QJsonObject feedbackObject;
feedbackObject["Message"] = ui->txtUserFeedback->toPlainText();
feedback.setObject(feedbackObject);
Telemetry->push(TelemetryCategory::UserFeedback, feedback);
ui->txtUserFeedback->setPlainText(QString());
}
else
{
QMessageBox::information(this, tr("User Feedback"), tr("A feedback message have to between 3-1024 characters long"));
}
#endif
}
void OptionsDialog::on_cmdCopyStatsID_clicked() void OptionsDialog::on_cmdCopyStatsID_clicked()
{ {
#ifdef GTA5SYNC_TELEMETRY #ifdef GTA5SYNC_TELEMETRY

View file

@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -47,7 +47,6 @@ private slots:
void on_cbIgnoreAspectRatio_toggled(bool checked); void on_cbIgnoreAspectRatio_toggled(bool checked);
void on_cmdExploreFolder_clicked(); void on_cmdExploreFolder_clicked();
void on_cbDefaultStyle_toggled(bool checked); void on_cbDefaultStyle_toggled(bool checked);
void on_cmdUserFeedbackSend_clicked();
void on_cmdCopyStatsID_clicked(); void on_cmdCopyStatsID_clicked();
signals: signals:
@ -80,6 +79,7 @@ private:
void setupInterfaceSettings(); void setupInterfaceSettings();
void setupStatisticsSettings(); void setupStatisticsSettings();
void setupSnapmaticPictureViewer(); void setupSnapmaticPictureViewer();
void setupWindowsGameSettings();
void applySettings(); void applySettings();
}; };

View file

@ -20,7 +20,7 @@
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>3</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tabProfile"> <widget class="QWidget" name="tabProfile">
<attribute name="title"> <attribute name="title">
@ -382,6 +382,72 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabGame">
<attribute name="title">
<string>Game</string>
</attribute>
<layout class="QVBoxLayout" name="vlGame">
<item>
<widget class="QGroupBox" name="gbSocialClub">
<property name="title">
<string>Social Club Version</string>
</property>
<layout class="QVBoxLayout" name="vlGameSocialClub">
<item>
<widget class="QLabel" name="labSocialClubFound">
<property name="text">
<string>Found: %1</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labSocialClubLanguage">
<property name="text">
<string>Language: %1</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gbSteam">
<property name="title">
<string>Steam Version</string>
</property>
<layout class="QVBoxLayout" name="vlGameSteam">
<item>
<widget class="QLabel" name="labSteamFound">
<property name="text">
<string>Found: %1</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labSteamLanguage">
<property name="text">
<string>Language: %1</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="vsGame">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabStats"> <widget class="QWidget" name="tabStats">
<attribute name="title"> <attribute name="title">
<string>Feedback</string> <string>Feedback</string>
@ -420,11 +486,11 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="gbCategorys"> <widget class="QGroupBox" name="gbCategories">
<property name="title"> <property name="title">
<string>Categories</string> <string>Categories</string>
</property> </property>
<layout class="QVBoxLayout" name="vlCategorys"> <layout class="QVBoxLayout" name="vlCategories">
<item> <item>
<widget class="QCheckBox" name="cbGeneralStats"> <widget class="QCheckBox" name="cbGeneralStats">
<property name="enabled"> <property name="enabled">
@ -458,6 +524,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="cbUsageData">
<property name="text">
<string>Personal Usage Data</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -466,74 +539,32 @@
<property name="title"> <property name="title">
<string>Other</string> <string>Other</string>
</property> </property>
<layout class="QHBoxLayout" name="hlOtherStats"> <layout class="QVBoxLayout" name="vlFeedbackOther">
<item> <item>
<widget class="QLabel" name="labParticipationID"> <layout class="QHBoxLayout" name="hlParticipation">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Participation ID: %1</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cmdCopyStatsID">
<property name="text">
<string>&amp;Copy</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gbUserFeedback">
<property name="title">
<string>User Feedback</string>
</property>
<layout class="QVBoxLayout" name="vlUserFeedback">
<item>
<widget class="QPlainTextEdit" name="txtUserFeedback"/>
</item>
<item>
<layout class="QHBoxLayout" name="hlUserFeedbackButtons">
<item> <item>
<widget class="QLabel" name="labUserFeedback"> <widget class="QLabel" name="labParticipationID">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>Limit: 1 message/day</string> <string>Participation ID: %1</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="hsUserFeedbackButtons"> <widget class="QPushButton" name="cmdCopyStatsID">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cmdUserFeedbackSend">
<property name="text"> <property name="text">
<string>&amp;Send</string> <string>&amp;Copy</string>
</property> </property>
<property name="autoDefault"> <property name="autoDefault">
<bool>false</bool> <bool>false</bool>
@ -683,26 +714,6 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabSync">
<attribute name="title">
<string>Sync</string>
</attribute>
<layout class="QVBoxLayout" name="vlSync">
<item>
<widget class="QLabel" name="labSync">
<property name="text">
<string>Sync is not implemented at current time</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
<item> <item>

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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
@ -27,10 +27,12 @@
#include "SnapmaticEditor.h" #include "SnapmaticEditor.h"
#include "StandardPaths.h" #include "StandardPaths.h"
#include "PictureExport.h" #include "PictureExport.h"
#include "ImportDialog.h"
#include "StringParser.h" #include "StringParser.h"
#include "GlobalString.h" #include "GlobalString.h"
#include "UiModLabel.h" #include "UiModLabel.h"
#include "AppEnv.h" #include "AppEnv.h"
#include "config.h"
#ifdef GTA5SYNC_WIN #ifdef GTA5SYNC_WIN
#if QT_VERSION >= 0x050200 #if QT_VERSION >= 0x050200
@ -44,6 +46,7 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <QApplication> #include <QApplication>
#include <QFontMetrics> #include <QFontMetrics>
#include <QJsonObject>
#include <QSizePolicy> #include <QSizePolicy>
#include <QStaticText> #include <QStaticText>
#include <QFileDialog> #include <QFileDialog>
@ -66,6 +69,10 @@
#include <QUrl> #include <QUrl>
#include <QDir> #include <QDir>
#ifdef GTA5SYNC_TELEMETRY
#include "TelemetryClass.h"
#endif
// Macros for better Overview + RAM // Macros for better Overview + RAM
#define locX QString::number(picture->getSnapmaticProperties().location.x) #define locX QString::number(picture->getSnapmaticProperties().location.x)
#define locY QString::number(picture->getSnapmaticProperties().location.y) #define locY QString::number(picture->getSnapmaticProperties().location.y)
@ -131,9 +138,10 @@ void PictureDialog::setupPictureDialog()
// Avatar area // Avatar area
qreal screenRatio = AppEnv::screenRatio(); qreal screenRatio = AppEnv::screenRatio();
if (screenRatio != 1) qreal screenRatioPR = AppEnv::screenRatioPR();
if (screenRatio != 1 || screenRatioPR != 1)
{ {
avatarAreaPicture = QImage(":/img/avatararea.png").scaledToHeight(536 * screenRatio, Qt::FastTransformation); avatarAreaPicture = QImage(":/img/avatararea.png").scaledToHeight(536 * screenRatio * screenRatioPR, Qt::FastTransformation);
} }
else else
{ {
@ -143,6 +151,11 @@ void PictureDialog::setupPictureDialog()
avatarLocY = 66; avatarLocY = 66;
avatarSize = 470; avatarSize = 470;
// DPI calculation (picture)
ui->labPicture->setFixedSize(960 * screenRatio, 536 * screenRatio);
ui->labPicture->setFocusPolicy(Qt::StrongFocus);
ui->labPicture->setScaledContents(true);
// Overlay area // Overlay area
renderOverlayPicture(); renderOverlayPicture();
overlayEnabled = true; overlayEnabled = true;
@ -178,8 +191,12 @@ void PictureDialog::setupPictureDialog()
installEventFilter(this); installEventFilter(this);
installEventFilter(ui->labPicture); installEventFilter(ui->labPicture);
ui->labPicture->setFixedSize(960 * screenRatio, 536 * screenRatio);
ui->labPicture->setFocusPolicy(Qt::StrongFocus); // DPI calculation
ui->hlButtons->setSpacing(6 * screenRatio);
ui->vlButtons->setSpacing(6 * screenRatio);
ui->vlButtons->setContentsMargins(0, 0, 5 * screenRatio, 5 * screenRatio);
ui->jsonLayout->setContentsMargins(4 * screenRatio, 10 * screenRatio, 4 * screenRatio, 4 * screenRatio);
// Pre-adapt window for DPI // Pre-adapt window for DPI
setFixedWidth(960 * screenRatio); setFixedWidth(960 * screenRatio);
@ -225,8 +242,8 @@ void PictureDialog::addPreviousNextButtons()
QToolBar *uiToolbar = new QToolBar("Picture Toolbar", this); QToolBar *uiToolbar = new QToolBar("Picture Toolbar", this);
uiToolbar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); uiToolbar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
uiToolbar->setObjectName("uiToolbar"); uiToolbar->setObjectName("uiToolbar");
uiToolbar->addAction(QIcon(":/img/back.png"), "", this, SLOT(previousPictureRequestedSlot())); uiToolbar->addAction(QIcon(":/img/back.svgz"), "", this, SLOT(previousPictureRequestedSlot()));
uiToolbar->addAction(QIcon(":/img/next.png"), "", this, SLOT(nextPictureRequestedSlot())); uiToolbar->addAction(QIcon(":/img/next.svgz"), "", this, SLOT(nextPictureRequestedSlot()));
layout()->setMenuBar(uiToolbar); layout()->setMenuBar(uiToolbar);
naviEnabled = true; naviEnabled = true;
@ -330,7 +347,7 @@ LRESULT PictureDialog::HitTestNCA(HWND hWnd, LPARAM lParam)
void PictureDialog::resizeEvent(QResizeEvent *event) void PictureDialog::resizeEvent(QResizeEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
// int newDialogHeight = ui->labPicture->pixmap()->height(); // int newDialogHeight = (ui->labPicture->pixmap()->height() / AppEnv::screenRatioPR());
// newDialogHeight = newDialogHeight + ui->jsonFrame->height(); // newDialogHeight = newDialogHeight + ui->jsonFrame->height();
// if (naviEnabled) newDialogHeight = newDialogHeight + layout()->menuBar()->height(); // if (naviEnabled) newDialogHeight = newDialogHeight + layout()->menuBar()->height();
// int buttomBorderSize = (frameSize().height() - size().height()); // int buttomBorderSize = (frameSize().height() - size().height());
@ -351,7 +368,7 @@ void PictureDialog::resizeEvent(QResizeEvent *event)
void PictureDialog::adaptNewDialogSize(QSize newLabelSize) void PictureDialog::adaptNewDialogSize(QSize newLabelSize)
{ {
Q_UNUSED(newLabelSize) Q_UNUSED(newLabelSize)
int newDialogHeight = ui->labPicture->pixmap()->height(); int newDialogHeight = (ui->labPicture->pixmap()->height() / AppEnv::screenRatioPR());
newDialogHeight = newDialogHeight + ui->jsonFrame->height(); newDialogHeight = newDialogHeight + ui->jsonFrame->height();
if (naviEnabled) newDialogHeight = newDialogHeight + layout()->menuBar()->height(); if (naviEnabled) newDialogHeight = newDialogHeight + layout()->menuBar()->height();
setMaximumSize(width(), newDialogHeight); setMaximumSize(width(), newDialogHeight);
@ -362,14 +379,14 @@ void PictureDialog::adaptNewDialogSize(QSize newLabelSize)
updateGeometry(); updateGeometry();
} }
void PictureDialog::stylizeDialog() void PictureDialog::styliseDialog()
{ {
#ifdef GTA5SYNC_WIN #ifdef GTA5SYNC_WIN
#if QT_VERSION >= 0x050200 #if QT_VERSION >= 0x050200
if (QtWin::isCompositionEnabled()) if (QtWin::isCompositionEnabled())
{ {
QPalette palette; QPalette palette;
QtWin::extendFrameIntoClientArea(this, 0, this->layout()->menuBar()->height(), 0, 0); QtWin::extendFrameIntoClientArea(this, 0, qRound(layout()->menuBar()->height() * AppEnv::screenRatioPR()), 0, 0);
ui->jsonFrame->setStyleSheet(QString("QFrame { background: %1; }").arg(palette.window().color().name())); ui->jsonFrame->setStyleSheet(QString("QFrame { background: %1; }").arg(palette.window().color().name()));
setStyleSheet("PictureDialog { background: transparent; }"); setStyleSheet("PictureDialog { background: transparent; }");
} }
@ -392,7 +409,7 @@ bool PictureDialog::event(QEvent *event)
{ {
if (event->type() == QWinEvent::CompositionChange || event->type() == QWinEvent::ColorizationChange) if (event->type() == QWinEvent::CompositionChange || event->type() == QWinEvent::ColorizationChange)
{ {
stylizeDialog(); styliseDialog();
} }
} }
#endif #endif
@ -553,24 +570,25 @@ void PictureDialog::renderOverlayPicture()
{ {
// Generating Overlay Preview // Generating Overlay Preview
qreal screenRatio = AppEnv::screenRatio(); qreal screenRatio = AppEnv::screenRatio();
QRect preferedRect = QRect(0, 0, 200 * screenRatio, 160 * screenRatio); qreal screenRatioPR = AppEnv::screenRatioPR();
QRect preferedRect = QRect(0, 0, 200 * screenRatio * screenRatioPR, 160 * screenRatio * screenRatioPR);
QString overlayText = tr("Key 1 - Avatar Preview Mode\nKey 2 - Toggle Overlay\nArrow Keys - Navigate"); QString overlayText = tr("Key 1 - Avatar Preview Mode\nKey 2 - Toggle Overlay\nArrow Keys - Navigate");
QFont overlayPainterFont; QFont overlayPainterFont;
overlayPainterFont.setPixelSize(12 * screenRatio); overlayPainterFont.setPixelSize(12 * screenRatio * screenRatioPR);
QFontMetrics fontMetrics(overlayPainterFont); QFontMetrics fontMetrics(overlayPainterFont);
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) if (overlaySpace.height() < 74 * screenRatio * screenRatioPR)
{ {
hOverlay = Qt::AlignVCenter; hOverlay = Qt::AlignVCenter;
preferedRect.setHeight(71 * screenRatio); preferedRect.setHeight(71 * screenRatio * screenRatioPR);
overlaySpace.setHeight(80 * screenRatio); overlaySpace.setHeight(80 * screenRatio * screenRatioPR);
} }
else else
{ {
overlaySpace.setHeight(overlaySpace.height() + 6 * screenRatio); overlaySpace.setHeight(overlaySpace.height() + 6 * screenRatio * screenRatioPR);
} }
QImage overlayImage(overlaySpace.size(), QImage::Format_ARGB32_Premultiplied); QImage overlayImage(overlaySpace.size(), QImage::Format_ARGB32_Premultiplied);
@ -582,13 +600,13 @@ 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) if (overlaySpace.width() < 194 * screenRatio * screenRatioPR)
{ {
overlaySpace.setWidth(200 * screenRatio); overlaySpace.setWidth(200 * screenRatio * screenRatioPR);
} }
else else
{ {
overlaySpace.setWidth(overlaySpace.width() + 6 * screenRatio); overlaySpace.setWidth(overlaySpace.width() + 6 * screenRatio * screenRatioPR);
} }
QImage overlayBorderImage(overlaySpace.width(), overlaySpace.height(), QImage::Format_ARGB6666_Premultiplied); QImage overlayBorderImage(overlaySpace.width(), overlaySpace.height(), QImage::Format_ARGB6666_Premultiplied);
@ -598,7 +616,7 @@ void PictureDialog::renderOverlayPicture()
overlayTempImage.fill(Qt::transparent); overlayTempImage.fill(Qt::transparent);
QPainter overlayTempPainter(&overlayTempImage); QPainter overlayTempPainter(&overlayTempImage);
overlayTempPainter.drawImage(0, 0, overlayBorderImage); overlayTempPainter.drawImage(0, 0, overlayBorderImage);
overlayTempPainter.drawImage(3 * screenRatio, 3 * screenRatio, overlayImage); overlayTempPainter.drawImage(3 * screenRatio * screenRatioPR, 3 * screenRatio * screenRatioPR, overlayImage);
overlayTempPainter.end(); overlayTempPainter.end();
} }
@ -671,63 +689,51 @@ void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture)
void PictureDialog::renderPicture() void PictureDialog::renderPicture()
{ {
qreal screenRatio = AppEnv::screenRatio(); qreal screenRatio = AppEnv::screenRatio();
qreal screenRatioPR = AppEnv::screenRatioPR();
if (!previewMode) if (!previewMode)
{ {
if (overlayEnabled) if (overlayEnabled)
{ {
QPixmap shownImagePixmap(960 * screenRatio, 536 * screenRatio); QPixmap shownImagePixmap(960 * screenRatio * screenRatioPR, 536 * screenRatio * screenRatioPR);
shownImagePixmap.fill(Qt::transparent); shownImagePixmap.fill(Qt::transparent);
QPainter shownImagePainter(&shownImagePixmap); QPainter shownImagePainter(&shownImagePixmap);
if (screenRatio == 1) shownImagePainter.drawImage(0, 0, snapmaticPicture.scaled(960 * screenRatio * screenRatioPR, 536 * screenRatio * screenRatioPR, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
{ shownImagePainter.drawImage(3 * screenRatio * screenRatioPR, 3 * screenRatio * screenRatioPR, overlayTempImage);
shownImagePainter.drawImage(0, 0, snapmaticPicture);
shownImagePainter.drawImage(3 * screenRatio, 3 * screenRatio, overlayTempImage);
}
else
{
shownImagePainter.drawImage(0, 0, snapmaticPicture.scaledToHeight(536 * screenRatio, Qt::SmoothTransformation));
shownImagePainter.drawImage(3 * screenRatio, 3 * screenRatio, overlayTempImage);
}
shownImagePainter.end(); shownImagePainter.end();
#if QT_VERSION >= 0x050600
shownImagePixmap.setDevicePixelRatio(screenRatioPR);
#endif
ui->labPicture->setPixmap(shownImagePixmap); ui->labPicture->setPixmap(shownImagePixmap);
} }
else else
{ {
if (screenRatio != 1) QPixmap shownImagePixmap(960 * screenRatio * screenRatioPR, 536 * screenRatio * screenRatioPR);
{ shownImagePixmap.fill(Qt::transparent);
QPixmap shownImagePixmap(960 * screenRatio, 536 * screenRatio); QPainter shownImagePainter(&shownImagePixmap);
shownImagePixmap.fill(Qt::transparent); shownImagePainter.drawImage(0, 0, snapmaticPicture.scaled(960 * screenRatio * screenRatioPR, 536 * screenRatio * screenRatioPR, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
QPainter shownImagePainter(&shownImagePixmap); shownImagePainter.end();
shownImagePainter.drawImage(0, 0, snapmaticPicture.scaledToHeight(536 * screenRatio, Qt::SmoothTransformation)); #if QT_VERSION >= 0x050600
shownImagePainter.end(); shownImagePixmap.setDevicePixelRatio(screenRatioPR);
ui->labPicture->setPixmap(shownImagePixmap); #endif
} ui->labPicture->setPixmap(shownImagePixmap);
else
{
ui->labPicture->setPixmap(QPixmap::fromImage(snapmaticPicture));
}
} }
} }
else else
{ {
// Generating Avatar Preview // Generating Avatar Preview
QPixmap avatarPixmap(960 * screenRatio, 536 * screenRatio); QPixmap avatarPixmap(960 * screenRatio * screenRatioPR, 536 * screenRatio * screenRatioPR);
QPainter snapPainter(&avatarPixmap); QPainter snapPainter(&avatarPixmap);
QFont snapPainterFont; QFont snapPainterFont;
snapPainterFont.setPixelSize(12 * screenRatio); snapPainterFont.setPixelSize(12 * screenRatio * screenRatioPR);
if (screenRatio == 1) snapPainter.drawImage(0, 0, snapmaticPicture.scaled(960 * screenRatio * screenRatioPR, 536 * screenRatio * screenRatioPR, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
{
snapPainter.drawImage(0, 0, snapmaticPicture);
}
else
{
snapPainter.drawImage(0, 0, snapmaticPicture.scaledToHeight(536 * screenRatio, Qt::SmoothTransformation));
}
snapPainter.drawImage(0, 0, avatarAreaPicture); snapPainter.drawImage(0, 0, avatarAreaPicture);
snapPainter.setPen(QColor::fromRgb(255, 255, 255, 255)); snapPainter.setPen(QColor::fromRgb(255, 255, 255, 255));
snapPainter.setFont(snapPainterFont); snapPainter.setFont(snapPainterFont);
snapPainter.drawText(QRect(3 * screenRatio, 3 * screenRatio, 140 * screenRatio, 536 * screenRatio), Qt::AlignLeft | Qt::TextWordWrap, tr("Avatar Preview Mode\nPress 1 for Default View")); snapPainter.drawText(QRect(3 * screenRatio * screenRatioPR, 3 * screenRatio * screenRatioPR, 140 * screenRatio * screenRatioPR, 536 * screenRatio * screenRatioPR), Qt::AlignLeft | Qt::TextWordWrap, tr("Avatar Preview Mode\nPress 1 for Default View"));
snapPainter.end(); snapPainter.end();
#if QT_VERSION >= 0x050600
avatarPixmap.setDevicePixelRatio(screenRatioPR);
#endif
ui->labPicture->setPixmap(avatarPixmap); ui->labPicture->setPixmap(avatarPixmap);
} }
} }
@ -755,10 +761,15 @@ void PictureDialog::playerNameUpdated()
QString PictureDialog::generateCrewString() QString PictureDialog::generateCrewString()
{ {
SnapmaticPicture *picture = smpic; // used by macro SnapmaticPicture *picture = smpic; // used by macro
QString crewIDStr = crewID; // save operation time const QString crewIDStr = crewID; // save operation time
if (crewIDStr != "0" && !crewIDStr.isEmpty()) if (crewIDStr != "0" && !crewIDStr.isEmpty())
{ {
return QString("<a href=\"https://socialclub.rockstargames.com/crew/" % QString(crewStr).replace(" ", "_") % "/" % crewIDStr % "\">" % crewStr % "</a>"); if (crewIDStr != crewStr) {
return QString("<a href=\"https://socialclub.rockstargames.com/crew/" % QString(crewStr).replace(" ", "_") % "/" % crewIDStr % "\">" % crewStr % "</a>");
}
else {
return QString(crewIDStr);
}
} }
return tr("No Crew"); return tr("No Crew");
} }
@ -770,11 +781,15 @@ QString PictureDialog::generatePlayersString()
QString plyrsStr; QString plyrsStr;
if (playersList.length() >= 1) if (playersList.length() >= 1)
{ {
for (QString player : playersList) for (const QString player : playersList)
{ {
QString playerName; const QString playerName = profileDB->getPlayerName(player);
playerName = profileDB->getPlayerName(player); if (player != playerName) {
plyrsStr += ", <a href=\"https://socialclub.rockstargames.com/member/" % playerName % "/" % player % "\">" % playerName % "</a>"; plyrsStr += ", <a href=\"https://socialclub.rockstargames.com/member/" % playerName % "/" % player % "\">" % playerName % "</a>";
}
else {
plyrsStr += ", " % player;
}
} }
plyrsStr.remove(0, 2); plyrsStr.remove(0, 2);
} }
@ -909,6 +924,23 @@ void PictureDialog::openPreviewMap()
else else
{ {
updated(); updated();
#ifdef GTA5SYNC_TELEMETRY
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "LocationEdited";
jsonObject["ExtraFlags"] = "Viewer";
jsonObject["EditedSize"] = QString::number(picture->getContentMaxLength());
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
#endif
} }
} }
delete mapLocDialog; delete mapLocDialog;
@ -940,25 +972,66 @@ void PictureDialog::editSnapmaticProperties()
void PictureDialog::editSnapmaticImage() void PictureDialog::editSnapmaticImage()
{ {
SnapmaticPicture *picture = smpic; QImage *currentImage = new QImage(smpic->getImage());
ImageEditorDialog *imageEditor; ImportDialog *importDialog;
if (rqFullscreen && fullscreenWidget != nullptr) if (rqFullscreen && fullscreenWidget != nullptr)
{ {
imageEditor = new ImageEditorDialog(picture, profileName, fullscreenWidget); importDialog = new ImportDialog(profileName, fullscreenWidget);
} }
else else
{ {
imageEditor = new ImageEditorDialog(picture, profileName, this); importDialog = new ImportDialog(profileName, this);
} }
imageEditor->setWindowIcon(windowIcon()); importDialog->setWindowIcon(windowIcon());
imageEditor->setModal(true); importDialog->setImage(currentImage);
#ifndef Q_OS_ANDROID importDialog->enableOverwriteMode();
imageEditor->show(); importDialog->setModal(true);
#else importDialog->exec();
snapmaticEditor->showMaximized(); if (importDialog->isImportAgreed())
{
const QByteArray previousPicture = smpic->getPictureStream();
bool success = smpic->setImage(importDialog->image());
if (success)
{
QString currentFilePath = smpic->getPictureFilePath();
QString originalFilePath = smpic->getOriginalPictureFilePath();
QString backupFileName = originalFilePath % ".bak";
if (!QFile::exists(backupFileName))
{
QFile::copy(currentFilePath, backupFileName);
}
if (!smpic->exportPicture(currentFilePath))
{
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"));
return;
}
smpic->emitCustomSignal("PictureUpdated");
#ifdef GTA5SYNC_TELEMETRY
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "ImageEdited";
jsonObject["ExtraFlags"] = "Viewer";
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
#endif #endif
imageEditor->exec(); }
delete imageEditor; else
{
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of Image Error"));
return;
}
}
delete importDialog;
} }
void PictureDialog::editSnapmaticRawJson() void PictureDialog::editSnapmaticRawJson()

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -56,7 +56,7 @@ public:
void setSnapmaticPicture(SnapmaticPicture *picture, int index); void setSnapmaticPicture(SnapmaticPicture *picture, int index);
void setSnapmaticPicture(SnapmaticPicture *picture); void setSnapmaticPicture(SnapmaticPicture *picture);
void addPreviousNextButtons(); void addPreviousNextButtons();
void stylizeDialog(); void styliseDialog();
bool isIndexed(); bool isIndexed();
int getIndex(); int getIndex();
~PictureDialog(); ~PictureDialog();

View file

@ -43,9 +43,6 @@
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="pixmap">
<pixmap resource="res/app.qrc">:/img/960x536.png</pixmap>
</property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
</property> </property>
@ -230,9 +227,7 @@
</slots> </slots>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources> <resources/>
<include location="res/app.qrc"/>
</resources>
<connections> <connections>
<connection> <connection>
<sender>cmdClose</sender> <sender>cmdClose</sender>

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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
@ -35,6 +35,7 @@ PlayerListDialog::PlayerListDialog(QStringList players, ProfileDatabase *profile
listUpdated = false; listUpdated = false;
ui->setupUi(this); ui->setupUi(this);
ui->cmdCancel->setDefault(true);
ui->cmdCancel->setFocus(); ui->cmdCancel->setFocus();
// Set Icon for Apply Button // Set Icon for Apply Button
@ -78,7 +79,9 @@ PlayerListDialog::PlayerListDialog(QStringList players, ProfileDatabase *profile
} }
else else
{ {
drawSwitchButtons(); ui->cmdMakeAv->setIcon(QIcon(":/img/back.svgz"));
ui->cmdMakeSe->setIcon(QIcon(":/img/next.svgz"));
ui->cmdMakeAd->setIcon(QIcon(":/img/add.svgz"));
} }
buildInterface(); buildInterface();
@ -100,79 +103,6 @@ PlayerListDialog::~PlayerListDialog()
delete ui; delete ui;
} }
void PlayerListDialog::drawSwitchButtons()
{
QFont painterFont = ui->cmdApply->font();
QPalette palette;
QFontMetrics fontMetrics(painterFont);
QRect makeAvRect = fontMetrics.boundingRect(QRect(0, 0, 0, 0), Qt::AlignCenter | Qt::TextDontClip, "<");
QRect makeSeRect = fontMetrics.boundingRect(QRect(0, 0, 0, 0), Qt::AlignCenter | Qt::TextDontClip, ">");
QRect makeAdRect = fontMetrics.boundingRect(QRect(0, 0, 0, 0), Qt::AlignCenter | Qt::TextDontClip, "+");
int makeAvSize;
if (makeAvRect.height() > makeAvRect.width())
{
makeAvSize = makeAvRect.height();
}
else
{
makeAvSize = makeAvRect.width();
}
int makeSeSize;
if (makeSeRect.height() > makeSeRect.width())
{
makeSeSize = makeSeRect.height();
}
else
{
makeSeSize = makeSeRect.width();
}
int makeAdSize;
if (makeAdRect.height() > makeAdRect.width())
{
makeAdSize = makeAdRect.height();
}
else
{
makeAdSize = makeAdRect.width();
}
QImage avImage(makeAvSize, makeAvSize, QImage::Format_ARGB32_Premultiplied);
avImage.fill(Qt::transparent);
QImage seImage(makeSeSize, makeSeSize, QImage::Format_ARGB32_Premultiplied);
seImage.fill(Qt::transparent);
QImage adImage(makeAdSize, makeAdSize, QImage::Format_ARGB32_Premultiplied);
adImage.fill(Qt::transparent);
QPainter avPainter(&avImage);
avPainter.setFont(painterFont);
avPainter.setBrush(palette.buttonText());
avPainter.setPen(palette.buttonText().color());
avPainter.drawText(0, 0, makeAvSize, makeAvSize, Qt::AlignCenter | Qt::TextDontClip, "<");
avPainter.end();
QPainter sePainter(&seImage);
sePainter.setFont(painterFont);
sePainter.setBrush(palette.buttonText());
sePainter.setPen(palette.buttonText().color());
sePainter.drawText(0, 0, makeSeSize, makeSeSize, Qt::AlignCenter | Qt::TextDontClip, ">");
sePainter.end();
QPainter adPainter(&adImage);
adPainter.setFont(painterFont);
adPainter.setBrush(palette.buttonText());
adPainter.setPen(palette.buttonText().color());
adPainter.drawText(0, 0, makeAdSize, makeAdSize, Qt::AlignCenter | Qt::TextDontClip, "+");
adPainter.end();
ui->cmdMakeAv->setIconSize(avImage.size());
ui->cmdMakeSe->setIconSize(seImage.size());
ui->cmdMakeAd->setIconSize(adImage.size());
ui->cmdMakeAv->setIcon(QIcon(QPixmap::fromImage(avImage)));
ui->cmdMakeSe->setIcon(QIcon(QPixmap::fromImage(seImage)));
ui->cmdMakeAd->setIcon(QIcon(QPixmap::fromImage(adImage)));
}
void PlayerListDialog::on_cmdCancel_clicked() void PlayerListDialog::on_cmdCancel_clicked()
{ {
close(); close();

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -48,7 +48,6 @@ private:
ProfileDatabase *profileDB; ProfileDatabase *profileDB;
Ui::PlayerListDialog *ui; Ui::PlayerListDialog *ui;
bool listUpdated; bool listUpdated;
void drawSwitchButtons();
void buildInterface(); void buildInterface();
signals: signals:

View file

@ -51,8 +51,8 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="cmdMakeSe"> <widget class="QPushButton" name="cmdMakeSe">
<property name="text"> <property name="focusPolicy">
<string/> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="autoDefault"> <property name="autoDefault">
<bool>false</bool> <bool>false</bool>
@ -61,6 +61,9 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="cmdMakeAv"> <widget class="QPushButton" name="cmdMakeAv">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
@ -71,6 +74,9 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="cmdMakeAd"> <widget class="QPushButton" name="cmdMakeAd">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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,10 +29,15 @@
#include "ProfileLoader.h" #include "ProfileLoader.h"
#include "ExportThread.h" #include "ExportThread.h"
#include "ImportDialog.h" #include "ImportDialog.h"
#include "UiModLabel.h"
#include "pcg_basic.h"
#include "AppEnv.h" #include "AppEnv.h"
#include "config.h" #include "config.h"
#include <QNetworkAccessManager>
#include <QProgressDialog> #include <QProgressDialog>
#include <QNetworkRequest>
#include <QStringBuilder> #include <QStringBuilder>
#include <QNetworkReply>
#include <QImageReader> #include <QImageReader>
#include <QProgressBar> #include <QProgressBar>
#include <QInputDialog> #include <QInputDialog>
@ -41,20 +46,31 @@
#include <QMessageBox> #include <QMessageBox>
#include <QMouseEvent> #include <QMouseEvent>
#include <QFileDialog> #include <QFileDialog>
#include <QVBoxLayout>
#include <QEventLoop> #include <QEventLoop>
#include <QScrollBar> #include <QScrollBar>
#include <QClipboard>
#include <QFileInfo> #include <QFileInfo>
#include <QPalette>
#include <QPainter> #include <QPainter>
#include <QRegExp> #include <QRegExp>
#include <QAction> #include <QAction>
#include <QDebug> #include <QDebug>
#include <QColor> #include <QColor>
#include <QTimer> #include <QTimer>
#include <QStyle>
#include <QFile> #include <QFile>
#include <QUrl> #include <QUrl>
#include <QDir> #include <QDir>
#include <random>
#include <ctime>
#ifdef GTA5SYNC_TELEMETRY
#include "TelemetryClass.h"
#include <QJsonDocument>
#include <QJsonObject>
#endif
#define importTimeFormat "HHmmss" #define importTimeFormat "HHmmss"
#define findRetryLimit 500 #define findRetryLimit 500
@ -76,8 +92,15 @@ ProfileInterface::ProfileInterface(ProfileDatabase *profileDB, CrewDatabase *cre
saSpacerItem = nullptr; saSpacerItem = nullptr;
updatePalette(); updatePalette();
ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER)); QString appVersion = GTA5SYNC_APPVER;
ui->saProfileContent->setFilesMode(true); #ifndef GTA5SYNC_BUILDTYPE_REL
#ifdef GTA5SYNC_COMMIT
if (!appVersion.contains("-")) { appVersion = appVersion % "-" % GTA5SYNC_COMMIT; }
#endif
#endif
ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion));
ui->saProfileContent->setFilesDropEnabled(true);
ui->saProfileContent->setImageDropEnabled(true);
// Set Icon for Close Button // Set Icon for Close Button
if (QIcon::hasThemeIcon("dialog-close")) if (QIcon::hasThemeIcon("dialog-close"))
@ -117,6 +140,9 @@ ProfileInterface::ProfileInterface(ProfileDatabase *profileDB, CrewDatabase *cre
} }
#endif #endif
// Seed RNG
pcg32_srandom_r(&rng, time(NULL), (intptr_t)&rng);
setMouseTracking(true); setMouseTracking(true);
installEventFilter(this); installEventFilter(this);
} }
@ -459,7 +485,7 @@ fileDialogPreOpen: //Work?
fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog); fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
fileDialog.setWindowTitle(tr("Import...")); fileDialog.setWindowTitle(tr("Import..."));
fileDialog.setLabelText(QFileDialog::Accept, tr("Import")); fileDialog.setLabelText(QFileDialog::Accept, tr("Import..."));
// Getting readable Image formats // Getting readable Image formats
QString imageFormatsStr = " "; QString imageFormatsStr = " ";
@ -495,8 +521,7 @@ fileDialogPreOpen: //Work?
{ {
QString selectedFile = selectedFiles.at(0); QString selectedFile = selectedFiles.at(0);
QDateTime importDateTime = QDateTime::currentDateTime(); QDateTime importDateTime = QDateTime::currentDateTime();
int currentTime = importDateTime.toString(importTimeFormat).toInt(); if (!importFile(selectedFile, importDateTime, true)) goto fileDialogPreOpen; //Work?
if (!importFile(selectedFile, importDateTime, &currentTime, true)) goto fileDialogPreOpen; //Work?
} }
else if (selectedFiles.length() > 1) else if (selectedFiles.length() > 1)
{ {
@ -504,7 +529,7 @@ fileDialogPreOpen: //Work?
} }
else else
{ {
QMessageBox::warning(this, tr("Import"), tr("No valid file is selected")); QMessageBox::warning(this, tr("Import..."), tr("No valid file is selected"));
goto fileDialogPreOpen; //Work? goto fileDialogPreOpen; //Work?
} }
} }
@ -515,7 +540,7 @@ fileDialogPreOpen: //Work?
settings.endGroup(); settings.endGroup();
} }
void ProfileInterface::importFilesProgress(QStringList selectedFiles) bool ProfileInterface::importFilesProgress(QStringList selectedFiles)
{ {
int maximumId = selectedFiles.length(); int maximumId = selectedFiles.length();
int overallId = 0; int overallId = 0;
@ -539,14 +564,13 @@ void ProfileInterface::importFilesProgress(QStringList selectedFiles)
// THREADING HERE PLEASE // THREADING HERE PLEASE
QDateTime importDateTime = QDateTime::currentDateTime(); QDateTime importDateTime = QDateTime::currentDateTime();
int currentTime = importDateTime.time().toString(importTimeFormat).toInt();
for (QString selectedFile : selectedFiles) for (QString selectedFile : selectedFiles)
{ {
overallId++; overallId++;
pbDialog.setValue(overallId); pbDialog.setValue(overallId);
pbDialog.setLabelText(tr("Import file %1 of %2 files").arg(QString::number(overallId), QString::number(maximumId))); pbDialog.setLabelText(tr("Import file %1 of %2 files").arg(QString::number(overallId), QString::number(maximumId)));
importDateTime = QDateTime::currentDateTime(); importDateTime = QDateTime::currentDateTime();
if (!importFile(selectedFile, importDateTime, &currentTime, false)) if (!importFile(selectedFile, importDateTime, false))
{ {
failed << QFileInfo(selectedFile).fileName(); failed << QFileInfo(selectedFile).fileName();
} }
@ -560,27 +584,49 @@ void ProfileInterface::importFilesProgress(QStringList selectedFiles)
if (errorStr != "") if (errorStr != "")
{ {
errorStr.remove(0, 2); errorStr.remove(0, 2);
QMessageBox::warning(this, tr("Import"), tr("Import failed with...\n\n%1").arg(errorStr)); QMessageBox::warning(this, tr("Import..."), tr("Import failed with...\n\n%1").arg(errorStr));
return false;
} }
return true;
} }
bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime, int *currentTime, bool notMultiple) bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime, bool notMultiple)
{ {
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.contains('.')) || selectedFileName.right(4) == ".g5e")
{ {
SnapmaticPicture *picture = new SnapmaticPicture(selectedFile); SnapmaticPicture *picture = new SnapmaticPicture(selectedFile);
if (picture->readingPicture(true, true, true)) if (picture->readingPicture(true, true, true))
{ {
bool success = importSnapmaticPicture(picture, notMultiple); bool success = importSnapmaticPicture(picture, notMultiple);
if (!success) delete picture; if (!success) delete picture;
#ifdef GTA5SYNC_TELEMETRY
if (success && notMultiple)
{
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "ImportSuccess";
jsonObject["ImportSize"] = QString::number(picture->getContentMaxLength());
jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonObject["ImportType"] = "Snapmatic";
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
}
#endif
return success; return success;
} }
else else
{ {
if (notMultiple) QMessageBox::warning(this, tr("Import"), tr("Failed to read Snapmatic picture")); if (notMultiple) QMessageBox::warning(this, tr("Import..."), tr("Failed to read Snapmatic picture"));
delete picture; delete picture;
return false; return false;
} }
@ -592,16 +638,35 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime
{ {
bool success = importSavegameData(savegame, selectedFile, notMultiple); bool success = importSavegameData(savegame, selectedFile, notMultiple);
if (!success) delete savegame; if (!success) delete savegame;
#ifdef GTA5SYNC_TELEMETRY
if (success && notMultiple)
{
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "ImportSuccess";
jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonObject["ImportType"] = "Savegame";
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
}
#endif
return success; return success;
} }
else else
{ {
if (notMultiple) QMessageBox::warning(this, tr("Import"), tr("Failed to read Savegame file")); if (notMultiple) QMessageBox::warning(this, tr("Import..."), tr("Failed to read Savegame file"));
delete savegame; delete savegame;
return false; return false;
} }
} }
else if(isSupportedImageFile(selectedFileName)) else if (isSupportedImageFile(selectedFileName))
{ {
SnapmaticPicture *picture = new SnapmaticPicture(":/template/template.g5e"); SnapmaticPicture *picture = new SnapmaticPicture(":/template/template.g5e");
if (picture->readingPicture(true, false, true, false)) if (picture->readingPicture(true, false, true, false))
@ -672,17 +737,16 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime
return false; return false;
} }
SnapmaticProperties spJson = picture->getSnapmaticProperties(); SnapmaticProperties spJson = picture->getSnapmaticProperties();
spJson.uid = QString(QString::number(*currentTime) % spJson.uid = getRandomUid();
QString::number(importDateTime.date().dayOfYear())).toInt();
bool fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid)); bool fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid));
bool fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".bak");
bool fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden"); bool fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden");
int cEnough = 0; int cEnough = 0;
while ((fExists || fExistsHidden) && cEnough < findRetryLimit) while ((fExists || fExistsBackup || fExistsHidden) && cEnough < findRetryLimit)
{ {
*currentTime = *currentTime - 1; spJson.uid = getRandomUid();
spJson.uid = QString(QString::number(*currentTime) %
QString::number(importDateTime.date().dayOfYear())).toInt();
fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid)); fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid));
fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".bak");
fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden"); fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden");
cEnough++; cEnough++;
} }
@ -702,23 +766,23 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime
QFile snapmaticFile(selectedFile); QFile snapmaticFile(selectedFile);
if (!snapmaticFile.open(QFile::ReadOnly)) if (!snapmaticFile.open(QFile::ReadOnly))
{ {
QMessageBox::warning(this, tr("Import"), tr("Can't import %1 because file can't be open").arg("\""+selectedFileName+"\"")); QMessageBox::warning(this, tr("Import..."), tr("Can't import %1 because file can't be open").arg("\""+selectedFileName+"\""));
delete picture; delete picture;
return false; return false;
} }
QImage *importImage = new QImage(); QImage *snapmaticImage = new QImage();
QImageReader snapmaticImageReader; QImageReader snapmaticImageReader;
snapmaticImageReader.setDecideFormatFromContent(true); snapmaticImageReader.setDecideFormatFromContent(true);
snapmaticImageReader.setDevice(&snapmaticFile); snapmaticImageReader.setDevice(&snapmaticFile);
if (!snapmaticImageReader.read(importImage)) if (!snapmaticImageReader.read(snapmaticImage))
{ {
QMessageBox::warning(this, tr("Import"), tr("Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\"")); QMessageBox::warning(this, tr("Import..."), tr("Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\""));
delete importImage; delete snapmaticImage;
delete picture; delete picture;
return false; return false;
} }
ImportDialog *importDialog = new ImportDialog(this); ImportDialog *importDialog = new ImportDialog(profileName, this);
importDialog->setImage(importImage); importDialog->setImage(snapmaticImage);
importDialog->setModal(true); importDialog->setModal(true);
importDialog->show(); importDialog->show();
importDialog->exec(); importDialog->exec();
@ -727,17 +791,16 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime
if (picture->setImage(importDialog->image())) if (picture->setImage(importDialog->image()))
{ {
SnapmaticProperties spJson = picture->getSnapmaticProperties(); SnapmaticProperties spJson = picture->getSnapmaticProperties();
spJson.uid = QString(QString::number(*currentTime) % spJson.uid = getRandomUid();
QString::number(importDateTime.date().dayOfYear())).toInt();
bool fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid)); bool fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid));
bool fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".bak");
bool fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden"); bool fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden");
int cEnough = 0; int cEnough = 0;
while ((fExists || fExistsHidden) && cEnough < findRetryLimit) while ((fExists || fExistsBackup || fExistsHidden) && cEnough < findRetryLimit)
{ {
*currentTime = *currentTime - 1; spJson.uid = getRandomUid();
spJson.uid = QString(QString::number(*currentTime) %
QString::number(importDateTime.date().dayOfYear())).toInt();
fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid)); fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid));
fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".bak");
fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden"); fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden");
cEnough++; cEnough++;
} }
@ -748,6 +811,27 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime
picture->setPictureTitle(importDialog->getImageTitle()); picture->setPictureTitle(importDialog->getImageTitle());
picture->updateStrings(); picture->updateStrings();
success = importSnapmaticPicture(picture, notMultiple); success = importSnapmaticPicture(picture, notMultiple);
#ifdef GTA5SYNC_TELEMETRY
if (success)
{
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "ImportSuccess";
jsonObject["ExtraFlag"] = "Dialog";
jsonObject["ImportSize"] = QString::number(picture->getContentMaxLength());
jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonObject["ImportType"] = "Image";
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
}
#endif
} }
} }
else else
@ -775,6 +859,26 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime
bool success = importSnapmaticPicture(picture, notMultiple); bool success = importSnapmaticPicture(picture, notMultiple);
delete savegame; delete savegame;
if (!success) delete picture; if (!success) delete picture;
#ifdef GTA5SYNC_TELEMETRY
if (success && notMultiple)
{
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "ImportSuccess";
jsonObject["ImportSize"] = QString::number(picture->getContentMaxLength());
jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonObject["ImportType"] = "Snapmatic";
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
}
#endif
return success; return success;
} }
else if (savegame->readingSavegame()) else if (savegame->readingSavegame())
@ -782,6 +886,25 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime
bool success = importSavegameData(savegame, selectedFile, notMultiple); bool success = importSavegameData(savegame, selectedFile, notMultiple);
delete picture; delete picture;
if (!success) delete savegame; if (!success) delete savegame;
#ifdef GTA5SYNC_TELEMETRY
if (success && notMultiple)
{
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "ImportSuccess";
jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonObject["ImportType"] = "Savegame";
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
}
#endif
return success; return success;
} }
else else
@ -792,31 +915,251 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime
#endif #endif
delete picture; delete picture;
delete savegame; delete savegame;
if (notMultiple) QMessageBox::warning(this, tr("Import"), tr("Can't import %1 because file format can't be detected").arg("\""+selectedFileName+"\"")); if (notMultiple) QMessageBox::warning(this, tr("Import..."), tr("Can't import %1 because file format can't be detected").arg("\""+selectedFileName+"\""));
return false; return false;
} }
} }
} }
if (notMultiple) QMessageBox::warning(this, tr("Import"), tr("No valid file is selected")); if (notMultiple) QMessageBox::warning(this, tr("Import..."), tr("No valid file is selected"));
return false; return false;
} }
bool ProfileInterface::importUrls(const QMimeData *mimeData)
{
QStringList pathList;
for (QUrl currentUrl : mimeData->urls())
{
if (currentUrl.isLocalFile())
{
pathList += currentUrl.toLocalFile();
}
}
if (pathList.length() == 1)
{
QString selectedFile = pathList.at(0);
return importFile(selectedFile, QDateTime::currentDateTime(), true);
}
else if (pathList.length() > 1)
{
return importFilesProgress(pathList);
}
return false;
}
bool ProfileInterface::importRemote(QUrl remoteUrl)
{
bool retValue = false;
QDialog urlPasteDialog(this);
#if QT_VERSION >= 0x050000
urlPasteDialog.setObjectName(QStringLiteral("UrlPasteDialog"));
#else
urlPasteDialog.setObjectName(QString::fromUtf8("UrlPasteDialog"));
#endif
urlPasteDialog.setWindowFlags(urlPasteDialog.windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowCloseButtonHint);
urlPasteDialog.setWindowTitle(tr("Import..."));
urlPasteDialog.setModal(true);
QVBoxLayout urlPasteLayout(&urlPasteDialog);
#if QT_VERSION >= 0x050000
urlPasteLayout.setObjectName(QStringLiteral("UrlPasteLayout"));
#else
urlPasteLayout.setObjectName(QString::fromUtf8("UrlPasteLayout"));
#endif
urlPasteDialog.setLayout(&urlPasteLayout);
UiModLabel urlPasteLabel(&urlPasteDialog);
#if QT_VERSION >= 0x050000
urlPasteLabel.setObjectName(QStringLiteral("UrlPasteLabel"));
#else
urlPasteLabel.setObjectName(QString::fromUtf8("UrlPasteLabel"));
#endif
urlPasteLabel.setText(tr("Prepare Content for Import..."));
urlPasteLayout.addWidget(&urlPasteLabel);
urlPasteDialog.setFixedSize(urlPasteDialog.sizeHint());
urlPasteDialog.show();
QNetworkAccessManager *netManager = new QNetworkAccessManager();
QNetworkRequest netRequest(remoteUrl);
netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent());
netRequest.setRawHeader("Accept", "text/html");
netRequest.setRawHeader("Accept-Charset", "utf-8");
netRequest.setRawHeader("Accept-Language", "en-US,en;q=0.9");
netRequest.setRawHeader("Connection", "keep-alive");
QNetworkReply *netReply = netManager->get(netRequest);
QEventLoop *downloadLoop = new QEventLoop();
QObject::connect(netReply, SIGNAL(finished()), downloadLoop, SLOT(quit()));
QTimer::singleShot(30000, downloadLoop, SLOT(quit()));
downloadLoop->exec();
downloadLoop->disconnect();
delete downloadLoop;
urlPasteDialog.close();
if (netReply->isFinished())
{
QImage *snapmaticImage = new QImage();
QImageReader snapmaticImageReader;
snapmaticImageReader.setDecideFormatFromContent(true);
snapmaticImageReader.setDevice(netReply);
if (snapmaticImageReader.read(snapmaticImage))
{
retValue = importImage(snapmaticImage, QDateTime::currentDateTime());
}
else
{
delete snapmaticImage;
}
}
else
{
netReply->abort();
}
delete netReply;
delete netManager;
return retValue;
}
bool ProfileInterface::importImage(QImage *snapmaticImage, QDateTime importDateTime)
{
SnapmaticPicture *picture = new SnapmaticPicture(":/template/template.g5e");
if (picture->readingPicture(true, false, true, false))
{
bool success = false;
ImportDialog *importDialog = new ImportDialog(profileName, this);
importDialog->setImage(snapmaticImage);
importDialog->setModal(true);
importDialog->show();
importDialog->exec();
if (importDialog->isImportAgreed())
{
if (picture->setImage(importDialog->image()))
{
SnapmaticProperties spJson = picture->getSnapmaticProperties();
spJson.uid = getRandomUid();
bool fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid));
bool fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".bak");
bool fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden");
int cEnough = 0;
while ((fExists || fExistsBackup || fExistsHidden) && cEnough < findRetryLimit)
{
spJson.uid = getRandomUid();
fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid));
fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".bak");
fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(spJson.uid) % ".hidden");
cEnough++;
}
spJson.createdDateTime = importDateTime;
spJson.createdTimestamp = spJson.createdDateTime.toTime_t();
picture->setSnapmaticProperties(spJson);
picture->setPicFileName(QString("PGTA5%1").arg(QString::number(spJson.uid)));
picture->setPictureTitle(importDialog->getImageTitle());
picture->updateStrings();
success = importSnapmaticPicture(picture, true);
}
}
else
{
delete picture;
success = true;
}
delete importDialog;
if (!success) delete picture;
return success;
}
else
{
delete picture;
return false;
}
}
bool ProfileInterface::importSnapmaticPicture(SnapmaticPicture *picture, bool warn) bool ProfileInterface::importSnapmaticPicture(SnapmaticPicture *picture, bool warn)
{ {
QString picFileName = picture->getPictureFileName(); QString picFileName = picture->getPictureFileName();
qDebug() << picFileName;
QString adjustedFileName = picture->getOriginalPictureFileName(); QString adjustedFileName = picture->getOriginalPictureFileName();
if (picFileName.left(4) != "PGTA") if (picFileName.left(4) != "PGTA")
{ {
if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e")); if (warn) QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e"));
return false; return false;
} }
else if (QFile::exists(profileFolder % "/" % adjustedFileName) || QFile::exists(profileFolder % "/" % adjustedFileName % ".hidden")) else if (QFile::exists(profileFolder % "/" % adjustedFileName) || QFile::exists(profileFolder % "/" % adjustedFileName % ".hidden"))
{ {
if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Snapmatic picture, the picture is already in the game")); SnapmaticProperties snapmaticProperties = picture->getSnapmaticProperties();
return false; if (warn)
{
int uchoice = QMessageBox::question(this, tr("Import..."), tr("A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp?").arg(QString::number(snapmaticProperties.uid)), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (uchoice == QMessageBox::Yes)
{
// Update Snapmatic uid
snapmaticProperties.uid = getRandomUid();
snapmaticProperties.createdDateTime = QDateTime::currentDateTime();
snapmaticProperties.createdTimestamp = snapmaticProperties.createdDateTime.toTime_t();
bool fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid));
bool fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".bak");
bool fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".hidden");
int cEnough = 0;
while ((fExists || fExistsBackup || fExistsHidden) && cEnough < findRetryLimit)
{
snapmaticProperties.uid = getRandomUid();
fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid));
fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".bak");
fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".hidden");
cEnough++;
}
if (fExists || fExistsBackup || fExistsHidden)
{
// That should never happen
return false;
}
if (!picture->setSnapmaticProperties(snapmaticProperties))
{
// That should never happen
return false;
}
picture->updateStrings();
picFileName = picture->getPictureFileName();
adjustedFileName = picture->getOriginalPictureFileName();
}
else
{
return false;
}
}
else
{
// Update Snapmatic uid
snapmaticProperties.uid = getRandomUid();
snapmaticProperties.createdDateTime = QDateTime::currentDateTime();
snapmaticProperties.createdTimestamp = snapmaticProperties.createdDateTime.toTime_t();
bool fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid));
bool fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".bak");
bool fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".hidden");
int cEnough = 0;
while ((fExists || fExistsBackup || fExistsHidden) && cEnough < findRetryLimit)
{
snapmaticProperties.uid = getRandomUid();
fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid));
fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".bak");
fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".hidden");
cEnough++;
}
if (fExists || fExistsBackup || fExistsHidden)
{
// That should never happen
return false;
}
if (!picture->setSnapmaticProperties(snapmaticProperties))
{
// That should never happen
return false;
}
picture->updateStrings();
picFileName = picture->getPictureFileName();
adjustedFileName = picture->getOriginalPictureFileName();
}
} }
else if (picture->exportPicture(profileFolder % "/" % adjustedFileName, SnapmaticFormat::PGTA_Format)) if (picture->exportPicture(profileFolder % "/" % adjustedFileName, SnapmaticFormat::PGTA_Format))
{ {
picture->setSnapmaticFormat(SnapmaticFormat::PGTA_Format); picture->setSnapmaticFormat(SnapmaticFormat::PGTA_Format);
picture->setPicFilePath(profileFolder % "/" % adjustedFileName); picture->setPicFilePath(profileFolder % "/" % adjustedFileName);
@ -825,7 +1168,7 @@ bool ProfileInterface::importSnapmaticPicture(SnapmaticPicture *picture, bool wa
} }
else else
{ {
if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Snapmatic picture, can't copy the file into profile")); if (warn) QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Snapmatic picture, can't copy the file into profile"));
return false; return false;
} }
} }
@ -862,13 +1205,13 @@ bool ProfileInterface::importSavegameData(SavegameData *savegame, QString sgdPat
} }
else else
{ {
if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Savegame, can't copy the file into profile")); if (warn) QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Savegame, can't copy the file into profile"));
return false; return false;
} }
} }
else else
{ {
if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Savegame, no Savegame slot is left")); if (warn) QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Savegame, no Savegame slot is left"));
return false; return false;
} }
} }
@ -1087,7 +1430,7 @@ void ProfileInterface::deleteSelected()
if (widget->getWidgetType() == "SnapmaticWidget") if (widget->getWidgetType() == "SnapmaticWidget")
{ {
SnapmaticWidget *picWidget = qobject_cast<SnapmaticWidget*>(widget); SnapmaticWidget *picWidget = qobject_cast<SnapmaticWidget*>(widget);
if (picWidget->getPicture()->deletePicFile()) if (picWidget->getPicture()->deletePictureFile())
{ {
pictureDeleted(picWidget); pictureDeleted(picWidget);
} }
@ -1244,7 +1587,7 @@ void ProfileInterface::contextMenuTriggeredPIC(QContextMenuEvent *ev)
{ {
previousWidget->setStyleSheet(QLatin1String("")); previousWidget->setStyleSheet(QLatin1String(""));
} }
picWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color: rgb(%1, %2, %3)}QLabel#labPicStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); picWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}"));
previousWidget = picWidget; previousWidget = picWidget;
} }
QMenu contextMenu(picWidget); QMenu contextMenu(picWidget);
@ -1295,7 +1638,7 @@ void ProfileInterface::contextMenuTriggeredSGD(QContextMenuEvent *ev)
{ {
previousWidget->setStyleSheet(QLatin1String("")); previousWidget->setStyleSheet(QLatin1String(""));
} }
sgdWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color: rgb(%1, %2, %3)}QLabel#labSavegameStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); sgdWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color:palette(highlight)}QLabel#labSavegameStr{color:palette(highlighted-text)}"));
previousWidget = sgdWidget; previousWidget = sgdWidget;
} }
QMenu contextMenu(sgdWidget); QMenu contextMenu(sgdWidget);
@ -1322,38 +1665,86 @@ void ProfileInterface::contextMenuTriggeredSGD(QContextMenuEvent *ev)
void ProfileInterface::on_saProfileContent_dropped(const QMimeData *mimeData) void ProfileInterface::on_saProfileContent_dropped(const QMimeData *mimeData)
{ {
if (!mimeData) return; if (!mimeData) return;
QStringList pathList; if (mimeData->hasImage())
for (QUrl currentUrl : mimeData->urls())
{ {
if (currentUrl.isLocalFile()) QImage *snapmaticImage = new QImage(qvariant_cast<QImage>(mimeData->imageData()));
{ importImage(snapmaticImage, QDateTime::currentDateTime());
pathList += currentUrl.toLocalFile();
}
} }
else if (mimeData->hasUrls())
if (pathList.length() == 1)
{ {
QString selectedFile = pathList.at(0); importUrls(mimeData);
QDateTime importDateTime = QDateTime::currentDateTime();
int currentTime = importDateTime.toString(importTimeFormat).toInt();
importFile(selectedFile, QDateTime::currentDateTime(), &currentTime, true);
}
else if (pathList.length() > 1)
{
importFilesProgress(pathList);
} }
} }
void ProfileInterface::retranslateUi() void ProfileInterface::retranslateUi()
{ {
ui->retranslateUi(this); ui->retranslateUi(this);
ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER)); QString appVersion = GTA5SYNC_APPVER;
#ifndef GTA5SYNC_BUILDTYPE_REL
#ifdef GTA5SYNC_COMMIT
if (!appVersion.contains("-")) { appVersion = appVersion % "-" % GTA5SYNC_COMMIT; }
#endif
#endif
ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion));
} }
bool ProfileInterface::eventFilter(QObject *watched, QEvent *event) bool ProfileInterface::eventFilter(QObject *watched, QEvent *event)
{ {
if (event->type() == QEvent::MouseMove) if (event->type() == QEvent::KeyPress)
{
if (isProfileLoaded)
{
QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(event);
switch (keyEvent->key())
{
case Qt::Key_V:
if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier) && !QApplication::keyboardModifiers().testFlag(Qt::ShiftModifier))
{
const QMimeData *clipboardData = QApplication::clipboard()->mimeData();
if (clipboardData->hasImage())
{
QImage *snapmaticImage = new QImage(qvariant_cast<QImage>(clipboardData->imageData()));
importImage(snapmaticImage, QDateTime::currentDateTime());
}
else if (clipboardData->hasUrls())
{
if (clipboardData->urls().length() >= 2)
{
importUrls(clipboardData);
}
else if (clipboardData->urls().length() == 1)
{
QUrl clipboardUrl = clipboardData->urls().at(0);
if (clipboardUrl.isLocalFile())
{
importFile(clipboardUrl.toLocalFile(), QDateTime::currentDateTime(), true);
}
else
{
importRemote(clipboardUrl);
}
}
}
else if (clipboardData->hasText())
{
QUrl clipboardUrl = QUrl::fromUserInput(clipboardData->text());
if (clipboardUrl.isValid())
{
if (clipboardUrl.isLocalFile())
{
importFile(clipboardUrl.toLocalFile(), QDateTime::currentDateTime(), true);
}
else
{
importRemote(clipboardUrl);
}
}
}
}
}
}
}
else if (event->type() == QEvent::MouseMove)
{ {
if ((watched->objectName() == "SavegameWidget" || watched->objectName() == "SnapmaticWidget") && isProfileLoaded) if ((watched->objectName() == "SavegameWidget" || watched->objectName() == "SnapmaticWidget") && isProfileLoaded)
{ {
@ -1365,7 +1756,7 @@ bool ProfileInterface::eventFilter(QObject *watched, QEvent *event)
{ {
if (pWidget != previousWidget) if (pWidget != previousWidget)
{ {
pWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color: rgb(%1, %2, %3)}QLabel#labPicStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); pWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}"));
styleSheetChanged = true; styleSheetChanged = true;
} }
} }
@ -1373,7 +1764,7 @@ bool ProfileInterface::eventFilter(QObject *watched, QEvent *event)
{ {
if (pWidget != previousWidget) if (pWidget != previousWidget)
{ {
pWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color: rgb(%1, %2, %3)}QLabel#labSavegameStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); pWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color:palette(highlight)}QLabel#labSavegameStr{color:palette(highlighted-text)}"));
styleSheetChanged = true; styleSheetChanged = true;
} }
} }
@ -1410,7 +1801,7 @@ bool ProfileInterface::eventFilter(QObject *watched, QEvent *event)
{ {
if (pWidget != previousWidget) if (pWidget != previousWidget)
{ {
pWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color: rgb(%1, %2, %3)}QLabel#labPicStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); pWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}"));
styleSheetChanged = true; styleSheetChanged = true;
} }
} }
@ -1418,7 +1809,7 @@ bool ProfileInterface::eventFilter(QObject *watched, QEvent *event)
{ {
if (pWidget != previousWidget) if (pWidget != previousWidget)
{ {
pWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color: rgb(%1, %2, %3)}QLabel#labSavegameStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); pWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color:palette(highlight)}QLabel#labSavegameStr{color:palette(highlighted-text)}"));
styleSheetChanged = true; styleSheetChanged = true;
} }
} }
@ -1456,6 +1847,14 @@ bool ProfileInterface::eventFilter(QObject *watched, QEvent *event)
} }
} }
} }
else if (watched->objectName() == "ProfileInterface")
{
if (previousWidget != nullptr)
{
previousWidget->setStyleSheet(QLatin1String(""));
previousWidget = nullptr;
}
}
} }
return false; return false;
} }
@ -1478,7 +1877,7 @@ void ProfileInterface::hoverProfileWidgetCheck()
{ {
if (pWidget != previousWidget) if (pWidget != previousWidget)
{ {
pWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color: rgb(%1, %2, %3)}QLabel#labPicStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); pWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}"));
styleSheetChanged = true; styleSheetChanged = true;
} }
} }
@ -1486,7 +1885,7 @@ void ProfileInterface::hoverProfileWidgetCheck()
{ {
if (pWidget != previousWidget) if (pWidget != previousWidget)
{ {
pWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color: rgb(%1, %2, %3)}QLabel#labSavegameStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); pWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color:palette(highlight)}QLabel#labSavegameStr{color:palette(highlighted-text)}"));
styleSheetChanged = true; styleSheetChanged = true;
} }
} }
@ -1511,20 +1910,16 @@ void ProfileInterface::hoverProfileWidgetCheck()
void ProfileInterface::updatePalette() void ProfileInterface::updatePalette()
{ {
QPalette palette; ui->saProfile->setStyleSheet(QString("QWidget#saProfileContent{background-color:palette(base)}"));
QColor baseColor = palette.base().color();
highlightBackColor = palette.highlight().color();
highlightTextColor = palette.highlightedText().color();
ui->saProfile->setStyleSheet(QString("QWidget#saProfileContent{background-color: rgb(%1, %2, %3)}").arg(QString::number(baseColor.red()), QString::number(baseColor.green()), QString::number(baseColor.blue())));
if (previousWidget != nullptr) if (previousWidget != nullptr)
{ {
if (previousWidget->getWidgetType() == "SnapmaticWidget") if (previousWidget->getWidgetType() == "SnapmaticWidget")
{ {
previousWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color: rgb(%1, %2, %3)}QLabel#labPicStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); previousWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}"));
} }
else if (previousWidget->getWidgetType() == "SavegameWidget") else if (previousWidget->getWidgetType() == "SavegameWidget")
{ {
previousWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color: rgb(%1, %2, %3)}QLabel#labSavegameStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); previousWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}"));
} }
} }
} }
@ -1653,7 +2048,13 @@ void ProfileInterface::massTool(MassTool tool)
return; return;
} }
PlayerListDialog *playerListDialog = new PlayerListDialog(QStringList(), profileDB, this); QStringList players;
if (snapmaticWidgets.length() == 1)
{
players = snapmaticWidgets.at(0)->getPicture()->getSnapmaticProperties().playersList;
}
PlayerListDialog *playerListDialog = new PlayerListDialog(players, profileDB, this);
playerListDialog->setModal(true); playerListDialog->setModal(true);
playerListDialog->show(); playerListDialog->show();
playerListDialog->exec(); playerListDialog->exec();
@ -1661,7 +2062,7 @@ void ProfileInterface::massTool(MassTool tool)
{ {
return; return;
} }
QStringList players = playerListDialog->getPlayerList(); players = playerListDialog->getPlayerList();
delete playerListDialog; delete playerListDialog;
// Prepare Progress // Prepare Progress
@ -1747,9 +2148,14 @@ void ProfileInterface::massTool(MassTool tool)
} }
int crewID = 0; int crewID = 0;
if (snapmaticWidgets.length() == 1)
{
crewID = snapmaticWidgets.at(0)->getPicture()->getSnapmaticProperties().crewID;
}
{ {
preSelectionCrewID: preSelectionCrewID:
bool ok; bool ok;
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")))
@ -1761,7 +2167,11 @@ preSelectionCrewID:
{ {
itemList += QString("%1 (%2)").arg(crew, crewDB->getCrewName(crew.toInt())); itemList += QString("%1 (%2)").arg(crew, crewDB->getCrewName(crew.toInt()));
} }
QString newCrew = QInputDialog::getItem(this, QApplication::translate("SnapmaticEditor", "Snapmatic Crew"), QApplication::translate("SnapmaticEditor", "New Snapmatic crew:"), itemList, 0, true, &ok, windowFlags()^Qt::Dialog^Qt::WindowMinMaxButtonsHint); if (crewList.contains(QString::number(crewID)))
{
indexNum = crewList.indexOf(QRegExp(QString::number(crewID)));
}
QString newCrew = QInputDialog::getItem(this, QApplication::translate("SnapmaticEditor", "Snapmatic Crew"), QApplication::translate("SnapmaticEditor", "New Snapmatic crew:"), itemList, indexNum, true, &ok, windowFlags()^Qt::Dialog^Qt::WindowMinMaxButtonsHint);
if (ok && !newCrew.isEmpty()) if (ok && !newCrew.isEmpty())
{ {
if (newCrew.contains(" ")) newCrew = newCrew.split(" ").at(0); if (newCrew.contains(" ")) newCrew = newCrew.split(" ").at(0);
@ -1774,6 +2184,10 @@ preSelectionCrewID:
goto preSelectionCrewID; goto preSelectionCrewID;
} }
} }
if (!crewList.contains(newCrew))
{
crewDB->addCrew(crewID);
}
crewID = newCrew.toInt(); crewID = newCrew.toInt();
} }
else else
@ -1865,6 +2279,10 @@ preSelectionCrewID:
} }
QString snapmaticTitle; QString snapmaticTitle;
if (snapmaticWidgets.length() == 1)
{
snapmaticTitle = snapmaticWidgets.at(0)->getPicture()->getPictureTitle();
}
{ {
preSelectionTitle: preSelectionTitle:
bool ok; bool ok;
@ -1944,3 +2362,9 @@ preSelectionTitle:
break; break;
} }
} }
int ProfileInterface::getRandomUid()
{
int random_int = pcg32_boundedrand_r(&rng, 2147483647);
return random_int;
}

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -29,6 +29,7 @@
#include "ExportThread.h" #include "ExportThread.h"
#include "SavegameData.h" #include "SavegameData.h"
#include "CrewDatabase.h" #include "CrewDatabase.h"
#include "pcg_basic.h"
#include <QProgressDialog> #include <QProgressDialog>
#include <QSpacerItem> #include <QSpacerItem>
#include <QDateTime> #include <QDateTime>
@ -100,21 +101,23 @@ private:
QMap<ProfileWidget*,QString> widgets; QMap<ProfileWidget*,QString> widgets;
QSpacerItem *saSpacerItem; QSpacerItem *saSpacerItem;
QStringList fixedPictures; QStringList fixedPictures;
QColor highlightBackColor;
QColor highlightTextColor;
QString enabledPicStr; QString enabledPicStr;
QString profileFolder; QString profileFolder;
QString profileName; QString profileName;
QString loadingStr; QString loadingStr;
QString language; QString language;
pcg32_random_t rng;
bool contextMenuOpened; bool contextMenuOpened;
bool isProfileLoaded; bool isProfileLoaded;
int selectedWidgts; int selectedWidgts;
int contentMode; int contentMode;
bool isSupportedImageFile(QString selectedFileName); bool isSupportedImageFile(QString selectedFileName);
bool importFile(QString selectedFile, QDateTime importDateTime, int *currentTime, bool notMultiple); bool importFile(QString selectedFile, QDateTime importDateTime, bool notMultiple);
void importFilesProgress(QStringList selectedFiles); bool importUrls(const QMimeData *mimeData);
bool importRemote(QUrl remoteUrl);
bool importImage(QImage *snapmaticImage, QDateTime importDateTime);
bool importFilesProgress(QStringList selectedFiles);
bool importSnapmaticPicture(SnapmaticPicture *picture, bool warn = true); bool importSnapmaticPicture(SnapmaticPicture *picture, bool warn = true);
bool importSavegameData(SavegameData *savegame, QString sgdPath, bool warn = true); bool importSavegameData(SavegameData *savegame, QString sgdPath, bool warn = true);
void pictureLoaded(SnapmaticPicture *picture, bool inserted); void pictureLoaded(SnapmaticPicture *picture, bool inserted);
@ -124,6 +127,7 @@ private:
void insertSnapmaticIPI(QWidget *widget); void insertSnapmaticIPI(QWidget *widget);
void insertSavegameIPI(QWidget *widget); void insertSavegameIPI(QWidget *widget);
void sortingProfileInterface(); void sortingProfileInterface();
int getRandomUid();
signals: signals:
void profileLoaded(); void profileLoaded();

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -7,34 +7,45 @@ Grand Theft Auto V Savegame and Snapmatic viewer/editor
- Let choose between multiple Social Club accounts as GTA V profiles IDs - Let choose between multiple Social Club accounts as GTA V profiles IDs
#### Screenshots #### Screenshots
![Snapmatic Picture Viewer](https://i.imgur.com/dQdW3hx.png) ![Snapmatic Picture Viewer](res/src/picture.png)
![User Interface](https://i.imgur.com/SRNQdq6.png) ![User Interface](res/src/mainui.png)
![Snapmatic Properties](https://i.imgur.com/j1Lodiu.png) ![Snapmatic Properties](res/src/prop.png)
#### Build gta5view for Windows
# Note: Install Docker Community Edition and Git before continuing
git clone https://gitlab.com/Syping/gta5view && cd gta5view
docker pull syping/qt5-static-mingw
docker run --rm -v ${PWD}:/gta5view -it syping/qt5-static-mingw
cd /gta5view && mkdir -p build && cd build
qmake-static ../gta5view.pro
make depend
make -j $(nproc --all)
#### Build gta5view for Debian/Ubuntu #### Build gta5view for Debian/Ubuntu
# Note: You can use 'sudo make install' instead of 'sudo checkinstall' sudo apt-get install git gcc g++ qtbase5-dev qttranslations5-l10n qt5-qmake make
sudo apt-get install git gcc g++ qtbase5-dev qttranslations5-l10n qt5-qmake make checkinstall git clone https://gitlab.com/Syping/gta5view && cd gta5view
git clone https://github.com/SyDevTeam/gta5view && cd gta5view mkdir -p build && cd build
mkdir -p build && cd build ../configure --prefix=/opt/gta5view
qmake -qt=5 GTA5SYNC_PREFIX=/usr ../gta5view.pro # or just qmake GTA5SYNC_PREFIX=/usr ../gta5view.pro make depend
make -j $(nproc --all) make -j $(nproc --all)
sudo checkinstall --pkgname=gta5view --pkggroup=utility --requires=libqt5core5a,libqt5gui5,libqt5network5,libqt5widgets5,qttranslations5-l10n sudo make install
#### Build gta5view for Windows
# Note: Install Docker Community Edition and Git before continuing #### Build gta5view for Fedora
git clone https://github.com/SyDevTeam/gta5view && cd gta5view
docker pull syping/qt5-static-mingw sudo dnf install git gcc gcc-c++ qt5-qtbase-devel qt5-qttranslations make
docker run --rm -v ${PWD}:/gta5view -it syping/qt5-static-mingw git clone https://gitlab.com/Syping/gta5view && cd gta5view
cd /gta5view && mkdir -p build && cd build mkdir -p build && cd build
qmake-static ../gta5view.pro ../configure --prefix=/opt/gta5view
make -j $(nproc --all) make depend
make -j $(nproc --all)
sudo make install
#### Build gta5view for Windows (Beginner) #### Build gta5view for Windows (Beginner)
Download the [Qt Framework](https://www.qt.io/) and install the MinGW version. Download the [Qt Framework](https://www.qt.io/) and install the MinGW version.
Download the Source Code over [GitHub](https://github.com/SyDevTeam/gta5view/archive/1.5.x.zip) or with your Git client. Download the Source Code over the Repository or with your Git client.
Open the gta5view.pro Project file with Qt Creator and build it over Qt Creator. Open the gta5view.pro Project file with Qt Creator and build it over Qt Creator.
#### Download Binary Releases #### Download Binary Releases

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/ *****************************************************************************/
#include "SnapmaticPicture.h"
#include "StringParser.h" #include "StringParser.h"
#include "SavegameData.h" #include "SavegameData.h"
#include <QStringBuilder> #include <QStringBuilder>
@ -42,7 +43,7 @@ bool SavegameData::readingSavegame()
QFile *saveFile = new QFile(savegameFileName); QFile *saveFile = new QFile(savegameFileName);
if (!saveFile->open(QFile::ReadOnly)) if (!saveFile->open(QFile::ReadOnly))
{ {
lastStep = "1;/1,OpenFile," % StringParser::convertDrawStringForLog(savegameFileName); lastStep = "1;/1,OpenFile," % SnapmaticPicture::convertDrawStringForLog(savegameFileName);
saveFile->deleteLater(); saveFile->deleteLater();
delete saveFile; delete saveFile;
return false; return false;
@ -51,7 +52,7 @@ bool SavegameData::readingSavegame()
// Reading Savegame Header // Reading Savegame Header
if (!saveFile->isReadable()) if (!saveFile->isReadable())
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(savegameFileName) % ",1,NOHEADER"; lastStep = "2;/3,ReadingFile," % SnapmaticPicture::convertDrawStringForLog(savegameFileName) % ",1,NOHEADER";
saveFile->close(); saveFile->close();
saveFile->deleteLater(); saveFile->deleteLater();
delete saveFile; delete saveFile;
@ -78,7 +79,7 @@ QString SavegameData::getSavegameDataString(const QByteArray &savegameHeader)
QList<QByteArray> savegameBytesList = savegameBytes.split(char(0x01)); QList<QByteArray> savegameBytesList = savegameBytes.split(char(0x01));
savegameBytes = savegameBytesList.at(1); savegameBytes = savegameBytesList.at(1);
savegameBytesList.clear(); savegameBytesList.clear();
return StringParser::parseTitleString(savegameBytes, savegameBytes.length()); return SnapmaticPicture::parseTitleString(savegameBytes, savegameBytes.length());
} }
bool SavegameData::readingSavegameFromFile(const QString &fileName) bool SavegameData::readingSavegameFromFile(const QString &fileName)

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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

View file

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -24,6 +24,7 @@
#include "SavegameData.h" #include "SavegameData.h"
#include "SavegameCopy.h" #include "SavegameCopy.h"
#include "AppEnv.h" #include "AppEnv.h"
#include "config.h"
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>
#include <QSettings> #include <QSettings>
@ -37,6 +38,13 @@
#include <QMenu> #include <QMenu>
#include <QUrl> #include <QUrl>
#ifdef GTA5SYNC_TELEMETRY
#include "TelemetryClass.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QDateTime>
#endif
SavegameWidget::SavegameWidget(QWidget *parent) : SavegameWidget::SavegameWidget(QWidget *parent) :
ProfileWidget(parent), ProfileWidget(parent),
ui(new Ui::SavegameWidget) ui(new Ui::SavegameWidget)
@ -50,9 +58,8 @@ SavegameWidget::SavegameWidget(QWidget *parent) :
qreal screenRatio = AppEnv::screenRatio(); qreal screenRatio = AppEnv::screenRatio();
ui->labSavegamePic->setFixedSize(48 * screenRatio, 27 * screenRatio); ui->labSavegamePic->setFixedSize(48 * screenRatio, 27 * screenRatio);
QPixmap savegamePixmap(":/img/savegame.png"); ui->labSavegamePic->setScaledContents(true);
if (screenRatio != 1) savegamePixmap = savegamePixmap.scaledToHeight(ui->labSavegamePic->height(), Qt::SmoothTransformation); ui->labSavegamePic->setPixmap(QPixmap(":/img/savegame.svgz"));
ui->labSavegamePic->setPixmap(savegamePixmap);
QString exportSavegameStr = tr("Export Savegame..."); QString exportSavegameStr = tr("Export Savegame...");
Q_UNUSED(exportSavegameStr) Q_UNUSED(exportSavegameStr)
@ -134,9 +141,41 @@ void SavegameWidget::on_cmdDelete_clicked()
if (!QFile::exists(sgdPath)) if (!QFile::exists(sgdPath))
{ {
emit savegameDeleted(); emit savegameDeleted();
#ifdef GTA5SYNC_TELEMETRY
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "DeleteSuccess";
jsonObject["ExtraFlags"] = "Savegame";
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
#endif
} }
else if(QFile::remove(sgdPath)) else if (QFile::remove(sgdPath))
{ {
#ifdef GTA5SYNC_TELEMETRY
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "DeleteSuccess";
jsonObject["ExtraFlags"] = "Savegame";
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
#endif
emit savegameDeleted(); emit savegameDeleted();
} }
else else

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2018 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
@ -22,6 +22,7 @@
#include "PlayerListDialog.h" #include "PlayerListDialog.h"
#include "StringParser.h" #include "StringParser.h"
#include "AppEnv.h" #include "AppEnv.h"
#include "config.h"
#include <QStringListIterator> #include <QStringListIterator>
#include <QStringBuilder> #include <QStringBuilder>
#include <QTextDocument> #include <QTextDocument>
@ -30,6 +31,12 @@
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>
#ifdef GTA5SYNC_TELEMETRY
#include "TelemetryClass.h"
#include <QJsonDocument>
#include <QJsonObject>
#endif
SnapmaticEditor::SnapmaticEditor(CrewDatabase *crewDB, ProfileDatabase *profileDB, QWidget *parent) : SnapmaticEditor::SnapmaticEditor(CrewDatabase *crewDB, ProfileDatabase *profileDB, QWidget *parent) :
QDialog(parent), crewDB(crewDB), profileDB(profileDB), QDialog(parent), crewDB(crewDB), profileDB(profileDB),
ui(new Ui::SnapmaticEditor) ui(new Ui::SnapmaticEditor)
@ -38,6 +45,7 @@ SnapmaticEditor::SnapmaticEditor(CrewDatabase *crewDB, ProfileDatabase *profileD
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
ui->setupUi(this); ui->setupUi(this);
ui->cmdCancel->setDefault(true);
ui->cmdCancel->setFocus(); ui->cmdCancel->setFocus();
// Set Icon for Apply Button // Set Icon for Apply Button
@ -260,11 +268,11 @@ void SnapmaticEditor::setSnapmaticTitle(const QString &title)
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</a>").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</a>").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()));
@ -329,7 +337,24 @@ void SnapmaticEditor::on_cmdApply_clicked()
} }
else else
{ {
smpic->updateStrings();
smpic->emitUpdate(); smpic->emitUpdate();
#ifdef GTA5SYNC_TELEMETRY
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "PropertyEdited";
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
#endif
} }
} }
close(); close();
@ -427,6 +452,10 @@ void SnapmaticEditor::on_labCrew_linkActivated(const QString &link)
return; return;
} }
} }
if (!crewList.contains(newCrew))
{
crewDB->addCrew(crewID);
}
crewID = newCrew.toInt(); crewID = newCrew.toInt();
setSnapmaticCrew(returnCrewName(crewID)); setSnapmaticCrew(returnCrewName(crewID));
} }

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -236,6 +236,9 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip">
<string>Apply changes</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Apply</string> <string>&amp;Apply</string>
</property> </property>
@ -249,6 +252,9 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip">
<string>Discard changes</string>
</property>
<property name="text"> <property name="text">
<string>&amp;Cancel</string> <string>&amp;Cancel</string>
</property> </property>

View file

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5sync-spv Grand Theft Auto Snapmatic Picture Viewer * gta5spv Grand Theft Auto Snapmatic Picture Viewer
* Copyright (C) 2016-2017 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
@ -17,12 +17,12 @@
*****************************************************************************/ *****************************************************************************/
#include "SnapmaticPicture.h" #include "SnapmaticPicture.h"
#include "StringParser.h"
#include <QStringBuilder> #include <QStringBuilder>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QStringList> #include <QStringList>
#include <QVariantMap> #include <QVariantMap>
#include <QTextCodec>
#include <QJsonArray> #include <QJsonArray>
#include <QFileInfo> #include <QFileInfo>
#include <QPainter> #include <QPainter>
@ -44,6 +44,7 @@
#define snapmaticUsefulLength 260 #define snapmaticUsefulLength 260
#define snapmaticFileMaxSize 528192 #define snapmaticFileMaxSize 528192
#define jpegHeaderLineDifStr 2 #define jpegHeaderLineDifStr 2
#define jpegHeaderLineDifLim 8
#define jpegPreHeaderLength 14 #define jpegPreHeaderLength 14
#define jpegPicStreamLength 524288 #define jpegPicStreamLength 524288
#define jsonStreamLength 3076 #define jsonStreamLength 3076
@ -57,6 +58,9 @@
#define titlStreamEditorLength 256 #define titlStreamEditorLength 256
#define titlStreamCharacterMax 39 #define titlStreamCharacterMax 39
// LIMIT ALLOCATIONS
#define jpegStreamLimitBegin 288
// IMAGES VALUES // IMAGES VALUES
#define snapmaticResolutionW 960 #define snapmaticResolutionW 960
#define snapmaticResolutionH 536 #define snapmaticResolutionH 536
@ -91,6 +95,7 @@ void SnapmaticPicture::reset()
// INIT PIC BOOLS // INIT PIC BOOLS
isCustomFormat = false; isCustomFormat = false;
isModernFormat = false;
isFormatSwitch = false; isFormatSwitch = false;
isLoadedInRAM = false; isLoadedInRAM = false;
lowRamMode = false; lowRamMode = false;
@ -101,7 +106,7 @@ void SnapmaticPicture::reset()
jsonStr = QString(); jsonStr = QString();
// SNAPMATIC DEFAULTS // SNAPMATIC DEFAULTS
#ifdef GTA5SYNC_CSDF #ifdef GTA5SYNC_NOASSIST
careSnapDefault = false; careSnapDefault = false;
#else #else
careSnapDefault = true; careSnapDefault = true;
@ -121,7 +126,7 @@ bool SnapmaticPicture::preloadFile()
if (!picFile->open(QFile::ReadOnly)) if (!picFile->open(QFile::ReadOnly))
{ {
lastStep = "1;/1,OpenFile," % StringParser::convertDrawStringForLog(picFilePath); lastStep = "1;/1,OpenFile," % convertDrawStringForLog(picFilePath);
delete picFile; delete picFile;
return false; return false;
} }
@ -138,6 +143,7 @@ bool SnapmaticPicture::preloadFile()
else else
{ {
isCustomFormat = false; isCustomFormat = false;
isModernFormat = false;
isLoadedInRAM = true; isLoadedInRAM = true;
} }
} }
@ -187,35 +193,59 @@ bool SnapmaticPicture::preloadFile()
rawPicContent = qUncompress(g5eContent); rawPicContent = qUncompress(g5eContent);
// Setting is values // Setting is values
isModernFormat = false;
isLoadedInRAM = true; isLoadedInRAM = true;
} }
else else
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",4,G5E_FORMATERROR"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",4,G5E_FORMATERROR";
return false; return false;
} }
} }
else else
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",3,G5E_FORMATERROR"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,G5E_FORMATERROR";
return false; return false;
} }
} }
else else
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",2,G5E_FORMATERROR"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",2,G5E_FORMATERROR";
return false;
}
}
else if (g5eContent.left(2).toHex() == QByteArray("3200"))
{
g5eContent.remove(0, 2);
if (g5eContent.left(2).toHex() == QByteArray("0001"))
{
g5eContent.remove(0, 2);
rawPicContent = qUncompress(g5eContent);
// Setting is values
isModernFormat = true;
isLoadedInRAM = true;
}
else if (g5eContent.left(2).toHex() == QByteArray("0002"))
{
lastStep = "2;/4,ReadingFile," % convertDrawStringForLog(picFilePath) % ",2,G5E2_FORMATWRONG,G5E2_SGD";
return false;
}
else
{
lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",2,G5E2_MISSINGEXTENSION";
return false; return false;
} }
} }
else else
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",1,G5E_NOTCOMPATIBLE"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",1,G5E_NOTCOMPATIBLE";
return false; return false;
} }
} }
else else
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",1,G5E_FORMATERROR"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",1,G5E_FORMATERROR";
return false; return false;
} }
} }
@ -244,7 +274,7 @@ bool SnapmaticPicture::readingPicture(bool writeEnabled_, bool cacheEnabled_, bo
// Reading Snapmatic Header // Reading Snapmatic Header
if (!picStream->isReadable()) if (!picStream->isReadable())
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",1,NOHEADER"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",1,NOHEADER";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
@ -253,7 +283,7 @@ bool SnapmaticPicture::readingPicture(bool writeEnabled_, bool cacheEnabled_, bo
pictureHead = getSnapmaticHeaderString(snapmaticHeaderLine); pictureHead = getSnapmaticHeaderString(snapmaticHeaderLine);
if (pictureHead == QLatin1String("MALFORMED")) if (pictureHead == QLatin1String("MALFORMED"))
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",1,MALFORMEDHEADER"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",1,MALFORMEDHEADER";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
@ -262,7 +292,7 @@ bool SnapmaticPicture::readingPicture(bool writeEnabled_, bool cacheEnabled_, bo
// Reading JPEG Header Line // Reading JPEG Header Line
if (!picStream->isReadable()) if (!picStream->isReadable())
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",2,NOHEADER"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",2,NOHEADER";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
@ -273,33 +303,27 @@ bool SnapmaticPicture::readingPicture(bool writeEnabled_, bool cacheEnabled_, bo
jpegHeaderLine.remove(0, jpegHeaderLineDifStr); jpegHeaderLine.remove(0, jpegHeaderLineDifStr);
if (jpegHeaderLine.left(4) != QByteArray("JPEG")) if (jpegHeaderLine.left(4) != QByteArray("JPEG"))
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",2,NOJPEG"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",2,NOJPEG";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
} }
// Get JPEG Size Limit
jpegHeaderLine.remove(0, jpegHeaderLineDifLim);
QString jpegHeaderLineStr = QString::fromUtf8(jpegHeaderLine.toHex().remove(8 - 2, 2));
QString hexadecimalStr = jpegHeaderLineStr.mid(4, 2) % jpegHeaderLineStr.mid(2, 2) % jpegHeaderLineStr.mid(0, 2);
jpegRawContentSize = hexadecimalStr.toInt(0, 16);
// Read JPEG Stream // Read JPEG Stream
if (!picStream->isReadable()) if (!picStream->isReadable())
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",2,NOPIC"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",2,NOPIC";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
} }
QByteArray jpegRawContent = picStream->read(jpegPicStreamLength); QByteArray jpegRawContent = picStream->read(jpegPicStreamLength);
if (jpegRawContent.contains("\xFF\xD9"))
{
int jpegRawContentSizeT = jpegRawContent.indexOf("\xFF\xD9") + 2;
jpegRawContentSizeE = jpegRawContentSizeT;
jpegRawContentSize = jpegRawContentSizeT;
if (jpegRawContent.contains("\xFF\x45\x4F\x49"))
{
jpegRawContentSizeT = jpegRawContent.indexOf("\xFF\x45\x4F\x49");
}
jpegRawContent = jpegRawContent.left(jpegRawContentSize);
jpegRawContentSize = jpegRawContentSizeT;
}
if (cacheEnabled) picOk = cachePicture.loadFromData(jpegRawContent, "JPEG"); if (cacheEnabled) picOk = cachePicture.loadFromData(jpegRawContent, "JPEG");
if (!cacheEnabled) if (!cacheEnabled)
{ {
@ -336,14 +360,14 @@ bool SnapmaticPicture::readingPicture(bool writeEnabled_, bool cacheEnabled_, bo
// Read JSON Stream // Read JSON Stream
if (!picStream->isReadable()) if (!picStream->isReadable())
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",3,NOJSON"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,NOJSON";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
} }
else if (picStream->read(4) != QByteArray("JSON")) else if (picStream->read(4) != QByteArray("JSON"))
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",3,CTJSON"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,CTJSON";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
@ -354,14 +378,14 @@ bool SnapmaticPicture::readingPicture(bool writeEnabled_, bool cacheEnabled_, bo
if (!picStream->isReadable()) if (!picStream->isReadable())
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",4,NOTITL"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",4,NOTITL";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
} }
else if (picStream->read(4) != QByteArray("TITL")) else if (picStream->read(4) != QByteArray("TITL"))
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",4,CTTITL"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",4,CTTITL";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
@ -371,14 +395,14 @@ bool SnapmaticPicture::readingPicture(bool writeEnabled_, bool cacheEnabled_, bo
if (!picStream->isReadable()) if (!picStream->isReadable())
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",5,NODESC"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",5,NODESC";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return picOk; return picOk;
} }
else if (picStream->read(4) != QByteArray("DESC")) else if (picStream->read(4) != QByteArray("DESC"))
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",5,CTDESC"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",5,CTDESC";
picStream->close(); picStream->close();
delete picStream; delete picStream;
return false; return false;
@ -403,7 +427,7 @@ QString SnapmaticPicture::getSnapmaticHeaderString(const QByteArray &snapmaticHe
QList<QByteArray> snapmaticBytesList = snapmaticHeader.left(snapmaticUsefulLength).split('\x01'); QList<QByteArray> snapmaticBytesList = snapmaticHeader.left(snapmaticUsefulLength).split('\x01');
if (snapmaticBytesList.length() < 2) { return QLatin1String("MALFORMED"); } if (snapmaticBytesList.length() < 2) { return QLatin1String("MALFORMED"); }
QByteArray snapmaticBytes = snapmaticBytesList.at(1); QByteArray snapmaticBytes = snapmaticBytesList.at(1);
return StringParser::parseTitleString(snapmaticBytes, snapmaticBytes.length()); return parseTitleString(snapmaticBytes, snapmaticBytes.length());
} }
QString SnapmaticPicture::getSnapmaticJSONString(const QByteArray &jsonBytes) QString SnapmaticPicture::getSnapmaticJSONString(const QByteArray &jsonBytes)
@ -440,6 +464,7 @@ 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 (isModernFormat) { picFileName = "PGTA5" % QString::number(localProperties.uid); }
picExportFileName = exportStr % "_" % cmpPicTitl; picExportFileName = exportStr % "_" % cmpPicTitl;
} }
@ -480,7 +505,7 @@ bool SnapmaticPicture::setImage(const QImage &picture)
picStreamT.close(); picStreamT.close();
if (saveSuccess) if (saveSuccess)
{ {
if (picByteArrayT.length() > jpegRawContentSize) if (picByteArrayT.length() > jpegPicStreamLength)
{ {
comLvl--; comLvl--;
saveSuccess = false; saveSuccess = false;
@ -500,29 +525,34 @@ bool SnapmaticPicture::setPictureStream(const QByteArray &streamArray) // clean
{ {
if (writeEnabled) if (writeEnabled)
{ {
bool customEOI = false;
QByteArray picByteArray = streamArray; QByteArray picByteArray = streamArray;
if (lowRamMode) { rawPicContent = qUncompress(rawPicContent); } if (lowRamMode) { rawPicContent = qUncompress(rawPicContent); }
QBuffer snapmaticStream(&rawPicContent); QBuffer snapmaticStream(&rawPicContent);
snapmaticStream.open(QIODevice::ReadWrite); snapmaticStream.open(QIODevice::ReadWrite);
if (!snapmaticStream.seek(jpegStreamEditorBegin)) return false; if (!snapmaticStream.seek(jpegStreamEditorBegin)) return false;
if (picByteArray.length() > jpegPicStreamLength) return false; if (picByteArray.length() > jpegPicStreamLength) return false;
if (picByteArray.length() < jpegRawContentSize && jpegRawContentSize + 4 < jpegPicStreamLength)
{
customEOI = true;
}
while (picByteArray.length() != jpegPicStreamLength) while (picByteArray.length() != jpegPicStreamLength)
{ {
picByteArray += '\x00'; picByteArray += '\x00';
} }
if (customEOI)
{
picByteArray.replace(jpegRawContentSize, 4, "\xFF\x45\x4F\x49");
}
int result = snapmaticStream.write(picByteArray); int result = snapmaticStream.write(picByteArray);
QString hexadecimalStr;
hexadecimalStr.setNum(streamArray.length(), 16);
while (hexadecimalStr.length() != 6)
{
hexadecimalStr.prepend('0');
}
hexadecimalStr = hexadecimalStr.mid(4, 2) % hexadecimalStr.mid(2, 2) % hexadecimalStr.mid(0, 2);
bool updatedRawContentSize = false;
if (snapmaticStream.seek(jpegStreamLimitBegin))
{
snapmaticStream.write(QByteArray::fromHex(hexadecimalStr.toUtf8()));
updatedRawContentSize = true;
}
snapmaticStream.close(); snapmaticStream.close();
if (result != 0) if (result != 0)
{ {
if (updatedRawContentSize) { jpegRawContentSize = streamArray.length(); }
if (cacheEnabled) if (cacheEnabled)
{ {
QImage replacedPicture; QImage replacedPicture;
@ -792,7 +822,7 @@ QImage SnapmaticPicture::getImage(bool fastLoad)
QFile *picFile = new QFile(picFilePath); QFile *picFile = new QFile(picFilePath);
if (!picFile->open(QFile::ReadOnly)) if (!picFile->open(QFile::ReadOnly))
{ {
lastStep = "1;/1,OpenFile," % StringParser::convertDrawStringForLog(picFilePath); lastStep = "1;/1,OpenFile," % convertDrawStringForLog(picFilePath);
delete picFile; delete picFile;
return QImage(); return QImage();
} }
@ -1004,7 +1034,7 @@ void SnapmaticPicture::parseJsonContent()
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 { jsonIncomplete = true; } // else { jsonIncomplete = true; } // Game release Snapmatic pictures prior May 2015 left out rsedtr, so don't force exists on that one
if (!jsonIncomplete && !jsonError) if (!jsonIncomplete && !jsonError)
{ {
@ -1014,15 +1044,15 @@ void SnapmaticPicture::parseJsonContent()
{ {
if (jsonIncomplete && jsonError) if (jsonIncomplete && jsonError)
{ {
lastStep = "2;/4,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE,JSONERROR"; lastStep = "2;/4,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE,JSONERROR";
} }
else if (jsonIncomplete) else if (jsonIncomplete)
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE";
} }
else if (jsonError) else if (jsonError)
{ {
lastStep = "2;/3,ReadingFile," % StringParser::convertDrawStringForLog(picFilePath) % ",3,JSONERROR"; lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONERROR";
} }
jsonOk = false; jsonOk = false;
} }
@ -1132,27 +1162,13 @@ bool SnapmaticPicture::exportPicture(const QString &fileName, SnapmaticFormat fo
{ {
if (format == SnapmaticFormat::G5E_Format) if (format == SnapmaticFormat::G5E_Format)
{ {
// Modern compressed export // Modern compressed export (v2)
QByteArray stockFileNameUTF8 = picFileName.toUtf8();
QByteArray numberLength = QByteArray::number(stockFileNameUTF8.length());
if (numberLength.length() == 1)
{
numberLength.insert(0, '0');
}
else if (numberLength.length() != 2)
{
numberLength = "00";
}
QByteArray g5eHeader; QByteArray g5eHeader;
g5eHeader.reserve(stockFileNameUTF8.length() + 16); g5eHeader.reserve(10);
g5eHeader += '\x00'; // First Null Byte g5eHeader += '\x00'; // First Null Byte
g5eHeader += QByteArray("G5E"); // GTA 5 Export g5eHeader += QByteArray("G5E"); // GTA 5 Export
g5eHeader += '\x10'; g5eHeader += '\x00'; // 2 byte GTA 5 Export Version g5eHeader += '\x32'; g5eHeader += '\x00'; // 2 byte GTA 5 Export Version
g5eHeader += QByteArray("LEN"); // Before Length g5eHeader += '\x00'; g5eHeader += '\x01'; // 2 byte GTA 5 Export Type
g5eHeader += QByteArray::fromHex(numberLength); // Length in HEX before Compressed
g5eHeader += QByteArray("FIL"); // Before File Name
g5eHeader += stockFileNameUTF8; // File Name
g5eHeader += QByteArray("COM"); // Before Compressed
if (picFile->write(g5eHeader) == -1) { writeFailure = true; } if (picFile->write(g5eHeader) == -1) { writeFailure = true; }
if (!lowRamMode) if (!lowRamMode)
{ {
@ -1377,7 +1393,7 @@ 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() <= titlStreamCharacterMax && title.length() > 0) if (title.length() <= titlStreamCharacterMax && title.length() > 0)
{ {
for (QChar titleChar : title) for (const QChar &titleChar : title)
{ {
if (!verifyTitleChar(titleChar)) return false; if (!verifyTitleChar(titleChar)) return false;
} }
@ -1396,3 +1412,25 @@ bool SnapmaticPicture::verifyTitleChar(const QChar &titleChar)
} }
return false; return false;
} }
// STRING OPERATIONS
QString SnapmaticPicture::parseTitleString(const QByteArray &commitBytes, int maxLength)
{
Q_UNUSED(maxLength)
QString retStr = QTextCodec::codecForName("UTF-16LE")->toUnicode(commitBytes).trimmed();
retStr.remove(QChar('\x00'));
return retStr;
}
QString SnapmaticPicture::convertDrawStringForLog(const QString &inputStr)
{
QString outputStr = inputStr;
return outputStr.replace("&","&u;").replace(",", "&c;");
}
QString SnapmaticPicture::convertLogStringForDraw(const QString &inputStr)
{
QString outputStr = inputStr;
return outputStr.replace("&c;",",").replace("&u;", "&");
}

View file

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5sync-spv Grand Theft Auto Snapmatic Picture Viewer * gta5spv Grand Theft Auto Snapmatic Picture Viewer
* Copyright (C) 2016-2017 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
@ -134,6 +134,11 @@ public:
// VERIFY CONTENT // VERIFY CONTENT
static bool verifyTitle(const QString &title); static bool verifyTitle(const QString &title);
// STRING OPERATIONS
static QString parseTitleString(const QByteArray &commitBytes, int maxLength);
static QString convertDrawStringForLog(const QString &inputStr);
static QString convertLogStringForDraw(const QString &inputStr);
private: private:
QString getSnapmaticHeaderString(const QByteArray &snapmaticHeader); QString getSnapmaticHeaderString(const QByteArray &snapmaticHeader);
QString getSnapmaticJSONString(const QByteArray &jsonBytes); QString getSnapmaticJSONString(const QByteArray &jsonBytes);
@ -155,6 +160,7 @@ private:
bool isLoadedInRAM; bool isLoadedInRAM;
bool isCustomFormat; bool isCustomFormat;
bool isFormatSwitch; bool isFormatSwitch;
bool isModernFormat;
bool careSnapDefault; bool careSnapDefault;
int jpegRawContentSize; int jpegRawContentSize;
int jpegRawContentSizeE; int jpegRawContentSizeE;

View file

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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
@ -27,6 +27,7 @@
#include "PictureDialog.h" #include "PictureDialog.h"
#include "PictureExport.h" #include "PictureExport.h"
#include "StringParser.h" #include "StringParser.h"
#include "ImportDialog.h"
#include "AppEnv.h" #include "AppEnv.h"
#include "config.h" #include "config.h"
#include <QStringBuilder> #include <QStringBuilder>
@ -37,6 +38,12 @@
#include <QMenu> #include <QMenu>
#include <QFile> #include <QFile>
#ifdef GTA5SYNC_TELEMETRY
#include "TelemetryClass.h"
#include <QJsonDocument>
#include <QJsonObject>
#endif
SnapmaticWidget::SnapmaticWidget(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QString profileName, QWidget *parent) : SnapmaticWidget::SnapmaticWidget(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QString profileName, QWidget *parent) :
ProfileWidget(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), profileName(profileName), ProfileWidget(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), profileName(profileName),
ui(new Ui::SnapmaticWidget) ui(new Ui::SnapmaticWidget)
@ -71,9 +78,16 @@ void SnapmaticWidget::setSnapmaticPicture(SnapmaticPicture *picture)
QObject::connect(picture, SIGNAL(customSignal(QString)), this, SLOT(customSignal(QString))); QObject::connect(picture, SIGNAL(customSignal(QString)), this, SLOT(customSignal(QString)));
qreal screenRatio = AppEnv::screenRatio(); qreal screenRatio = AppEnv::screenRatio();
qreal screenRatioPR = AppEnv::screenRatioPR();
ui->labPicture->setFixedSize(48 * screenRatio, 27 * screenRatio); ui->labPicture->setFixedSize(48 * screenRatio, 27 * screenRatio);
QPixmap SnapmaticPixmap = QPixmap::fromImage(picture->getImage().scaled(ui->labPicture->width(), ui->labPicture->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::AutoColor); ui->labPicture->setScaledContents(true);
QPixmap SnapmaticPixmap = QPixmap::fromImage(picture->getImage().scaled(ui->labPicture->width() * screenRatioPR, ui->labPicture->height() * screenRatioPR, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::AutoColor);
#if QT_VERSION >= 0x050600
SnapmaticPixmap.setDevicePixelRatio(screenRatioPR);
#endif
ui->labPicStr->setText(smpic->getPictureStr() % "\n" % smpic->getPictureTitl()); ui->labPicStr->setText(smpic->getPictureStr() % "\n" % smpic->getPictureTitl());
ui->labPicture->setPixmap(SnapmaticPixmap); ui->labPicture->setPixmap(SnapmaticPixmap);
@ -106,7 +120,7 @@ void SnapmaticWidget::on_cmdView_clicked()
{ {
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
settings.beginGroup("Interface"); settings.beginGroup("Interface");
bool navigationBar = settings.value("NavigationBar", false).toBool(); bool navigationBar = settings.value("NavigationBar", true).toBool();
settings.endGroup(); settings.endGroup();
PictureDialog *picDialog = new PictureDialog(profileDB, crewDB, profileName, this); PictureDialog *picDialog = new PictureDialog(profileDB, crewDB, profileName, this);
@ -128,7 +142,7 @@ void SnapmaticWidget::on_cmdView_clicked()
picDialog->showMaximized(); picDialog->showMaximized();
#else #else
picDialog->show(); picDialog->show();
if (navigationBar) picDialog->stylizeDialog(); if (navigationBar) picDialog->styliseDialog();
//picDialog->adaptNewDialogSize(); //picDialog->adaptNewDialogSize();
picDialog->setMinimumSize(picDialog->size()); picDialog->setMinimumSize(picDialog->size());
picDialog->setMaximumSize(picDialog->size()); picDialog->setMaximumSize(picDialog->size());
@ -157,8 +171,25 @@ 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->deletePicFile()) if (smpic->deletePictureFile())
{ {
#ifdef GTA5SYNC_TELEMETRY
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "DeleteSuccess";
jsonObject["ExtraFlags"] = "Snapmatic";
jsonObject["DeletedSize"] = QString::number(smpic->getContentMaxLength());
jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
#endif
return true; return true;
} }
else else
@ -320,11 +351,57 @@ void SnapmaticWidget::editSnapmaticRawJson()
void SnapmaticWidget::editSnapmaticImage() void SnapmaticWidget::editSnapmaticImage()
{ {
ImageEditorDialog *imageEditor = new ImageEditorDialog(smpic, profileName, this); QImage *currentImage = new QImage(smpic->getImage());
imageEditor->setModal(true); ImportDialog *importDialog = new ImportDialog(profileName, this);
imageEditor->show(); importDialog->setImage(currentImage);
imageEditor->exec(); importDialog->enableOverwriteMode();
delete imageEditor; importDialog->setModal(true);
importDialog->exec();
if (importDialog->isImportAgreed())
{
const QByteArray previousPicture = smpic->getPictureStream();
bool success = smpic->setImage(importDialog->image());
if (success)
{
QString currentFilePath = smpic->getPictureFilePath();
QString originalFilePath = smpic->getOriginalPictureFilePath();
QString backupFileName = originalFilePath % ".bak";
if (!QFile::exists(backupFileName))
{
QFile::copy(currentFilePath, backupFileName);
}
if (!smpic->exportPicture(currentFilePath))
{
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"));
return;
}
smpic->emitCustomSignal("PictureUpdated");
#ifdef GTA5SYNC_TELEMETRY
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "ImageEdited";
jsonObject["ExtraFlags"] = "Interface";
jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
#endif
}
else
{
QMessageBox::warning(this, QApplication::translate("ImageEditorDialog", "Snapmatic Image Editor"), QApplication::translate("ImageEditorDialog", "Patching of Snapmatic Image failed because of Image Error"));
return;
}
}
delete importDialog;
} }
void SnapmaticWidget::openMapViewer() void SnapmaticWidget::openMapViewer()
@ -357,6 +434,26 @@ void SnapmaticWidget::openMapViewer()
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
else
{
QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
telemetrySettings.beginGroup("Telemetry");
bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
telemetrySettings.endGroup();
if (pushUsageData && Telemetry->canPush())
{
QJsonDocument jsonDocument;
QJsonObject jsonObject;
jsonObject["Type"] = "LocationEdited";
jsonObject["ExtraFlags"] = "Interface";
jsonObject["EditedSize"] = QString::number(picture->getContentMaxLength());
jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
jsonDocument.setObject(jsonObject);
Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
}
}
#endif
} }
delete mapLocDialog; delete mapLocDialog;
} }

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

View file

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* gta5sync GRAND THEFT AUTO V SYNC * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 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

Some files were not shown because too many files have changed in this diff Show more