diff --git a/.ci/app.rc b/.ci/app.rc deleted file mode 100644 index 8a785d2..0000000 --- a/.ci/app.rc +++ /dev/null @@ -1,33 +0,0 @@ -IDI_ICON1 ICON DISCARDABLE "5sync.ico" -#define RT_MANIFEST 24 -#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "gta5view.exe.manifest" -#include -VS_VERSION_INFO VERSIONINFO -FILEVERSION MAJOR_VER, MINOR_VER, PATCH_VER, INT_BUILD_VER -PRODUCTVERSION MAJOR_VER, MINOR_VER, PATCH_VER, INT_BUILD_VER -FILEFLAGSMASK 0x3fL -FILEFLAGS 0 -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_APP -FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0809, 1200 - END - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Syping" - VALUE "FileDescription", "gta5view" - VALUE "FileVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER" - VALUE "InternalName", "gta5view" - VALUE "LegalCopyright", "Copyright 2016-2023 Syping" - VALUE "OriginalFilename", "gta5view.exe" - VALUE "ProductName", "gta5view" - VALUE "ProductVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER" - END - END -END diff --git a/.ci/ci.sh b/.ci/ci.sh deleted file mode 100755 index 8cc49f6..0000000 --- a/.ci/ci.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash - -if [ $(git name-rev --tags --name-only $(git rev-parse HEAD)) == "undefined" ]; then - export APPLICATION_VERSION=$(lua -e 'for line in io.lines("config.h") do local m = string.match(line, "#define GTA5SYNC_APPVER \"(.+)\"$"); if m then print(m); os.exit(0) end end') -else - export APPLICATION_VERSION=$(git name-rev --tags --name-only $(git rev-parse HEAD)) -fi -export PACKAGE_VERSION=$(grep -oE '^[^\-]*' <<< $APPLICATION_VERSION) -export PACKAGE_BUILD=$(grep -oP '\-\K.+' <<< $APPLICATION_VERSION) -export EXECUTABLE_VERSION=${PACKAGE_VERSION}${PACKAGE_BUILD}${EXECUTABLE_TAG} - -export APPLICATION_MAJOR_VERSION=$(cut -d. -f1 <<< $APPLICATION_VERSION) -export APPLICATION_MINOR_VERSION=$(cut -d. -f2 <<< $APPLICATION_VERSION) -export APPLICATION_PATCH_VERSION=$(cut -d. -f3 <<< $APPLICATION_VERSION) - -if [ "${PACKAGE_BUILD}" == "" ]; then - export PACKAGE_BUILD=1 -else - export APPLICATION_BUILD_INT_VERSION=$(grep -oE '[1-9]*$' <<< $PACKAGE_BUILD) - export APPLICATION_BUILD_STR_VERSION=-${PACKAGE_BUILD} -fi - -cat ".ci/app.rc" | sed \ - -e "s/MAJOR_VER/$APPLICATION_MAJOR_VERSION/g" \ - -e "s/MINOR_VER/$APPLICATION_MINOR_VERSION/g" \ - -e "s/PATCH_VER/$APPLICATION_PATCH_VERSION/g" \ - -e "s/INT_BUILD_VER/0/g" \ - -e "s/STR_BUILD_VER/$APPLICATION_BUILD_STR_VERSION/g" \ - -e "s/STR_BUILD_VER/$APPLICATION_BUILD_STR_VERSION/g" \ - > "res/app.rc" - -if [ "${BUILD_TYPE}" == "ALPHA" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Alpha" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Alpha\\\\\\\"" -elif [ "${BUILD_TYPE}" == "Alpha" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Alpha" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Alpha\\\\\\\"" -elif [ "${BUILD_TYPE}" == "BETA" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Beta" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Beta\\\\\\\"" -elif [ "${BUILD_TYPE}" == "Beta" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Beta" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Beta\\\\\\\"" -elif [ "${BUILD_TYPE}" == "DEV" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Developer" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Developer\\\\\\\"" -elif [ "${BUILD_TYPE}" == "Development" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Developer" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Developer\\\\\\\"" -elif [ "${BUILD_TYPE}" == "DAILY" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Daily Build" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Daily Build\\\\\\\"" -elif [ "${BUILD_TYPE}" == "Daily" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Daily Build" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Daily Build\\\\\\\"" -elif [ "${BUILD_TYPE}" == "RC" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release Candidate" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release Candidate\\\\\\\"" -elif [ "${BUILD_TYPE}" == "Release Candidate" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release Candidate" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release Candidate\\\\\\\"" -elif [ "${BUILD_TYPE}" == "REL" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release\\\\\\\"" -elif [ "${BUILD_TYPE}" == "Release" ]; then - export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release" - export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release\\\\\\\"" -fi - -export PROJECT_DIR=$(pwd) - -.ci/${BUILD_SCRIPT} diff --git a/.ci/debian_build.sh b/.ci/debian_build.sh deleted file mode 100755 index 57aa9c9..0000000 --- a/.ci/debian_build.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -# Creating folders -cd ${PROJECT_DIR} && \ -echo "gta5view build version is ${APPLICATION_VERSION}" && \ -mkdir -p build && \ -mkdir -p assets && \ -chmod -x res/gta5sync_*.qm res/*.desktop res/*gta5view*.png && \ -cd build && \ -mkdir -p qt5 && \ -cd qt5 && \ -echo "Grand Theft Auto V Snapmatic and Savegame viewer/editor" > ./description-pak && \ -cd .. && \ - -# Set compiler -export CC=clang && \ -export CXX=clang++ && \ - -# Prepare checkinstall step -mkdir -p /usr/share/gta5view && \ - -# Starting build -cd qt5 && \ -cmake \ - "-DCMAKE_INSTALL_PREFIX=/usr" \ - "${CMAKE_BUILD_TYPE}" \ - "-DFORCE_QT_VERSION=5" \ - "-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \ - "-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \ - "-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \ - "-DWITH_DONATE=ON" \ - "-DWITH_TELEMETRY=ON" \ - "-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \ - "-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \ - "-DQCONF_BUILD=ON" \ - ../../ && \ -make -j 4 && \ -checkinstall -D --default --nodoc --install=no --pkgname=gta5view --pkgversion=${PACKAGE_VERSION} --pkgrelease=${PACKAGE_BUILD} --pkggroup=utility --maintainer="Syping \" --requires=libqt5core5a,libqt5gui5,libqt5network5,libqt5svg5,libqt5widgets5,qttranslations5-l10n --conflicts=gta5view-qt4,gta5view-qt5 --replaces=gta5view-qt4,gta5view-qt5 --pakdir=${PROJECT_DIR}/assets diff --git a/.ci/debian_ci.sh b/.ci/debian_ci.sh deleted file mode 100755 index bc14a86..0000000 --- a/.ci/debian_ci.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -# Install packages -.ci/debian_install.sh && \ - -# Build gta5view -.ci/debian_build.sh && \ -cd ${PROJECT_DIR} diff --git a/.ci/debian_docker.sh b/.ci/debian_docker.sh deleted file mode 100755 index 80f6c42..0000000 --- a/.ci/debian_docker.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -if [ "${DOCKER_USER}" != "" ]; then - DOCKER_IMAGE=${DOCKER_USER}/debian:${DEBIAN_VERSION} -else - DOCKER_IMAGE=debian:${DEBIAN_VERSION} -fi -PROJECT_DIR_DOCKER=/gta5view - -cd ${PROJECT_DIR} && \ -docker pull ${DOCKER_IMAGE} && \ -docker run --rm \ - -v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \ - ${DOCKER_IMAGE} \ - /bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export APT_INSTALL=${APT_INSTALL} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/debian_install.sh && .ci/debian_build.sh" diff --git a/.ci/debian_install.sh b/.ci/debian_install.sh deleted file mode 100755 index 12356e9..0000000 --- a/.ci/debian_install.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# Source OS Release -source /etc/os-release - -# When Debian add backports -if [ "${ID}" == "debian" ]; then - echo "deb http://deb.debian.org/debian ${VERSION_CODENAME}-backports main" >> /etc/apt/sources.list -fi - -# Install packages -apt-get update -qq && \ -apt-get install -qq ${APT_INSTALL} checkinstall cmake dpkg-dev fakeroot g++ gcc qtbase5-dev qt5-qmake qttranslations5-l10n libqt5svg5-dev diff --git a/.ci/donate.txt b/.ci/donate.txt deleted file mode 100644 index 407130d..0000000 --- a/.ci/donate.txt +++ /dev/null @@ -1 +0,0 @@ -btc:187NSQSPzdMpQDGhxZAuw4AhZ7LgoAPV7D,eth:0x19d71DfCa86104d37a13D3c5d419936421CDC569,ltc:LKr6yvBoMMGmcxViS8Kc1A2sDjVSWTXn4m,xmr:43TB3ZMP5nk1pu5EQXRGPzdTKvmFEBGgccX3tNhRknLLiUYQ7z7dNedVHEA6WrWdByZv1isvFmjSGhCF7ddx3eRxFdm5Fzz \ No newline at end of file diff --git a/.ci/dropbox_uploader.sh b/.ci/dropbox_uploader.sh deleted file mode 100755 index ca8ee36..0000000 --- a/.ci/dropbox_uploader.sh +++ /dev/null @@ -1,1763 +0,0 @@ -#!/usr/bin/env bash -# -# Dropbox Uploader -# -# Copyright (C) 2010-2017 Andrea Fabrizi -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# - -#Default configuration file -CONFIG_FILE=~/.dropbox_uploader - -#Default chunk size in Mb for the upload process -#It is recommended to increase this value only if you have enough free space on your /tmp partition -#Lower values may increase the number of http requests -CHUNK_SIZE=50 - -#Curl location -#If not set, curl will be searched into the $PATH -#CURL_BIN="/usr/bin/curl" - -#Default values -TMP_DIR="/tmp" -DEBUG=0 -QUIET=0 -SHOW_PROGRESSBAR=0 -SKIP_EXISTING_FILES=0 -ERROR_STATUS=0 -EXCLUDE=() - -#Don't edit these... -API_LONGPOLL_FOLDER="https://notify.dropboxapi.com/2/files/list_folder/longpoll" -API_CHUNKED_UPLOAD_START_URL="https://content.dropboxapi.com/2/files/upload_session/start" -API_CHUNKED_UPLOAD_FINISH_URL="https://content.dropboxapi.com/2/files/upload_session/finish" -API_CHUNKED_UPLOAD_APPEND_URL="https://content.dropboxapi.com/2/files/upload_session/append_v2" -API_UPLOAD_URL="https://content.dropboxapi.com/2/files/upload" -API_DOWNLOAD_URL="https://content.dropboxapi.com/2/files/download" -API_DELETE_URL="https://api.dropboxapi.com/2/files/delete" -API_MOVE_URL="https://api.dropboxapi.com/2/files/move" -API_COPY_URL="https://api.dropboxapi.com/2/files/copy" -API_METADATA_URL="https://api.dropboxapi.com/2/files/get_metadata" -API_LIST_FOLDER_URL="https://api.dropboxapi.com/2/files/list_folder" -API_LIST_FOLDER_CONTINUE_URL="https://api.dropboxapi.com/2/files/list_folder/continue" -API_ACCOUNT_INFO_URL="https://api.dropboxapi.com/2/users/get_current_account" -API_ACCOUNT_SPACE_URL="https://api.dropboxapi.com/2/users/get_space_usage" -API_MKDIR_URL="https://api.dropboxapi.com/2/files/create_folder" -API_SHARE_URL="https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings" -API_SHARE_LIST="https://api.dropboxapi.com/2/sharing/list_shared_links" -API_SAVEURL_URL="https://api.dropboxapi.com/2/files/save_url" -API_SAVEURL_JOBSTATUS_URL="https://api.dropboxapi.com/2/files/save_url/check_job_status" -API_SEARCH_URL="https://api.dropboxapi.com/2/files/search" -APP_CREATE_URL="https://www.dropbox.com/developers/apps" -RESPONSE_FILE="$TMP_DIR/du_resp_$RANDOM" -CHUNK_FILE="$TMP_DIR/du_chunk_$RANDOM" -TEMP_FILE="$TMP_DIR/du_tmp_$RANDOM" -BIN_DEPS="sed basename date grep stat dd mkdir" -VERSION="1.0" - -umask 077 - -#Check the shell -if [ -z "$BASH_VERSION" ]; then - echo -e "Error: this script requires the BASH shell!" - exit 1 -fi - -shopt -s nullglob #Bash allows filename patterns which match no files to expand to a null string, rather than themselves -shopt -s dotglob #Bash includes filenames beginning with a "." in the results of filename expansion - -#Check temp folder -if [[ ! -d "$TMP_DIR" ]]; then - echo -e "Error: the temporary folder $TMP_DIR doesn't exists!" - echo -e "Please edit this script and set the TMP_DIR variable to a valid temporary folder to use." - exit 1 -fi - -#Look for optional config file parameter -while getopts ":qpskdhf:x:" opt; do - case $opt in - - f) - CONFIG_FILE=$OPTARG - ;; - - d) - DEBUG=1 - ;; - - q) - QUIET=1 - ;; - - p) - SHOW_PROGRESSBAR=1 - ;; - - k) - CURL_ACCEPT_CERTIFICATES="-k" - ;; - - s) - SKIP_EXISTING_FILES=1 - ;; - - h) - HUMAN_READABLE_SIZE=1 - ;; - - x) - EXCLUDE+=( $OPTARG ) - ;; - - \?) - echo "Invalid option: -$OPTARG" >&2 - exit 1 - ;; - - :) - echo "Option -$OPTARG requires an argument." >&2 - exit 1 - ;; - - esac -done - -if [[ $DEBUG != 0 ]]; then - echo $VERSION - uname -a 2> /dev/null - cat /etc/issue 2> /dev/null - set -x - RESPONSE_FILE="$TMP_DIR/du_resp_debug" -fi - -if [[ $CURL_BIN == "" ]]; then - BIN_DEPS="$BIN_DEPS curl" - CURL_BIN="curl" -fi - -#Dependencies check -which $BIN_DEPS > /dev/null -if [[ $? != 0 ]]; then - for i in $BIN_DEPS; do - which $i > /dev/null || - NOT_FOUND="$i $NOT_FOUND" - done - echo -e "Error: Required program could not be found: $NOT_FOUND" - exit 1 -fi - -#Check if readlink is installed and supports the -m option -#It's not necessary, so no problem if it's not installed -which readlink > /dev/null -if [[ $? == 0 && $(readlink -m "//test" 2> /dev/null) == "/test" ]]; then - HAVE_READLINK=1 -else - HAVE_READLINK=0 -fi - -#Forcing to use the builtin printf, if it's present, because it's better -#otherwise the external printf program will be used -#Note that the external printf command can cause character encoding issues! -builtin printf "" 2> /dev/null -if [[ $? == 0 ]]; then - PRINTF="builtin printf" - PRINTF_OPT="-v o" -else - PRINTF=$(which printf) - if [[ $? != 0 ]]; then - echo -e "Error: Required program could not be found: printf" - fi - PRINTF_OPT="" -fi - -#Print the message based on $QUIET variable -function print -{ - if [[ $QUIET == 0 ]]; then - echo -ne "$1"; - fi -} - -#Returns unix timestamp -function utime -{ - date '+%s' -} - -#Remove temporary files -function remove_temp_files -{ - if [[ $DEBUG == 0 ]]; then - rm -fr "$RESPONSE_FILE" - rm -fr "$CHUNK_FILE" - rm -fr "$TEMP_FILE" - fi -} - -#Converts bytes to human readable format -function convert_bytes -{ - if [[ $HUMAN_READABLE_SIZE == 1 && "$1" != "" ]]; then - if (($1 > 1073741824));then - echo $(($1/1073741824)).$(($1%1073741824/100000000))"G"; - elif (($1 > 1048576));then - echo $(($1/1048576)).$(($1%1048576/100000))"M"; - elif (($1 > 1024));then - echo $(($1/1024)).$(($1%1024/100))"K"; - else - echo $1; - fi - else - echo $1; - fi -} - -#Returns the file size in bytes -function file_size -{ - #Generic GNU - SIZE=$(stat --format="%s" "$1" 2> /dev/null) - if [ $? -eq 0 ]; then - echo $SIZE - return - fi - - #Some embedded linux devices - SIZE=$(stat -c "%s" "$1" 2> /dev/null) - if [ $? -eq 0 ]; then - echo $SIZE - return - fi - - #BSD, OSX and other OSs - SIZE=$(stat -f "%z" "$1" 2> /dev/null) - if [ $? -eq 0 ]; then - echo $SIZE - return - fi - - echo "0" -} - - -#Usage -function usage -{ - echo -e "Dropbox Uploader v$VERSION" - echo -e "Andrea Fabrizi - andrea.fabrizi@gmail.com\n" - echo -e "Usage: $0 [PARAMETERS] COMMAND..." - echo -e "\nCommands:" - - echo -e "\t upload " - echo -e "\t download [LOCAL_FILE/DIR]" - echo -e "\t delete " - echo -e "\t move " - echo -e "\t copy " - echo -e "\t mkdir " - echo -e "\t list [REMOTE_DIR]" - echo -e "\t monitor [REMOTE_DIR] [TIMEOUT]" - echo -e "\t share " - echo -e "\t saveurl " - echo -e "\t search " - echo -e "\t info" - echo -e "\t space" - echo -e "\t unlink" - - echo -e "\nOptional parameters:" - echo -e "\t-f Load the configuration file from a specific file" - echo -e "\t-s Skip already existing files when download/upload. Default: Overwrite" - echo -e "\t-d Enable DEBUG mode" - echo -e "\t-q Quiet mode. Don't show messages" - echo -e "\t-h Show file sizes in human readable format" - echo -e "\t-p Show cURL progress meter" - echo -e "\t-k Doesn't check for SSL certificates (insecure)" - echo -e "\t-x Ignores/excludes directories or files from syncing. -x filename -x directoryname. example: -x .git" - - echo -en "\nFor more info and examples, please see the README file.\n\n" - remove_temp_files - exit 1 -} - -#Check the curl exit code -function check_http_response -{ - CODE=$? - - #Checking curl exit code - case $CODE in - - #OK - 0) - - ;; - - #Proxy error - 5) - print "\nError: Couldn't resolve proxy. The given proxy host could not be resolved.\n" - - remove_temp_files - exit 1 - ;; - - #Missing CA certificates - 60|58|77) - print "\nError: cURL is not able to performs peer SSL certificate verification.\n" - print "Please, install the default ca-certificates bundle.\n" - print "To do this in a Debian/Ubuntu based system, try:\n" - print " sudo apt-get install ca-certificates\n\n" - print "If the problem persists, try to use the -k option (insecure).\n" - - remove_temp_files - exit 1 - ;; - - 6) - print "\nError: Couldn't resolve host.\n" - - remove_temp_files - exit 1 - ;; - - 7) - print "\nError: Couldn't connect to host.\n" - - remove_temp_files - exit 1 - ;; - - esac - - #Checking response file for generic errors - if grep -q "HTTP/1.1 400" "$RESPONSE_FILE"; then - ERROR_MSG=$(sed -n -e 's/{"error": "\([^"]*\)"}/\1/p' "$RESPONSE_FILE") - - case $ERROR_MSG in - *access?attempt?failed?because?this?app?is?not?configured?to?have*) - echo -e "\nError: The Permission type/Access level configured doesn't match the DropBox App settings!\nPlease run \"$0 unlink\" and try again." - exit 1 - ;; - esac - - fi - -} - -#Urlencode -function urlencode -{ - #The printf is necessary to correctly decode unicode sequences - local string=$($PRINTF "${1}") - local strlen=${#string} - local encoded="" - - for (( pos=0 ; pos /dev/null - check_http_response - - local TYPE=$(sed -n 's/{".tag": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE") - - case $TYPE in - - file) - echo "FILE" - ;; - - folder) - echo "DIR" - ;; - - deleted) - echo "ERR" - ;; - - *) - echo "ERR" - ;; - - esac -} - -#Generic upload wrapper around db_upload_file and db_upload_dir functions -#$1 = Local source file/dir -#$2 = Remote destination file/dir -function db_upload -{ - local SRC=$(normalize_path "$1") - local DST=$(normalize_path "$2") - - for j in "${EXCLUDE[@]}" - do : - if [[ $(echo "$SRC" | grep "$j" | wc -l) -gt 0 ]]; then - print "Skipping excluded file/dir: "$j - return - fi - done - - #Checking if the file/dir exists - if [[ ! -e $SRC && ! -d $SRC ]]; then - print " > No such file or directory: $SRC\n" - ERROR_STATUS=1 - return - fi - - #Checking if the file/dir has read permissions - if [[ ! -r $SRC ]]; then - print " > Error reading file $SRC: permission denied\n" - ERROR_STATUS=1 - return - fi - - TYPE=$(db_stat "$DST") - - #If DST it's a file, do nothing, it's the default behaviour - if [[ $TYPE == "FILE" ]]; then - DST="$DST" - - #if DST doesn't exists and doesn't ends with a /, it will be the destination file name - elif [[ $TYPE == "ERR" && "${DST: -1}" != "/" ]]; then - DST="$DST" - - #if DST doesn't exists and ends with a /, it will be the destination folder - elif [[ $TYPE == "ERR" && "${DST: -1}" == "/" ]]; then - local filename=$(basename "$SRC") - DST="$DST/$filename" - - #If DST it's a directory, it will be the destination folder - elif [[ $TYPE == "DIR" ]]; then - local filename=$(basename "$SRC") - DST="$DST/$filename" - fi - - #It's a directory - if [[ -d $SRC ]]; then - db_upload_dir "$SRC" "$DST" - - #It's a file - elif [[ -e $SRC ]]; then - db_upload_file "$SRC" "$DST" - - #Unsupported object... - else - print " > Skipping not regular file \"$SRC\"\n" - fi -} - -#Generic upload wrapper around db_chunked_upload_file and db_simple_upload_file -#The final upload function will be choosen based on the file size -#$1 = Local source file -#$2 = Remote destination file -function db_upload_file -{ - local FILE_SRC=$(normalize_path "$1") - local FILE_DST=$(normalize_path "$2") - - shopt -s nocasematch - - #Checking not allowed file names - basefile_dst=$(basename "$FILE_DST") - if [[ $basefile_dst == "thumbs.db" || \ - $basefile_dst == "desktop.ini" || \ - $basefile_dst == ".ds_store" || \ - $basefile_dst == "icon\r" || \ - $basefile_dst == ".dropbox" || \ - $basefile_dst == ".dropbox.attr" \ - ]]; then - print " > Skipping not allowed file name \"$FILE_DST\"\n" - return - fi - - shopt -u nocasematch - - #Checking file size - FILE_SIZE=$(file_size "$FILE_SRC") - - #Checking if the file already exists - TYPE=$(db_stat "$FILE_DST") - if [[ $TYPE != "ERR" && $SKIP_EXISTING_FILES == 1 ]]; then - print " > Skipping already existing file \"$FILE_DST\"\n" - return - fi - - # Checking if the file has the correct check sum - if [[ $TYPE != "ERR" ]]; then - sha_src=$(db_sha_local "$FILE_SRC") - sha_dst=$(db_sha "$FILE_DST") - if [[ $sha_src == $sha_dst && $sha_src != "ERR" ]]; then - print "> Skipping file \"$FILE_SRC\", file exists with the same hash\n" - return - fi - fi - - if [[ $FILE_SIZE -gt 157286000 ]]; then - #If the file is greater than 150Mb, the chunked_upload API will be used - db_chunked_upload_file "$FILE_SRC" "$FILE_DST" - else - db_simple_upload_file "$FILE_SRC" "$FILE_DST" - fi - -} - -#Simple file upload -#$1 = Local source file -#$2 = Remote destination file -function db_simple_upload_file -{ - local FILE_SRC=$(normalize_path "$1") - local FILE_DST=$(normalize_path "$2") - - if [[ $SHOW_PROGRESSBAR == 1 && $QUIET == 0 ]]; then - CURL_PARAMETERS="--progress-bar" - LINE_CR="\n" - else - CURL_PARAMETERS="-L -s" - LINE_CR="" - fi - - print " > Uploading \"$FILE_SRC\" to \"$FILE_DST\"... $LINE_CR" - $CURL_BIN $CURL_ACCEPT_CERTIFICATES $CURL_PARAMETERS -X POST -i --globoff -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Dropbox-API-Arg: {\"path\": \"$FILE_DST\",\"mode\": \"overwrite\",\"autorename\": true,\"mute\": false}" --header "Content-Type: application/octet-stream" --data-binary @"$FILE_SRC" "$API_UPLOAD_URL" - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - print "DONE\n" - else - print "FAILED\n" - print "An error occurred requesting /upload\n" - ERROR_STATUS=1 - fi -} - -#Chunked file upload -#$1 = Local source file -#$2 = Remote destination file -function db_chunked_upload_file -{ - local FILE_SRC=$(normalize_path "$1") - local FILE_DST=$(normalize_path "$2") - - - if [[ $SHOW_PROGRESSBAR == 1 && $QUIET == 0 ]]; then - VERBOSE=1 - CURL_PARAMETERS="--progress-bar" - else - VERBOSE=0 - CURL_PARAMETERS="-L -s" - fi - - - - local FILE_SIZE=$(file_size "$FILE_SRC") - local OFFSET=0 - local UPLOAD_ID="" - local UPLOAD_ERROR=0 - local CHUNK_PARAMS="" - - ## Ceil division - let NUMBEROFCHUNK=($FILE_SIZE/1024/1024+$CHUNK_SIZE-1)/$CHUNK_SIZE - - if [[ $VERBOSE == 1 ]]; then - print " > Uploading \"$FILE_SRC\" to \"$FILE_DST\" by $NUMBEROFCHUNK chunks ...\n" - else - print " > Uploading \"$FILE_SRC\" to \"$FILE_DST\" by $NUMBEROFCHUNK chunks " - fi - - #Starting a new upload session - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Dropbox-API-Arg: {\"close\": false}" --header "Content-Type: application/octet-stream" --data-binary @/dev/null "$API_CHUNKED_UPLOAD_START_URL" 2> /dev/null - check_http_response - - SESSION_ID=$(sed -n 's/{"session_id": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE") - - chunkNumber=1 - #Uploading chunks... - while ([[ $OFFSET != "$FILE_SIZE" ]]); do - - let OFFSET_MB=$OFFSET/1024/1024 - - #Create the chunk - dd if="$FILE_SRC" of="$CHUNK_FILE" bs=1048576 skip=$OFFSET_MB count=$CHUNK_SIZE 2> /dev/null - local CHUNK_REAL_SIZE=$(file_size "$CHUNK_FILE") - - if [[ $VERBOSE == 1 ]]; then - print " >> Uploading chunk $chunkNumber of $NUMBEROFCHUNK\n" - fi - - #Uploading the chunk... - echo > "$RESPONSE_FILE" - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST $CURL_PARAMETERS --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Dropbox-API-Arg: {\"cursor\": {\"session_id\": \"$SESSION_ID\",\"offset\": $OFFSET},\"close\": false}" --header "Content-Type: application/octet-stream" --data-binary @"$CHUNK_FILE" "$API_CHUNKED_UPLOAD_APPEND_URL" - #check_http_response not needed, because we have to retry the request in case of error - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - let OFFSET=$OFFSET+$CHUNK_REAL_SIZE - UPLOAD_ERROR=0 - if [[ $VERBOSE != 1 ]]; then - print "." - fi - ((chunkNumber=chunkNumber+1)) - else - if [[ $VERBOSE != 1 ]]; then - print "*" - fi - let UPLOAD_ERROR=$UPLOAD_ERROR+1 - - #On error, the upload is retried for max 3 times - if [[ $UPLOAD_ERROR -gt 2 ]]; then - print " FAILED\n" - print "An error occurred requesting /chunked_upload\n" - ERROR_STATUS=1 - return - fi - fi - - done - - UPLOAD_ERROR=0 - - #Commit the upload - while (true); do - - echo > "$RESPONSE_FILE" - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Dropbox-API-Arg: {\"cursor\": {\"session_id\": \"$SESSION_ID\",\"offset\": $OFFSET},\"commit\": {\"path\": \"$FILE_DST\",\"mode\": \"overwrite\",\"autorename\": true,\"mute\": false}}" --header "Content-Type: application/octet-stream" --data-binary @/dev/null "$API_CHUNKED_UPLOAD_FINISH_URL" 2> /dev/null - #check_http_response not needed, because we have to retry the request in case of error - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - UPLOAD_ERROR=0 - break - else - print "*" - let UPLOAD_ERROR=$UPLOAD_ERROR+1 - - #On error, the commit is retried for max 3 times - if [[ $UPLOAD_ERROR -gt 2 ]]; then - print " FAILED\n" - print "An error occurred requesting /commit_chunked_upload\n" - ERROR_STATUS=1 - return - fi - fi - - done - - print " DONE\n" -} - -#Directory upload -#$1 = Local source dir -#$2 = Remote destination dir -function db_upload_dir -{ - local DIR_SRC=$(normalize_path "$1") - local DIR_DST=$(normalize_path "$2") - - #Creatig remote directory - db_mkdir "$DIR_DST" - - for file in "$DIR_SRC/"*; do - db_upload "$file" "$DIR_DST" - done -} - -#Generic download wrapper -#$1 = Remote source file/dir -#$2 = Local destination file/dir -function db_download -{ - local SRC=$(normalize_path "$1") - local DST=$(normalize_path "$2") - - TYPE=$(db_stat "$SRC") - - #It's a directory - if [[ $TYPE == "DIR" ]]; then - - #If the DST folder is not specified, I assume that is the current directory - if [[ $DST == "" ]]; then - DST="." - fi - - #Checking if the destination directory exists - if [[ ! -d $DST ]]; then - local basedir="" - else - local basedir=$(basename "$SRC") - fi - - local DEST_DIR=$(normalize_path "$DST/$basedir") - print " > Downloading folder \"$SRC\" to \"$DEST_DIR\"... \n" - - if [[ ! -d "$DEST_DIR" ]]; then - print " > Creating local directory \"$DEST_DIR\"... " - mkdir -p "$DEST_DIR" - - #Check - if [[ $? == 0 ]]; then - print "DONE\n" - else - print "FAILED\n" - ERROR_STATUS=1 - return - fi - fi - - if [[ $SRC == "/" ]]; then - SRC_REQ="" - else - SRC_REQ="$SRC" - fi - - OUT_FILE=$(db_list_outfile "$SRC_REQ") - if [ $? -ne 0 ]; then - # When db_list_outfile fail, the error message is OUT_FILE - print "$OUT_FILE\n" - ERROR_STATUS=1 - return - fi - - #For each entry... - while read -r line; do - - local FILE=${line%:*} - local META=${line##*:} - local TYPE=${META%;*} - local SIZE=${META#*;} - - #Removing unneeded / - FILE=${FILE##*/} - - if [[ $TYPE == "file" ]]; then - db_download_file "$SRC/$FILE" "$DEST_DIR/$FILE" - elif [[ $TYPE == "folder" ]]; then - db_download "$SRC/$FILE" "$DEST_DIR" - fi - - done < $OUT_FILE - - rm -fr $OUT_FILE - - #It's a file - elif [[ $TYPE == "FILE" ]]; then - - #Checking DST - if [[ $DST == "" ]]; then - DST=$(basename "$SRC") - fi - - #If the destination is a directory, the file will be download into - if [[ -d $DST ]]; then - DST="$DST/$SRC" - fi - - db_download_file "$SRC" "$DST" - - #Doesn't exists - else - print " > No such file or directory: $SRC\n" - ERROR_STATUS=1 - return - fi -} - -#Simple file download -#$1 = Remote source file -#$2 = Local destination file -function db_download_file -{ - local FILE_SRC=$(normalize_path "$1") - local FILE_DST=$(normalize_path "$2") - - if [[ $SHOW_PROGRESSBAR == 1 && $QUIET == 0 ]]; then - CURL_PARAMETERS="-L --progress-bar" - LINE_CR="\n" - else - CURL_PARAMETERS="-L -s" - LINE_CR="" - fi - - #Checking if the file already exists - if [[ -e $FILE_DST && $SKIP_EXISTING_FILES == 1 ]]; then - print " > Skipping already existing file \"$FILE_DST\"\n" - return - fi - - # Checking if the file has the correct check sum - if [[ $TYPE != "ERR" ]]; then - sha_src=$(db_sha "$FILE_SRC") - sha_dst=$(db_sha_local "$FILE_DST") - if [[ $sha_src == $sha_dst && $sha_src != "ERR" ]]; then - print "> Skipping file \"$FILE_SRC\", file exists with the same hash\n" - return - fi - fi - - #Creating the empty file, that for two reasons: - #1) In this way I can check if the destination file is writable or not - #2) Curl doesn't automatically creates files with 0 bytes size - dd if=/dev/zero of="$FILE_DST" count=0 2> /dev/null - if [[ $? != 0 ]]; then - print " > Error writing file $FILE_DST: permission denied\n" - ERROR_STATUS=1 - return - fi - - print " > Downloading \"$FILE_SRC\" to \"$FILE_DST\"... $LINE_CR" - $CURL_BIN $CURL_ACCEPT_CERTIFICATES $CURL_PARAMETERS -X POST --globoff -D "$RESPONSE_FILE" -o "$FILE_DST" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Dropbox-API-Arg: {\"path\": \"$FILE_SRC\"}" "$API_DOWNLOAD_URL" - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - print "DONE\n" - else - print "FAILED\n" - rm -fr "$FILE_DST" - ERROR_STATUS=1 - return - fi -} - -#Saveurl -#$1 = URL -#$2 = Remote file destination -function db_saveurl -{ - local URL="$1" - local FILE_DST=$(normalize_path "$2") - local FILE_NAME=$(basename "$URL") - - print " > Downloading \"$URL\" to \"$FILE_DST\"..." - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"path\": \"$FILE_DST/$FILE_NAME\", \"url\": \"$URL\"}" "$API_SAVEURL_URL" 2> /dev/null - check_http_response - - JOB_ID=$(sed -n 's/.*"async_job_id": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE") - if [[ $JOB_ID == "" ]]; then - print " > Error getting the job id\n" - return - fi - - #Checking the status - while (true); do - - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"async_job_id\": \"$JOB_ID\"}" "$API_SAVEURL_JOBSTATUS_URL" 2> /dev/null - check_http_response - - STATUS=$(sed -n 's/{".tag": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE") - case $STATUS in - - in_progress) - print "+" - ;; - - complete) - print " DONE\n" - break - ;; - - failed) - print " ERROR\n" - MESSAGE=$(sed -n 's/.*"error_summary": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE") - print " > Error: $MESSAGE\n" - break - ;; - - esac - - sleep 2 - - done -} - -#Prints account info -function db_account_info -{ - print "Dropbox Uploader v$VERSION\n\n" - print " > Getting info... " - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" "$API_ACCOUNT_INFO_URL" 2> /dev/null - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - - name=$(sed -n 's/.*"display_name": "\([^"]*\).*/\1/p' "$RESPONSE_FILE") - echo -e "\n\nName:\t\t$name" - - uid=$(sed -n 's/.*"account_id": "\([^"]*\).*/\1/p' "$RESPONSE_FILE") - echo -e "UID:\t\t$uid" - - email=$(sed -n 's/.*"email": "\([^"]*\).*/\1/p' "$RESPONSE_FILE") - echo -e "Email:\t\t$email" - - country=$(sed -n 's/.*"country": "\([^"]*\).*/\1/p' "$RESPONSE_FILE") - echo -e "Country:\t$country" - - echo "" - - else - print "FAILED\n" - ERROR_STATUS=1 - fi -} - -#Prints account space usage info -function db_account_space -{ - print "Dropbox Uploader v$VERSION\n\n" - print " > Getting space usage info... " - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" "$API_ACCOUNT_SPACE_URL" 2> /dev/null - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - - quota=$(sed -n 's/.*"allocated": \([0-9]*\).*/\1/p' "$RESPONSE_FILE") - let quota_mb=$quota/1024/1024 - echo -e "\n\nQuota:\t$quota_mb Mb" - - used=$(sed -n 's/.*"used": \([0-9]*\).*/\1/p' "$RESPONSE_FILE") - let used_mb=$used/1024/1024 - echo -e "Used:\t$used_mb Mb" - - let free_mb=$((quota-used))/1024/1024 - echo -e "Free:\t$free_mb Mb" - - echo "" - - else - print "FAILED\n" - ERROR_STATUS=1 - fi -} - -#Account unlink -function db_unlink -{ - echo -ne "Are you sure you want unlink this script from your Dropbox account? [y/n]" - read -r answer - if [[ $answer == "y" ]]; then - rm -fr "$CONFIG_FILE" - echo -ne "DONE\n" - fi -} - -#Delete a remote file -#$1 = Remote file to delete -function db_delete -{ - local FILE_DST=$(normalize_path "$1") - - print " > Deleting \"$FILE_DST\"... " - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"path\": \"$FILE_DST\"}" "$API_DELETE_URL" 2> /dev/null - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - print "DONE\n" - else - print "FAILED\n" - ERROR_STATUS=1 - fi -} - -#Move/Rename a remote file -#$1 = Remote file to rename or move -#$2 = New file name or location -function db_move -{ - local FILE_SRC=$(normalize_path "$1") - local FILE_DST=$(normalize_path "$2") - - TYPE=$(db_stat "$FILE_DST") - - #If the destination it's a directory, the source will be moved into it - if [[ $TYPE == "DIR" ]]; then - local filename=$(basename "$FILE_SRC") - FILE_DST=$(normalize_path "$FILE_DST/$filename") - fi - - print " > Moving \"$FILE_SRC\" to \"$FILE_DST\" ... " - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"from_path\": \"$FILE_SRC\", \"to_path\": \"$FILE_DST\"}" "$API_MOVE_URL" 2> /dev/null - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - print "DONE\n" - else - print "FAILED\n" - ERROR_STATUS=1 - fi -} - -#Copy a remote file to a remote location -#$1 = Remote file to rename or move -#$2 = New file name or location -function db_copy -{ - local FILE_SRC=$(normalize_path "$1") - local FILE_DST=$(normalize_path "$2") - - TYPE=$(db_stat "$FILE_DST") - - #If the destination it's a directory, the source will be copied into it - if [[ $TYPE == "DIR" ]]; then - local filename=$(basename "$FILE_SRC") - FILE_DST=$(normalize_path "$FILE_DST/$filename") - fi - - print " > Copying \"$FILE_SRC\" to \"$FILE_DST\" ... " - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"from_path\": \"$FILE_SRC\", \"to_path\": \"$FILE_DST\"}" "$API_COPY_URL" 2> /dev/null - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - print "DONE\n" - else - print "FAILED\n" - ERROR_STATUS=1 - fi -} - -#Create a new directory -#$1 = Remote directory to create -function db_mkdir -{ - local DIR_DST=$(normalize_path "$1") - - print " > Creating Directory \"$DIR_DST\"... " - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"path\": \"$DIR_DST\"}" "$API_MKDIR_URL" 2> /dev/null - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - print "DONE\n" - elif grep -q "^HTTP/1.1 403 Forbidden" "$RESPONSE_FILE"; then - print "ALREADY EXISTS\n" - else - print "FAILED\n" - ERROR_STATUS=1 - fi -} - -#List a remote folder and returns the path to the file containing the output -#$1 = Remote directory -#$2 = Cursor (Optional) -function db_list_outfile -{ - - local DIR_DST="$1" - local HAS_MORE="false" - local CURSOR="" - - if [[ -n "$2" ]]; then - CURSOR="$2" - HAS_MORE="true" - fi - - OUT_FILE="$TMP_DIR/du_tmp_out_$RANDOM" - - while (true); do - - if [[ $HAS_MORE == "true" ]]; then - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"cursor\": \"$CURSOR\"}" "$API_LIST_FOLDER_CONTINUE_URL" 2> /dev/null - else - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"path\": \"$DIR_DST\",\"include_media_info\": false,\"include_deleted\": false,\"include_has_explicit_shared_members\": false}" "$API_LIST_FOLDER_URL" 2> /dev/null - fi - - check_http_response - - HAS_MORE=$(sed -n 's/.*"has_more": *\([a-z]*\).*/\1/p' "$RESPONSE_FILE") - CURSOR=$(sed -n 's/.*"cursor": *"\([^"]*\)".*/\1/p' "$RESPONSE_FILE") - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - - #Extracting directory content [...] - #and replacing "}, {" with "}\n{" - #I don't like this piece of code... but seems to be the only way to do this with SED, writing a portable code... - local DIR_CONTENT=$(sed -n 's/.*: \[{\(.*\)/\1/p' "$RESPONSE_FILE" | sed 's/}, *{/}\ - {/g') - - #Converting escaped quotes to unicode format - echo "$DIR_CONTENT" | sed 's/\\"/\\u0022/' > "$TEMP_FILE" - - #Extracting files and subfolders - while read -r line; do - - local FILE=$(echo "$line" | sed -n 's/.*"path_display": *"\([^"]*\)".*/\1/p') - local TYPE=$(echo "$line" | sed -n 's/.*".tag": *"\([^"]*\).*/\1/p') - local SIZE=$(convert_bytes $(echo "$line" | sed -n 's/.*"size": *\([0-9]*\).*/\1/p')) - - echo -e "$FILE:$TYPE;$SIZE" >> "$OUT_FILE" - - done < "$TEMP_FILE" - - if [[ $HAS_MORE == "false" ]]; then - break - fi - - else - return - fi - - done - - echo $OUT_FILE -} - -#List remote directory -#$1 = Remote directory -function db_list -{ - local DIR_DST=$(normalize_path "$1") - - print " > Listing \"$DIR_DST\"... " - - if [[ "$DIR_DST" == "/" ]]; then - DIR_DST="" - fi - - OUT_FILE=$(db_list_outfile "$DIR_DST") - if [ -z "$OUT_FILE" ]; then - print "FAILED\n" - ERROR_STATUS=1 - return - else - print "DONE\n" - fi - - #Looking for the biggest file size - #to calculate the padding to use - local padding=0 - while read -r line; do - local FILE=${line%:*} - local META=${line##*:} - local SIZE=${META#*;} - - if [[ ${#SIZE} -gt $padding ]]; then - padding=${#SIZE} - fi - done < "$OUT_FILE" - - #For each entry, printing directories... - while read -r line; do - - local FILE=${line%:*} - local META=${line##*:} - local TYPE=${META%;*} - local SIZE=${META#*;} - - #Removing unneeded / - FILE=${FILE##*/} - - if [[ $TYPE == "folder" ]]; then - FILE=$(echo -e "$FILE") - $PRINTF " [D] %-${padding}s %s\n" "$SIZE" "$FILE" - fi - - done < "$OUT_FILE" - - #For each entry, printing files... - while read -r line; do - - local FILE=${line%:*} - local META=${line##*:} - local TYPE=${META%;*} - local SIZE=${META#*;} - - #Removing unneeded / - FILE=${FILE##*/} - - if [[ $TYPE == "file" ]]; then - FILE=$(echo -e "$FILE") - $PRINTF " [F] %-${padding}s %s\n" "$SIZE" "$FILE" - fi - - done < "$OUT_FILE" - - rm -fr "$OUT_FILE" -} - -#Longpoll remote directory only once -#$1 = Timeout -#$2 = Remote directory -function db_monitor_nonblock -{ - local TIMEOUT=$1 - local DIR_DST=$(normalize_path "$2") - - if [[ "$DIR_DST" == "/" ]]; then - DIR_DST="" - fi - - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"path\": \"$DIR_DST\",\"include_media_info\": false,\"include_deleted\": false,\"include_has_explicit_shared_members\": false}" "$API_LIST_FOLDER_URL" 2> /dev/null - check_http_response - - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - - local CURSOR=$(sed -n 's/.*"cursor": *"\([^"]*\)".*/\1/p' "$RESPONSE_FILE") - - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Content-Type: application/json" --data "{\"cursor\": \"$CURSOR\",\"timeout\": ${TIMEOUT}}" "$API_LONGPOLL_FOLDER" 2> /dev/null - check_http_response - - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - local CHANGES=$(sed -n 's/.*"changes" *: *\([a-z]*\).*/\1/p' "$RESPONSE_FILE") - else - ERROR_MSG=$(grep "Error in call" "$RESPONSE_FILE") - print "FAILED to longpoll (http error): $ERROR_MSG\n" - ERROR_STATUS=1 - return 1 - fi - - if [[ -z "$CHANGES" ]]; then - print "FAILED to longpoll (unexpected response)\n" - ERROR_STATUS=1 - return 1 - fi - - if [ "$CHANGES" == "true" ]; then - - OUT_FILE=$(db_list_outfile "$DIR_DST" "$CURSOR") - - if [ -z "$OUT_FILE" ]; then - print "FAILED to list changes\n" - ERROR_STATUS=1 - return - fi - - #For each entry, printing directories... - while read -r line; do - - local FILE=${line%:*} - local META=${line##*:} - local TYPE=${META%;*} - local SIZE=${META#*;} - - #Removing unneeded / - FILE=${FILE##*/} - - if [[ $TYPE == "folder" ]]; then - FILE=$(echo -e "$FILE") - $PRINTF " [D] %s\n" "$FILE" - elif [[ $TYPE == "file" ]]; then - FILE=$(echo -e "$FILE") - $PRINTF " [F] %s %s\n" "$SIZE" "$FILE" - elif [[ $TYPE == "deleted" ]]; then - FILE=$(echo -e "$FILE") - $PRINTF " [-] %s\n" "$FILE" - fi - - done < "$OUT_FILE" - - rm -fr "$OUT_FILE" - fi - - else - ERROR_STATUS=1 - return 1 - fi - -} - -#Longpoll continuously remote directory -#$1 = Timeout -#$2 = Remote directory -function db_monitor -{ - local TIMEOUT=$1 - local DIR_DST=$(normalize_path "$2") - - while (true); do - db_monitor_nonblock "$TIMEOUT" "$2" - done -} - -#Share remote file -#$1 = Remote file -function db_share -{ - local FILE_DST=$(normalize_path "$1") - - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"path\": \"$FILE_DST\",\"settings\": {\"requested_visibility\": \"public\"}}" "$API_SHARE_URL" 2> /dev/null - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - print " > Share link: " - SHARE_LINK=$(sed -n 's/.*"url": "\([^"]*\).*/\1/p' "$RESPONSE_FILE") - echo "$SHARE_LINK" - else - get_Share "$FILE_DST" - fi -} - -#Query existing shared link -#$1 = Remote file -function get_Share -{ - local FILE_DST=$(normalize_path "$1") - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"path\": \"$FILE_DST\",\"direct_only\": true}" "$API_SHARE_LIST" - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - print " > Share link: " - SHARE_LINK=$(sed -n 's/.*"url": "\([^"]*\).*/\1/p' "$RESPONSE_FILE") - echo "$SHARE_LINK" - else - print "FAILED\n" - MESSAGE=$(sed -n 's/.*"error_summary": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE") - print " > Error: $MESSAGE\n" - ERROR_STATUS=1 - fi -} - -#Search on Dropbox -#$1 = query -function db_search -{ - local QUERY="$1" - - print " > Searching for \"$QUERY\"... " - - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"path\": \"\",\"query\": \"$QUERY\",\"start\": 0,\"max_results\": 1000,\"mode\": \"filename\"}" "$API_SEARCH_URL" 2> /dev/null - check_http_response - - #Check - if grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; then - print "DONE\n" - else - print "FAILED\n" - ERROR_STATUS=1 - fi - - #Extracting directory content [...] - #and replacing "}, {" with "}\n{" - #I don't like this piece of code... but seems to be the only way to do this with SED, writing a portable code... - local DIR_CONTENT=$(sed 's/}, *{/}\ -{/g' "$RESPONSE_FILE") - - #Converting escaped quotes to unicode format - echo "$DIR_CONTENT" | sed 's/\\"/\\u0022/' > "$TEMP_FILE" - - #Extracting files and subfolders - rm -fr "$RESPONSE_FILE" - while read -r line; do - - local FILE=$(echo "$line" | sed -n 's/.*"path_display": *"\([^"]*\)".*/\1/p') - local TYPE=$(echo "$line" | sed -n 's/.*".tag": *"\([^"]*\).*/\1/p') - local SIZE=$(convert_bytes $(echo "$line" | sed -n 's/.*"size": *\([0-9]*\).*/\1/p')) - - echo -e "$FILE:$TYPE;$SIZE" >> "$RESPONSE_FILE" - - done < "$TEMP_FILE" - - #Looking for the biggest file size - #to calculate the padding to use - local padding=0 - while read -r line; do - local FILE=${line%:*} - local META=${line##*:} - local SIZE=${META#*;} - - if [[ ${#SIZE} -gt $padding ]]; then - padding=${#SIZE} - fi - done < "$RESPONSE_FILE" - - #For each entry, printing directories... - while read -r line; do - - local FILE=${line%:*} - local META=${line##*:} - local TYPE=${META%;*} - local SIZE=${META#*;} - - if [[ $TYPE == "folder" ]]; then - FILE=$(echo -e "$FILE") - $PRINTF " [D] %-${padding}s %s\n" "$SIZE" "$FILE" - fi - - done < "$RESPONSE_FILE" - - #For each entry, printing files... - while read -r line; do - - local FILE=${line%:*} - local META=${line##*:} - local TYPE=${META%;*} - local SIZE=${META#*;} - - if [[ $TYPE == "file" ]]; then - FILE=$(echo -e "$FILE") - $PRINTF " [F] %-${padding}s %s\n" "$SIZE" "$FILE" - fi - - done < "$RESPONSE_FILE" - -} - -#Query the sha256-dropbox-sum of a remote file -#see https://www.dropbox.com/developers/reference/content-hash for more information -#$1 = Remote file -function db_sha -{ - local FILE=$(normalize_path "$1") - - if [[ $FILE == "/" ]]; then - echo "ERR" - return - fi - - #Checking if it's a file or a directory and get the sha-sum - $CURL_BIN $CURL_ACCEPT_CERTIFICATES -X POST -L -s --show-error --globoff -i -o "$RESPONSE_FILE" --header "Authorization: Bearer $OAUTH_ACCESS_TOKEN" --header "Content-Type: application/json" --data "{\"path\": \"$FILE\"}" "$API_METADATA_URL" 2> /dev/null - check_http_response - - local TYPE=$(sed -n 's/{".tag": *"*\([^"]*\)"*.*/\1/p' "$RESPONSE_FILE") - if [[ $TYPE == "folder" ]]; then - echo "ERR" - return - fi - - local SHA256=$(sed -n 's/.*"content_hash": "\([^"]*\).*/\1/p' "$RESPONSE_FILE") - echo "$SHA256" -} - -#Query the sha256-dropbox-sum of a local file -#see https://www.dropbox.com/developers/reference/content-hash for more information -#$1 = Local file -function db_sha_local -{ - local FILE=$(normalize_path "$1") - local FILE_SIZE=$(file_size "$FILE") - local OFFSET=0 - local SKIP=0 - local SHA_CONCAT="" - - which shasum > /dev/null - if [[ $? != 0 ]]; then - echo "ERR" - return - fi - - while ([[ $OFFSET -lt "$FILE_SIZE" ]]); do - dd if="$FILE" of="$CHUNK_FILE" bs=4194304 skip=$SKIP count=1 2> /dev/null - local SHA=$(shasum -a 256 "$CHUNK_FILE" | awk '{print $1}') - SHA_CONCAT="${SHA_CONCAT}${SHA}" - - let OFFSET=$OFFSET+4194304 - let SKIP=$SKIP+1 - done - - shaHex=$(echo $SHA_CONCAT | sed 's/\([0-9A-F]\{2\}\)/\\x\1/gI') - echo -ne $shaHex | shasum -a 256 | awk '{print $1}' -} - -################ -#### SETUP #### -################ - -#CHECKING FOR AUTH FILE -if [[ -e $CONFIG_FILE ]]; then - - #Loading data... and change old format config if necesary. - source "$CONFIG_FILE" 2>/dev/null || { - sed -i'' 's/:/=/' "$CONFIG_FILE" && source "$CONFIG_FILE" 2>/dev/null - } - - #Checking if it's still a v1 API configuration file - if [[ $APPKEY != "" || $APPSECRET != "" ]]; then - echo -ne "The config file contains the old deprecated v1 oauth tokens.\n" - echo -ne "Please run again the script and follow the configuration wizard. The old configuration file has been backed up to $CONFIG_FILE.old\n" - mv "$CONFIG_FILE" "$CONFIG_FILE".old - exit 1 - fi - - #Checking loaded data - if [[ $OAUTH_ACCESS_TOKEN = "" ]]; then - echo -ne "Error loading data from $CONFIG_FILE...\n" - echo -ne "It is recommended to run $0 unlink\n" - remove_temp_files - exit 1 - fi - -#NEW SETUP... -else - - echo -ne "\n This is the first time you run this script, please follow the instructions:\n\n" - echo -ne " 1) Open the following URL in your Browser, and log in using your account: $APP_CREATE_URL\n" - echo -ne " 2) Click on \"Create App\", then select \"Dropbox API app\"\n" - echo -ne " 3) Now go on with the configuration, choosing the app permissions and access restrictions to your DropBox folder\n" - echo -ne " 4) Enter the \"App Name\" that you prefer (e.g. MyUploader$RANDOM$RANDOM$RANDOM)\n\n" - - echo -ne " Now, click on the \"Create App\" button.\n\n" - - echo -ne " When your new App is successfully created, please click on the Generate button\n" - echo -ne " under the 'Generated access token' section, then copy and paste the new access token here:\n\n" - - echo -ne " # Access token: " - read -r OAUTH_ACCESS_TOKEN - - echo -ne "\n > The access token is $OAUTH_ACCESS_TOKEN. Looks ok? [y/N]: " - read -r answer - if [[ $answer != "y" ]]; then - remove_temp_files - exit 1 - fi - - echo "OAUTH_ACCESS_TOKEN=$OAUTH_ACCESS_TOKEN" > "$CONFIG_FILE" - echo " The configuration has been saved." - - remove_temp_files - exit 0 -fi - -################ -#### START #### -################ - -COMMAND="${*:$OPTIND:1}" -ARG1="${*:$OPTIND+1:1}" -ARG2="${*:$OPTIND+2:1}" - -let argnum=$#-$OPTIND - -#CHECKING PARAMS VALUES -case $COMMAND in - - upload) - - if [[ $argnum -lt 2 ]]; then - usage - fi - - FILE_DST="${*:$#:1}" - - for (( i=OPTIND+1; i<$#; i++ )); do - FILE_SRC="${*:$i:1}" - db_upload "$FILE_SRC" "/$FILE_DST" - done - - ;; - - download) - - if [[ $argnum -lt 1 ]]; then - usage - fi - - FILE_SRC="$ARG1" - FILE_DST="$ARG2" - - db_download "/$FILE_SRC" "$FILE_DST" - - ;; - - saveurl) - - if [[ $argnum -lt 1 ]]; then - usage - fi - - URL=$ARG1 - FILE_DST="$ARG2" - - db_saveurl "$URL" "/$FILE_DST" - - ;; - - share) - - if [[ $argnum -lt 1 ]]; then - usage - fi - - FILE_DST="$ARG1" - - db_share "/$FILE_DST" - - ;; - - info) - - db_account_info - - ;; - - space) - - db_account_space - - ;; - - delete|remove) - - if [[ $argnum -lt 1 ]]; then - usage - fi - - FILE_DST="$ARG1" - - db_delete "/$FILE_DST" - - ;; - - move|rename) - - if [[ $argnum -lt 2 ]]; then - usage - fi - - FILE_SRC="$ARG1" - FILE_DST="$ARG2" - - db_move "/$FILE_SRC" "/$FILE_DST" - - ;; - - copy) - - if [[ $argnum -lt 2 ]]; then - usage - fi - - FILE_SRC="$ARG1" - FILE_DST="$ARG2" - - db_copy "/$FILE_SRC" "/$FILE_DST" - - ;; - - mkdir) - - if [[ $argnum -lt 1 ]]; then - usage - fi - - DIR_DST="$ARG1" - - db_mkdir "/$DIR_DST" - - ;; - - search) - - if [[ $argnum -lt 1 ]]; then - usage - fi - - QUERY=$ARG1 - - db_search "$QUERY" - - ;; - - list) - - DIR_DST="$ARG1" - - #Checking DIR_DST - if [[ $DIR_DST == "" ]]; then - DIR_DST="/" - fi - - db_list "/$DIR_DST" - - ;; - - monitor) - - DIR_DST="$ARG1" - TIMEOUT=$ARG2 - - #Checking DIR_DST - if [[ $DIR_DST == "" ]]; then - DIR_DST="/" - fi - - print " > Monitoring \"$DIR_DST\" for changes...\n" - - if [[ -n $TIMEOUT ]]; then - db_monitor_nonblock $TIMEOUT "/$DIR_DST" - else - db_monitor 60 "/$DIR_DST" - fi - - ;; - - unlink) - - db_unlink - - ;; - - *) - - if [[ $COMMAND != "" ]]; then - print "Error: Unknown command: $COMMAND\n\n" - ERROR_STATUS=1 - fi - usage - - ;; - -esac - -remove_temp_files - -if [[ $ERROR_STATUS -ne 0 ]]; then - echo "Some error occured. Please check the log." -fi - -exit $ERROR_STATUS diff --git a/.ci/gta5view.nsi b/.ci/gta5view.nsi deleted file mode 100644 index 1ddd882..0000000 --- a/.ci/gta5view.nsi +++ /dev/null @@ -1,364 +0,0 @@ -###################################################################### - -!define APP_NAME "gta5view" -!define APP_EXT ".g5e" -!define COMP_NAME "Syping" -!define WEB_SITE "https://gta5view.syping.de/" -!define VERSION "1.10.2.0" -!define COPYRIGHT "Copyright © 2016-2022 Syping" -!define DESCRIPTION "Open Source Snapmatic and Savegame viewer/editor for GTA V" -!define INSTALLER_NAME "gta5view_setup.exe" -!define MAIN_APP_EXE "gta5view.exe" -!define INSTALL_TYPE "SetShellVarContext all" -!define REG_ROOT "HKLM" -!define REG_APP_PATH "Software\Microsoft\Windows\CurrentVersion\App Paths\${MAIN_APP_EXE}" -!define UNINSTALL_PATH "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" -!define LICENSE_TXT "../LICENSE" - -###################################################################### - -VIProductVersion "${VERSION}" -VIAddVersionKey "ProductName" "${APP_NAME}" -VIAddVersionKey "ProductVersion" "${VERSION}" -VIAddVersionKey "CompanyName" "${COMP_NAME}" -VIAddVersionKey "LegalCopyright" "${COPYRIGHT}" -VIAddVersionKey "FileDescription" "${DESCRIPTION}" -VIAddVersionKey "FileVersion" "${VERSION}" - -###################################################################### - -!include "x64.nsh" -SetCompressor LZMA -Name "${APP_NAME}" -Caption "${APP_NAME}" -OutFile "${INSTALLER_NAME}" -#BrandingText "${APP_NAME}" -XPStyle on -Unicode true -InstallDirRegKey "${REG_ROOT}" "${REG_APP_PATH}" "" -InstallDir "$PROGRAMFILES64\Syping\gta5view" - -###################################################################### - -!include "MUI2.nsh" - -!define MUI_ABORTWARNING -!define MUI_UNABORTWARNING - -!define MUI_LANGDLL_REGISTRY_ROOT "${REG_ROOT}" -!define MUI_LANGDLL_REGISTRY_KEY "${UNINSTALL_PATH}" -!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language" - -!insertmacro MUI_PAGE_WELCOME - -!ifdef LICENSE_TXT -!insertmacro MUI_PAGE_LICENSE "${LICENSE_TXT}" -!endif - -!insertmacro MUI_PAGE_DIRECTORY - -!ifdef REG_START_MENU -!define MUI_STARTMENUPAGE_NODISABLE -!define MUI_STARTMENUPAGE_DEFAULTFOLDER "gta5view" -!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${REG_ROOT}" -!define MUI_STARTMENUPAGE_REGISTRY_KEY "${UNINSTALL_PATH}" -!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${REG_START_MENU}" -!insertmacro MUI_PAGE_STARTMENU Application $SM_Folder -!endif - -!insertmacro MUI_PAGE_INSTFILES - -!define MUI_FINISHPAGE_RUN "$INSTDIR\${MAIN_APP_EXE}" -!insertmacro MUI_PAGE_FINISH - -!insertmacro MUI_UNPAGE_CONFIRM - -!insertmacro MUI_UNPAGE_INSTFILES - -!insertmacro MUI_UNPAGE_FINISH - -!insertmacro MUI_LANGUAGE "English" -!insertmacro MUI_LANGUAGE "French" -!insertmacro MUI_LANGUAGE "German" -!insertmacro MUI_LANGUAGE "Korean" -!insertmacro MUI_LANGUAGE "Russian" -!insertmacro MUI_LANGUAGE "Ukrainian" -!insertmacro MUI_LANGUAGE "TradChinese" - -!insertmacro MUI_RESERVEFILE_LANGDLL - -###################################################################### - -Function .onInit -!insertmacro MUI_LANGDLL_DISPLAY -!ifdef WIN32 - MessageBox MB_OK|MB_ICONSTOP "Windows 32-Bit is not supported anymore!" - Quit -!endif -SetRegView 64 -FunctionEnd - -###################################################################### - -Section -MainProgram -${INSTALL_TYPE} -SetOverwrite ifnewer -SetOutPath "$INSTDIR" -File "../build/gta5view.exe" -File "/opt/llvm-mingw/x86_64-w64-mingw32/bin/libc++.dll" -File "/opt/llvm-mingw/x86_64-w64-mingw32/bin/libunwind.dll" -File "/usr/local/lib/x86_64-w64-mingw32/openssl/bin/libcrypto-1_1-x64.dll" -File "/usr/local/lib/x86_64-w64-mingw32/openssl/bin/libssl-1_1-x64.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Core.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Gui.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Network.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Svg.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Widgets.dll" -SetOutPath "$INSTDIR\lang" -File "../build/gta5sync_en_US.qm" -File "../build/gta5sync_de.qm" -File "../build/gta5sync_fr.qm" -File "../build/gta5sync_ko.qm" -File "../build/gta5sync_ru.qm" -File "../build/gta5sync_uk.qm" -File "../build/gta5sync_zh_TW.qm" -File "../build/qtbase_en_GB.qm" -File "../res/qt5/qtbase_de.qm" -File "../res/qt5/qtbase_fr.qm" -File "../res/qt5/qtbase_ko.qm" -File "../res/qt5/qtbase_ru.qm" -File "../res/qt5/qtbase_uk.qm" -File "../res/qt5/qtbase_zh_TW.qm" -SetOutPath "$INSTDIR\resources" -File "../res/add.svgz" -File "../res/avatararea.png" -File "../res/avatarareaimport.png" -File "../res/back.svgz" -File "../res/flag-de.png" -File "../res/flag-fr.png" -File "../res/flag-gb.png" -File "../res/flag-kr.png" -File "../res/flag-ru.png" -File "../res/flag-tw.png" -File "../res/flag-ua.png" -File "../res/flag-us.png" -File "../res/gta5view-16.png" -File "../res/gta5view-24.png" -File "../res/gta5view-32.png" -File "../res/gta5view-40.png" -File "../res/gta5view-48.png" -File "../res/gta5view-64.png" -File "../res/gta5view-96.png" -File "../res/gta5view-128.png" -File "../res/gta5view-256.png" -File "../res/mapcayoperico.jpg" -File "../res/mappreview.jpg" -File "../res/next.svgz" -File "../res/pointmaker-8.png" -File "../res/pointmaker-16.png" -File "../res/pointmaker-24.png" -File "../res/pointmaker-32.png" -File "../res/savegame.svgz" -File "../res/watermark_1b.png" -File "../res/watermark_2b.png" -File "../res/watermark_2r.png" -SetOutPath "$INSTDIR\imageformats" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qgif.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qicns.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qico.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qjpeg.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qsvg.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qtga.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qtiff.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qwbmp.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qwebp.dll" -SetOutPath "$INSTDIR\platforms" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/platforms/qwindows.dll" -SetOutPath "$INSTDIR\styles" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/styles/qcleanlooksstyle.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/styles/qplastiquestyle.dll" -File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/styles/qwindowsvistastyle.dll" -SectionEnd - -###################################################################### - -Section -Icons_Reg -SetOutPath "$INSTDIR" -WriteUninstaller "$INSTDIR\uninstall.exe" - -!ifdef REG_START_MENU -!insertmacro MUI_STARTMENU_WRITE_BEGIN Application -CreateDirectory "$SMPROGRAMS\$SM_Folder" -CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}" -CreateShortCut "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe" - -!ifdef WEB_SITE -WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}" -CreateShortCut "$SMPROGRAMS\$SM_Folder\gta5view Website.lnk" "$INSTDIR\${APP_NAME} website.url" -!endif -!insertmacro MUI_STARTMENU_WRITE_END -!endif - -!ifndef REG_START_MENU -CreateDirectory "$SMPROGRAMS\gta5view" -CreateShortCut "$SMPROGRAMS\gta5view\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}" -CreateShortCut "$SMPROGRAMS\gta5view\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe" - -!ifdef WEB_SITE -WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}" -CreateShortCut "$SMPROGRAMS\gta5view\gta5view Website.lnk" "$INSTDIR\${APP_NAME} website.url" -!endif -!endif - -WriteRegStr ${REG_ROOT} "${REG_APP_PATH}" "" "$INSTDIR\${MAIN_APP_EXE}" -WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayName" "${APP_NAME}" -WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "UninstallString" "$INSTDIR\uninstall.exe" -WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayIcon" "$INSTDIR\${MAIN_APP_EXE}" -WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayVersion" "${VERSION}" -WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "Publisher" "${COMP_NAME}" - -!ifdef WEB_SITE -WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "URLInfoAbout" "${WEB_SITE}" -!endif -SectionEnd - -###################################################################### - -Section -ShellAssoc -WriteRegStr ${REG_ROOT} "Software\Classes\${APP_NAME}\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},0" -WriteRegStr ${REG_ROOT} "Software\Classes\${APP_NAME}\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' -WriteRegStr ${REG_ROOT} "Software\Classes\${APP_EXT}" "" "${APP_NAME}" -WriteRegStr ${REG_ROOT} "Software\Classes\${APP_EXT}" "Content Type" "application/x-gta5view-export" -System::Call 'SHELL32::SHChangeNotify(i0x8000000,i0,p0,p0)' -SectionEnd - -###################################################################### - -Section -un.ShellAssoc -ClearErrors -ReadRegStr $0 ${REG_ROOT} "Software\Classes\${APP_EXT}" "" -DeleteRegKey ${REG_ROOT} "Software\Classes\${APP_NAME}" -${IfNot} ${Errors} -${AndIf} $0 == "${APP_NAME}" -DeleteRegValue ${REG_ROOT} "Software\Classes\${APP_EXT}" "" -DeleteRegKey /IfEmpty ${REG_ROOT} "Software\Classes\${APP_EXT}" -${EndIf} -System::Call 'SHELL32::SHChangeNotify(i0x8000000,i0,p0,p0)' -SectionEnd - -###################################################################### - -Section Uninstall -${INSTALL_TYPE} -Delete "$INSTDIR\gta5view.exe" -Delete "$INSTDIR\libc++.dll" -Delete "$INSTDIR\libunwind.dll" -Delete "$INSTDIR\libcrypto-1_1-x64.dll" -Delete "$INSTDIR\libssl-1_1-x64.dll" -Delete "$INSTDIR\Qt5Core.dll" -Delete "$INSTDIR\Qt5Gui.dll" -Delete "$INSTDIR\Qt5Network.dll" -Delete "$INSTDIR\Qt5Svg.dll" -Delete "$INSTDIR\Qt5Widgets.dll" -Delete "$INSTDIR\lang\gta5sync_en_US.qm" -Delete "$INSTDIR\lang\gta5sync_de.qm" -Delete "$INSTDIR\lang\gta5sync_fr.qm" -Delete "$INSTDIR\lang\gta5sync_ko.qm" -Delete "$INSTDIR\lang\gta5sync_ru.qm" -Delete "$INSTDIR\lang\gta5sync_uk.qm" -Delete "$INSTDIR\lang\gta5sync_zh_TW.qm" -Delete "$INSTDIR\lang\qtbase_en_GB.qm" -Delete "$INSTDIR\lang\qtbase_de.qm" -Delete "$INSTDIR\lang\qtbase_fr.qm" -Delete "$INSTDIR\lang\qtbase_ko.qm" -Delete "$INSTDIR\lang\qtbase_ru.qm" -Delete "$INSTDIR\lang\qtbase_uk.qm" -Delete "$INSTDIR\lang\qtbase_zh_TW.qm" -Delete "$INSTDIR\resources\add.svgz" -Delete "$INSTDIR\resources\avatararea.png" -Delete "$INSTDIR\resources\avatarareaimport.png" -Delete "$INSTDIR\resources\back.svgz" -Delete "$INSTDIR\resources\flag-de.png" -Delete "$INSTDIR\resources\flag-fr.png" -Delete "$INSTDIR\resources\flag-gb.png" -Delete "$INSTDIR\resources\flag-kr.png" -Delete "$INSTDIR\resources\flag-ru.png" -Delete "$INSTDIR\resources\flag-tw.png" -Delete "$INSTDIR\resources\flag-ua.png" -Delete "$INSTDIR\resources\flag-us.png" -Delete "$INSTDIR\resources\gta5view-16.png" -Delete "$INSTDIR\resources\gta5view-24.png" -Delete "$INSTDIR\resources\gta5view-32.png" -Delete "$INSTDIR\resources\gta5view-40.png" -Delete "$INSTDIR\resources\gta5view-48.png" -Delete "$INSTDIR\resources\gta5view-64.png" -Delete "$INSTDIR\resources\gta5view-96.png" -Delete "$INSTDIR\resources\gta5view-128.png" -Delete "$INSTDIR\resources\gta5view-256.png" -Delete "$INSTDIR\resources\mapcayoperico.jpg" -Delete "$INSTDIR\resources\mappreview.jpg" -Delete "$INSTDIR\resources\next.svgz" -Delete "$INSTDIR\resources\pointmaker-8.png" -Delete "$INSTDIR\resources\pointmaker-16.png" -Delete "$INSTDIR\resources\pointmaker-24.png" -Delete "$INSTDIR\resources\pointmaker-32.png" -Delete "$INSTDIR\resources\savegame.svgz" -Delete "$INSTDIR\resources\watermark_1b.png" -Delete "$INSTDIR\resources\watermark_2b.png" -Delete "$INSTDIR\resources\watermark_2r.png" -Delete "$INSTDIR\imageformats\qgif.dll" -Delete "$INSTDIR\imageformats\qicns.dll" -Delete "$INSTDIR\imageformats\qico.dll" -Delete "$INSTDIR\imageformats\qjpeg.dll" -Delete "$INSTDIR\imageformats\qsvg.dll" -Delete "$INSTDIR\imageformats\qtga.dll" -Delete "$INSTDIR\imageformats\qtiff.dll" -Delete "$INSTDIR\imageformats\qwbmp.dll" -Delete "$INSTDIR\imageformats\qwebp.dll" -Delete "$INSTDIR\platforms\qwindows.dll" -Delete "$INSTDIR\styles\qcleanlooksstyle.dll" -Delete "$INSTDIR\styles\qplastiquestyle.dll" -Delete "$INSTDIR\styles\qwindowsvistastyle.dll" -RmDir "$INSTDIR\lang" -RmDir "$INSTDIR\imageformats" -RmDir "$INSTDIR\platforms" -RmDir "$INSTDIR\styles" - -Delete "$INSTDIR\uninstall.exe" -!ifdef WEB_SITE -Delete "$INSTDIR\${APP_NAME} website.url" -!endif - -RmDir "$INSTDIR" - -!ifdef REG_START_MENU -!insertmacro MUI_STARTMENU_GETFOLDER "Application" $SM_Folder -Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk" -Delete "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk" -!ifdef WEB_SITE -Delete "$SMPROGRAMS\$SM_Folder\gta5view Website.lnk" -!endif -RmDir "$SMPROGRAMS\$SM_Folder" -!endif - -!ifndef REG_START_MENU -Delete "$SMPROGRAMS\gta5view\${APP_NAME}.lnk" -Delete "$SMPROGRAMS\gta5view\Uninstall ${APP_NAME}.lnk" -!ifdef WEB_SITE -Delete "$SMPROGRAMS\gta5view\gta5view Website.lnk" -!endif -RmDir "$SMPROGRAMS\gta5view" -!endif - -DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}" -DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}" -SectionEnd - -###################################################################### - -Function un.onInit -!insertmacro MUI_UNGETLANGUAGE -SetRegView 64 -FunctionEnd - -###################################################################### diff --git a/.ci/osx_build.sh b/.ci/osx_build.sh deleted file mode 100755 index c8545c4..0000000 --- a/.ci/osx_build.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -# Creating folders -cd ${PROJECT_DIR} && \ -echo "gta5view build version is ${APPLICATION_VERSION}" && \ -echo "gta5view image name is gta5view-osx_${APPLICATION_VERSION}.dmg" && \ -mkdir -p build && \ -mkdir -p assets && \ -cd build && \ - -/usr/local/bin/cmake \ - "-DCMAKE_PREFIX_PATH=/usr/local/opt/qt" \ - "${CMAKE_BUILD_TYPE}" \ - "-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \ - "-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \ - "-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \ - "-DWITH_DONATE=ON" \ - "-DWITH_TELEMETRY=ON" \ - "-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \ - "-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \ - ../ && \ -make -j 4 && \ -/usr/local/opt/qt/bin/macdeployqt gta5view.app -dmg && \ -cp -Rf gta5view.dmg ../assets/gta5view-osx_${APPLICATION_VERSION}.dmg diff --git a/.ci/osx_ci.sh b/.ci/osx_ci.sh deleted file mode 100755 index 59a722e..0000000 --- a/.ci/osx_ci.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -# Install packages -.ci/osx_install.sh && \ - -# Build gta5view -.ci/osx_build.sh && \ -cd ${PROJECT_DIR} diff --git a/.ci/osx_install.sh b/.ci/osx_install.sh deleted file mode 100755 index 9c5c5f3..0000000 --- a/.ci/osx_install.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Install packages -brew upgrade cmake qt diff --git a/.ci/windows_build.sh b/.ci/windows_build.sh deleted file mode 100755 index 4b85c38..0000000 --- a/.ci/windows_build.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -# Prepare environment variable -export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \ - -# Creating folders -cd ${PROJECT_DIR} && \ -echo "gta5view build version is ${APPLICATION_VERSION}" && \ -echo "gta5view executable is ${GTA5VIEW_EXECUTABLE}" && \ -mkdir -p build && \ -mkdir -p assets && \ - -# Starting build -cd build && \ -mingw64-qt-cmake \ - "${CMAKE_BUILD_TYPE}" \ - "-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \ - "-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \ - "-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \ - "-DWITH_DONATE=ON" \ - "-DWITH_TELEMETRY=ON" \ - "-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \ - "-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \ - .. && \ -make -j 4 && \ -x86_64-w64-mingw32-strip -s gta5view.exe && \ -cp -Rf *.exe ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} && \ -cd ${PROJECT_DIR}/assets diff --git a/.ci/windows_docker.sh b/.ci/windows_docker.sh deleted file mode 100755 index 54862f1..0000000 --- a/.ci/windows_docker.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -DOCKER_IMAGE=sypingauto/gta5view-build:1.10-static -PROJECT_DIR_DOCKER=/gta5view - -cd ${PROJECT_DIR} && \ -docker pull ${DOCKER_IMAGE} && \ -docker run --rm \ - -v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \ - ${DOCKER_IMAGE} \ - /bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/windows_build.sh" && \ - -# Prepare environment variable -export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \ - -# Upload Assets to Dropbox -if [ "${PACKAGE_CODE}" == "gta5-mods" ]; then - ${PROJECT_DIR}/.ci/dropbox_uploader.sh mkdir gta5-mods/${PACKAGE_VERSION} - ${PROJECT_DIR}/.ci/dropbox_uploader.sh upload ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} gta5-mods/${PACKAGE_VERSION}/${GTA5VIEW_EXECUTABLE} && \ - rm -rf ${GTA5VIEW_EXECUTABLE} -elif [ "${PACKAGE_CODE}" == "gtainside" ]; then - ${PROJECT_DIR}/.ci/dropbox_uploader.sh mkdir gtainside/${PACKAGE_VERSION} - ${PROJECT_DIR}/.ci/dropbox_uploader.sh upload ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} gtainside/${PACKAGE_VERSION}/${GTA5VIEW_EXECUTABLE} && \ - rm -rf ${GTA5VIEW_EXECUTABLE} -fi diff --git a/.ci/wininstall_build.sh b/.ci/wininstall_build.sh deleted file mode 100755 index 8ecbe4e..0000000 --- a/.ci/wininstall_build.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -# Creating folders -cd ${PROJECT_DIR} && \ -echo "gta5view build version is ${APPLICATION_VERSION}" && \ -mkdir -p build && \ -mkdir -p assets && \ - -# Starting build -cd build && \ -mingw64-qt-cmake \ - "${CMAKE_BUILD_TYPE}" \ - "-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \ - "-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \ - "-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \ - "-DWITH_DONATE=ON" \ - "-DWITH_TELEMETRY=ON" \ - "-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \ - "-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \ - "-DQCONF_BUILD=ON" \ - "-DGTA5VIEW_INLANG=RUNDIR:SEPARATOR:lang" \ - "-DGTA5VIEW_LANG=RUNDIR:SEPARATOR:lang" \ - "-DGTA5VIEW_PLUG=RUNDIR:SEPARATOR:plugins" \ - .. && \ -make -j 4 && \ -x86_64-w64-mingw32-strip -s gta5view.exe && \ -cd ${PROJECT_DIR}/assets && \ -makensis "-XTarget amd64-unicode" -NOCD ${PROJECT_DIR}/.ci/gta5view.nsi && \ -mv -f gta5view_setup.exe gta5view-${EXECUTABLE_VERSION}_setup.exe diff --git a/.ci/wininstall_docker.sh b/.ci/wininstall_docker.sh deleted file mode 100755 index 7a51180..0000000 --- a/.ci/wininstall_docker.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -DOCKER_IMAGE=sypingauto/gta5view-build:1.10-shared -PROJECT_DIR_DOCKER=/gta5view - -cd ${PROJECT_DIR} && \ -docker pull ${DOCKER_IMAGE} && \ -docker run --rm \ - -v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \ - ${DOCKER_IMAGE} \ - /bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/wininstall_build.sh" diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index ba4a1c5..0000000 --- a/.drone.yml +++ /dev/null @@ -1,36 +0,0 @@ -kind: pipeline -type: docker - -environment: - BUILD_TYPE: "REL" - -steps: -- name: Windows Installer - image: sypingauto/gta5view-build:1.10-shared - environment: - BUILD_SCRIPT: "wininstall_build.sh" - QT_SELECT: "qt5-x86_64-w64-mingw32" - TCA_PASS: - from_secret: tca_pass - commands: - - .drone/drone.sh - volumes: - - name: gta5view - path: /srv/gta5view -- name: Windows Portable - image: sypingauto/gta5view-build:1.10-static - environment: - BUILD_SCRIPT: "windows_build.sh" - QT_SELECT: "qt5-x86_64-w64-mingw32" - TCA_PASS: - from_secret: tca_pass - commands: - - .drone/drone.sh - volumes: - - name: gta5view - path: /srv/gta5view - -volumes: -- name: gta5view - host: - path: /srv/gta5view diff --git a/.drone/TelemetryClassAuthenticator.cpp.enc b/.drone/TelemetryClassAuthenticator.cpp.enc deleted file mode 100644 index e905d2f..0000000 Binary files a/.drone/TelemetryClassAuthenticator.cpp.enc and /dev/null differ diff --git a/.drone/drone.sh b/.drone/drone.sh deleted file mode 100755 index b489e12..0000000 --- a/.drone/drone.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -# Cleanup previous Drone build -if [ -d "assets" ]; then - rm -rf assets -fi -if [ -d "build" ]; then - rm -rf build -fi - -# Decrypt Telemetry Authenticator -rm -rf tmext/TelemetryClassAuthenticator.cpp && \ -openssl aes-256-cbc -k ${TCA_PASS} -in .drone/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d -pbkdf2 - -# Check if build is not tagged -if [ "${DRONE_TAG}" == "" ]; then - export EXECUTABLE_TAG=-$(git rev-parse --short HEAD) -else - export EXECUTABLE_TAG= -fi - -# Check if package code is not set -if [ "${PACKAGE_CODE}" == "" ]; then - export PACKAGE_CODE=Drone -fi - -# Init Application Commit Hash -export APPLICATION_COMMIT=$(git rev-parse --short HEAD) - -# Start CI script and copying assets into gta5view directory -.ci/ci.sh && \ -mkdir -p /srv/gta5view/${APPLICATION_COMMIT} && \ -cp -Rf assets/* /srv/gta5view/${APPLICATION_COMMIT}/ diff --git a/.flatpak/de.syping.gta5view.yaml b/.flatpak/de.syping.gta5view.yaml deleted file mode 100644 index c9a9775..0000000 --- a/.flatpak/de.syping.gta5view.yaml +++ /dev/null @@ -1,22 +0,0 @@ -app-id: de.syping.gta5view -runtime: org.kde.Platform -runtime-version: '5.15-21.08' -sdk: org.kde.Sdk -command: gta5view -finish-args: - - --share=network - - --share=ipc - - --socket=fallback-x11 - - --socket=wayland - - --device=dri -modules: - - name: gta5view - buildsystem: cmake-ninja - config-opts: - - -DFLATPAK_BUILD=ON - - -DQCONF_BUILD=ON - - -DGTA5VIEW_BUILDCODE=Flatpak - - -DGTA5VIEW_BUILDTYPE=Release - sources: - - type: dir - path: ../ diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index cd1cbfb..0000000 --- a/.gitattributes +++ /dev/null @@ -1,28 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto eol=lf - -# Development files -*.cpp text eol=lf -*.h text eol=lf -*.ui text eol=lf -*.qrc text eol=lf - -# Development resources -*.ini text eol=lf - -# Linux development files -*.desktop text eol=lf - -# Windows development files -*.rc text eol=crlf -*.nsi text eol=crlf -*.exe.manifest text eol=crlf - -# Binary files -*.png binary -*.jpg binary -*.qm binary -*.ico binary -*.icns binary -*.xcf binary -*.g5e binary diff --git a/.gitignore b/.gitignore index fcd678b..245b0b6 100644 --- a/.gitignore +++ b/.gitignore @@ -28,8 +28,4 @@ *.app # Qt project user file -*.pro.user - -# Gettext translation files -*.po -*.pot +*.pro.user \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 72ea2e6..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,31 +0,0 @@ -stages: - - build - -variables: - BUILD_TYPE: "REL" - -Windows Installer: - stage: build - image: sypingauto/gta5view-build:1.10-shared - variables: - BUILD_SCRIPT: "wininstall_build.sh" - QT_SELECT: "qt5-x86_64-w64-mingw32" - script: - - .gitlab/gitlab.sh - artifacts: - name: "gta5view-$CI_COMMIT_REF_NAME-${CI_COMMIT_SHA:0:8}_setup" - paths: - - "gta5view-*.exe" - -Windows Portable: - stage: build - image: sypingauto/gta5view-build:1.10-static - variables: - BUILD_SCRIPT: "windows_build.sh" - QT_SELECT: "qt5-x86_64-w64-mingw32" - script: - - .gitlab/gitlab.sh - artifacts: - name: "gta5view-$CI_COMMIT_REF_NAME-${CI_COMMIT_SHA:0:8}_portable" - paths: - - "gta5view-*.exe" diff --git a/.gitlab/TelemetryClassAuthenticator.cpp.enc b/.gitlab/TelemetryClassAuthenticator.cpp.enc deleted file mode 100644 index 3c7445b..0000000 Binary files a/.gitlab/TelemetryClassAuthenticator.cpp.enc and /dev/null differ diff --git a/.gitlab/gitlab.sh b/.gitlab/gitlab.sh deleted file mode 100755 index 87d2078..0000000 --- a/.gitlab/gitlab.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# Decrypt Telemetry Authenticator -rm -rf tmext/TelemetryClassAuthenticator.cpp && \ -openssl aes-256-cbc -k ${tca_pass} -in .gitlab/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d - -# Check if build is not tagged -if [ "${CI_COMMIT_TAG}" == "" ]; then - export EXECUTABLE_TAG=-$(git rev-parse --short HEAD) -else - export EXECUTABLE_TAG= -fi - -# Check if package code is not set -if [ "${PACKAGE_CODE}" == "" ]; then - export PACKAGE_CODE=GitLab -fi - -# Init Application Commit Hash -export APPLICATION_COMMIT=$(git rev-parse --short HEAD) - -# Start CI script and copying assets into base directory -.ci/ci.sh && \ -cp -Rf assets/* ./ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f6c3397..0000000 --- a/.travis.yml +++ /dev/null @@ -1,50 +0,0 @@ -dist: bionic -sudo: required - -language: cpp - -services: - - docker - -env: - global: - - BUILD_TYPE=REL - -matrix: - include: - - env: - - BUILD_SCRIPT=debian_docker.sh - - RELEASE_LABEL="Debian 64-Bit Package" - - DEBIAN_VERSION=buster - - DOCKER_USER=amd64 - - APT_INSTALL=clang - - env: - - BUILD_SCRIPT=windows_docker.sh - - QT_SELECT=qt5-x86_64-w64-mingw32 - - RELEASE_LABEL="Windows 64-Bit Portable" - - env: - - BUILD_SCRIPT=wininstall_docker.sh - - QT_SELECT=qt5-x86_64-w64-mingw32 - - RELEASE_LABEL="Windows 64-Bit Installer" - - os: osx - osx_image: xcode14.2 - env: - - BUILD_SCRIPT=osx_ci.sh - - RELEASE_LABEL="Mac OS X 64-Bit Disk Image" - -before_install: - - ".travis/source.sh" - -script: - - ".travis/travis.sh" - -deploy: - provider: releases - api_key: - secure: o7VneEz1aHfdVwZvOZLfopf6uJWNrFsZaBvunTmXFzpmNFhlNS1qwqgMUkIA2yBRbZ3wIzVs4vfwIHv7W9yE/PqK+AYL+R8+AwKGrwlgT4HqJNuk6VM/LNJ6GwT/qkQuaoOVw29bUjmzzgIRdHmw53SlJv6Hh1VE8HphlTT//aex6nCfcFhUZ0BETdZDWz5FSHwL3NalUoqfKfQrJeky5RXzCyCANQC2tKt0bV46GaWIgWrDo2KCTNqPtRWWf5GDmnkXE5IYRMQ3mXvO9iYh0v5Y2jo4PiXGUiFUU6Z3aAWFAiPdGclrBO697cf3lCTzDMhuCETR153qFYsLShUlFf61ITAmCeHAWETjZDri0lmPONo3GoNB6alGfYEA51qw14kXakrTpICtTJj7gw/gtUYOabW6hrzmieNzMBIy62RikDPjyakFnuwW2qNHRlD65e0jYv+6nCpb6E+OV16Ysh1zhV2vTfpfzVmSuyu2J+ELqXD3OZCXRSPpDIih9UQ8335p8FBji6jHORcgym/TRgdgRmENibh8tLzWp+UjpWHuWfcpvZgOskjfwU0iDMCayMJ7tDpOhXHcAhDRnd6XRIiOJ5YZCzflj2nEwmt3YUd7DwXS/AU+WHOmcNQBjXBxF/FJa35XXcy3HKJM5TTKqtph3medo30us5yXHeG6NNg= - label: ${RELEASE_LABEL} - file_glob: true - file: assets/* - skip_cleanup: true - on: - tags: true diff --git a/.travis/TelemetryClassAuthenticator.cpp.enc b/.travis/TelemetryClassAuthenticator.cpp.enc deleted file mode 100644 index 498ad86..0000000 Binary files a/.travis/TelemetryClassAuthenticator.cpp.enc and /dev/null differ diff --git a/.travis/dropbox_uploader.enc b/.travis/dropbox_uploader.enc deleted file mode 100644 index 60a77f9..0000000 --- a/.travis/dropbox_uploader.enc +++ /dev/null @@ -1 +0,0 @@ -PoQN<1x%{w|RtZv[kAZ2Ϋ`J,4vϥ@eʥ~U$+P|y<&H \ No newline at end of file diff --git a/.travis/source.sh b/.travis/source.sh deleted file mode 100755 index 833e125..0000000 --- a/.travis/source.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -rm -rf tmext/TelemetryClassAuthenticator.cpp && \ -openssl aes-256-cbc -K $encrypted_db000a5d87d6_key -iv $encrypted_db000a5d87d6_iv -in .travis/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d && \ -openssl aes-256-cbc -K $encrypted_d57e7d2f8877_key -iv $encrypted_d57e7d2f8877_iv -in .travis/dropbox_uploader.enc -out ~/.dropbox_uploader -d diff --git a/.travis/travis.sh b/.travis/travis.sh deleted file mode 100755 index 94154d5..0000000 --- a/.travis/travis.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# Install lua -if [ "${TRAVIS_OS_NAME}" == "osx" ]; then - brew install lua -else - sudo apt-get update -qq && \ - sudo apt-get install -qq lua5.2 -fi - -# Check if build is not tagged -if [ "${TRAVIS_TAG}" == "" ]; then - export EXECUTABLE_TAG=-$(git rev-parse --short HEAD) -else - export EXECUTABLE_TAG= -fi - -# Check if package code is not set -if [ "${PACKAGE_CODE}" == "" ]; then - export PACKAGE_CODE=GitHub -fi - -# Init Application Commit Hash -export APPLICATION_COMMIT=$(git rev-parse --short HEAD) - -# Start CI script -.ci/ci.sh diff --git a/.travis/ubuntu_travis.sh b/.travis/ubuntu_travis.sh deleted file mode 100755 index d93bcbd..0000000 --- a/.travis/ubuntu_travis.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# Install packages -sudo .ci/debian_install.sh && \ - -# Build gta5view -sudo .ci/debian_build.sh && \ -cd ${PROJECT_DIR} diff --git a/AboutDialog.cpp b/AboutDialog.cpp old mode 100644 new mode 100755 index 12852cf..f492236 --- a/AboutDialog.cpp +++ b/AboutDialog.cpp @@ -1,126 +1,40 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include -#include -#include -#include "AboutDialog.h" -#include "ui_AboutDialog.h" -#include "AppEnv.h" -#include "config.h" - -AboutDialog::AboutDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::AboutDialog) -{ - // Set Window Flags -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - - // Build Strings - QString appVersion = QApplication::applicationVersion(); - const char* literalBuildType = GTA5SYNC_BUILDTYPE; - const QString buildType = tr(literalBuildType); - const QString projectBuild = AppEnv::getBuildDateTime(); - const QString buildStr = GTA5SYNC_BUILDSTRING; -#ifdef GTA5SYNC_COMMIT - if ((strcmp(literalBuildType, REL_BUILDTYPE) != 0) && !appVersion.contains("-")) - appVersion = appVersion % "-" % GTA5SYNC_COMMIT; -#endif - - // Translator Comments - //: Translated by translator, example Translated by Syping - const QString translatedByStr = tr("Translated by %1"); - //: Insert your name here and profile here in following scheme, First Translator,First Profile\\nSecond Translator\\nThird Translator,Second Profile - const QString translatorVal = tr("TRANSLATOR"); - QStringList translatorContent; - if (translatorVal != "TRANSLATOR") { - const QStringList translatorList = translatorVal.split('\n'); - for (const QString &translatorStr : translatorList) { - QStringList translatorStrList = translatorStr.split(','); - const QString translatorName = translatorStrList.at(0); - translatorStrList.removeFirst(); - QString translatorProfile = translatorStrList.join(QString()); - if (!translatorProfile.isEmpty()) { - translatorContent += QString("%2").arg(translatorProfile, translatorName); - } - else { - translatorContent += translatorName; - } - } - } - - // Project Description - const QString projectDes = tr("A project for viewing Grand Theft Auto V Snapmatic
\nPictures and Savegames"); - - // Copyright Description - QString copyrightDes1 = tr("Copyright © %2 %3"); - copyrightDes1 = copyrightDes1.arg(GTA5SYNC_APPVENDORLINK, GTA5SYNC_APPVENDOR, GTA5SYNC_COPYRIGHT); - QString copyrightDes2 = tr("%1 is licensed under GNU GPLv3"); - copyrightDes2 = copyrightDes2.arg(GTA5SYNC_APPSTR); - QString copyrightDesA; - if (!translatorContent.isEmpty()) { - copyrightDesA = copyrightDes1 % "
" % translatedByStr.arg(translatorContent.join(", ")) % "
" % copyrightDes2; - } - else { - copyrightDesA = copyrightDes1 % "
" % copyrightDes2; - } - - // Setup User Interface - ui->setupUi(this); - aboutStr = ui->labAbout->text(); - titleStr = windowTitle(); - ui->labAbout->setText(aboutStr.arg(GTA5SYNC_APPSTR, projectDes, appVersion % " (" % buildType % ")", projectBuild, buildStr, qVersion(), copyrightDesA)); - setWindowTitle(titleStr.arg(GTA5SYNC_APPSTR)); - - // Set Icon for Close Button - if (QIcon::hasThemeIcon("dialog-close")) { - ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) { - ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close")); - } - - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); - if (!translatorContent.isEmpty()) { - resize(375 * screenRatio, 270 * screenRatio); - } - else { - resize(375 * screenRatio, 260 * screenRatio); - } -} - -AboutDialog::~AboutDialog() -{ - delete ui; -} - -void AboutDialog::on_labAbout_linkActivated(const QString &link) -{ - if (link.left(12) == "g5e://about?") { - QStringList aboutStrList = QString(link).remove(0, 12).split(":"); - QMessageBox::information(this, QString::fromUtf8(QByteArray::fromBase64(aboutStrList.at(0).toUtf8())), QString::fromUtf8(QByteArray::fromBase64(aboutStrList.at(1).toUtf8()))); - } - else { - QDesktopServices::openUrl(QUrl(link)); - } -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include +#include "AboutDialog.h" +#include "ui_AboutDialog.h" +#include "config.h" + +AboutDialog::AboutDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutDialog) +{ + ui->setupUi(this); + aboutStr = ui->labAbout->text(); + QString appVersion = qApp->applicationVersion(); + QString buildType = GTA5SYNC_BUILDTYPE; + buildType.replace("_", " "); + QString buildStr = QString("%1, %2").arg(QT_VERSION_STR, GTA5SYNC_COMPILER); + ui->labAbout->setText(aboutStr.arg(appVersion % " (" % buildType % ")", buildStr, qVersion(), __DATE__, __TIME__)); +} + +AboutDialog::~AboutDialog() +{ + delete ui; +} diff --git a/AboutDialog.h b/AboutDialog.h old mode 100644 new mode 100755 index a13dcc0..1ff5484 --- a/AboutDialog.h +++ b/AboutDialog.h @@ -1,44 +1,43 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef ABOUTDIALOG_H -#define ABOUTDIALOG_H - -#include - -namespace Ui { -class AboutDialog; -} - -class AboutDialog : public QDialog -{ - Q_OBJECT -public: - explicit AboutDialog(QWidget *parent = 0); - ~AboutDialog(); - -private slots: - void on_labAbout_linkActivated(const QString &link); - -private: - Ui::AboutDialog *ui; - QString aboutStr; - QString titleStr; -}; - -#endif // ABOUTDIALOG_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef ABOUTDIALOG_H +#define ABOUTDIALOG_H + +#include + +namespace Ui { +class AboutDialog; +} + +class AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent = 0); + ~AboutDialog(); + +private slots: + +private: + Ui::AboutDialog *ui; + QString aboutStr; +}; + +#endif // ABOUTDIALOG_H diff --git a/AboutDialog.ui b/AboutDialog.ui old mode 100644 new mode 100755 index 3672e20..883ed7f --- a/AboutDialog.ui +++ b/AboutDialog.ui @@ -1,102 +1,106 @@ - - - AboutDialog - - - - 0 - 0 - 375 - 260 - - - - About %1 - - - true - - - - - - - 0 - 0 - - - - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -Version %3<br/> -Created on %4<br/> -Built with Qt %5<br/> -Running with Qt %6<br/> -<br/> -%7 - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - false - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - &Close - - - - - - - - - - - cmdClose - clicked() - AboutDialog - close() - - - 327 - 228 - - - 187 - 124 - - - - - + + + AboutDialog + + + + 0 + 0 + 375 + 260 + + + + About gta5view + + + true + + + + + + + 0 + 0 + + + + <span style=" font-weight:600;">gta5view</span><br/> +<br/> +A project for viewing Grand Theft Auto V Snapmatic<br/> +Pictures and Savegames<br/> +<br/> +Project version: %1<br/> +Project build: %4, %5<br/> +Compiled with Qt %2<br/> +Running with Qt %3<br/> +<br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5view is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + false + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + &Close + + + + + + + + + + + + + + cmdClose + clicked() + AboutDialog + close() + + + 327 + 228 + + + 187 + 124 + + + + + diff --git a/AppEnv.cpp b/AppEnv.cpp old mode 100644 new mode 100755 index 9d112a5..11b67d7 --- a/AppEnv.cpp +++ b/AppEnv.cpp @@ -1,457 +1,132 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "config.h" -#include "AppEnv.h" -#include "StringParser.h" -#include "StandardPaths.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#if QT_VERSION < 0x050000 -#include -#endif - -AppEnv::AppEnv() -{ -} - -// Build Stuff - -QString AppEnv::getBuildDateTime() -{ - return GTA5SYNC_BUILDDATETIME; -} - -QString AppEnv::getBuildCode() -{ - return GTA5SYNC_BUILDCODE; -} - -// Folder Stuff - -QString AppEnv::getGameFolder(bool *ok) -{ - QDir dir; - QString GTAV_FOLDER = QString::fromUtf8(qgetenv("GTAV_FOLDER")); - if (GTAV_FOLDER != "") { - dir.setPath(GTAV_FOLDER); - if (dir.exists()) { - if (ok != NULL) - *ok = true; - qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); - return dir.absolutePath(); - } - } - - const QString GTAV_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/GTA V"; - QString GTAV_returnFolder = GTAV_defaultFolder; - - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("dir"); - bool forceDir = settings.value("force", false).toBool(); - GTAV_returnFolder = settings.value("dir", GTAV_defaultFolder).toString(); - settings.endGroup(); - - if (forceDir) { - dir.setPath(GTAV_returnFolder); - if (dir.exists()) { - if (ok != 0) - *ok = true; - qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); - return dir.absolutePath(); - } - } - - dir.setPath(GTAV_defaultFolder); - if (dir.exists()) { - if (ok != 0) - *ok = true; - qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); - return dir.absolutePath(); - } - - if (!forceDir) { - dir.setPath(GTAV_returnFolder); - if (dir.exists()) { - if (ok != 0) - *ok = true; - qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); - return dir.absolutePath(); - } - } - - if (ok != 0) - *ok = false; - return QString(); -} - -bool AppEnv::setGameFolder(QString gameFolder) -{ - QDir dir; - dir.setPath(gameFolder); - if (dir.exists()) { - qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); - return true; - } - return false; -} - -QString AppEnv::getExLangFolder() -{ - return StringParser::convertBuildedString(GTA5SYNC_LANG); -} - -QString AppEnv::getInLangFolder() -{ -#ifdef GTA5SYNC_QCONF -#ifdef GTA5SYNC_INLANG - return StringParser::convertBuildedString(GTA5SYNC_INLANG); -#else - return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("/APPNAME:/translations")); -#endif -#else -#ifdef GTA5SYNC_INLANG - return StringParser::convertBuildedString(GTA5SYNC_INLANG); -#else - return QLatin1String(":/tr"); -#endif -#endif -} - -QString AppEnv::getPluginsFolder() -{ - return StringParser::convertBuildedString(GTA5SYNC_PLUG); -} - -QString AppEnv::getImagesFolder() -{ -#if defined(GTA5SYNC_QCONF) && defined(GTA5SYNC_CMAKE) -#ifdef Q_OS_WIN - return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("/resources")); -#else - return StringParser::convertBuildedString(GTA5SYNC_SHARE % QLatin1String("/APPNAME:/resources")); -#endif -#else - return QLatin1String(":/img"); -#endif -} - -QString AppEnv::getShareFolder() -{ - return StringParser::convertBuildedString(GTA5SYNC_SHARE); -} - -// Web Stuff - -QByteArray AppEnv::getUserAgent() -{ -#if QT_VERSION >= 0x050400 -#ifdef Q_OS_WIN - QString kernelVersion = QSysInfo::kernelVersion(); - const QStringList &kernelVersionList = kernelVersion.split("."); - if (kernelVersionList.length() > 2) { - kernelVersion = kernelVersionList.at(0) % "." % kernelVersionList.at(1); - } - QString runArch = QSysInfo::buildCpuArchitecture(); - if (runArch == "x86_64") { - runArch = "Win64; x64"; - } - else if (runArch == "i686") { - const QString &curArch = QSysInfo::currentCpuArchitecture(); - if (curArch == "x86_64") { - runArch = "WOW64"; - } - else if (curArch == "i686") { - runArch = "Win32; x86"; - } - } - return QString("Mozilla/5.0 (Windows NT %1; %2) %3/%4").arg(kernelVersion, runArch, GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8(); -#else - return QString("Mozilla/5.0 (%1; %2) %3/%4").arg(QSysInfo::kernelType(), QSysInfo::kernelVersion(), GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8(); -#endif -#else - return QString("Mozilla/5.0 %1/%2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8(); -#endif -} - -QUrl AppEnv::getCrewFetchingUrl(QString crewID) -{ - return QUrl(QString("https://socialclub.rockstargames.com/crew/%1/%1").arg(crewID)); -} - -QUrl AppEnv::getPlayerFetchingUrl(QString crewID, QString pageNumber) -{ - return QUrl(QString("https://socialclub.rockstargames.com/crewsapi/GetMembersList?crewId=%1&pageNumber=%2&pageSize=5000").arg(crewID, pageNumber)); -} - -QUrl AppEnv::getPlayerFetchingUrl(QString crewID, int pageNumber) -{ - return getPlayerFetchingUrl(crewID, QString::number(pageNumber)); -} - -// Game Stuff - -GameVersion AppEnv::getGameVersion() -{ -#ifdef Q_OS_WIN - QString argumentValue; -#ifdef _WIN64 - argumentValue = "\\WOW6432Node"; -#endif - QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat); - QString installFolderSc = registrySettingsSc.value("InstallFolder", "").toString(); - QDir installFolderScDir(installFolderSc); - bool scVersionInstalled = false; - if (!installFolderSc.isEmpty() && installFolderScDir.exists()) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "gameVersionFoundSocialClubVersion"; -#endif - scVersionInstalled = true; - } - - QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\GTAV").arg(argumentValue), QSettings::NativeFormat); - QString installFolderSteam = registrySettingsSteam.value("installfoldersteam", "").toString(); - if (installFolderSteam.right(5) == "\\GTAV") { - installFolderSteam = installFolderSteam.remove(installFolderSteam.length() - 5, 5); - } - QDir installFolderSteamDir(installFolderSteam); - bool steamVersionInstalled = false; - if (!installFolderSteam.isEmpty() && installFolderSteamDir.exists()) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "gameVersionFoundSteamVersion"; -#endif - steamVersionInstalled = true; - } - - if (scVersionInstalled && steamVersionInstalled) { - return GameVersion::BothVersions; - } - else if (scVersionInstalled) { - return GameVersion::SocialClubVersion; - } - else if (steamVersionInstalled) { - return GameVersion::SteamVersion; - } - else { - return GameVersion::NoVersion; - } -#else - return GameVersion::NoVersion; -#endif -} - -GameLanguage AppEnv::getGameLanguage(GameVersion gameVersion) -{ - if (gameVersion == GameVersion::SocialClubVersion) { -#ifdef Q_OS_WIN - QString argumentValue; -#ifdef _WIN64 - argumentValue = "\\WOW6432Node"; -#endif - QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat); - QString languageSc = registrySettingsSc.value("Language", "").toString(); - return gameLanguageFromString(languageSc); -#else - return GameLanguage::Undefined; -#endif - } - else if (gameVersion == GameVersion::SteamVersion) { -#ifdef Q_OS_WIN - QString argumentValue; -#ifdef _WIN64 - argumentValue = "\\WOW6432Node"; -#endif - QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V Steam").arg(argumentValue), QSettings::NativeFormat); - QString languageSteam = registrySettingsSteam.value("Language", "").toString(); - return gameLanguageFromString(languageSteam); -#else - return GameLanguage::Undefined; -#endif - } - return GameLanguage::Undefined; -} - -GameLanguage AppEnv::gameLanguageFromString(QString gameLanguage) -{ - if (gameLanguage == "en-US") { - return GameLanguage::English; - } - else if (gameLanguage == "fr-FR") { - return GameLanguage::French; - } - else if (gameLanguage == "it-IT") { - return GameLanguage::Italian; - } - else if (gameLanguage == "de-DE") { - return GameLanguage::German; - } - else if (gameLanguage == "es-ES") { - return GameLanguage::Spanish; - } - else if (gameLanguage == "es-MX") { - return GameLanguage::Mexican; - } - else if (gameLanguage == "pt-BR") { - return GameLanguage::Brasilian; - } - else if (gameLanguage == "ru-RU") { - return GameLanguage::Russian; - } - else if (gameLanguage == "pl-PL") { - return GameLanguage::Polish; - } - else if (gameLanguage == "ja-JP") { - return GameLanguage::Japanese; - } - else if (gameLanguage == "zh-CHS") { - return GameLanguage::SChinese; - } - else if (gameLanguage == "zh-CHT") { - return GameLanguage::TChinese; - } - else if (gameLanguage == "ko-KR") { - return GameLanguage::Korean; - } - return GameLanguage::Undefined; -} - -QString AppEnv::gameLanguageToString(GameLanguage gameLanguage) -{ - switch (gameLanguage) { - case GameLanguage::English: - return "en-US"; - case GameLanguage::French: - return "fr-FR"; - case GameLanguage::Italian: - return "it-IT"; - case GameLanguage::German: - return "de-DE"; - case GameLanguage::Spanish: - return "es-ES"; - case GameLanguage::Mexican: - return "es-MX"; - case GameLanguage::Brasilian: - return "pt-BR"; - case GameLanguage::Polish: - return "pl-PL"; - case GameLanguage::Japanese: - return "ja-JP"; - case GameLanguage::SChinese: - return "zh-CHS"; - case GameLanguage::TChinese: - return "zh-CHT"; - case GameLanguage::Korean: - return "ko-KR"; - default: - return "Undefinied"; - } -} - -bool AppEnv::setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage) -{ - bool socialClubVersion = false; - bool steamVersion = false; - if (gameVersion == GameVersion::SocialClubVersion) { - socialClubVersion = true; - } - else if (gameVersion == GameVersion::SteamVersion) { - steamVersion = true; - } - else if (gameVersion == GameVersion::BothVersions) { - socialClubVersion = true; - steamVersion = true; - } - else { - return false; - } - if (socialClubVersion) { -#ifdef Q_OS_WIN - QString argumentValue; -#ifdef _WIN64 - argumentValue = "\\WOW6432Node"; -#endif - QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat); - if (gameLanguage != GameLanguage::Undefined) { - registrySettingsSc.setValue("Language", gameLanguageToString(gameLanguage)); - } - else { - registrySettingsSc.remove("Language"); - } - registrySettingsSc.sync(); - if (registrySettingsSc.status() != QSettings::NoError) { - return false; - } -#else - Q_UNUSED(gameLanguage) -#endif - } - if (steamVersion) { -#ifdef Q_OS_WIN - QString argumentValue; -#ifdef _WIN64 - argumentValue = "\\WOW6432Node"; -#endif - QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V Steam").arg(argumentValue), QSettings::NativeFormat); - if (gameLanguage != GameLanguage::Undefined) { - registrySettingsSteam.setValue("Language", gameLanguageToString(gameLanguage)); - } - else { - registrySettingsSteam.remove("Language"); - } - registrySettingsSteam.sync(); - if (registrySettingsSteam.status() != QSettings::NoError) { - return false; - } -#else - Q_UNUSED(gameLanguage) -#endif - } - return true; -} - -// Screen Stuff - -qreal AppEnv::screenRatio() -{ -#if QT_VERSION >= 0x050000 - qreal dpi = QApplication::primaryScreen()->logicalDotsPerInch(); -#else - qreal dpi = QApplication::desktop()->logicalDpiX(); -#endif -#ifdef Q_OS_MAC - return (dpi / 72); -#else - return (dpi / 96); -#endif -} - -qreal AppEnv::screenRatioPR() -{ -#if QT_VERSION >= 0x050600 - return QApplication::primaryScreen()->devicePixelRatio(); -#else - return 1; -#endif -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "config.h" +#include "AppEnv.h" +#include "StringParser.h" +#include "StandardPaths.h" +#include +#include +#include +#include +#include +using namespace std; + +AppEnv::AppEnv() +{ + +} + +// Folder Stuff + +QString AppEnv::getGameFolder(bool *ok) +{ + QDir dir; + QString GTAV_FOLDER = QString::fromUtf8(qgetenv("GTAV_FOLDER")); + if (GTAV_FOLDER != "") + { + dir.setPath(GTAV_FOLDER); + if (dir.exists()) + { + if (ok != NULL) *ok = true; + qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); + return dir.absolutePath(); + } + } + + QString GTAV_defaultFolder = StandardPaths::documentsLocation() + QDir::separator() + "Rockstar Games" + QDir::separator() + "GTA V"; + QString GTAV_returnFolder = GTAV_defaultFolder; + + QSettings SyncSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + SyncSettings.beginGroup("dir"); + bool forceDir = SyncSettings.value("force", false).toBool(); + GTAV_returnFolder = SyncSettings.value("dir", GTAV_defaultFolder).toString(); + SyncSettings.endGroup(); + + if (forceDir) + { + dir.setPath(GTAV_returnFolder); + if (dir.exists()) + { + if (ok != 0) *ok = true; + qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); + return dir.absolutePath(); + } + } + + dir.setPath(GTAV_defaultFolder); + if (dir.exists()) + { + if (ok != 0) *ok = true; + qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); + return dir.absolutePath(); + } + + if (!forceDir) + { + dir.setPath(GTAV_returnFolder); + if (dir.exists()) + { + if (ok != 0) *ok = true; + qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); + return dir.absolutePath(); + } + } + + if (ok != 0) *ok = false; + return ""; +} + +bool AppEnv::setGameFolder(QString gameFolder) +{ + QDir dir; + dir.setPath(gameFolder); + if (dir.exists()) + { + qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8()); + return true; + } + return false; +} + +QString AppEnv::getLangFolder() +{ + return StringParser::convertBuildedString(QString::fromUtf8(GTA5SYNC_LANG)); +} + +QString AppEnv::getPluginsFolder() +{ + return StringParser::convertBuildedString(QString::fromUtf8(GTA5SYNC_PLUG)); +} + +// Web Stuff + +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(); +} + +QUrl AppEnv::getCrewFetchingUrl(QString crewID) +{ + return QUrl(QString("https://socialclub.rockstargames.com/reference/crewfeed/%1").arg(crewID)); +} + +QUrl AppEnv::getPlayerFetchingUrl(QString crewID, QString pageNumber) +{ + return QUrl(QString("https://socialclub.rockstargames.com/crewsapi/GetMembersList?crewId=%1&pageNumber=%2").arg(crewID, pageNumber)); +} diff --git a/AppEnv.h b/AppEnv.h old mode 100644 new mode 100755 index 1e182a2..ed24295 --- a/AppEnv.h +++ b/AppEnv.h @@ -1,64 +1,42 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef APPENV_H -#define APPENV_H - -#include -#include - -enum class GameVersion : int { NoVersion = 0, SocialClubVersion = 1, SteamVersion = 2, BothVersions = 3 }; -enum class GameLanguage : int { Undefined = 0, English = 1, French = 2, Italian = 3, German = 4, Spanish = 5, Mexican = 6, Brasilian = 7, Russian = 8, Polish = 9, Japanese = 10, SChinese = 11, TChinese = 12, Korean = 13 }; - -class AppEnv -{ -public: - AppEnv(); - - // Build Stuff - static QString getBuildDateTime(); - static QString getBuildCode(); - - // Folder Stuff - static QString getGameFolder(bool *ok = 0); - static bool setGameFolder(QString gameFolder); - static QString getExLangFolder(); - static QString getInLangFolder(); - static QString getImagesFolder(); - static QString getPluginsFolder(); - static QString getShareFolder(); - - // Web Stuff - static QByteArray getUserAgent(); - static QUrl getCrewFetchingUrl(QString crewID); - static QUrl getPlayerFetchingUrl(QString crewID, QString pageNumber); - static QUrl getPlayerFetchingUrl(QString crewID, int pageNumber); - - // Game Stuff - static GameVersion getGameVersion(); - static GameLanguage getGameLanguage(GameVersion gameVersion); - static GameLanguage gameLanguageFromString(QString gameLanguage); - static QString gameLanguageToString(GameLanguage gameLanguage); - static bool setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage); - - // Screen Stuff - static qreal screenRatio(); - static qreal screenRatioPR(); -}; - -#endif // APPENV_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef APPENV_H +#define APPENV_H + +#include +#include + +class AppEnv +{ +public: + AppEnv(); + + // Folder Stuff + static QString getGameFolder(bool *ok = 0); + static bool setGameFolder(QString gameFolder); + static QString getLangFolder(); + static QString getPluginsFolder(); + + // Web Stuff + static QByteArray getUserAgent(); + static QUrl getCrewFetchingUrl(QString crewID); + static QUrl getPlayerFetchingUrl(QString crewID, QString pageNumber); +}; + +#endif // APPENV_H diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index dbd21a8..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,382 +0,0 @@ -cmake_minimum_required(VERSION 3.7) - -project(gta5view LANGUAGES C CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(FORCE_QT_VERSION "" CACHE STRING "Force Qt Version") -if(FORCE_QT_VERSION) - set(QT_VERSION_MAJOR ${FORCE_QT_VERSION}) -else() - find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) -endif() -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network Svg Widgets REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET) - -if(WIN32) - list(APPEND GTA5VIEW_LIBS - dwmapi - ) - list(APPEND GTA5VIEW_DEFINES - -DUNICODE - -D_UNICODE - -DWIN32 - ) - list(APPEND GTA5VIEW_RESOURCES - res/app.rc - ) -endif() -if(APPLE) - list(APPEND GTA5VIEW_RESOURCES - res/gta5view.icns - ) - set(MACOSX_BUNDLE_BUNDLE_NAME gta5view) - set(MACOSX_BUNDLE_BUNDLE_VERSION 1.10.2) - set(MACOSX_BUNDLE_ICON_FILE gta5view.icns) - set(MACOSX_BUNDLE_GUI_IDENTIFIER de.syping.gta5view) - set_source_files_properties(res/gta5view.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") -endif() - -list(APPEND GTA5VIEW_DEFINES - -DGTA5SYNC_CMAKE - -DGTA5SYNC_PROJECT -) - -set(GTA5VIEW_SOURCES - main.cpp - AboutDialog.cpp - AppEnv.cpp - CrewDatabase.cpp - DatabaseThread.cpp - ExportDialog.cpp - ExportThread.cpp - GlobalString.cpp - IconLoader.cpp - ImportDialog.cpp - JsonEditorDialog.cpp - MapLocationDialog.cpp - OptionsDialog.cpp - PictureDialog.cpp - PictureExport.cpp - PictureWidget.cpp - PlayerListDialog.cpp - ProfileDatabase.cpp - ProfileInterface.cpp - ProfileLoader.cpp - ProfileWidget.cpp - RagePhoto.cpp - SavegameCopy.cpp - SavegameData.cpp - SavegameDialog.cpp - SavegameWidget.cpp - SidebarGenerator.cpp - SnapmaticEditor.cpp - SnapmaticPicture.cpp - SnapmaticWidget.cpp - StandardPaths.cpp - StringParser.cpp - TranslationClass.cpp - UserInterface.cpp - anpro/imagecropper.cpp - pcg/pcg_basic.c - uimod/JSHighlighter.cpp - uimod/UiModLabel.cpp - uimod/UiModWidget.cpp -) - -set(GTA5VIEW_HEADERS - config.h - wrapper.h - AboutDialog.h - AppEnv.h - CrewDatabase.h - DatabaseThread.h - ExportDialog.h - ExportThread.h - GlobalString.h - IconLoader.h - ImportDialog.h - JsonEditorDialog.h - MapLocationDialog.h - OptionsDialog.h - PictureDialog.h - PictureExport.h - PictureWidget.h - PlayerListDialog.h - ProfileDatabase.h - ProfileInterface.h - ProfileLoader.h - ProfileWidget.h - RagePhoto.h - SavegameCopy.h - SavegameData.h - SavegameDialog.h - SavegameWidget.h - SidebarGenerator.h - SnapmaticEditor.h - SnapmaticPicture.h - SnapmaticWidget.h - StandardPaths.h - StringParser.h - TranslationClass.h - UserInterface.h - anpro/imagecropper.h - pcg/pcg_basic.h - uimod/JSHighlighter.h - uimod/UiModLabel.h - uimod/UiModWidget.h -) - -set(GTA5VIEW_INCLUDEDIR - anpro - pcg - uimod -) - -set(GTA5VIEW_FORMS - AboutDialog.ui - ExportDialog.ui - ImportDialog.ui - JsonEditorDialog.ui - MapLocationDialog.ui - OptionsDialog.ui - PictureDialog.ui - PlayerListDialog.ui - ProfileInterface.ui - SavegameDialog.ui - SavegameWidget.ui - SnapmaticEditor.ui - SnapmaticWidget.ui - UserInterface.ui -) - -set(GTA5VIEW_TRANSLATIONS - res/gta5sync_de.ts - res/gta5sync_en_US.ts - res/gta5sync_fr.ts - res/gta5sync_ko.ts - res/gta5sync_ru.ts - res/gta5sync_uk.ts - res/gta5sync_zh_TW.ts -) - -list(APPEND GTA5VIEW_RESOURCES - res/global.qrc - res/template.qrc -) -set_property(SOURCE res/global.qrc PROPERTY AUTORCC_OPTIONS "-threshold;0;-compress;9") - -if(Qt5LinguistTools_FOUND) - qt5_add_translation(GTA5VIEW_QMFILES - ${GTA5VIEW_TRANSLATIONS} - res/qt5/qtbase_en_GB.ts - ) - set(LINGUIST_FOUND TRUE) -elseif(Qt6LinguistTools_FOUND) - qt6_add_translation(GTA5VIEW_QMFILES - ${GTA5VIEW_TRANSLATIONS} - res/qt6/qtbase_en_GB.ts - ) - set(LINGUIST_FOUND TRUE) -else() - set(GTA5VIEW_QMFILES - res/gta5sync_de.qm - res/gta5sync_en_US.qm - res/gta5sync_fr.qm - res/gta5sync_ko.qm - res/gta5sync_ru.qm - res/gta5sync_uk.qm - res/gta5sync_zh_TW.qm - res/qt${QT_VERSION_MAJOR}/qtbase_en_GB.qm - ) -endif() - -option(QCONF_BUILD "System installation intended Qconf build" OFF) -if(QCONF_BUILD) - list(APPEND GTA5VIEW_DEFINES - -DGTA5SYNC_QCONF - ) -else() - list(APPEND GTA5VIEW_RESOURCES - res/img.qrc - res/tr_g5p.qrc - res/qt${QT_VERSION_MAJOR}/tr_qt.qrc - ) -endif() - -option(FLATPAK_BUILD "Flatpak modifications and optimisations" OFF) -if(FLATPAK_BUILD) - list(APPEND GTA5VIEW_DEFINES - -DGTA5SYNC_FLATPAK - ) -endif() - -option(WITH_DONATE "Donate menu option and donation dialog" OFF) -if(WITH_DONATE) - set(DONATE_ADDRESSES "" CACHE STRING "Donation addresses") - list(APPEND GTA5VIEW_HEADERS - anpro/QrCode.h - ) - list(APPEND GTA5VIEW_SOURCES - anpro/QrCode.cpp - ) - list(APPEND GTA5VIEW_DEFINES - -DGTA5SYNC_DONATE - ) - list(APPEND GTA5VIEW_RESOURCES - res/donate.qrc - ) - if(DONATE_ADDRESSES) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_DONATE_ADDRESSES=\"${DONATE_ADDRESSES}\"" - ) - endif() -endif() - -option(WITH_MOTD "Developer message system directed to users" OFF) -if(WITH_MOTD) - set(MOTD_WEBURL "" CACHE STRING "Messages WebURL") - list(APPEND GTA5VIEW_HEADERS - MessageThread.h - ) - list(APPEND GTA5VIEW_SOURCES - MessageThread.cpp - ) - list(APPEND GTA5VIEW_DEFINES - -DGTA5SYNC_MOTD - ) - if(MOTD_WEBURL) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_MOTD_WEBURL=\"${MOTD_WEBURL}\"" - ) - endif() -endif() - -option(WITH_TELEMETRY "Hardware survey and basic telemetry system" OFF) -if(WITH_TELEMETRY) - set(TELEMETRY_AUTHID "" CACHE STRING "Telemetry AuthID") - set(TELEMETRY_AUTHPW "" CACHE STRING "Telemetry AuthPW") - set(TELEMETRY_PUSHURL "" CACHE STRING "Telemetry PushURL") - set(TELEMETRY_REGURL "" CACHE STRING "Telemetry RegURL") - set(TELEMETRY_WEBURL "" CACHE STRING "Telemetry WebURL") - list(APPEND GTA5VIEW_HEADERS - TelemetryClass.h - tmext/TelemetryClassAuthenticator.h - ) - list(APPEND GTA5VIEW_SOURCES - TelemetryClass.cpp - tmext/TelemetryClassAuthenticator.cpp - ) - list(APPEND GTA5VIEW_INCLUDEDIR - tmext - ) - list(APPEND GTA5VIEW_DEFINES - -DGTA5SYNC_TELEMETRY - ) - if(TELEMETRY_AUTHID AND TELEMETRY_AUTHPW AND TELEMETRY_PUSHURL AND TELEMETRY_REGURL) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_TELEMETRY_AUTHID=\"${TELEMETRY_AUTHID}\"" - "-DGTA5SYNC_TELEMETRY_AUTHPW=\"${TELEMETRY_AUTHPW}\"" - "-DGTA5SYNC_TELEMETRY_PUSHURL=\"${TELEMETRY_PUSHURL}\"" - "-DGTA5SYNC_TELEMETRY_REGURL=\"${TELEMETRY_REGURL}\"" - ) - endif() - if(TELEMETRY_WEBURL) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_TELEMETRY_WEBURL=\"${TELEMETRY_WEBURL}\"" - ) - endif() - if(WIN32) - list(APPEND GTA5VIEW_LIBS - d3d9 - ) - endif() -endif() - -if(GTA5VIEW_APPVER) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_APPVER=\"${GTA5VIEW_APPVER}\"" - ) -endif() -if(GTA5VIEW_BUILDCODE) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_BUILDCODE=\"${GTA5VIEW_BUILDCODE}\"" - ) -endif() -if(GTA5VIEW_BUILDTYPE) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_BUILDTYPE=\"${GTA5VIEW_BUILDTYPE}\"" - ) -endif() -if(GTA5VIEW_COMMIT) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_COMMIT=\"${GTA5VIEW_COMMIT}\"" - ) -endif() - -if(GTA5VIEW_INLANG) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_INLANG=\"${GTA5VIEW_INLANG}\"" - ) -endif() -if(GTA5VIEW_LANG) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_LANG=\"${GTA5VIEW_LANG}\"" - ) -endif() -if(GTA5VIEW_PLUG) - list(APPEND GTA5VIEW_DEFINES - "-DGTA5SYNC_PLUG=\"${GTA5VIEW_PLUG}\"" - ) -endif() - -add_executable(gta5view - WIN32 MACOSX_BUNDLE - ${GTA5VIEW_HEADERS} - ${GTA5VIEW_SOURCES} - ${GTA5VIEW_FORMS} - ${GTA5VIEW_RESOURCES} -) - -if(LINGUIST_FOUND AND QCONF_BUILD) - add_custom_target(translations DEPENDS ${GTA5VIEW_QMFILES}) - add_dependencies(gta5view translations) -endif() - -if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.16.0") - target_precompile_headers(gta5view PRIVATE config.h) -endif() - -if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.14.0") - qt5_import_plugins(gta5view INCLUDE Qt5::QSvgPlugin) -endif() - -target_compile_definitions(gta5view PRIVATE ${GTA5VIEW_DEFINES}) -target_include_directories(gta5view PRIVATE ${GTA5VIEW_INCLUDEDIR}) -target_link_libraries(gta5view PRIVATE Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::Widgets ${GTA5VIEW_LIBS}) - -install(TARGETS gta5view DESTINATION bin) -install(FILES res/de.syping.gta5view.desktop DESTINATION share/applications) -install(FILES res/de.syping.gta5view.metainfo.xml DESTINATION share/metainfo) -install(FILES res/de.syping.gta5view.xml DESTINATION share/mime/packages) -install(FILES res/gta5view-16.png DESTINATION share/icons/hicolor/16x16/apps RENAME de.syping.gta5view.png) -install(FILES res/gta5view-24.png DESTINATION share/icons/hicolor/24x24/apps RENAME de.syping.gta5view.png) -install(FILES res/gta5view-32.png DESTINATION share/icons/hicolor/32x32/apps RENAME de.syping.gta5view.png) -install(FILES res/gta5view-48.png DESTINATION share/icons/hicolor/48x48/apps RENAME de.syping.gta5view.png) -install(FILES res/gta5view-64.png DESTINATION share/icons/hicolor/64x64/apps RENAME de.syping.gta5view.png) -install(FILES res/gta5view-96.png DESTINATION share/icons/hicolor/96x96/apps RENAME de.syping.gta5view.png) -install(FILES res/gta5view-128.png DESTINATION share/icons/hicolor/128x128/apps RENAME de.syping.gta5view.png) -install(FILES res/gta5view-256.png DESTINATION share/icons/hicolor/256x256/apps RENAME de.syping.gta5view.png) -install(FILES res/gta5view-512.png DESTINATION share/icons/hicolor/512x512/apps RENAME de.syping.gta5view.png) -if(QCONF_BUILD) - include(res/img.cmake) - install(FILES ${GTA5VIEW_IMGFILES} DESTINATION share/gta5view/resources) - install(FILES ${GTA5VIEW_QMFILES} DESTINATION share/gta5view/translations) -endif() diff --git a/CrewDatabase.cpp b/CrewDatabase.cpp old mode 100644 new mode 100755 index 0fa96c6..9a34a50 --- a/CrewDatabase.cpp +++ b/CrewDatabase.cpp @@ -1,176 +1,81 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "StandardPaths.h" -#include "CrewDatabase.h" -#include "config.h" -#include -#include -#include -#include -#include - -CrewDatabase::CrewDatabase(QObject *parent) : QObject(parent) -{ - QDir dir; - dir.mkpath(StandardPaths::dataLocation()); - dir.setPath(StandardPaths::dataLocation()); - QString dirPath = dir.absolutePath(); - QString defaultConfPath = dirPath % "/crews.ini"; - - QSettings confPathSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - confPathSettings.beginGroup("Database"); - QString confPathFile = confPathSettings.value("Crews", defaultConfPath).toString(); - confPathSettings.endGroup(); - - crewDB = new QSettings(confPathFile, QSettings::IniFormat); - crewDB->beginGroup("Crews"); - - addProcess = false; -} - -CrewDatabase::~CrewDatabase() -{ - crewDB->endGroup(); - delete crewDB; -} - -QStringList CrewDatabase::getCrews() -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "getCrews"; -#endif - return getCrews_p(); -} - -QStringList CrewDatabase::getCrews_p() -{ -#ifdef GTA5SYNC_DEBUG - qDebug() << "getCrews_p"; -#endif - QStringList compatibleCrewList = getCompatibleCrews_p(); - crewDB->endGroup(); - crewDB->beginGroup("CrewList"); - QStringList crewIDs = crewDB->value("IDs", QStringList()).toStringList(); - crewIDs += compatibleCrewList; - crewIDs.removeDuplicates(); - crewDB->endGroup(); - crewDB->beginGroup("Crews"); - return crewIDs; -} - -QStringList CrewDatabase::getCompatibleCrews() -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "getCompatibleCrews"; -#endif - return getCompatibleCrews_p(); -} - -QStringList CrewDatabase::getCompatibleCrews_p() -{ -#ifdef GTA5SYNC_DEBUG - qDebug() << "getCompatibleCrews_p"; -#endif - return crewDB->childKeys(); -} - -QString CrewDatabase::getCrewName(QString crewID) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "getCrewName" << crewID; -#endif - QString crewStr = crewDB->value(crewID, crewID).toString(); - if (crewID == "0") crewStr = tr("No Crew", ""); - return crewStr; -} - -QString CrewDatabase::getCrewName(int crewID) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "getCrewName" << crewID; -#endif - QString crewStr = crewDB->value(QString::number(crewID), crewID).toString(); - if (crewID == 0) crewStr = tr("No Crew", ""); - return crewStr; -} - -void CrewDatabase::setCrewName(int crewID, QString crewName) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "setCrewName" << crewID << crewName; -#endif - crewDB->setValue(QString::number(crewID), crewName); -} - -void CrewDatabase::addCrew(int crewID) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "addCrew" << crewID; -#endif - QStringList crews = getCrews_p(); - crews += QString::number(crewID); - crews.removeDuplicates(); - crewDB->endGroup(); - crewDB->beginGroup("CrewList"); - crewDB->setValue("IDs", crews); - crewDB->endGroup(); - crewDB->beginGroup("Crews"); -} - -bool CrewDatabase::isCompatibleCrew(QString crewNID) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "isCompatibleCrew" << crewNID; -#endif - return crewDB->contains(crewNID); -} - -bool CrewDatabase::isCompatibleCrew(int crewID) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "isCompatibleCrew" << crewID; -#endif - return crewDB->contains(QString::number(crewID)); -} - -void CrewDatabase::setAddingCrews(bool addingCrews) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "setAddingCrews" << addingCrews; -#endif - addProcess = addingCrews; -} - -bool CrewDatabase::isAddingCrews() -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "isAddingCrews"; -#endif - return addProcess; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "StandardPaths.h" +#include "CrewDatabase.h" +#include "config.h" +#include +#include + +CrewDatabase::CrewDatabase(QObject *parent) : QObject(parent) +{ + QDir dir; + dir.mkpath(StandardPaths::dataLocation()); + dir.setPath(StandardPaths::dataLocation()); + QString dirPath = dir.absolutePath(); + QString defaultConfPath = dirPath + QDir::separator() + "crews.ini"; + + QSettings confPathSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + confPathSettings.beginGroup("Database"); + QString confPathFile = confPathSettings.value("Crews", defaultConfPath).toString(); + confPathSettings.endGroup(); + + crewDB = new QSettings(confPathFile, QSettings::IniFormat); + crewDB->beginGroup("Crews"); +} + +CrewDatabase::~CrewDatabase() +{ + crewDB->endGroup(); + delete crewDB; +} + +QStringList CrewDatabase::getCrews() +{ + QStringList compatibleCrewList = crewDB->childKeys(); + crewDB->endGroup(); + crewDB->beginGroup("CrewList"); + QStringList crewIDs = crewDB->value("IDs", QStringList()).toStringList(); + crewIDs.append(compatibleCrewList); + crewIDs.removeDuplicates(); + crewDB->endGroup(); + crewDB->beginGroup("Crews"); + return crewIDs; +} + +QString CrewDatabase::getCrewName(int crewID) +{ + return crewDB->value(QString::number(crewID), crewID).toString(); +} + +void CrewDatabase::setCrewName(int crewID, QString crewName) +{ + crewDB->setValue(QString::number(crewID), crewName); +} + +void CrewDatabase::addCrew(int crewID) +{ + QStringList crews = getCrews(); + crews.append(QString::number(crewID)); + crews.removeDuplicates(); + crewDB->endGroup(); + crewDB->beginGroup("CrewList"); + crewDB->setValue("IDs", crews); + crewDB->endGroup(); + crewDB->beginGroup("Crews"); +} diff --git a/CrewDatabase.h b/CrewDatabase.h old mode 100644 new mode 100755 index 692ea79..6204fe9 --- a/CrewDatabase.h +++ b/CrewDatabase.h @@ -1,54 +1,43 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef CREWDATABASE_H -#define CREWDATABASE_H - -#include -#include -#include -#include - -class CrewDatabase : public QObject -{ - Q_OBJECT -public: - explicit CrewDatabase(QObject *parent = 0); - QString getCrewName(QString crewID); - QString getCrewName(int crewID); - QStringList getCompatibleCrews(); - QStringList getCrews(); - void setAddingCrews(bool addingCrews); - bool isCompatibleCrew(QString crewNID); - bool isCompatibleCrew(int crewID); - bool isAddingCrews(); - ~CrewDatabase(); - -private: - mutable QMutex mutex; - bool addProcess; - QSettings *crewDB; - QStringList getCrews_p(); - QStringList getCompatibleCrews_p(); - -public slots: - void setCrewName(int crewID, QString crewName); - void addCrew(int crewID); -}; - -#endif // CREWDATABASE_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef CREWDATABASE_H +#define CREWDATABASE_H + +#include +#include +#include + +class CrewDatabase : public QObject +{ + Q_OBJECT +public: + explicit CrewDatabase(QObject *parent = 0); + void setCrewName(int crewID, QString crewName); + QString getCrewName(int crewID); + QStringList getCrews(); + ~CrewDatabase(); + +private: + QSettings *crewDB; + +public slots: + void addCrew(int crewID); +}; + +#endif // CREWDATABASE_H diff --git a/DatabaseThread.cpp b/DatabaseThread.cpp old mode 100644 new mode 100755 index 9173eac..8ca7ac0 --- a/DatabaseThread.cpp +++ b/DatabaseThread.cpp @@ -1,223 +1,223 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "DatabaseThread.h" -#include "CrewDatabase.h" -#include "AppEnv.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define crewMaxPages 83 -#define maxLoadFails 3 - -DatabaseThread::DatabaseThread(CrewDatabase *crewDB, QObject *parent) : QThread(parent), crewDB(crewDB) -{ - continueLastCrew = true; - threadRunning = true; -} - -void DatabaseThread::run() -{ - QEventLoop threadLoop; - - QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit())); - - while (threadRunning) { - QTimer::singleShot(300000, &threadLoop, SLOT(quit())); - threadLoop.exec(); - } -} - -void DatabaseThread::scanCrewReference(const QStringList &crewList, const int &requestDelay) -{ - for (const QString &crewID : crewList) { - if (threadRunning && crewID != QLatin1String("0")) { - QNetworkAccessManager *netManager = new QNetworkAccessManager(); - QNetworkRequest netRequest(AppEnv::getCrewFetchingUrl(crewID)); -#if QT_VERSION >= 0x050600 -#if QT_VERSION < 0x060000 - netRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); -#endif -#endif - netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent()); - netRequest.setRawHeader("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())); - if (!continueLastCrew) - QObject::connect(this, SIGNAL(threadTerminated()), downloadLoop, SLOT(quit())); - QTimer::singleShot(30000, downloadLoop, SLOT(quit())); - downloadLoop->exec(); - downloadLoop->disconnect(); - delete downloadLoop; - - if (netReply->isFinished()) { - QString crewName; - QByteArray crewHtml = netReply->readAll(); - QStringList crewHtmlSplit1 = QString::fromUtf8(crewHtml).split("Rockstar Games Social Club - Crew : "); - if (crewHtmlSplit1.length() >= 2) { - QStringList crewHtmlSplit2 = QString(crewHtmlSplit1.at(1)).split(""); - if (crewHtmlSplit2.length() >= 1) { - crewName = crewHtmlSplit2.at(0); - } - } - if (!crewName.isEmpty()) { - emit crewNameFound(crewID.toInt(), crewName); - } - } - else { - netReply->abort(); - } - - if (threadRunning) { - QEventLoop *waitingLoop = new QEventLoop(); - QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit())); - if (!continueLastCrew) - QObject::connect(this, SIGNAL(threadTerminated()), waitingLoop, SLOT(quit())); - waitingLoop->exec(); - waitingLoop->disconnect(); - delete waitingLoop; - } - - delete netReply; - delete netManager; - } - } -} - -void DatabaseThread::scanCrewMembersList(const QStringList &crewList, const int &maxPages, const int &requestDelay) -{ - for (const QString &crewID : crewList) { - if (threadRunning && crewID != QLatin1String("0")) { - int currentFail = 0; - int currentPage = 0; - int foundPlayers = 0; - int totalPlayers = 1000; - - while(foundPlayers < totalPlayers && currentPage < maxPages && (continueLastCrew ? true : threadRunning)) { - QNetworkAccessManager *netManager = new QNetworkAccessManager(); - QNetworkRequest netRequest(AppEnv::getPlayerFetchingUrl(crewID, currentPage)); -#if QT_VERSION >= 0x050600 -#if QT_VERSION < 0x060000 - netRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); -#endif -#endif - netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent()); - netRequest.setRawHeader("Accept", "application/json"); - 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())); - if (!continueLastCrew) - QObject::connect(this, SIGNAL(threadTerminated()), downloadLoop, SLOT(quit())); - QTimer::singleShot(30000, downloadLoop, SLOT(quit())); - downloadLoop->exec(); - downloadLoop->disconnect(); - delete downloadLoop; - - if (netReply->isFinished()) { - QByteArray crewJson = netReply->readAll(); - QJsonDocument crewDocument = QJsonDocument::fromJson(crewJson); - QJsonObject crewObject = crewDocument.object(); - QVariantMap crewMap = crewObject.toVariantMap(); - - if (crewMap.contains("Total")) { totalPlayers = crewMap["Total"].toInt(); } - - if (crewMap.contains("Members")) { - const QList memberList = crewMap["Members"].toList(); - for (const QVariant &memberVariant : memberList) { - QMap memberMap = memberVariant.toMap(); - if (memberMap.contains("RockstarId") && memberMap.contains("Name")) { - int RockstarId = memberMap["RockstarId"].toInt(); - QString memberName = memberMap["Name"].toString(); - if (!memberName.isEmpty() && RockstarId != 0) { - foundPlayers++; - emit playerNameFound(RockstarId, memberName); - } - } - } - } - currentPage++; - } - else { - currentFail++; - if (currentFail == maxLoadFails) { - currentFail = 0; - currentPage++; - } - } - - delete netReply; - delete netManager; - - if (foundPlayers < totalPlayers && currentPage < maxPages && (continueLastCrew ? true : threadRunning)) { - QEventLoop *waitingLoop = new QEventLoop(); - QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit())); - if (!continueLastCrew) { QObject::connect(this, SIGNAL(threadTerminated()), waitingLoop, SLOT(quit())); } - waitingLoop->exec(); - waitingLoop->disconnect(); - delete waitingLoop; - } - } - } - } -} - -void DatabaseThread::deleteCompatibleCrews(QStringList *crewList) -{ - for (const QString &crewNID : *crewList) { - if (crewDB->isCompatibleCrew(crewNID)) { - crewList->removeAll(crewNID); - } - } -} - -QStringList DatabaseThread::deleteCompatibleCrews(const QStringList &crewList) -{ - QStringList crewListR = crewList; - for (const QString &crewNID : crewListR) { - if (crewDB->isCompatibleCrew(crewNID)) { - crewListR.removeAll(crewNID); - } - } - return crewListR; -} - -void DatabaseThread::terminateThread() -{ - threadRunning = false; - emit threadTerminated(); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "DatabaseThread.h" +#include "CrewDatabase.h" +#include "AppEnv.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DatabaseThread::DatabaseThread(CrewDatabase *crewDB, QObject *parent) : QThread(parent), crewDB(crewDB) +{ + crewMaxPages = 83; + threadRunning = true; +} + +void DatabaseThread::run() +{ + QEventLoop threadLoop; + QStringList crewList; + + // Quick time scan + if (crewList.length() <= 3) + { + scanCrewReference(crewList, 2500); + scanCrewMembersList(crewList, 3, 2500); + emit playerNameUpdated(); + } + else if (crewList.length() <= 5) + { + scanCrewReference(crewList, 2500); + scanCrewMembersList(crewList, 2, 2500); + emit playerNameUpdated(); + } + + QEventLoop *waitingLoop = new QEventLoop(); + QTimer::singleShot(10000, waitingLoop, SLOT(quit())); + waitingLoop->exec(); + delete waitingLoop; + + while (threadRunning) + { + crewList = crewDB->getCrews(); + + // Long time scan + scanCrewReference(crewList, 10000); + scanCrewMembersList(crewList, crewMaxPages, 10000); + emit playerNameUpdated(); + + QTimer::singleShot(300000, &threadLoop, SLOT(quit())); + threadLoop.exec(); + } +} + +void DatabaseThread::scanCrewReference(QStringList crewList, int requestDelay) +{ + foreach (const QString &crewID, crewList) + { + if (crewID != "0") + { + QNetworkAccessManager *netManager = new QNetworkAccessManager(); + + QNetworkRequest netRequest(AppEnv::getCrewFetchingUrl(crewID)); + 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-Language", "en-US;q=0.5,en;q=0.3"); + 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(); + delete downloadLoop; + + if (netReply->isFinished()) + { + QByteArray crewJson = netReply->readAll(); + QJsonDocument crewDocument = QJsonDocument::fromJson(crewJson); + QJsonObject crewObject = crewDocument.object(); + QVariantMap crewMap = crewObject.toVariantMap(); + QString crewName; + bool isFound = false; + + if (crewMap.contains("activities")) + { + QList activitiesList = crewMap["activities"].toList(); + foreach (const QVariant &activitiesVariant, activitiesList) + { + QMap activityRootMap = activitiesVariant.toMap(); + foreach(const QVariant &activityRootVariant, activityRootMap) + { + QMap activityMap = activityRootVariant.toMap(); + foreach(const QVariant &activityVariant, activityMap) + { + QMap activityFinalMap = activityVariant.toMap(); + if (activityFinalMap.contains("id") && activityFinalMap["id"] == crewID) + { + if (activityFinalMap.contains("name") && isFound == false) + { + isFound = true; + crewName = activityFinalMap["name"].toString(); + } + } + } + } + } + } + if (!crewName.isNull()) + { + crewDB->setCrewName(crewID.toInt(), crewName); + } + } + + QEventLoop *waitingLoop = new QEventLoop(); + QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit())); + waitingLoop->exec(); + delete waitingLoop; + + netReply->deleteLater(); + delete netReply; + netManager->deleteLater(); + delete netManager; + } + } +} + +void DatabaseThread::scanCrewMembersList(QStringList crewList, int maxPages, int requestDelay) +{ + foreach (const QString &crewID, crewList) + { + if (crewID != "0") + { + int currentPage = 0; + int foundPlayers = 0; + int totalPlayers = 1000; + + while(foundPlayers < totalPlayers && currentPage < maxPages) + { + QNetworkAccessManager *netManager = new QNetworkAccessManager(); + + QNetworkRequest netRequest(AppEnv::getPlayerFetchingUrl(crewID, QString::number(currentPage))); + 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-Language", "en-US;q=0.5,en;q=0.3"); + 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(); + delete downloadLoop; + + if (netReply->isFinished()) + { + QByteArray crewJson = netReply->readAll(); + QJsonDocument crewDocument = QJsonDocument::fromJson(crewJson); + QJsonObject crewObject = crewDocument.object(); + QVariantMap crewMap = crewObject.toVariantMap(); + + if (crewMap.contains("Total")) { totalPlayers = crewMap["Total"].toInt(); } + + if (crewMap.contains("Members")) + { + QList memberList = crewMap["Members"].toList(); + foreach (const QVariant &memberVariant, memberList) + { + QMap memberMap = memberVariant.toMap(); + foundPlayers++; + if (memberMap.contains("RockstarId") && memberMap.contains("Name")) + { + int RockstarId = memberMap["RockstarId"].toInt(); + QString memberName = memberMap["Name"].toString(); + if (memberName != "" && RockstarId != 0) + { + emit playerNameFound(RockstarId, memberName); + } + } + } + } + + QEventLoop *waitingLoop = new QEventLoop(); + QTimer::singleShot(requestDelay, waitingLoop, SLOT(quit())); + waitingLoop->exec(); + delete waitingLoop; + + currentPage++; + } + + netReply->deleteLater(); + delete netReply; + netManager->deleteLater(); + delete netManager; + } + } + } +} diff --git a/DatabaseThread.h b/DatabaseThread.h old mode 100644 new mode 100755 index 37c6f76..068b55c --- a/DatabaseThread.h +++ b/DatabaseThread.h @@ -1,56 +1,49 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef DATABASETHREAD_H -#define DATABASETHREAD_H - -#include "CrewDatabase.h" -#include -#include - -class DatabaseThread : public QThread -{ - Q_OBJECT -public: - explicit DatabaseThread(CrewDatabase *crewDB, QObject *parent = 0); - -public slots: - void terminateThread(); - -private: - CrewDatabase *crewDB; - void scanCrewMembersList(const QStringList &crewList, const int &maxPages, const int &requestDelay); - void scanCrewReference(const QStringList &crewList, const int &requestDelay); - void deleteCompatibleCrews(QStringList *crewList); - QStringList deleteCompatibleCrews(const QStringList &crewList); - bool continueLastCrew; - bool threadRunning; - int plyrPerReq; - -protected: - void run(); - -signals: - void crewNameFound(int crewID, QString crewName); - void crewNameUpdated(); - void playerNameFound(int playerID, QString playerName); - void playerNameUpdated(); - void threadTerminated(); -}; - -#endif // DATABASETHREAD_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef DATABASETHREAD_H +#define DATABASETHREAD_H + +#include "CrewDatabase.h" +#include +#include + +class DatabaseThread : public QThread +{ + Q_OBJECT +public: + explicit DatabaseThread(CrewDatabase *crewDB, QObject *parent = 0); + +private: + CrewDatabase *crewDB; + void scanCrewMembersList(QStringList crewList, int maxPages, int requestDelay); + void scanCrewReference(QStringList crewList, int requestDelay); + bool threadRunning; + int crewMaxPages; + int plyrPerReq; + +protected: + void run(); + +signals: + void playerNameFound(int playerID, QString playerName); + void playerNameUpdated(); + +}; + +#endif // DATABASETHREAD_H diff --git a/ExportDialog.cpp b/ExportDialog.cpp old mode 100644 new mode 100755 index 43d8d97..37cb338 --- a/ExportDialog.cpp +++ b/ExportDialog.cpp @@ -1,48 +1,48 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "ExportDialog.h" -#include "ui_ExportDialog.h" - -ExportDialog::ExportDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::ExportDialog) -{ - ui->setupUi(this); - success = false; -} - -ExportDialog::~ExportDialog() -{ - delete ui; -} - -bool ExportDialog::isSucceeded() -{ - return success; -} - -void ExportDialog::on_cmdSnapmaticClose_clicked() -{ - this->close(); -} - -void ExportDialog::setupPictureExport() -{ - ui->swExport->setCurrentWidget(ui->pageSnapmatic); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "ExportDialog.h" +#include "ui_ExportDialog.h" + +ExportDialog::ExportDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ExportDialog) +{ + ui->setupUi(this); + success = false; +} + +ExportDialog::~ExportDialog() +{ + delete ui; +} + +bool ExportDialog::isSucceeded() +{ + return success; +} + +void ExportDialog::on_cmdSnapmaticClose_clicked() +{ + this->close(); +} + +void ExportDialog::setupPictureExport() +{ + ui->swExport->setCurrentWidget(ui->pageSnapmatic); +} diff --git a/ExportDialog.h b/ExportDialog.h old mode 100644 new mode 100755 index 5da4b91..3202812 --- a/ExportDialog.h +++ b/ExportDialog.h @@ -1,46 +1,46 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef EXPORTDIALOG_H -#define EXPORTDIALOG_H - -#include - -namespace Ui { -class ExportDialog; -} - -class ExportDialog : public QDialog -{ - Q_OBJECT - -public: - explicit ExportDialog(QWidget *parent = 0); - void setupPictureExport(); - bool isSucceeded(); - ~ExportDialog(); - -private slots: - void on_cmdSnapmaticClose_clicked(); - -private: - Ui::ExportDialog *ui; - bool success; -}; - -#endif // EXPORTDIALOG_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef EXPORTDIALOG_H +#define EXPORTDIALOG_H + +#include + +namespace Ui { +class ExportDialog; +} + +class ExportDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ExportDialog(QWidget *parent = 0); + void setupPictureExport(); + bool isSucceeded(); + ~ExportDialog(); + +private slots: + void on_cmdSnapmaticClose_clicked(); + +private: + Ui::ExportDialog *ui; + bool success; +}; + +#endif // EXPORTDIALOG_H diff --git a/ExportDialog.ui b/ExportDialog.ui old mode 100644 new mode 100755 index d00b208..5f92f26 --- a/ExportDialog.ui +++ b/ExportDialog.ui @@ -1,226 +1,226 @@ - - - ExportDialog - - - - 0 - 0 - 400 - 300 - - - - Dialog - - - true - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - Export Format - - - - - - &JPEG/PNG format - - - - - - - GTA &Snapmatic format - - - - - - - - - - Export Size - - - - - - Default &Size - - - - - - - &Desktop Size - - - - - - - &Custom Size - - - - - - - - - false - - - Custom Size: - - - - - - - false - - - 1 - - - 3840 - - - 960 - - - - - - - x - - - - - - - false - - - 1 - - - 2160 - - - 536 - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - &Export - - - - - - - - 0 - 0 - - - - &Close - - - - - - - - - - - - - - - + + + ExportDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + Export Format + + + + + + &JPEG/PNG format + + + + + + + GTA &Snapmatic format + + + + + + + + + + Export Size + + + + + + Default &Size + + + + + + + &Desktop Size + + + + + + + &Custom Size + + + + + + + + + false + + + Custom Size: + + + + + + + false + + + 1 + + + 3840 + + + 960 + + + + + + + x + + + + + + + false + + + 1 + + + 2160 + + + 536 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + &Export + + + + + + + + 0 + 0 + + + + &Close + + + + + + + + + + + + + + + + + + diff --git a/ExportThread.cpp b/ExportThread.cpp old mode 100644 new mode 100755 index 63aef4f..1187985 --- a/ExportThread.cpp +++ b/ExportThread.cpp @@ -1,199 +1,181 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2020 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SnapmaticPicture.h" -#include "ProfileInterface.h" -#include "PictureExport.h" -#include "ProfileWidget.h" -#include "ExportThread.h" -#include "SavegameData.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include - -#if QT_VERSION >= 0x050000 -#include -#else -#include -#endif - -ExportThread::ExportThread(QMap profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent) : QThread(parent), - profileMap(profileMap), exportDirectory(exportDirectory), pictureCopyEnabled(pictureCopyEnabled), pictureExportEnabled(pictureExportEnabled), exportCount(exportCount) -{ - -} - -void ExportThread::run() -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - - // Picture Settings - // Quality Settings - settings.beginGroup("Pictures"); - int defaultQuality = 100; - QSize defExportSize = SnapmaticPicture::getSnapmaticResolution(); - int customQuality = settings.value("CustomQuality", defaultQuality).toInt(); - if (customQuality < 1 || customQuality > 100) - { - customQuality = 100; - } - bool useCustomQuality = settings.value("CustomQualityEnabled", false).toBool(); - - // Size Settings - QSize cusExportSize = settings.value("CustomSize", defExportSize).toSize(); - if (cusExportSize.width() > 3840) - { - cusExportSize.setWidth(3840); - } - else if (cusExportSize.height() > 2160) - { - cusExportSize.setHeight(2160); - } - if (cusExportSize.width() < 1) - { - cusExportSize.setWidth(1); - } - else if (cusExportSize.height() < 1) - { - cusExportSize.setHeight(1); - } - QString sizeMode = settings.value("ExportSizeMode", "Default").toString(); - Qt::AspectRatioMode aspectRatio = (Qt::AspectRatioMode)settings.value("AspectRatio", Qt::KeepAspectRatio).toInt(); - settings.endGroup(); - // End Picture Settings - - int intExportProgress = 0; - for (ProfileWidget *widget : profileMap.keys()) - { - if (widget->isSelected()) - { - if (widget->getWidgetType() == "SnapmaticWidget") - { - SnapmaticWidget *picWidget = qobject_cast(widget); - SnapmaticPicture *picture = picWidget->getPicture(); - - if (pictureExportEnabled) - { - QString exportFileName = PictureExport::getPictureFileName(picture); - if (exportFileName.right(4) != ".jpg" && exportFileName.right(4) != ".png") - { - exportFileName += ".jpg"; - } - - intExportProgress++; - emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount))); - emit exportProgressUpdate(intExportProgress); - - // Scale Picture - QImage exportPicture = picture->getImage(); - if (sizeMode == "Desktop") - { -#if QT_VERSION >= 0x050000 - qreal screenRatioPR = AppEnv::screenRatioPR(); - QRect desktopResolution = QApplication::primaryScreen()->geometry(); - int desktopSizeWidth = qRound((double)desktopResolution.width() * screenRatioPR); - int desktopSizeHeight = qRound((double)desktopResolution.height() * screenRatioPR); -#else - QRect desktopResolution = QApplication::desktop()->screenGeometry(); - int desktopSizeWidth = desktopResolution.width(); - int desktopSizeHeight = desktopResolution.height(); -#endif - exportPicture = exportPicture.scaled(desktopSizeWidth, desktopSizeHeight, aspectRatio, Qt::SmoothTransformation); - } - else if (sizeMode == "Custom") - { - exportPicture = exportPicture.scaled(cusExportSize, aspectRatio, Qt::SmoothTransformation); - } - - bool isSaved; - if (useCustomQuality) - { - isSaved = exportPicture.save(exportDirectory % "/" % exportFileName, "JPEG", customQuality); - } - else - { - isSaved = exportPicture.save(exportDirectory % "/" % exportFileName, "JPEG", 100); - } - - if (!isSaved) - { - failedExportPictures += exportFileName; - } - } - if (pictureCopyEnabled) - { - QString exportFileName = PictureExport::getPictureFileName(picture); - if (exportFileName.right(4) != ".g5e") - { - exportFileName += ".g5e"; - } - - intExportProgress++; - emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount))); - emit exportProgressUpdate(intExportProgress); - - QString exportFilePath = exportDirectory % "/" % exportFileName; - if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);} - if (!picture->exportPicture(exportDirectory % "/" % exportFileName, SnapmaticFormat::G5E_Format)) - { - failedCopyPictures += exportFileName; - } - } - } - else if (widget->getWidgetType() == "SavegameWidget") - { - SavegameWidget *sgdWidget = qobject_cast(widget); - SavegameData *savegame = sgdWidget->getSavegame(); - - QString originalFileName = savegame->getSavegameFileName(); - QFileInfo originalFileInfo(originalFileName); - QString exportFileName = originalFileInfo.fileName(); - - intExportProgress++; - emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount))); - emit exportProgressUpdate(intExportProgress); - - QString exportFilePath = exportDirectory % "/" % exportFileName; - if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);} - if (!QFile::copy(originalFileName, exportFilePath)) - { - failedSavegames += exportFileName; - } - } - } - } - emit exportFinished(); -} - -QStringList ExportThread::getFailedCopyPictures() -{ - return failedCopyPictures; -} - -QStringList ExportThread::getFailedExportPictures() -{ - return failedExportPictures; -} - -QStringList ExportThread::getFailedSavegames() -{ - return failedSavegames; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "SnapmaticPicture.h" +#include "PictureExport.h" +#include "ProfileWidget.h" +#include "ExportThread.h" +#include "SavegameData.h" +#include "config.h" +#include +#include +#include +#include + +ExportThread::ExportThread(QMap profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent) : QThread(parent), + profileMap(profileMap), exportDirectory(exportDirectory), pictureCopyEnabled(pictureCopyEnabled), pictureExportEnabled(pictureExportEnabled), exportCount(exportCount) +{ + +} + +void ExportThread::run() +{ + QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + + // Picture Settings + // Quality Settings + settings.beginGroup("Pictures"); + int defaultQuality = 100; + QSize defExportSize = QSize(960, 536); + int customQuality = settings.value("CustomQuality", defaultQuality).toInt(); + if (customQuality < 1 || customQuality > 100) + { + customQuality = 100; + } + bool useCustomQuality = settings.value("CustomQualityEnabled", false).toBool(); + + // Size Settings + QSize cusExportSize = settings.value("CustomSize", defExportSize).toSize(); + if (cusExportSize.width() > 3840) + { + cusExportSize.setWidth(3840); + } + else if (cusExportSize.height() > 2160) + { + cusExportSize.setHeight(2160); + } + if (cusExportSize.width() < 1) + { + cusExportSize.setWidth(1); + } + else if (cusExportSize.height() < 1) + { + cusExportSize.setHeight(1); + } + QString sizeMode = settings.value("ExportSizeMode", "Default").toString(); + Qt::AspectRatioMode aspectRatio = (Qt::AspectRatioMode)settings.value("AspectRatio", Qt::KeepAspectRatio).toInt(); + settings.endGroup(); + // End Picture Settings + + int intExportProgress = 0; + foreach(ProfileWidget *widget, profileMap.keys()) + { + if (widget->isSelected()) + { + if (widget->getWidgetType() == "SnapmaticWidget") + { + SnapmaticWidget *picWidget = (SnapmaticWidget*)widget; + SnapmaticPicture *picture = picWidget->getPicture(); + + if (pictureExportEnabled) + { + QString exportFileName = PictureExport::getPictureFileName(picture); + + intExportProgress++; + emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount))); + emit exportProgressUpdate(intExportProgress); + + // Scale Picture + QImage exportPicture = picture->getPicture(); + if (sizeMode == "Desktop") + { + QRect desktopResolution = QApplication::desktop()->screenGeometry(); + exportPicture = exportPicture.scaled(desktopResolution.width(), desktopResolution.height(), aspectRatio, Qt::SmoothTransformation); + } + else if (sizeMode == "Custom") + { + exportPicture = exportPicture.scaled(cusExportSize, aspectRatio, Qt::SmoothTransformation); + } + + bool isSaved; + if (useCustomQuality) + { + isSaved = exportPicture.save(exportDirectory + "/" + exportFileName, "JPEG", customQuality); + } + else + { + isSaved = exportPicture.save(exportDirectory + "/" + exportFileName, "JPEG", 100); + } + + if (!isSaved) + { + failedExportPictures.append(exportFileName); + } + } + if (pictureCopyEnabled) + { + QString originalFileName = picWidget->getPicturePath(); + QString adjustedFileName = originalFileName; + if (adjustedFileName.right(7) == ".hidden") // for the hidden file system + { + adjustedFileName.remove(adjustedFileName.length() - 7, 7); + } + QFileInfo adjustedFileInfo(adjustedFileName); + QString exportFileName = adjustedFileInfo.fileName(); + + intExportProgress++; + emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount))); + emit exportProgressUpdate(intExportProgress); + + QString exportFilePath = exportDirectory + "/" + exportFileName; + if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);} + if (!QFile::copy(originalFileName, exportFilePath)) + { + failedCopyPictures.append(exportFileName); + } + } + } + else if (widget->getWidgetType() == "SavegameWidget") + { + SavegameWidget *sgdWidget = (SavegameWidget*)widget; + SavegameData *savegame = sgdWidget->getSavegame(); + + QString originalFileName = savegame->getSavegameFileName(); + QFileInfo originalFileInfo(originalFileName); + QString exportFileName = originalFileInfo.fileName(); + + intExportProgress++; + emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount))); + emit exportProgressUpdate(intExportProgress); + + QString exportFilePath = exportDirectory + "/" + exportFileName; + if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);} + if (!QFile::copy(originalFileName, exportFilePath)) + { + failedSavegames.append(exportFileName); + } + } + } + } + emit exportFinished(); +} + +QStringList ExportThread::getFailedCopyPictures() +{ + return failedCopyPictures; +} + +QStringList ExportThread::getFailedExportPictures() +{ + return failedExportPictures; +} + +QStringList ExportThread::getFailedSavegames() +{ + return failedSavegames; +} diff --git a/ExportThread.h b/ExportThread.h old mode 100644 new mode 100755 index 99ad28b..e6d380e --- a/ExportThread.h +++ b/ExportThread.h @@ -1,56 +1,56 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef EXPORTTHREAD_H -#define EXPORTTHREAD_H - -#include "SnapmaticWidget.h" -#include "SavegameWidget.h" -#include "ProfileWidget.h" -#include -#include - -class ExportThread : public QThread -{ - Q_OBJECT -public: - explicit ExportThread(QMap profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent = 0); - QStringList getFailedSavegames(); - QStringList getFailedCopyPictures(); - QStringList getFailedExportPictures(); - -protected: - void run(); - -private: - QMap profileMap; - QString exportDirectory; - bool pictureCopyEnabled; - bool pictureExportEnabled; - int exportCount; - QStringList failedSavegames; - QStringList failedCopyPictures; - QStringList failedExportPictures; - -signals: - void exportStringUpdate(QString currentFileName); - void exportProgressUpdate(int currentProgressValue); - void exportFinished(); -}; - -#endif // EXPORTTHREAD_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef EXPORTTHREAD_H +#define EXPORTTHREAD_H + +#include "SnapmaticWidget.h" +#include "SavegameWidget.h" +#include "ProfileWidget.h" +#include +#include + +class ExportThread : public QThread +{ + Q_OBJECT +public: + explicit ExportThread(QMap profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent = 0); + QStringList getFailedSavegames(); + QStringList getFailedCopyPictures(); + QStringList getFailedExportPictures(); + +protected: + void run(); + +private: + QMap profileMap; + QString exportDirectory; + bool pictureCopyEnabled; + bool pictureExportEnabled; + int exportCount; + QStringList failedSavegames; + QStringList failedCopyPictures; + QStringList failedExportPictures; + +signals: + void exportStringUpdate(QString currentFileName); + void exportProgressUpdate(int currentProgressValue); + void exportFinished(); +}; + +#endif // EXPORTTHREAD_H diff --git a/GlobalString.cpp b/GlobalString.cpp old mode 100644 new mode 100755 index 0a04a59..8fe6eb6 --- a/GlobalString.cpp +++ b/GlobalString.cpp @@ -1,84 +1,89 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "TranslationClass.h" -#include "GlobalString.h" -#include "config.h" -#include -#include -#include -#include -#include -#include - -GlobalString::GlobalString() -{ -} - -QMap GlobalString::getGlobalMap() -{ - QMap globalMap; - QSettings globalFile(getLanguageFile(), QSettings::IniFormat); -#if QT_VERSION < 0x060000 - globalFile.setIniCodec("UTF-8"); -#endif - globalFile.beginGroup("Global"); - for (const QString &globalStr : globalFile.childKeys()) { - globalMap[globalStr] = globalFile.value(globalStr, globalStr).toString(); - } - globalFile.endGroup(); - return globalMap; -} - -QString GlobalString::getString(QString valueStr, bool *ok) -{ - QString globalString = valueStr; - QSettings globalFile(getLanguageFile(), QSettings::IniFormat); -#if QT_VERSION < 0x060000 - globalFile.setIniCodec("UTF-8"); -#endif - globalFile.beginGroup("Global"); - QStringList globalStrList = globalFile.childKeys(); - if (globalStrList.contains(valueStr)) { - if (ok != nullptr) - *ok = true; - globalString = globalFile.value(valueStr, valueStr).toString(); - } - globalFile.endGroup(); - return globalString; -} - -QString GlobalString::getLanguageFile() -{ - QString language = getLanguage(); - QString languageFile = ":/global/global." % language % ".ini"; -#if QT_VERSION >= 0x050200 - if (!QFileInfo::exists(languageFile)) - languageFile = ":/global/global.en.ini"; -#else - if (!QFileInfo(languageFile).exists()) - languageFile = ":/global/global.en.ini"; -#endif - - return languageFile; -} - -QString GlobalString::getLanguage() -{ - return Translator->getCurrentAreaLanguage(); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include +#include +#include +#include +#include "GlobalString.h" +#include "config.h" + +GlobalString::GlobalString() +{ + +} + +QMap GlobalString::getGlobalMap() +{ + QMap globalMap; + QSettings globalFile(getLanguageFile(), QSettings::IniFormat); + globalFile.setIniCodec("UTF-8"); + globalFile.beginGroup("Global"); + QStringList globalStrList = globalFile.childKeys(); + foreach(const QString &globalStr, globalStrList) + { + globalMap[globalStr] = globalFile.value(globalStr, globalStr).toString(); + } + globalFile.endGroup(); + return globalMap; +} + +QString GlobalString::getString(QString valueStr, bool *ok) +{ + QString globalString = valueStr; + QSettings globalFile(getLanguageFile(), QSettings::IniFormat); + globalFile.setIniCodec("UTF-8"); + globalFile.beginGroup("Global"); + QStringList globalStrList = globalFile.childKeys(); + if (globalStrList.contains(valueStr)) + { + if (ok != 0) *ok = true; + globalString = globalFile.value(valueStr, valueStr).toString(); + } + globalFile.endGroup(); + return globalString; +} + +QString GlobalString::getLanguageFile() +{ + QString language = getLanguage(); + QString languageFile = ":/global/global." + language + ".ini"; + if (!QFileInfo(languageFile).exists()) + { + languageFile = ":/global/global.en.ini"; + } + return languageFile; +} + +QString GlobalString::getLanguage() +{ + QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + settings.beginGroup("Interface"); + QString language = settings.value("Language","System").toString(); + settings.endGroup(); + if (language == "System" || language.trimmed() == "") + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + language = langList.at(0); + } + } + return language; +} diff --git a/GlobalString.h b/GlobalString.h old mode 100644 new mode 100755 index 711afa9..65abad2 --- a/GlobalString.h +++ b/GlobalString.h @@ -1,35 +1,35 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef GLOBALSTRING_H -#define GLOBALSTRING_H - -#include -#include - -class GlobalString -{ -public: - GlobalString(); - static QString getString(QString valueStr, bool *ok = nullptr); - static QString getLanguageFile(); - static QString getLanguage(); - static QMap getGlobalMap(); -}; - -#endif // GLOBALSTRING_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef GLOBALSTRING_H +#define GLOBALSTRING_H + +#include +#include + +class GlobalString +{ +public: + GlobalString(); + static QString getString(QString valueStr, bool *ok = 0); + static QString getLanguageFile(); + static QString getLanguage(); + static QMap getGlobalMap(); +}; + +#endif // GLOBALSTRING_H diff --git a/IconLoader.cpp b/IconLoader.cpp old mode 100644 new mode 100755 index 71ccee1..f093fb7 --- a/IconLoader.cpp +++ b/IconLoader.cpp @@ -1,61 +1,40 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "IconLoader.h" -#include "AppEnv.h" -#include -#include - -IconLoader::IconLoader() -{ -} - -QIcon IconLoader::loadingAppIcon() -{ - QIcon appIcon; -#if defined(GTA5SYNC_QCONF) && defined(GTA5SYNC_CMAKE) -#ifdef Q_OS_WIN - const QString pattern = AppEnv::getImagesFolder() % QLatin1String("/gta5view-%1.png"); -#else - const QString pattern = AppEnv::getShareFolder() % QLatin1String("/icons/hicolor/%1x%1/apps/de.syping.gta5view.png"); -#endif -#else - const QString pattern = AppEnv::getImagesFolder() % QLatin1String("/gta5view-%1.png"); -#endif - appIcon.addFile(pattern.arg("16"), QSize(16, 16)); - appIcon.addFile(pattern.arg("24"), QSize(24, 24)); - appIcon.addFile(pattern.arg("32"), QSize(32, 32)); - appIcon.addFile(pattern.arg("40"), QSize(40, 40)); - appIcon.addFile(pattern.arg("48"), QSize(48, 48)); - appIcon.addFile(pattern.arg("64"), QSize(64, 64)); - appIcon.addFile(pattern.arg("96"), QSize(96, 96)); - appIcon.addFile(pattern.arg("128"), QSize(128, 128)); - appIcon.addFile(pattern.arg("256"), QSize(256, 256)); - return appIcon; -} - -QIcon IconLoader::loadingPointmakerIcon() -{ - QIcon pointmakerIcon; - const QString pattern = AppEnv::getImagesFolder() % QLatin1String("/pointmaker-%1.png"); - pointmakerIcon.addFile(pattern.arg("8"), QSize(8, 8)); - pointmakerIcon.addFile(pattern.arg("16"), QSize(16, 16)); - pointmakerIcon.addFile(pattern.arg("24"), QSize(24, 24)); - pointmakerIcon.addFile(pattern.arg("32"), QSize(32, 32)); - return pointmakerIcon; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "IconLoader.h" +#include + +IconLoader::IconLoader() +{ + +} + +QIcon IconLoader::loadingAppIcon() +{ + QIcon appIcon; + appIcon.addFile(":/img/5sync-16.png", QSize(16, 16)); + appIcon.addFile(":/img/5sync-24.png", QSize(24, 24)); + appIcon.addFile(":/img/5sync-32.png", QSize(32, 32)); + appIcon.addFile(":/img/5sync-40.png", QSize(40, 40)); + appIcon.addFile(":/img/5sync-48.png", QSize(48, 48)); + appIcon.addFile(":/img/5sync-64.png", QSize(64, 64)); + appIcon.addFile(":/img/5sync-96.png", QSize(96, 96)); + appIcon.addFile(":/img/5sync-128.png", QSize(128, 128)); + appIcon.addFile(":/img/5sync-256.png", QSize(256, 256)); + return appIcon; +} diff --git a/IconLoader.h b/IconLoader.h old mode 100644 new mode 100755 index 8456688..3fd8f07 --- a/IconLoader.h +++ b/IconLoader.h @@ -1,32 +1,31 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef ICONLOADER_H -#define ICONLOADER_H - -#include - -class IconLoader -{ -public: - IconLoader(); - static QIcon loadingAppIcon(); - static QIcon loadingPointmakerIcon(); -}; - -#endif // ICONLOADER_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef ICONLOADER_H +#define ICONLOADER_H + +#include + +class IconLoader +{ +public: + IconLoader(); + static QIcon loadingAppIcon(); +}; + +#endif // ICONLOADER_H diff --git a/ImportDialog.cpp b/ImportDialog.cpp deleted file mode 100644 index 594cbf8..0000000 --- a/ImportDialog.cpp +++ /dev/null @@ -1,974 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017-2022 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "ui_ImportDialog.h" -#include "SnapmaticPicture.h" -#include "SidebarGenerator.h" -#include "StandardPaths.h" -#include "ImportDialog.h" -#include "imagecropper.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// IMAGES VALUES -#define snapmaticAvatarResolution 470 -#define snapmaticAvatarPlacementW 145 -#define snapmaticAvatarPlacementH 66 - -ImportDialog::ImportDialog(QString profileName, QWidget *parent) : - QDialog(parent), profileName(profileName), - ui(new Ui::ImportDialog) -{ - // Set Window Flags -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - - ui->setupUi(this); - ui->cmdOK->setDefault(true); - ui->cmdOK->setFocus(); - importAgreed = false; - settingsLocked = false; - watermarkAvatar = true; - watermarkPicture = false; - insideAvatarZone = false; - avatarAreaImage = QImage(AppEnv::getImagesFolder() % "/avatarareaimport.png"); - selectedColour = QColor::fromRgb(0, 0, 0, 255); - - // Set Icon for OK Button - if (QIcon::hasThemeIcon("dialog-ok")) { - ui->cmdOK->setIcon(QIcon::fromTheme("dialog-ok")); - } - else if (QIcon::hasThemeIcon("gtk-ok")) { - ui->cmdOK->setIcon(QIcon::fromTheme("gtk-ok")); - } - - // Set Icon for Cancel Button - if (QIcon::hasThemeIcon("dialog-cancel")) { - ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel")); - } - else if (QIcon::hasThemeIcon("gtk-cancel")) { - ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel")); - } - - ui->cbIgnore->setChecked(false); - ui->labColour->setText(tr("Background Colour: %1").arg(selectedColour.name())); - ui->labBackgroundImage->setText(tr("Background Image:")); - ui->cmdBackgroundWipe->setVisible(false); - - // Snapmatic Resolution - snapmaticResolution = SnapmaticPicture::getSnapmaticResolution(); - ui->cbResolution->addItem("GTA V", snapmaticResolution); - ui->cbResolution->addItem("FiveM", QSize(1920, 1072)); - ui->cbResolution->addItem("1280x720", QSize(1280, 720)); - ui->cbResolution->addItem("1920x1080", QSize(1920, 1080)); - ui->cbResolution->addItem("2560x1440", QSize(2560, 1440)); - - // Set Import Settings - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Import"); - QString currentProfile = settings.value("Profile", "Default").toString(); - settings.endGroup(); - processSettings(currentProfile); - - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); - snapmaticResolutionLW = 516 * screenRatio; // 430 - snapmaticResolutionLH = 288 * screenRatio; // 240 - ui->labPicture->setMinimumSize(snapmaticResolutionLW, snapmaticResolutionLH); - - ui->vlButtom->setSpacing(6 * screenRatio); -#ifndef Q_OS_MAC - ui->vlButtom->setContentsMargins(9 * screenRatio, 6 * screenRatio, 9 * screenRatio, 9 * screenRatio); -#else -#if QT_VERSION >= 0x060000 - if (QApplication::style()->objectName() == "macos") { -#else - if (QApplication::style()->objectName() == "macintosh") { -#endif - ui->vlButtom->setContentsMargins(9 * screenRatio, 9 * screenRatio, 9 * screenRatio, 9 * screenRatio); - } - else { - ui->vlButtom->setContentsMargins(9 * screenRatio, 6 * screenRatio, 9 * screenRatio, 9 * screenRatio); - } -#endif - - // Options menu - optionsMenu.addAction(tr("&Import new Picture..."), this, SLOT(importNewPicture())); - optionsMenu.addAction(tr("&Crop Picture..."), this, SLOT(cropPicture())); - optionsMenu.addSeparator(); - optionsMenu.addAction(tr("&Load Settings..."), this, SLOT(loadImportSettings())); - optionsMenu.addAction(tr("&Save Settings..."), this, SLOT(saveImportSettings())); - ui->cmdOptions->setMenu(&optionsMenu); - - const QSize windowSize = sizeHint(); - setMinimumSize(windowSize); - setMaximumSize(windowSize); -} - -ImportDialog::~ImportDialog() -{ - delete ui; -} - -void ImportDialog::processImage() -{ - if (workImage.isNull()) - return; - - QImage snapmaticImage = workImage; - QPixmap snapmaticPixmap(snapmaticResolution); - snapmaticPixmap.fill(selectedColour); - QPainter snapmaticPainter(&snapmaticPixmap); - qreal screenRatioPR = AppEnv::screenRatioPR(); - if (!backImage.isNull()) { - if (!ui->cbStretch->isChecked()) { - int diffWidth = 0; - int diffHeight = 0; - if (backImage.width() != snapmaticResolution.width()) { - diffWidth = snapmaticResolution.width() - backImage.width(); - diffWidth = diffWidth / 2; - } - else if (backImage.height() != snapmaticResolution.height()) { - diffHeight = snapmaticResolution.height() - backImage.height(); - diffHeight = diffHeight / 2; - } - snapmaticPainter.drawImage(0 + diffWidth, 0 + diffHeight, backImage); - } - else { - snapmaticPainter.drawImage(0, 0, QImage(backImage).scaled(snapmaticResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); - } - if (ui->cbAvatar->isChecked() && ui->cbForceAvatarColour->isChecked()) { - snapmaticPainter.fillRect(snapmaticAvatarPlacementW, snapmaticAvatarPlacementH, snapmaticAvatarResolution, snapmaticAvatarResolution, selectedColour); - } - } - if (insideAvatarZone) { - // Avatar mode - int diffWidth = 0; - int diffHeight = 0; - if (ui->cbIgnore->isChecked()) { - snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - } - else if (ui->cbBorderless->isChecked()) { - snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); - if (snapmaticImage.width() > snapmaticAvatarResolution) { - int diffWidth = snapmaticImage.width() - snapmaticAvatarResolution; - diffWidth = diffWidth / 2; - QImage croppedImage(snapmaticAvatarResolution, snapmaticAvatarResolution, QImage::Format_ARGB32); - croppedImage.fill(Qt::transparent); - QPainter croppedPainter(&croppedImage); - croppedPainter.drawImage(0 - diffWidth, 0, snapmaticImage); - croppedPainter.end(); - snapmaticImage = croppedImage; - } - else if (snapmaticImage.height() > snapmaticAvatarResolution) { - int diffHeight = snapmaticImage.height() - snapmaticAvatarResolution; - diffHeight = diffHeight / 2; - QImage croppedImage(snapmaticAvatarResolution, snapmaticAvatarResolution, QImage::Format_ARGB32); - croppedImage.fill(Qt::transparent); - QPainter croppedPainter(&croppedImage); - croppedPainter.drawImage(0, 0 - diffHeight, snapmaticImage); - croppedPainter.end(); - snapmaticImage = croppedImage; - } - } - else { - snapmaticImage = snapmaticImage.scaled(snapmaticAvatarResolution, snapmaticAvatarResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation); - if (snapmaticImage.width() > snapmaticImage.height()) { - diffHeight = snapmaticAvatarResolution - snapmaticImage.height(); - diffHeight = diffHeight / 2; - } - else if (snapmaticImage.width() < snapmaticImage.height()) { - diffWidth = snapmaticAvatarResolution - snapmaticImage.width(); - diffWidth = diffWidth / 2; - } - } - snapmaticPainter.drawImage(snapmaticAvatarPlacementW + diffWidth, snapmaticAvatarPlacementH + diffHeight, snapmaticImage); - if (ui->cbWatermark->isChecked()) - processWatermark(&snapmaticPainter); - imageTitle = tr("Custom Avatar", "Custom Avatar Description in SC, don't use Special Character!"); - } - else { - // Picture mode - int diffWidth = 0; - int diffHeight = 0; - if (ui->cbIgnore->isChecked()) { - snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - } - else if (ui->cbBorderless->isChecked()) { - snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); - if (snapmaticImage.width() > snapmaticResolution.width()) { - int diffWidth = snapmaticImage.width() - snapmaticResolution.width(); - diffWidth = diffWidth / 2; - QImage croppedImage(snapmaticResolution, QImage::Format_ARGB32); - croppedImage.fill(Qt::transparent); - QPainter croppedPainter(&croppedImage); - croppedPainter.drawImage(0 - diffWidth, 0, snapmaticImage); - croppedPainter.end(); - snapmaticImage = croppedImage; - } - else if (snapmaticImage.height() > snapmaticResolution.height()) { - int diffHeight = snapmaticImage.height() - snapmaticResolution.height(); - diffHeight = diffHeight / 2; - QImage croppedImage(snapmaticResolution, QImage::Format_ARGB32); - croppedImage.fill(Qt::transparent); - QPainter croppedPainter(&croppedImage); - croppedPainter.drawImage(0, 0 - diffHeight, snapmaticImage); - croppedPainter.end(); - snapmaticImage = croppedImage; - } - } - else { - snapmaticImage = snapmaticImage.scaled(snapmaticResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation); - if (snapmaticImage.width() != snapmaticResolution.width()) { - diffWidth = snapmaticResolution.width() - snapmaticImage.width(); - diffWidth = diffWidth / 2; - } - else if (snapmaticImage.height() != snapmaticResolution.height()) { - diffHeight = snapmaticResolution.height() - snapmaticImage.height(); - diffHeight = diffHeight / 2; - } - } - snapmaticPainter.drawImage(0 + diffWidth, 0 + diffHeight, snapmaticImage); - if (ui->cbWatermark->isChecked()) - processWatermark(&snapmaticPainter); - imageTitle = tr("Custom Picture", "Custom Picture Description in SC, don't use Special Character!"); - } - snapmaticPainter.end(); - newImage = snapmaticPixmap.toImage(); -#if QT_VERSION >= 0x050600 - snapmaticPixmap.setDevicePixelRatio(screenRatioPR); -#endif - ui->labPicture->setPixmap(snapmaticPixmap.scaled(snapmaticResolutionLW * screenRatioPR, snapmaticResolutionLH * screenRatioPR, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); -} - -void ImportDialog::reworkImage() -{ - workImage = QImage(); - if (origImage.width() == origImage.height()) { - if (ui->cbResolution->currentIndex() == 0) { - insideAvatarZone = true; - ui->cbAvatar->setChecked(true); - } - else { - insideAvatarZone = false; - ui->cbAvatar->setChecked(false); - } - if (origImage.height() > snapmaticResolution.height()) { - workImage = origImage.scaled(snapmaticResolution.height(), snapmaticResolution.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - } - else { - workImage = origImage; - } - } - else if (origImage.width() > snapmaticResolution.width() && origImage.width() > origImage.height()) { - insideAvatarZone = false; - ui->cbAvatar->setChecked(false); - workImage = origImage.scaledToWidth(snapmaticResolution.width(), Qt::SmoothTransformation); - } - else if (origImage.height() > snapmaticResolution.height() && origImage.height() > origImage.width()) { - insideAvatarZone = false; - ui->cbAvatar->setChecked(false); - workImage = origImage.scaledToHeight(snapmaticResolution.height(), Qt::SmoothTransformation); - } - else { - insideAvatarZone = false; - ui->cbAvatar->setChecked(false); - workImage = origImage; - } - processImage(); -} - -void ImportDialog::processWatermark(QPainter *snapmaticPainter) -{ - bool blackWatermark = false; - bool redWatermark = false; - if (selectedColour.red() > 127) { - if (selectedColour.green() > 127 || selectedColour.blue() > 127) { - redWatermark = true; - } - } - else { - redWatermark = true; - } - if (selectedColour.lightness() > 127) { - blackWatermark = true; - } - // draw watermark - if (redWatermark) { - const QImage viewWatermark = QImage(AppEnv::getImagesFolder() % "/watermark_2r.png"); - snapmaticPainter->drawImage(snapmaticResolution.width() - viewWatermark.width(), 0, viewWatermark); - } - else - { - QImage viewWatermark = QImage(AppEnv::getImagesFolder() % "/watermark_2b.png"); - if (!blackWatermark) { - viewWatermark.invertPixels(QImage::InvertRgb); - } - snapmaticPainter->drawImage(snapmaticResolution.width() - viewWatermark.width(), 0, viewWatermark); - } - QImage textWatermark = QImage(AppEnv::getImagesFolder() % "/watermark_1b.png"); - if (!blackWatermark) { - textWatermark.invertPixels(QImage::InvertRgb); - } - snapmaticPainter->drawImage(snapmaticResolution.width() - textWatermark.width(), 0, textWatermark); -} - -void ImportDialog::processSettings(QString settingsProfile, bool setDefault) -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Import"); - if (setDefault) { - settings.setValue("Profile", settingsProfile); - } - if (settingsProfile == "Default") { - watermarkAvatar = true; - watermarkPicture = false; - selectedColour = QColor::fromRgb(0, 0, 0, 255); - backImage = QImage(); - ui->cbBorderless->setChecked(false); - ui->cbStretch->setChecked(false); - ui->cbForceAvatarColour->setChecked(false); - ui->cbUnlimited->setChecked(false); - ui->cbImportAsIs->setChecked(false); - ui->cbResolution->setCurrentIndex(0); - } - else { - settings.beginGroup(settingsProfile); - watermarkAvatar = settings.value("WatermarkAvatar", true).toBool(); - watermarkPicture = settings.value("WatermarkPicture", false).toBool(); - backImage = qvariant_cast(settings.value("BackgroundImage", QImage())); - selectedColour = qvariant_cast(settings.value("SelectedColour", QColor::fromRgb(0, 0, 0, 255))); - ui->cbBorderless->setChecked(settings.value("BorderlessImage", false).toBool()); - ui->cbStretch->setChecked(settings.value("BackgroundStretch", false).toBool()); - ui->cbForceAvatarColour->setChecked(settings.value("ForceAvatarColour", false).toBool()); - ui->cbUnlimited->setChecked(settings.value("UnlimitedBuffer", false).toBool()); - ui->cbImportAsIs->setChecked(settings.value("ImportAsIs", false).toBool()); - const QVariant data = settings.value("Resolution", SnapmaticPicture::getSnapmaticResolution()); -#if QT_VERSION >= 0x060000 - if (data.typeId() == QMetaType::QSize) -#else - if (data.type() == QVariant::Size) -#endif - { - int index = ui->cbResolution->findData(data); - if (index != -1) { - ui->cbResolution->setCurrentIndex(index); - } - } - settings.endGroup(); - } - if (!workImage.isNull()) { - if (ui->cbAvatar->isChecked()) { - ui->cbWatermark->setChecked(watermarkAvatar); - } - else { - ui->cbWatermark->setChecked(watermarkPicture); - } - } - ui->labColour->setText(tr("Background Colour: %1").arg(selectedColour.name())); - if (!backImage.isNull()) { - ui->labBackgroundImage->setText(tr("Background Image: %1").arg(tr("Storage", "Background Image: Storage"))); - ui->cmdBackgroundWipe->setVisible(true); - } - else { - ui->labBackgroundImage->setText(tr("Background Image:")); - ui->cmdBackgroundWipe->setVisible(false); - } - settings.endGroup(); -} - -void ImportDialog::saveSettings(QString settingsProfile) -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Import"); - settings.beginGroup(settingsProfile); - settings.setValue("WatermarkAvatar", watermarkAvatar); - settings.setValue("WatermarkPicture", watermarkPicture); - settings.setValue("BackgroundImage", backImage); - settings.setValue("SelectedColour", selectedColour); - settings.setValue("BorderlessImage", ui->cbBorderless->isChecked()); - settings.setValue("BackgroundStretch", ui->cbStretch->isChecked()); - settings.setValue("ForceAvatarColour", ui->cbForceAvatarColour->isChecked()); -#if QT_VERSION >= 0x050000 - const QVariant data = ui->cbResolution->currentData(); -#else - const QVariant data = ui->cbResolution->itemData(ui->cbResolution->currentIndex()); -#endif -#if QT_VERSION >= 0x060000 - if (data.typeId() == QMetaType::QSize) -#else - if (data.type() == QVariant::Size) -#endif - { - settings.setValue("Resolution", data); - } - else { - settings.setValue("Resolution", SnapmaticPicture::getSnapmaticResolution()); - } - settings.setValue("UnlimitedBuffer", ui->cbUnlimited->isChecked()); - settings.setValue("ImportAsIs", ui->cbImportAsIs->isChecked()); - settings.endGroup(); - settings.setValue("Profile", settingsProfile); - settings.endGroup(); -} - -void ImportDialog::cropPicture() -{ - qreal screenRatio = AppEnv::screenRatio(); - - QDialog cropDialog(this); -#if QT_VERSION >= 0x050000 - cropDialog.setObjectName(QStringLiteral("CropDialog")); -#else - cropDialog.setObjectName(QString::fromUtf8("CropDialog")); -#endif - cropDialog.setWindowTitle(tr("Crop Picture...")); - cropDialog.setWindowFlags(cropDialog.windowFlags()^Qt::WindowContextHelpButtonHint); - cropDialog.setModal(true); - - QVBoxLayout cropLayout; -#if QT_VERSION >= 0x050000 - cropLayout.setObjectName(QStringLiteral("CropLayout")); -#else - cropLayout.setObjectName(QString::fromUtf8("CropLayout")); -#endif - cropLayout.setContentsMargins(0, 0, 0, 0); - cropLayout.setSpacing(0); - cropDialog.setLayout(&cropLayout); - - ImageCropper imageCropper(&cropDialog); -#if QT_VERSION >= 0x050000 - imageCropper.setObjectName(QStringLiteral("ImageCropper")); -#else - imageCropper.setObjectName(QString::fromUtf8("ImageCropper")); -#endif - imageCropper.setBackgroundColor(Qt::black); - imageCropper.setCroppingRectBorderColor(QColor(255, 255, 255, 127)); - imageCropper.setImage(QPixmap::fromImage(origImage, Qt::AutoColor)); - imageCropper.setProportion(QSize(1, 1)); - imageCropper.setFixedSize(workImage.size()); - cropLayout.addWidget(&imageCropper); - - QHBoxLayout buttonLayout; -#if QT_VERSION >= 0x050000 - cropLayout.setObjectName(QStringLiteral("ButtonLayout")); -#else - cropLayout.setObjectName(QString::fromUtf8("ButtonLayout")); -#endif - cropLayout.addLayout(&buttonLayout); - - QPushButton cropButton(&cropDialog); -#if QT_VERSION >= 0x050000 - cropButton.setObjectName(QStringLiteral("CropButton")); -#else - cropButton.setObjectName(QString::fromUtf8("CropButton")); -#endif - cropButton.setMinimumSize(0, 40 * screenRatio); - cropButton.setText(tr("&Crop")); - cropButton.setToolTip(tr("Crop Picture")); - QObject::connect(&cropButton, SIGNAL(clicked(bool)), &cropDialog, SLOT(accept())); - - buttonLayout.addWidget(&cropButton); - - cropDialog.show(); - cropDialog.setFixedSize(cropDialog.sizeHint()); - if (cropDialog.exec() == QDialog::Accepted) { - QImage *croppedImage = new QImage(imageCropper.cropImage().toImage()); - setImage(croppedImage); - } -} - -void ImportDialog::importNewPicture() -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("FileDialogs"); - bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool(); - settings.beginGroup("ImportCopy"); - -fileDialogPreOpen: //Work? - QFileDialog fileDialog(this); - fileDialog.setFileMode(QFileDialog::ExistingFile); - fileDialog.setViewMode(QFileDialog::Detail); - fileDialog.setAcceptMode(QFileDialog::AcceptOpen); - fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog); - fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); - fileDialog.setWindowTitle(QApplication::translate("ProfileInterface", "Import...")); - fileDialog.setLabelText(QFileDialog::Accept, QApplication::translate("ProfileInterface", "Import")); - - // Getting readable Image formats - QString imageFormatsStr = " "; - for (const QByteArray &imageFormat : QImageReader::supportedImageFormats()) { - imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " "; - } - - QStringList filters; - filters << QApplication::translate("ProfileInterface", "All image files (%1)").arg(imageFormatsStr.trimmed()); - filters << QApplication::translate("ProfileInterface", "All files (**)"); - fileDialog.setNameFilters(filters); - - QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); - - fileDialog.setSidebarUrls(sidebarUrls); - fileDialog.setDirectory(settings.value(profileName % "+Directory", StandardPaths::documentsLocation()).toString()); - fileDialog.restoreGeometry(settings.value(profileName % "+Geometry", "").toByteArray()); - - if (fileDialog.exec()) { - QStringList selectedFiles = fileDialog.selectedFiles(); - if (selectedFiles.length() == 1) { - QString selectedFile = selectedFiles.at(0); - QString selectedFileName = QFileInfo(selectedFile).fileName(); - - QFile snapmaticFile(selectedFile); - if (!snapmaticFile.open(QFile::ReadOnly)) { - QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be open").arg("\""+selectedFileName+"\"")); - goto fileDialogPreOpen; - } - QImage *importImage = new QImage(); - QImageReader snapmaticImageReader; - snapmaticImageReader.setDecideFormatFromContent(true); - snapmaticImageReader.setDevice(&snapmaticFile); - if (!snapmaticImageReader.read(importImage)) { - QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\"")); - delete importImage; - goto fileDialogPreOpen; - } - setImage(importImage); - } - } - - settings.setValue(profileName % "+Geometry", fileDialog.saveGeometry()); - settings.setValue(profileName % "+Directory", fileDialog.directory().absolutePath()); - settings.endGroup(); - settings.endGroup(); -} - -void ImportDialog::loadImportSettings() -{ - if (settingsLocked) { - QMessageBox::information(this, tr("Load Settings..."), tr("Please import a new picture first")); - return; - } - bool ok; - QStringList profileList; - profileList << tr("Default", "Default as Default Profile") - << tr("Profile %1", "Profile %1 as Profile 1").arg("1") - << tr("Profile %1", "Profile %1 as Profile 1").arg("2") - << tr("Profile %1", "Profile %1 as Profile 1").arg("3") - << tr("Profile %1", "Profile %1 as Profile 1").arg("4") - << tr("Profile %1", "Profile %1 as Profile 1").arg("5"); - QString sProfile = QInputDialog::getItem(this, tr("Load Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags()); - if (ok) { - QString pProfile; - if (sProfile == tr("Default", "Default as Default Profile")) { - pProfile = "Default"; - } - else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1")) { - pProfile = "Profile 1"; - } - else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2")) { - pProfile = "Profile 2"; - } - else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3")) { - pProfile = "Profile 3"; - } - else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4")) - { - pProfile = "Profile 4"; - } - else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5")) { - pProfile = "Profile 5"; - } - processSettings(pProfile, true); - processImage(); - } -} - -void ImportDialog::saveImportSettings() -{ - if (settingsLocked) { - QMessageBox::information(this, tr("Save Settings..."), tr("Please import a new picture first")); - return; - } - bool ok; - QStringList profileList; - profileList << tr("Profile %1", "Profile %1 as Profile 1").arg("1") - << tr("Profile %1", "Profile %1 as Profile 1").arg("2") - << tr("Profile %1", "Profile %1 as Profile 1").arg("3") - << tr("Profile %1", "Profile %1 as Profile 1").arg("4") - << tr("Profile %1", "Profile %1 as Profile 1").arg("5"); - QString sProfile = QInputDialog::getItem(this, tr("Save Settings..."), tr("Please select your settings profile"), profileList, 0, false, &ok, windowFlags()); - if (ok) { - QString pProfile; - if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("1")) { - pProfile = "Profile 1"; - } - else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("2")) { - pProfile = "Profile 2"; - } - else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("3")) { - pProfile = "Profile 3"; - } - else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("4")) { - pProfile = "Profile 4"; - } - else if (sProfile == tr("Profile %1", "Profile %1 as Profile 1").arg("5")) { - pProfile = "Profile 5"; - } - saveSettings(pProfile); - } -} - -QImage ImportDialog::image() -{ - if (ui->cbImportAsIs->isChecked()) { - return origImage; - } - else { - return newImage; - } -} - -void ImportDialog::setImage(QImage *image_) -{ - origImage = *image_; - workImage = QImage(); - if (image_->width() == image_->height()) { - if (ui->cbResolution->currentIndex() == 0) { - insideAvatarZone = true; - ui->cbAvatar->setChecked(true); - } - else { - insideAvatarZone = false; - ui->cbAvatar->setChecked(false); - } - if (image_->height() > snapmaticResolution.height()) { - workImage = image_->scaled(snapmaticResolution.height(), snapmaticResolution.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - delete image_; - } - else { - workImage = *image_; - delete image_; - } - } - else if (image_->width() > snapmaticResolution.width() && image_->width() > image_->height()) { - insideAvatarZone = false; - ui->cbAvatar->setChecked(false); - workImage = image_->scaledToWidth(snapmaticResolution.width(), Qt::SmoothTransformation); - delete image_; - } - else if (image_->height() > snapmaticResolution.height() && image_->height() > image_->width()) { - insideAvatarZone = false; - ui->cbAvatar->setChecked(false); - workImage = image_->scaledToHeight(snapmaticResolution.height(), Qt::SmoothTransformation); - delete image_; - } - else { - insideAvatarZone = false; - ui->cbAvatar->setChecked(false); - workImage = *image_; - delete image_; - } - processImage(); - lockSettings(false); -} - -void ImportDialog::lockSettings(bool lock) -{ - ui->gbAdvanced->setDisabled(lock); - if (ui->cbImportAsIs->isChecked()) { - ui->gbBackground->setDisabled(true); - ui->gbSettings->setDisabled(true); - } - else { - ui->gbBackground->setDisabled(lock); - ui->gbSettings->setDisabled(lock); - } - ui->cmdOK->setDisabled(lock); - settingsLocked = lock; -} - -void ImportDialog::enableOverwriteMode() -{ - setWindowTitle(QApplication::translate("ImageEditorDialog", "Overwrite Image...")); - ui->cmdOK->setText(QApplication::translate("ImageEditorDialog", "&Overwrite")); - ui->cmdOK->setToolTip(QApplication::translate("ImageEditorDialog", "Apply changes")); - ui->cmdCancel->setText(QApplication::translate("ImageEditorDialog", "&Close")); - ui->cmdCancel->setToolTip(QApplication::translate("ImageEditorDialog", "Discard changes")); - ui->cmdCancel->setDefault(true); - ui->cmdCancel->setFocus(); - lockSettings(true); -} - -bool ImportDialog::isImportAgreed() -{ - return importAgreed; -} - -bool ImportDialog::isUnlimitedBuffer() -{ - return ui->cbUnlimited->isChecked(); -} - -bool ImportDialog::areSettingsLocked() -{ - return settingsLocked; -} - -QString ImportDialog::getImageTitle() -{ - if (ui->cbImportAsIs->isChecked()) { - return tr("Custom Picture", "Custom Picture Description in SC, don't use Special Character!"); - } - else { - return imageTitle; - } -} - -void ImportDialog::on_cbIgnore_toggled(bool checked) -{ - ui->cbBorderless->setDisabled(checked); - processImage(); -} - -void ImportDialog::on_cbAvatar_toggled(bool checked) -{ - if (ui->cbResolution->currentIndex() != 0) - return; - - if (!workImage.isNull() && workImage.width() == workImage.height() && !checked) { - if (QMessageBox::No == QMessageBox::warning(this, tr("Snapmatic Avatar Zone"), tr("Are you sure to use a square image outside of the Avatar Zone?\nWhen you want to use it as Avatar the image will be detached!"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) { - ui->cbAvatar->setChecked(true); - insideAvatarZone = true; - return; - } - } - insideAvatarZone = ui->cbAvatar->isChecked(); - watermarkBlock = true; - if (insideAvatarZone) { - ui->cbWatermark->setChecked(watermarkAvatar); - } - else { - ui->cbWatermark->setChecked(watermarkPicture); - } - watermarkBlock = false; - processImage(); -} - -void ImportDialog::on_cmdCancel_clicked() -{ - close(); -} - -void ImportDialog::on_cmdOK_clicked() -{ - importAgreed = true; - close(); -} - -void ImportDialog::on_labPicture_labelPainted() -{ - if (insideAvatarZone) { - QImage avatarAreaFinalImage(avatarAreaImage); - if (selectedColour.lightness() > 127) { - avatarAreaFinalImage.setColor(1, qRgb(0, 0, 0)); - } - QPainter labelPainter(ui->labPicture); - labelPainter.drawImage(0, 0, avatarAreaFinalImage.scaled(snapmaticResolutionLW, snapmaticResolutionLH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); - labelPainter.end(); - } -} - -void ImportDialog::on_cmdColourChange_clicked() -{ - QColor newSelectedColour = QColorDialog::getColor(selectedColour, this, tr("Select Colour...")); - if (newSelectedColour.isValid()) { - selectedColour = newSelectedColour; - ui->labColour->setText(tr("Background Colour: %1").arg(selectedColour.name())); - processImage(); - } -} - -void ImportDialog::on_cmdBackgroundChange_clicked() -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("FileDialogs"); - bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool(); - settings.beginGroup("ImportBackground"); - -fileDialogPreOpen: - QFileDialog fileDialog(this); - fileDialog.setFileMode(QFileDialog::ExistingFiles); - fileDialog.setViewMode(QFileDialog::Detail); - fileDialog.setAcceptMode(QFileDialog::AcceptOpen); - fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog); - fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); - fileDialog.setWindowTitle(QApplication::translate("ProfileInterface", "Import...")); - fileDialog.setLabelText(QFileDialog::Accept, QApplication::translate("ProfileInterface", "Import")); - - // Getting readable Image formats - QString imageFormatsStr = " "; - for (const QByteArray &imageFormat : QImageReader::supportedImageFormats()) { - imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " "; - } - - QStringList filters; - filters << QApplication::translate("ProfileInterface", "All image files (%1)").arg(imageFormatsStr.trimmed()); - filters << QApplication::translate("ProfileInterface", "All files (**)"); - fileDialog.setNameFilters(filters); - - QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); - - fileDialog.setSidebarUrls(sidebarUrls); - fileDialog.setDirectory(settings.value("Directory", StandardPaths::documentsLocation()).toString()); - fileDialog.restoreGeometry(settings.value("Geometry", "").toByteArray()); - - if (fileDialog.exec()) { - QStringList selectedFiles = fileDialog.selectedFiles(); - if (selectedFiles.length() == 1) { - QString selectedFile = selectedFiles.at(0); - QString selectedFileName = QFileInfo(selectedFile).fileName(); - - QFile snapmaticFile(selectedFile); - if (!snapmaticFile.open(QFile::ReadOnly)) { - QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be open").arg("\""+selectedFileName+"\"")); - goto fileDialogPreOpen; - } - QImage importImage; - QImageReader snapmaticImageReader; - snapmaticImageReader.setDecideFormatFromContent(true); - snapmaticImageReader.setDevice(&snapmaticFile); - if (!snapmaticImageReader.read(&importImage)) { - QMessageBox::warning(this, QApplication::translate("ProfileInterface", "Import"), QApplication::translate("ProfileInterface", "Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\"")); - goto fileDialogPreOpen; - } - backImage = importImage.scaled(snapmaticResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation); - backgroundPath = selectedFile; - ui->labBackgroundImage->setText(tr("Background Image: %1").arg(tr("File", "Background Image: File"))); - ui->cmdBackgroundWipe->setVisible(true); - processImage(); - } - } - - settings.setValue("Geometry", fileDialog.saveGeometry()); - settings.setValue("Directory", fileDialog.directory().absolutePath()); - settings.endGroup(); - settings.endGroup(); -} - -void ImportDialog::on_cmdBackgroundWipe_clicked() -{ - backImage = QImage(); - ui->labBackgroundImage->setText(tr("Background Image:")); - ui->cmdBackgroundWipe->setVisible(false); - processImage(); -} - -void ImportDialog::on_cbStretch_toggled(bool checked) -{ - Q_UNUSED(checked) - processImage(); -} - -void ImportDialog::on_cbForceAvatarColour_toggled(bool checked) -{ - Q_UNUSED(checked) - processImage(); -} - -void ImportDialog::on_cbWatermark_toggled(bool checked) -{ - if (!watermarkBlock) { - if (insideAvatarZone) { - watermarkAvatar = checked; - } - else { - watermarkPicture = checked; - } - processImage(); - } -} - -void ImportDialog::on_cbBorderless_toggled(bool checked) -{ - ui->cbIgnore->setDisabled(checked); - processImage(); -} - -void ImportDialog::on_cbImportAsIs_toggled(bool checked) -{ - ui->cbResolution->setDisabled(checked); - ui->labResolution->setDisabled(checked); - ui->gbBackground->setDisabled(checked); - ui->gbSettings->setDisabled(checked); -} - -void ImportDialog::on_cbResolution_currentIndexChanged(int index) -{ - Q_UNUSED(index) -#if QT_VERSION >= 0x050000 - const QVariant data = ui->cbResolution->currentData(); -#else - const QVariant data = ui->cbResolution->itemData(ui->cbResolution->currentIndex()); -#endif -#if QT_VERSION >= 0x060000 - if (data.typeId() == QMetaType::QSize) -#else - if (data.type() == QVariant::Size) -#endif - { - const QSize dataSize = data.toSize(); - if (dataSize == SnapmaticPicture::getSnapmaticResolution()) { - ui->cbAvatar->setEnabled(true); - snapmaticResolution = dataSize; - reworkImage(); - } - else { - if (!workImage.isNull() && workImage.width() == workImage.height() && ui->cbAvatar->isChecked()) { - if (QMessageBox::No == QMessageBox::warning(this, tr("Snapmatic Avatar Zone"), tr("Are you sure to use a square image outside of the Avatar Zone?\nWhen you want to use it as Avatar the image will be detached!"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) { - ui->cbResolution->setCurrentIndex(0); - ui->cbAvatar->setChecked(true); - insideAvatarZone = true; - return; - } - } - ui->cbAvatar->setChecked(false); - ui->cbAvatar->setDisabled(true); - insideAvatarZone = false; - ui->cbWatermark->setChecked(watermarkPicture); - snapmaticResolution = dataSize; - reworkImage(); - } - } -} diff --git a/ImportDialog.h b/ImportDialog.h deleted file mode 100644 index 1cd93ac..0000000 --- a/ImportDialog.h +++ /dev/null @@ -1,93 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef IMPORTDIALOG_H -#define IMPORTDIALOG_H - -#include -#include - -namespace Ui { -class ImportDialog; -} - -class ImportDialog : public QDialog -{ - Q_OBJECT - -public: - explicit ImportDialog(QString profileName, QWidget *parent = 0); - ~ImportDialog(); - QImage image(); - QString getImageTitle(); - void setImage(QImage *image); - void lockSettings(bool lock); - void enableOverwriteMode(); - bool isImportAgreed(); - bool isUnlimitedBuffer(); - bool areSettingsLocked(); - -private slots: - void processImage(); - void reworkImage(); - void cropPicture(); - void importNewPicture(); - void loadImportSettings(); - void saveImportSettings(); - void on_cbIgnore_toggled(bool checked); - void on_cbAvatar_toggled(bool checked); - void on_cmdCancel_clicked(); - void on_cmdOK_clicked(); - void on_labPicture_labelPainted(); - void on_cmdColourChange_clicked(); - void on_cmdBackgroundChange_clicked(); - void on_cmdBackgroundWipe_clicked(); - void on_cbStretch_toggled(bool checked); - void on_cbForceAvatarColour_toggled(bool checked); - void on_cbWatermark_toggled(bool checked); - void on_cbBorderless_toggled(bool checked); - void on_cbImportAsIs_toggled(bool checked); - void on_cbResolution_currentIndexChanged(int index); - -private: - QString profileName; - Ui::ImportDialog *ui; - QImage avatarAreaImage; - QString backgroundPath; - QString imageTitle; - QImage backImage; - QImage workImage; - QImage origImage; - QImage newImage; - QColor selectedColour; - QMenu optionsMenu; - QSize snapmaticResolution; - bool insideAvatarZone; - bool watermarkPicture; - bool watermarkAvatar; - bool watermarkBlock; - bool settingsLocked; - bool importAgreed; - int snapmaticResolutionLW; - int snapmaticResolutionLH; - void processWatermark(QPainter *snapmaticPainter); - void processSettings(QString settingsProfile, bool setDefault = false); - void saveSettings(QString settingsProfile); -}; - -#endif // IMPORTDIALOG_H diff --git a/ImportDialog.ui b/ImportDialog.ui deleted file mode 100644 index 5780456..0000000 --- a/ImportDialog.ui +++ /dev/null @@ -1,420 +0,0 @@ - - - ImportDialog - - - - 0 - 0 - 516 - 673 - - - - - 516 - 512 - - - - Import... - - - true - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 516 - 288 - - - - - - - - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - - 9 - - - 6 - - - 9 - - - 9 - - - - - Picture - - - - - - - - Ignore Aspect Ratio - - - - - - - Avatar - - - - - - - Watermark - - - - - - - Crop to Aspect Ratio - - - - - - - - - - - - Background - - - - - - - - - - Background Colour: <span style="color: %1">%1</span> - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Select background colour - - - ... - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - true - - - Ignore Aspect Ratio - - - - - - - Force Colour in Avatar Zone - - - - - - - - - Background Image: - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Select background image - - - ... - - - - - - - Remove background image - - - X - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - Advanced - - - - - - - - Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic - - - Unlimited Buffer - - - - - - - Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing - - - Import as-is - - - - - - - - - Resolution: - - - - - - - - 0 - 0 - - - - Snapmatic resolution - - - - - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - Import options - - - &Options - - - false - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Import picture - - - &OK - - - - - - - - 0 - 0 - - - - Discard picture - - - &Cancel - - - - - - - - - - - - - UiModLabel - QLabel -
uimod/UiModLabel.h
- - mouseMoved() - mouseReleased() - mousePressed() - mouseDoubleClicked() - -
-
- - -
diff --git a/JsonEditorDialog.cpp b/JsonEditorDialog.cpp deleted file mode 100644 index ae13966..0000000 --- a/JsonEditorDialog.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "JsonEditorDialog.h" -#include "ui_JsonEditorDialog.h" -#include "SnapmaticEditor.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include - -#if QT_VERSION >= 0x050200 -#include -#endif - -#ifdef GTA5SYNC_TELEMETRY -#include "TelemetryClass.h" -#endif - -JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) : - QDialog(parent), smpic(picture), - ui(new Ui::JsonEditorDialog) -{ - // Set Window Flags -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::WindowContextHelpButtonHint, false); - setWindowFlag(Qt::WindowMinMaxButtonsHint, true); -#else - setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowMinMaxButtonsHint); -#endif - - ui->setupUi(this); - ui->cmdClose->setDefault(true); - ui->cmdClose->setFocus(); - - // Set Icon for Close Button - if (QIcon::hasThemeIcon("dialog-close")) { - ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) { - ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close")); - } - - // Set Icon for Save Button - if (QIcon::hasThemeIcon("document-save")) { - ui->cmdSave->setIcon(QIcon::fromTheme("document-save")); - } - else if (QIcon::hasThemeIcon("gtk-save")) { - ui->cmdSave->setIcon(QIcon::fromTheme("gtk-save")); - } - - jsonCode = picture->getJsonStr(); - -#if QT_VERSION >= 0x050200 - ui->txtJSON->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); -#else - QFont jsonFont = ui->txtJSON->font(); - jsonFont.setStyleHint(QFont::Monospace); - jsonFont.setFixedPitch(true); - ui->txtJSON->setFont(jsonFont); -#endif - QFontMetrics fontMetrics(ui->txtJSON->font()); -#if QT_VERSION >= 0x050B00 - ui->txtJSON->setTabStopDistance(fontMetrics.horizontalAdvance(" ")); -#else - ui->txtJSON->setTabStopWidth(fontMetrics.width(" ")); -#endif - - QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonCode.toUtf8()); - ui->txtJSON->setStyleSheet("QPlainTextEdit{background-color: rgb(46, 47, 48); color: rgb(238, 231, 172);}"); - ui->txtJSON->setPlainText(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Indented)).trimmed()); - jsonHl = new JSHighlighter(ui->txtJSON->document()); - - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); -#ifndef Q_OS_MAC - ui->hlButtons->setSpacing(6 * screenRatio); - ui->hlButtons->setContentsMargins(9 * screenRatio, 0, 9 * screenRatio, 0); - ui->vlInterface->setContentsMargins(0, 0, 0, 9 * screenRatio); -#else - ui->hlButtons->setSpacing(6 * screenRatio); - ui->hlButtons->setContentsMargins(9 * screenRatio, 0, 9 * screenRatio, 0); - ui->vlInterface->setContentsMargins(0, 0, 0, 9 * screenRatio); -#endif - if (screenRatio > 1) { - ui->lineJSON->setMinimumHeight(qRound(1 * screenRatio)); - ui->lineJSON->setMaximumHeight(qRound(1 * screenRatio)); - ui->lineJSON->setLineWidth(qRound(1 * screenRatio)); - } - resize(450 * screenRatio, 550 * screenRatio); -} - -JsonEditorDialog::~JsonEditorDialog() -{ - delete jsonHl; - delete ui; -} - -void JsonEditorDialog::closeEvent(QCloseEvent *ev) -{ - QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " "); - QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8()); - QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8()); - QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact)); - QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact)); - if (newCode != originalCode) { - QMessageBox::StandardButton button = QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("

Unsaved changes detected

You want to save the JSON content before you quit?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel); - if (button == QMessageBox::Yes) { - if (saveJsonContent()) { - ev->accept(); - } - else { - ev->ignore(); - } - return; - } - else if (button == QMessageBox::No) { - ev->accept(); - return; - } - else { - ev->ignore(); - return; - } - } -} - -bool JsonEditorDialog::saveJsonContent() -{ - QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " "); - QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8()); - if (!jsonNew.isEmpty()) { - QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8()); - QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact)); - QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact)); - if (newCode != originalCode) { - QString currentFilePath = smpic->getPictureFilePath(); - QString originalFilePath = smpic->getOriginalPictureFilePath(); - QString backupFileName = originalFilePath % ".bak"; - if (!QFile::exists(backupFileName)) { - QFile::copy(currentFilePath, backupFileName); - } - smpic->setJsonStr(newCode, true); - if (!smpic->isJsonOk()) { - QString lastStep = smpic->getLastStep(false); - QString readableError; - if (lastStep.contains("JSONINCOMPLETE") && lastStep.contains("JSONERROR")) { - readableError = SnapmaticPicture::tr("JSON is incomplete and malformed"); - } - else if (lastStep.contains("JSONINCOMPLETE")) { - readableError = SnapmaticPicture::tr("JSON is incomplete"); - } - else if (lastStep.contains("JSONERROR")) { - readableError = SnapmaticPicture::tr("JSON is malformed"); - } - else { - readableError = tr("JSON Error"); - } - QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of %1").arg(readableError)); - smpic->setJsonStr(originalCode, true); - return false; - } - if (!smpic->exportPicture(currentFilePath)) { - QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error")); - smpic->setJsonStr(originalCode, true); - return false; - } - jsonCode = newCode; - smpic->updateStrings(); - smpic->emitUpdate(); -#ifdef GTA5SYNC_TELEMETRY - QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - telemetrySettings.beginGroup("Telemetry"); - bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool(); - telemetrySettings.endGroup(); - if (pushUsageData && Telemetry->canPush()) { - QJsonDocument jsonDocument; - QJsonObject jsonObject; - jsonObject["Type"] = "JSONEdited"; - jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength()); -#if QT_VERSION >= 0x060000 - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } -#endif - return true; - } - return true; - } - else { - QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of JSON Error")); - return false; - } -} - -void JsonEditorDialog::on_cmdClose_clicked() -{ - close(); -} - -void JsonEditorDialog::on_cmdSave_clicked() -{ - if (saveJsonContent()) - close(); -} diff --git a/JsonEditorDialog.h b/JsonEditorDialog.h deleted file mode 100644 index 4e618bb..0000000 --- a/JsonEditorDialog.h +++ /dev/null @@ -1,56 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef JSONEDITORDIALOG_H -#define JSONEDITORDIALOG_H - -#include "SnapmaticPicture.h" -#include "JSHighlighter.h" -#include - -namespace Ui { -class JsonEditorDialog; -} - -class JsonEditorDialog : public QDialog -{ - Q_OBJECT - -public: - explicit JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent = 0); - bool saveJsonContent(); - ~JsonEditorDialog(); - -protected: - void closeEvent(QCloseEvent *ev); - -private slots: - void on_cmdClose_clicked(); - void on_cmdSave_clicked(); - -signals: - void codeUpdated(QString jsonCode); - -private: - QString jsonCode; - JSHighlighter *jsonHl; - SnapmaticPicture *smpic; - Ui::JsonEditorDialog *ui; -}; - -#endif // JSONEDITORDIALOG_H diff --git a/JsonEditorDialog.ui b/JsonEditorDialog.ui deleted file mode 100644 index a52f087..0000000 --- a/JsonEditorDialog.ui +++ /dev/null @@ -1,145 +0,0 @@ - - - JsonEditorDialog - - - - 0 - 0 - 550 - 450 - - - - Snapmatic JSON Editor - - - - 0 - - - 0 - - - 0 - - - 9 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - - - - - - 0 - 1 - - - - - 16777215 - 1 - - - - QFrame[frameShape="4"] -{ - color: black; -} - - - QFrame::Plain - - - 1 - - - Qt::Horizontal - - - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Apply changes - - - &Save - - - - - - - - 0 - 0 - - - - Discard changes - - - &Close - - - - - - - - - - diff --git a/LICENSE b/LICENSE index f288702..3ebc8c9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. +The license for GRAND THEFT AUTO V SYNC is GNU GPLv3 diff --git a/LICENSE.GPL b/LICENSE.GPL old mode 100644 new mode 100755 index f288702..e963df8 --- a/LICENSE.GPL +++ b/LICENSE.GPL @@ -1,7 +1,7 @@ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -620,55 +620,3 @@ copy of the Program in return for a fee. END OF TERMS AND CONDITIONS - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/LICENSE.LGPL b/LICENSE.LGPL old mode 100644 new mode 100755 index 0a04128..add53b4 --- a/LICENSE.LGPL +++ b/LICENSE.LGPL @@ -1,165 +1,459 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/MapLocationDialog.cpp b/MapLocationDialog.cpp deleted file mode 100644 index b233a28..0000000 --- a/MapLocationDialog.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "MapLocationDialog.h" -#include "ui_MapLocationDialog.h" -#include "IconLoader.h" -#include "AppEnv.h" -#include -#include -#include - -MapLocationDialog::MapLocationDialog(double x, double y, QWidget *parent) : - QDialog(parent), xpos_old(x), ypos_old(y), - ui(new Ui::MapLocationDialog) -{ - // Set Window Flags -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - - ui->setupUi(this); - ui->cmdDone->setVisible(false); - ui->cmdApply->setVisible(false); - ui->cmdRevert->setVisible(false); - ui->cmdDone->setCursor(Qt::ArrowCursor); - ui->cmdClose->setCursor(Qt::ArrowCursor); - - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); - int widgetMargin = qRound(3 * screenRatio); - ui->hlMapDialog->setContentsMargins(widgetMargin, widgetMargin, widgetMargin, widgetMargin); - ui->vlMapDialog->setSpacing(widgetMargin); - setMinimumSize(500 * screenRatio, 600 * screenRatio); - setMaximumSize(500 * screenRatio, 600 * screenRatio); - - zoomPercent = 100; - changeMode = false; - propUpdate = false; -} - -MapLocationDialog::~MapLocationDialog() -{ - delete ui; -} - -void MapLocationDialog::drawPointOnMap(double xpos_d, double ypos_d) -{ - ui->labPos->setText(tr("X: %1\nY: %2", "X and Y position").arg(QString::number(xpos_d), QString::number(ypos_d))); - xpos_new = xpos_d; - ypos_new = ypos_d; - repaint(); -} - -void MapLocationDialog::setCayoPerico(bool isCayoPerico) -{ - qreal screenRatio = AppEnv::screenRatio(); - p_isCayoPerico = isCayoPerico; - if (isCayoPerico) { - setMinimumSize(500 * screenRatio, 500 * screenRatio); - setMaximumSize(500 * screenRatio, 500 * screenRatio); - ui->hlMapDialog->removeItem(ui->vlMapDialog); - ui->hlMapDialog->insertLayout(0, ui->vlMapDialog); - ui->hlMapDialog->removeItem(ui->vlPosLayout); - ui->hlMapDialog->addLayout(ui->vlPosLayout); - ui->labPos->setAlignment(Qt::AlignRight); - mapImage = QImage(AppEnv::getImagesFolder() % "/mapcayoperico.jpg"); - } - else { - mapImage = QImage(AppEnv::getImagesFolder() % "/mappreview.jpg"); - } - drawPointOnMap(xpos_old, ypos_old); -} - -void MapLocationDialog::updatePosFromEvent(double x, double y) -{ - QSize mapPixelSize = size(); - double x_per = x / mapPixelSize.width(); // get X % - double y_per = y / mapPixelSize.height(); // get Y % - double x_pos, y_pos; - if (p_isCayoPerico) { - x_pos = x_per * 2340; // 2340 is 100% for X (Cayo Perico) - y_pos = y_per * -2340; // -2340 is 100% for Y (Cayo Perico) - x_pos = x_pos + 3560; // +3560 gets corrected for X (Cayo Perico) - y_pos = y_pos - 3980; // -3980 gets corrected for Y (Cayo Perico) - } - else { - x_pos = x_per * 10000; // 10000 is 100% for X (Los Santos) - y_pos = y_per * -12000; // -12000 is 100% for Y (Los Santos) - x_pos = x_pos - 4000; // -4000 gets corrected for X (Los Santos) - y_pos = y_pos + 8000; // +8000 gets corrected for Y (Los Santos) - } - drawPointOnMap(x_pos, y_pos); -} - -void MapLocationDialog::paintEvent(QPaintEvent *ev) -{ - QPainter painter(this); - painter.setRenderHint(QPainter::SmoothPixmapTransform, true); - - // Screen Ratio - qreal screenRatio = AppEnv::screenRatio(); - qreal screenRatioPR = AppEnv::screenRatioPR(); - - // Paint Map - const double zoomLevel = static_cast(zoomPercent) / 100; - const QSize mapImageSize = mapImage.size(); - const QPointF mapImageMid(static_cast(mapImageSize.width()) / 2, static_cast(mapImageSize.height()) / 2); - const QSizeF srcImageSize(static_cast(mapImageSize.width()) / zoomLevel , static_cast(mapImageSize.height()) / zoomLevel); - const QPointF mapImageTopLeft(mapImageMid.x() - (srcImageSize.width() / 2), mapImageMid.y() - (srcImageSize.height() / 2)); - const QPointF mapImageBottomRight(mapImageMid.x() + (srcImageSize.width() / 2), mapImageMid.y() + (srcImageSize.height() / 2)); - painter.drawImage(QRect(QPoint(0, 0), size()), mapImage, QRectF(mapImageTopLeft, mapImageBottomRight)); - - // Paint Marker - QSize mapPixelSize = size(); - int pointMarkerSize = 8 * screenRatio; - int pointMarkerHalfSize = pointMarkerSize / 2; - double xpos_mp, ypos_mp; - if (p_isCayoPerico) { - double xpos_per = xpos_new - 3560; // correct X in reserve - double ypos_per = ypos_new + 3980; // correct y in reserve - xpos_per = xpos_per / 2340; // divide 100% for X - ypos_per = ypos_per / -2340; // divide 100% for Y - xpos_mp = xpos_per * mapPixelSize.width(); // locate window width pos - ypos_mp = ypos_per * mapPixelSize.height(); // locate window height pos - } - else { - double xpos_per = xpos_new + 4000; // correct X in reserve - double ypos_per = ypos_new - 8000; // correct y in reserve - xpos_per = xpos_per / 10000; // divide 100% for X - ypos_per = ypos_per / -12000; // divide 100% for Y - xpos_mp = xpos_per * mapPixelSize.width(); // locate window width pos - ypos_mp = ypos_per * mapPixelSize.height(); // locate window height pos - } - QPointF pointMarkerPos(xpos_mp, ypos_mp); - if (screenRatioPR != 1) { - pointMarkerPos.setX(pointMarkerPos.x() - pointMarkerHalfSize + screenRatioPR); - pointMarkerPos.setY(pointMarkerPos.y() - pointMarkerHalfSize + screenRatioPR); - } - else { - pointMarkerPos.setX(pointMarkerPos.x() - pointMarkerHalfSize); - pointMarkerPos.setY(pointMarkerPos.y() - pointMarkerHalfSize); - } - QPixmap mapMarkerPixmap = IconLoader::loadingPointmakerIcon().pixmap(QSize(pointMarkerSize, pointMarkerSize)); - painter.drawPixmap(pointMarkerPos, mapMarkerPixmap); - - QDialog::paintEvent(ev); -} - -void MapLocationDialog::mouseMoveEvent(QMouseEvent *ev) -{ - if (changeMode && ev->buttons() & Qt::LeftButton) { -#if QT_VERSION >= 0x060000 - const QPointF localPos = ev->position(); -#elif QT_VERSION >= 0x050000 - const QPointF localPos = ev->localPos(); -#else - const QPointF localPos = ev->posF(); -#endif -#ifdef Q_OS_WIN - qreal screenRatioPR = AppEnv::screenRatioPR(); - if (screenRatioPR != 1) { - updatePosFromEvent(localPos.x() - screenRatioPR, localPos.y() - screenRatioPR); - } - else { - updatePosFromEvent(localPos.x(), localPos.y()); - } -#else - updatePosFromEvent(localPos.x(), localPos.y()); -#endif - } - else if (dragStart && ev->buttons() & Qt::LeftButton) { -#if QT_VERSION >= 0x060000 - const QPointF dragNewPosition = ev->position(); -#elif QT_VERSION >= 0x050000 - const QPointF dragNewPosition = ev->localPos(); -#else - const QPointF dragNewPosition = ev->posF(); -#endif - mapDiffPosition = dragNewPosition - dragPosition + mapDiffPosition; - dragPosition = dragNewPosition; - } -} - -void MapLocationDialog::mousePressEvent(QMouseEvent *ev) -{ - if (!changeMode && ev->button() == Qt::LeftButton) { -#if QT_VERSION >= 0x060000 - dragPosition = ev->position(); -#elif QT_VERSION >= 0x050000 - dragPosition = ev->localPos(); -#else - dragPosition = ev->posF(); -#endif - dragStart = true; - } -} - -void MapLocationDialog::mouseReleaseEvent(QMouseEvent *ev) -{ - if (changeMode && ev->button() == Qt::LeftButton) { -#if QT_VERSION >= 0x060000 - const QPointF localPos = ev->position(); -#elif QT_VERSION >= 0x050000 - const QPointF localPos = ev->localPos(); -#else - const QPointF localPos = ev->posF(); -#endif -#ifdef Q_OS_WIN - qreal screenRatioPR = AppEnv::screenRatioPR(); - if (screenRatioPR != 1) { - updatePosFromEvent(localPos.x() - screenRatioPR, localPos.y() - screenRatioPR); - } - else { - updatePosFromEvent(localPos.x(), localPos.y()); - } -#else - updatePosFromEvent(localPos.x(), localPos.y()); -#endif - } - else if (dragStart && ev->button() == Qt::LeftButton) { - dragStart = false; - } -} - -void MapLocationDialog::wheelEvent(QWheelEvent *ev) -{ -#ifdef GTA5SYNC_EXPERIMENTAL -#if QT_VERSION >= 0x050000 - const QPoint numPixels = ev->pixelDelta(); - const QPoint numDegrees = ev->angleDelta(); -#else - QPoint numDegrees; - if (ev->orientation() == Qt::Horizontal) { - numDegrees.setX(ev->delta()); - } - else { - numDegrees.setY(ev->delta()); - } -#endif -#if QT_VERSION >= 0x050000 - if (!numPixels.isNull()) { - if (numPixels.y() < 0 && zoomPercent != 100) { - zoomPercent = zoomPercent - 10; - repaint(); - } - else if (numPixels.y() > 0 && zoomPercent != 400) { - zoomPercent = zoomPercent + 10; - repaint(); - } - return; - } -#endif - if (!numDegrees.isNull()) { - if (numDegrees.y() < 0 && zoomPercent != 100) { - zoomPercent = zoomPercent - 10; - repaint(); - } - else if (numDegrees.y() > 0 && zoomPercent != 400) { - zoomPercent = zoomPercent + 10; - repaint(); - } - } -#else - Q_UNUSED(ev) -#endif -} - -void MapLocationDialog::on_cmdChange_clicked() -{ - qreal screenRatio = AppEnv::screenRatio(); - int pointMakerSize = 8 * screenRatio; - QPixmap pointMakerPixmap = IconLoader::loadingPointmakerIcon().pixmap(QSize(pointMakerSize, pointMakerSize)); - QCursor pointMakerCursor(pointMakerPixmap); - ui->cmdDone->setVisible(true); - ui->cmdApply->setVisible(false); - ui->cmdChange->setVisible(false); - ui->cmdRevert->setVisible(false); - - setCursor(pointMakerCursor); - changeMode = true; -} - -void MapLocationDialog::on_cmdDone_clicked() -{ - ui->cmdDone->setVisible(false); - ui->cmdChange->setVisible(true); - if (xpos_new != xpos_old || ypos_new != ypos_old) { - ui->cmdApply->setVisible(true); - ui->cmdRevert->setVisible(true); - } - setCursor(Qt::ArrowCursor); - changeMode = false; -} - -void MapLocationDialog::on_cmdApply_clicked() -{ - propUpdate = true; - xpos_old = xpos_new; - ypos_old = ypos_new; - ui->cmdApply->setVisible(false); - ui->cmdRevert->setVisible(false); -} - -void MapLocationDialog::on_cmdRevert_clicked() -{ - drawPointOnMap(xpos_old, ypos_old); - ui->cmdApply->setVisible(false); - ui->cmdRevert->setVisible(false); -} - -bool MapLocationDialog::propUpdated() -{ - return propUpdate; -} - -double MapLocationDialog::getXpos() -{ - return xpos_old; -} - -double MapLocationDialog::getYpos() -{ - return ypos_old; -} - -void MapLocationDialog::on_cmdClose_clicked() -{ - close(); -} diff --git a/MapLocationDialog.h b/MapLocationDialog.h deleted file mode 100644 index c67e02f..0000000 --- a/MapLocationDialog.h +++ /dev/null @@ -1,73 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef MAPLOCATIONDIALOG_H -#define MAPLOCATIONDIALOG_H - -#include -#include - -namespace Ui { -class MapLocationDialog; -} - -class MapLocationDialog : public QDialog -{ - Q_OBJECT - -public: - explicit MapLocationDialog(double x, double y, QWidget *parent = 0); - void drawPointOnMap(double x, double y); - void setCayoPerico(bool isCayoPerico); - bool propUpdated(); - double getXpos(); - double getYpos(); - ~MapLocationDialog(); - -protected: - void paintEvent(QPaintEvent *ev); - void mouseMoveEvent(QMouseEvent *ev); - void mousePressEvent(QMouseEvent *ev); - void mouseReleaseEvent(QMouseEvent *ev); - void wheelEvent(QWheelEvent *ev); - -private slots: - void on_cmdApply_clicked(); - void on_cmdDone_clicked(); - void on_cmdClose_clicked(); - void on_cmdChange_clicked(); - void on_cmdRevert_clicked(); - void updatePosFromEvent(double x, double y); - -private: - int zoomPercent; - double xpos_old; - double ypos_old; - double xpos_new; - double ypos_new; - bool dragStart; - bool propUpdate; - bool changeMode; - bool p_isCayoPerico; - QImage mapImage; - QPointF dragPosition; - QPointF mapDiffPosition; - Ui::MapLocationDialog *ui; -}; - -#endif // MAPLOCATIONDIALOG_H diff --git a/MapLocationDialog.ui b/MapLocationDialog.ui deleted file mode 100644 index 06da9ed..0000000 --- a/MapLocationDialog.ui +++ /dev/null @@ -1,238 +0,0 @@ - - - MapLocationDialog - - - - 0 - 0 - 500 - 600 - - - - - 500 - 600 - - - - - 500 - 600 - - - - Snapmatic Map Viewer - - - QDialog#MapLocationDialog { - background-color: transparent; -} - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QLabel{ -color: rgb(255, 255, 255); -} - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - 3 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::NoFocus - - - Close viewer - - - &Close - - - false - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - Qt::NoFocus - - - Apply new position - - - &Apply - - - false - - - - - - - Qt::NoFocus - - - Revert old position - - - &Revert - - - false - - - - - - - Qt::NoFocus - - - Select new position - - - &Select - - - false - - - - - - - Qt::NoFocus - - - Quit select position - - - &Done - - - false - - - - - - - - - - - - diff --git a/MessageThread.cpp b/MessageThread.cpp deleted file mode 100644 index 2781ac6..0000000 --- a/MessageThread.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2020 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "TranslationClass.h" -#include "MessageThread.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include - -MessageThread::MessageThread(uint cacheId, QObject *parent) : QThread(parent), cacheId(cacheId) -{ - threadRunning = true; -} - -void MessageThread::run() -{ - QEventLoop threadLoop; - - QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit())); - - while (threadRunning) { - { -#ifdef GTA5SYNC_MOTD_WEBURL - QUrl motdWebUrl = QUrl(GTA5SYNC_MOTD_WEBURL); -#else - QUrl motdWebUrl = QUrl("https://motd.syping.de/gta5view-dev/"); -#endif - QUrlQuery urlQuery(motdWebUrl); - urlQuery.addQueryItem("code", GTA5SYNC_BUILDCODE); - urlQuery.addQueryItem("cacheid", QString::number(cacheId)); - urlQuery.addQueryItem("lang", Translator->getCurrentLanguage()); - urlQuery.addQueryItem("version", GTA5SYNC_APPVER); - motdWebUrl.setQuery(urlQuery); - - QNetworkAccessManager *netManager = new QNetworkAccessManager(); - QNetworkRequest netRequest(motdWebUrl); - netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent()); - QNetworkReply *netReply = netManager->get(netRequest); - - QEventLoop downloadLoop; - QObject::connect(netManager, SIGNAL(finished(QNetworkReply*)), &downloadLoop, SLOT(quit())); - QObject::connect(this, SIGNAL(threadTerminated()), &threadLoop, SLOT(quit())); - QTimer::singleShot(60000, &downloadLoop, SLOT(quit())); - downloadLoop.exec(); - - if (netReply->isFinished()) { - QByteArray jsonContent = netReply->readAll(); - QString headerData = QString::fromUtf8(netReply->rawHeader("gta5view")); - if (!headerData.isEmpty()) { - QMap headerMap; - const QStringList headerVarList = headerData.split(';'); - for (QString headerVar : headerVarList) { - QStringList varValueList = headerVar.split('='); - if (varValueList.length() >= 2) { - const QString variable = varValueList.at(0).trimmed(); - varValueList.removeFirst(); - const QString value = varValueList.join('='); - headerMap.insert(variable, value); - } - } - if (headerMap.value("update", "false") == "true") { - QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonContent); - emit messagesArrived(jsonDocument.object()); - } - if (headerMap.contains("cache")) { - bool uintOk; - uint cacheVal = headerMap.value("cache").toUInt(&uintOk); - if (uintOk) { - cacheId = cacheVal; - emit updateCacheId(cacheId); - } - } - } - } - - delete netReply; - delete netManager; - } - - QTimer::singleShot(300000, &threadLoop, SLOT(quit())); - threadLoop.exec(); - } -} - -void MessageThread::terminateThread() -{ - threadRunning = false; - emit threadTerminated(); -} diff --git a/MessageThread.h b/MessageThread.h deleted file mode 100644 index fa2d25b..0000000 --- a/MessageThread.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2020 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef MESSAGETHREAD_H -#define MESSAGETHREAD_H - -#include -#include -#include - -class MessageThread : public QThread -{ - Q_OBJECT -public: - explicit MessageThread(uint cacheId, QObject *parent = 0); - -public slots: - void terminateThread(); - -private: - bool threadRunning; - uint cacheId; - -protected: - void run(); - -signals: - void messagesArrived(const QJsonObject &messageObject); - void updateCacheId(uint cacheId); - void threadTerminated(); -}; - -#endif // MESSAGETHREAD_H diff --git a/OptionsDialog.cpp b/OptionsDialog.cpp old mode 100644 new mode 100755 index d096383..2125f2d --- a/OptionsDialog.cpp +++ b/OptionsDialog.cpp @@ -1,745 +1,436 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "OptionsDialog.h" -#include "ui_OptionsDialog.h" -#include "TranslationClass.h" -#include "StandardPaths.h" -#include "UserInterface.h" -#include "wrapper.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if QT_VERSION >= 0x050000 -#include -#else -#include -#endif - -#ifdef GTA5SYNC_TELEMETRY -#include "TelemetryClass.h" -#endif - -OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) : - QDialog(parent), profileDB(profileDB), - ui(new Ui::OptionsDialog) -{ - // Set Window Flags -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - - // Setup User Interface - ui->setupUi(this); - ui->tabWidget->setCurrentIndex(0); - ui->labPicCustomRes->setVisible(false); - ui->cmdCancel->setDefault(true); - ui->cmdCancel->setFocus(); - -#if QT_VERSION >= 0x050000 - qreal screenRatioPR = AppEnv::screenRatioPR(); - QRect desktopResolution = QApplication::primaryScreen()->geometry(); - int desktopSizeWidth = qRound((double)desktopResolution.width() * screenRatioPR); - int desktopSizeHeight = qRound((double)desktopResolution.height() * screenRatioPR); -#else - QRect desktopResolution = QApplication::desktop()->screenGeometry(this); - int desktopSizeWidth = desktopResolution.width(); - int desktopSizeHeight = desktopResolution.height(); -#endif - aspectRatio = Qt::KeepAspectRatio; - defExportSize = SnapmaticPicture::getSnapmaticResolution(); - cusExportSize = defExportSize; - defaultQuality = 100; - customQuality = 100; - contentMode = 0; - settings = new QSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - - percentString = ui->labPicQuality->text(); - ui->labPicQuality->setText(percentString.arg(QString::number(defaultQuality))); - ui->rbPicDesktopRes->setText(ui->rbPicDesktopRes->text().arg(QString::number(desktopSizeWidth), QString::number(desktopSizeHeight))); - ui->rbPicDefaultRes->setText(ui->rbPicDefaultRes->text().arg(QString::number(defExportSize.width()), QString::number(defExportSize.height()))); - - // Set Icon for OK Button - if (QIcon::hasThemeIcon("dialog-ok")) { - ui->cmdOK->setIcon(QIcon::fromTheme("dialog-ok")); - } - else if (QIcon::hasThemeIcon("gtk-ok")) { - ui->cmdOK->setIcon(QIcon::fromTheme("gtk-ok")); - } - - // Set Icon for Cancel Button - if (QIcon::hasThemeIcon("dialog-cancel")) { - ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel")); - } - else if (QIcon::hasThemeIcon("gtk-cancel")) { - ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel")); - } - - // Set Icon for Copy Button - if (QIcon::hasThemeIcon("edit-copy")) { - ui->cmdCopyStatsID->setIcon(QIcon::fromTheme("edit-copy")); - } - - setupTreeWidget(); - setupLanguageBox(); - setupRadioButtons(); - setupDefaultProfile(); - setupPictureSettings(); - setupCustomGTAFolder(); - setupInterfaceSettings(); - setupStatisticsSettings(); - setupSnapmaticPictureViewer(); - setupWindowsGameSettings(); - -#ifndef Q_QS_ANDROID - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); - resize(435 * screenRatio, 405 * screenRatio); -#endif - - ui->rbModern->setText(ui->rbModern->text().arg(GTA5SYNC_APPSTR)); - ui->rbClassic->setText(ui->rbClassic->text().arg(GTA5SYNC_APPSTR)); - setWindowTitle(windowTitle().arg(GTA5SYNC_APPSTR)); -} - -OptionsDialog::~OptionsDialog() -{ - delete settings; - qDeleteAll(playerItems.begin(), playerItems.end()); - playerItems.clear(); - delete ui; -} - -void OptionsDialog::setupTreeWidget() -{ - const QStringList players = profileDB->getPlayers(); - if (players.length() != 0) { - for (auto it = players.constBegin(); it != players.constEnd(); it++) { - bool ok; - int playerID = it->toInt(&ok); - if (ok) { - const QString playerName = profileDB->getPlayerName(playerID); - - QStringList playerTreeViewList; - playerTreeViewList += *it; - playerTreeViewList += playerName; - - QTreeWidgetItem *playerItem = new QTreeWidgetItem(playerTreeViewList); - ui->twPlayers->addTopLevelItem(playerItem); - playerItems += playerItem; - } - } - ui->twPlayers->sortItems(1, Qt::AscendingOrder); - } - else { - ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabPlayers)); - } -} - -void OptionsDialog::setupLanguageBox() -{ - settings->beginGroup("Interface"); - currentLanguage = settings->value("Language", "System").toString(); - currentAreaLanguage = settings->value("AreaLanguage", "Auto").toString(); - settings->endGroup(); - - const QString cbSysStr = tr("%1 (Language priority)", "First language a person can talk with a different person/application. \"Native\" or \"Not Native\".").arg(tr("System", - "System in context of System default")); -#ifdef Q_OS_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 - const QString cbAutoStr = tr("%1 (Closest to Interface)", "Next closest language compared to the Interface").arg(tr("Auto", "Automatic language choice.")); -#endif - ui->cbLanguage->addItem(cbSysStr, "System"); - ui->cbAreaLanguage->addItem(cbAutoStr, "Auto"); - - QStringList availableLanguages; - availableLanguages << QString("en_GB"); -#ifndef GTA5SYNC_QCONF - availableLanguages << TranslationClass::listTranslations(AppEnv::getExLangFolder()); -#endif - availableLanguages << TranslationClass::listTranslations(AppEnv::getInLangFolder()); - availableLanguages.removeDuplicates(); - availableLanguages.sort(); - - for (const QString &lang : qAsConst(availableLanguages)) { - QLocale langLocale(lang); - const QString cbLangStr = langLocale.nativeLanguageName() % " (" % langLocale.nativeCountryName() % ") [" % lang % "]"; - const QString langIconPath = AppEnv::getImagesFolder() % "/flag-" % TranslationClass::getCountryCode(langLocale) % ".png"; - - if (QFile::exists(langIconPath)) { - ui->cbLanguage->addItem(QIcon(langIconPath), cbLangStr, lang); - } - else { - ui->cbLanguage->addItem(cbLangStr, lang); - } - if (currentLanguage == lang) { -#if QT_VERSION >= 0x050000 - ui->cbLanguage->setCurrentText(cbLangStr); -#else - int indexOfLang = ui->cbLanguage->findText(cbLangStr); - ui->cbLanguage->setCurrentIndex(indexOfLang); -#endif - } - } - - QString aCurrentLanguage = QString("en_GB"); - if (Translator->isLanguageLoaded()) - aCurrentLanguage = Translator->getCurrentLanguage(); - QLocale currentLocale = QLocale(aCurrentLanguage); - ui->labCurrentLanguage->setText(tr("Current: %1").arg(currentLocale.nativeLanguageName() % " (" % currentLocale.nativeCountryName() % ") [" % aCurrentLanguage % "]")); - - availableLanguages.clear(); - availableLanguages << TranslationClass::listAreaTranslations(); - availableLanguages.removeDuplicates(); - availableLanguages.sort(); - - for (const QString &lang : qAsConst(availableLanguages)) { - // correcting Language Location if possible - QString aLang = lang; - if (QFile::exists(":/global/global." % lang % ".loc")) { - QFile locFile(":/global/global." % lang % ".loc"); - if (locFile.open(QFile::ReadOnly)) { - aLang = QString::fromUtf8(locFile.readLine()).trimmed(); - locFile.close(); - } - } - - QLocale langLocale(aLang); - const QString cbLangStr = langLocale.nativeLanguageName() % " (" % langLocale.nativeCountryName() % ") [" % aLang % "]"; - ui->cbAreaLanguage->addItem(cbLangStr, lang); - if (currentAreaLanguage == lang) { -#if QT_VERSION >= 0x050000 - ui->cbAreaLanguage->setCurrentText(cbLangStr); -#else - int indexOfLang = ui->cbAreaLanguage->findText(cbLangStr); - ui->cbAreaLanguage->setCurrentIndex(indexOfLang); -#endif - } - } - - QString aCurrentAreaLanguage = Translator->getCurrentAreaLanguage(); - if (QFile::exists(":/global/global." % aCurrentAreaLanguage % ".loc")) { - qDebug() << "locFile found"; - QFile locFile(":/global/global." % aCurrentAreaLanguage % ".loc"); - if (locFile.open(QFile::ReadOnly)) { - aCurrentAreaLanguage = QString::fromUtf8(locFile.readLine()).trimmed(); - locFile.close(); - } - } - currentLocale = QLocale(aCurrentAreaLanguage); - ui->labCurrentAreaLanguage->setText(tr("Current: %1").arg(currentLocale.nativeLanguageName() % " (" % currentLocale.nativeCountryName() % ") [" % aCurrentAreaLanguage % "]")); -} - -void OptionsDialog::setupRadioButtons() -{ - bool contentModeOk; - settings->beginGroup("Profile"); - contentMode = settings->value("ContentMode", 0).toInt(&contentModeOk); - settings->endGroup(); - - if (contentModeOk) { - switch (contentMode) { - case 0: - case 20: - ui->rbModern->setChecked(true); - ui->cbDoubleclick->setChecked(false); - break; - case 1: - case 2: - case 21: - ui->rbModern->setChecked(true); - ui->cbDoubleclick->setChecked(true); - break; - case 10: - ui->rbClassic->setChecked(true); - ui->cbDoubleclick->setChecked(false); - break; - case 11: - ui->rbClassic->setChecked(true); - ui->cbDoubleclick->setChecked(true); - break; - } - } -} - -void OptionsDialog::setupInterfaceSettings() -{ - settings->beginGroup("Startup"); - const QString currentStyle = QApplication::style()->objectName(); - const QString appStyle = settings->value("AppStyle", currentStyle).toString(); - bool customStyle = settings->value("CustomStyle", false).toBool(); - const QStringList availableStyles = QStyleFactory::keys(); - ui->cbStyleList->addItems(availableStyles); - if (availableStyles.contains(appStyle, Qt::CaseInsensitive)) { - // use 'for' for select to be sure it's case insensitive - int currentIndex = 0; - for (const QString ¤tStyleFF : availableStyles) { - if (currentStyleFF.toLower() == appStyle.toLower()) { - ui->cbStyleList->setCurrentIndex(currentIndex); - } - currentIndex++; - } - } - else { - if (availableStyles.contains(currentStyle, Qt::CaseInsensitive)) { - int currentIndex = 0; - for (const QString ¤tStyleFF : availableStyles) { - if (currentStyleFF.toLower() == currentStyle.toLower()) { - ui->cbStyleList->setCurrentIndex(currentIndex); - } - currentIndex++; - } - } - } - ui->cbDefaultStyle->setChecked(!customStyle); - ui->cbStyleList->setEnabled(customStyle); - const QFont currentFont = QApplication::font(); - const QFont appFont = qvariant_cast(settings->value("AppFont", currentFont)); - bool customFont = settings->value("CustomFont", false).toBool(); - ui->cbDefaultFont->setChecked(!customFont); - ui->cbFont->setEnabled(customFont); - ui->cbFont->setCurrentFont(appFont); - settings->endGroup(); -} - -void OptionsDialog::on_cmdOK_clicked() -{ - applySettings(); - close(); -} - -void OptionsDialog::applySettings() -{ - settings->beginGroup("Interface"); -#if QT_VERSION >= 0x050000 - settings->setValue("Language", ui->cbLanguage->currentData()); - settings->setValue("AreaLanguage", ui->cbAreaLanguage->currentData()); -#else - settings->setValue("Language", ui->cbLanguage->itemData(ui->cbLanguage->currentIndex())); - settings->setValue("AreaLanguage", ui->cbAreaLanguage->itemData(ui->cbAreaLanguage->currentIndex())); -#endif -#ifdef Q_OS_WIN -#if QT_VERSION >= 0x050200 - settings->setValue("NavigationBar", ui->cbSnapmaticNavigationBar->isChecked()); -#endif -#else - settings->setValue("NavigationBar", ui->cbSnapmaticNavigationBar->isChecked()); -#endif - settings->endGroup(); - - settings->beginGroup("Profile"); - int newContentMode = 20; - if (ui->rbModern->isChecked()) { - newContentMode = 20; - } - else if (ui->rbClassic->isChecked()) { - newContentMode = 10; - } - if (ui->cbDoubleclick->isChecked()) { - newContentMode++; - } - settings->setValue("ContentMode", newContentMode); -#if QT_VERSION >= 0x050000 - settings->setValue("Default", ui->cbProfiles->currentData()); -#else - settings->setValue("Default", ui->cbProfiles->itemData(ui->cbProfiles->currentIndex())); -#endif - settings->endGroup(); - - settings->beginGroup("Pictures"); - if (ui->cbPicCustomQuality->isChecked()) { - settings->setValue("CustomQuality", ui->hsPicQuality->value()); - } - settings->setValue("CustomQualityEnabled", ui->cbPicCustomQuality->isChecked()); - QString sizeMode = "Default"; - if (ui->rbPicDesktopRes->isChecked()) { - sizeMode = "Desktop"; - } - else if (ui->rbPicCustomRes->isChecked()) { - sizeMode = "Custom"; - settings->setValue("CustomSize", QSize(ui->sbPicExportWidth->value(), ui->sbPicExportHeight->value())); - } - settings->setValue("ExportSizeMode", sizeMode); - settings->setValue("AspectRatio", aspectRatio); - settings->endGroup(); - - bool forceCustomFolder = ui->cbForceCustomFolder->isChecked(); - settings->beginGroup("dir"); - settings->setValue("dir", ui->txtFolder->text()); - settings->setValue("force", forceCustomFolder); - settings->endGroup(); - - bool defaultStyle = ui->cbDefaultStyle->isChecked(); - settings->beginGroup("Startup"); - if (!defaultStyle) { - QString newStyle = ui->cbStyleList->currentText(); - settings->setValue("CustomStyle", true); - settings->setValue("AppStyle", newStyle); - QApplication::setStyle(QStyleFactory::create(newStyle)); - } - else { - settings->setValue("CustomStyle", false); - } - bool defaultFont = ui->cbDefaultFont->isChecked(); - if (!defaultFont) { - QFont newFont = ui->cbFont->currentFont(); - settings->setValue("CustomFont", true); - settings->setValue("AppFont", newFont); - QApplication::setFont(newFont); - } - else { - settings->setValue("CustomFont", false); - } - settings->endGroup(); - -#ifdef GTA5SYNC_TELEMETRY - settings->beginGroup("Telemetry"); - settings->setValue("PushAppConf", ui->cbAppConfigStats->isChecked()); - settings->setValue("PushUsageData", ui->cbUsageData->isChecked()); - if (!Telemetry->isStateForced()) { settings->setValue("IsEnabled", ui->cbParticipateStats->isChecked()); } - settings->endGroup(); - Telemetry->refresh(); - Telemetry->work(); - if (ui->cbUsageData->isChecked() && Telemetry->canPush()) { - QJsonDocument jsonDocument; - QJsonObject jsonObject; - jsonObject["Type"] = "SettingsUpdated"; -#if QT_VERSION >= 0x060000 - jsonObject["UpdateTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["UpdateTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } -#endif - -#if QT_VERSION >= 0x050000 - bool languageChanged = ui->cbLanguage->currentData().toString() != currentLanguage; - bool languageAreaChanged = ui->cbAreaLanguage->currentData().toString() != currentAreaLanguage; -#else - bool languageChanged = ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentLanguage; - bool languageAreaChanged = ui->cbAreaLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentAreaLanguage; -#endif - if (languageChanged) { - Translator->unloadTranslation(qApp); - Translator->initUserLanguage(); - Translator->loadTranslation(qApp); - } - else if (languageAreaChanged) { - Translator->initUserLanguage(); - } - - settings->sync(); - emit settingsApplied(newContentMode, languageChanged); - - if ((forceCustomFolder && ui->txtFolder->text() != currentCFolder) || (forceCustomFolder != currentFFolder && forceCustomFolder)) { - QMessageBox::information(this, tr("%1", "%1").arg(GTA5SYNC_APPSTR), tr("The new Custom Folder will initialise after you restart %1.").arg(GTA5SYNC_APPSTR)); - } -} - -void OptionsDialog::setupDefaultProfile() -{ - settings->beginGroup("Profile"); - defaultProfile = settings->value("Default", "").toString(); - settings->endGroup(); - - QString cbNoneStr = tr("No Profile", "No Profile, as default"); - ui->cbProfiles->addItem(cbNoneStr, ""); -} - -void OptionsDialog::commitProfiles(const QStringList &profiles) -{ - for (const QString &profile : profiles) { - ui->cbProfiles->addItem(tr("Profile: %1").arg(profile), profile); - if (defaultProfile == profile) { -#if QT_VERSION >= 0x050000 - ui->cbProfiles->setCurrentText(tr("Profile: %1").arg(profile)); -#else - int indexOfProfile = ui->cbProfiles->findText(tr("Profile: %1").arg(profile)); - ui->cbProfiles->setCurrentIndex(indexOfProfile); -#endif - } - } -} - -void OptionsDialog::on_rbPicCustomRes_toggled(bool checked) -{ - ui->labPicCustomRes->setEnabled(checked); - ui->sbPicExportWidth->setEnabled(checked); - ui->sbPicExportHeight->setEnabled(checked); - ui->labPicXDescription->setEnabled(checked); -} - -void OptionsDialog::on_cbPicCustomQuality_toggled(bool checked) -{ - ui->hsPicQuality->setEnabled(checked); - ui->labPicQuality->setEnabled(checked); - ui->labPicQualityDescription->setEnabled(checked); -} - -void OptionsDialog::on_hsPicQuality_valueChanged(int value) -{ - customQuality = value; - ui->labPicQuality->setText(percentString.arg(QString::number(value))); -} - -void OptionsDialog::setupPictureSettings() -{ - settings->beginGroup("Pictures"); - - // Quality Settings - customQuality = settings->value("CustomQuality", defaultQuality).toInt(); - if (customQuality < 1 || customQuality > 100) { - customQuality = 100; - } - ui->hsPicQuality->setValue(customQuality); - ui->cbPicCustomQuality->setChecked(settings->value("CustomQualityEnabled", false).toBool()); - - // Size Settings - cusExportSize = settings->value("CustomSize", defExportSize).toSize(); - if (cusExportSize.width() > 3840) { - cusExportSize.setWidth(3840); - } - else if (cusExportSize.height() > 2160) { - cusExportSize.setHeight(2160); - } - if (cusExportSize.width() < 1) { - cusExportSize.setWidth(1); - } - else if (cusExportSize.height() < 1) { - cusExportSize.setHeight(1); - } - ui->sbPicExportWidth->setValue(cusExportSize.width()); - ui->sbPicExportHeight->setValue(cusExportSize.height()); - - QString sizeMode = settings->value("ExportSizeMode", "Default").toString(); - if (sizeMode == "Desktop") { - ui->rbPicDesktopRes->setChecked(true); - } - else if (sizeMode == "Custom") { - ui->rbPicCustomRes->setChecked(true); - } - else { - ui->rbPicDefaultRes->setChecked(true); - } - - aspectRatio = (Qt::AspectRatioMode)settings->value("AspectRatio", Qt::KeepAspectRatio).toInt(); - if (aspectRatio == Qt::IgnoreAspectRatio) { - ui->cbIgnoreAspectRatio->setChecked(true); - } - - settings->endGroup(); -} - -void OptionsDialog::setupStatisticsSettings() -{ -#ifdef GTA5SYNC_TELEMETRY - ui->cbParticipateStats->setText(tr("Participate in %1 User Statistics").arg(GTA5SYNC_APPSTR)); - ui->labUserStats->setText(QString("%1").arg(tr("View %1 User Statistics Online").arg(GTA5SYNC_APPSTR), TelemetryClass::getWebURL().toString())); - - settings->beginGroup("Telemetry"); - ui->cbParticipateStats->setChecked(Telemetry->isEnabled()); - ui->cbAppConfigStats->setChecked(settings->value("PushAppConf", false).toBool()); - ui->cbUsageData->setChecked(settings->value("PushUsageData", false).toBool()); - settings->endGroup(); - - if (Telemetry->isStateForced()) { - ui->cbParticipateStats->setEnabled(false); - } - - if (Telemetry->isRegistered()) { - ui->labParticipationID->setText(tr("Participation ID: %1").arg(Telemetry->getRegisteredID())); - } - else { - ui->labParticipationID->setText(tr("Participation ID: %1").arg(tr("Not registered"))); - ui->cmdCopyStatsID->setVisible(false); - } -#else - ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabStats)); -#endif -} - -void OptionsDialog::setupWindowsGameSettings() -{ -#ifdef GTA5SYNC_GAME - GameVersion gameVersion = AppEnv::getGameVersion(); -#ifdef Q_OS_WIN - if (gameVersion != GameVersion::NoVersion) { - if (gameVersion == GameVersion::SocialClubVersion) { - ui->gbSteam->setDisabled(true); - ui->labSocialClubFound->setText(tr("Found: %1").arg(QString("%1").arg(tr("Yes")))); - ui->labSteamFound->setText(tr("Found: %1").arg(QString("%1").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("%1").arg(tr("No")))); - ui->labSteamFound->setText(tr("Found: %1").arg(QString("%1").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("%1").arg(tr("Yes")))); - ui->labSteamFound->setText(tr("Found: %1").arg(QString("%1").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) -{ - if (checked) { - aspectRatio = Qt::IgnoreAspectRatio; - } - else { - aspectRatio = Qt::KeepAspectRatio; - } -} - -void OptionsDialog::setupCustomGTAFolder() -{ - bool ok; - QString defaultGameFolder = AppEnv::getGameFolder(&ok); - settings->beginGroup("dir"); - currentCFolder = settings->value("dir", "").toString(); - currentFFolder = settings->value("force", false).toBool(); - if (currentCFolder == "" && ok) { - currentCFolder = defaultGameFolder; - } - ui->txtFolder->setText(currentCFolder); - ui->cbForceCustomFolder->setChecked(currentFFolder); - settings->endGroup(); -} - -void OptionsDialog::setupSnapmaticPictureViewer() -{ -#ifdef Q_OS_WIN -#if QT_VERSION >= 0x050200 - settings->beginGroup("Interface"); - ui->cbSnapmaticNavigationBar->setChecked(settings->value("NavigationBar", true).toBool()); - settings->endGroup(); -#else - ui->cbSnapmaticNavigationBar->setVisible(false); - ui->gbSnapmaticPictureViewer->setVisible(false); -#endif -#else - settings->beginGroup("Interface"); - ui->cbSnapmaticNavigationBar->setChecked(settings->value("NavigationBar", true).toBool()); - settings->endGroup(); -#endif -} - -void OptionsDialog::on_cmdExploreFolder_clicked() -{ - const QString GTAV_Folder = QFileDialog::getExistingDirectory(this, UserInterface::tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly); - if (QDir(GTAV_Folder).exists()) { - ui->txtFolder->setText(GTAV_Folder); - } -} - -void OptionsDialog::on_cbDefaultStyle_toggled(bool checked) -{ - ui->cbStyleList->setDisabled(checked); - ui->labStyle->setDisabled(checked); -} - -void OptionsDialog::on_cbDefaultFont_toggled(bool checked) -{ - ui->cbFont->setDisabled(checked); - ui->cmdFont->setDisabled(checked); - ui->labFont->setDisabled(checked); -} - -void OptionsDialog::on_cmdCopyStatsID_clicked() -{ -#ifdef GTA5SYNC_TELEMETRY - QApplication::clipboard()->setText(Telemetry->getRegisteredID()); -#endif -} - -void OptionsDialog::on_cbFont_currentFontChanged(const QFont &font) -{ - ui->cbFont->setFont(font); -} - -void OptionsDialog::on_cmdFont_clicked() -{ - bool ok; - const QFont font = QFontDialog::getFont(&ok, ui->cbFont->currentFont(), this); - if (ok) { - ui->cbFont->setCurrentFont(font); - ui->cbFont->setFont(font); - } -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "OptionsDialog.h" +#include "ui_OptionsDialog.h" +#include "StandardPaths.h" +#include "UserInterface.h" +#include "AppEnv.h" +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +OptionsDialog::OptionsDialog(ProfileDatabase *profileDB, QWidget *parent) : + QDialog(parent), profileDB(profileDB), + ui(new Ui::OptionsDialog) +{ + ui->setupUi(this); + ui->tabWidget->setCurrentIndex(0); + ui->labPicCustomRes->setVisible(false); + + QRect desktopResolution = QApplication::desktop()->screenGeometry(parent); + int desktopSizeWidth = desktopResolution.width(); + int desktopSizeHeight = desktopResolution.height(); + aspectRatio = Qt::KeepAspectRatio; + defExportSize = QSize(960, 536); + cusExportSize = defExportSize; + defaultQuality = 100; + customQuality = 100; + contentMode = 0; + settings = new QSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + + percentString = ui->labPicQuality->text(); + ui->labPicQuality->setText(percentString.arg(QString::number(defaultQuality))); + ui->rbPicDesktopRes->setText(ui->rbPicDesktopRes->text().arg(QString::number(desktopSizeWidth), QString::number(desktopSizeHeight))); + ui->rbPicDefaultRes->setText(ui->rbPicDefaultRes->text().arg(QString::number(defExportSize.width()), QString::number(defExportSize.height()))); + + setupTreeWidget(); + setupLanguageBox(); + setupRadioButtons(); + setupDefaultProfile(); + setupPictureSettings(); + setupCustomGTAFolder(); + setupSnapmaticPictureViewer(); + + this->setWindowTitle(windowTitle().arg(GTA5SYNC_APPSTR)); +} + +OptionsDialog::~OptionsDialog() +{ + delete settings; + foreach(QTreeWidgetItem *playerItem, playerItems) + { + delete playerItem; + } + delete ui; +} + +void OptionsDialog::setupTreeWidget() +{ + foreach(const QString &playerIDStr, profileDB->getPlayers()) + { + bool ok; + int playerID = playerIDStr.toInt(&ok); + if (ok) + { + QString playerName = profileDB->getPlayerName(playerID); + + QStringList playerTreeViewList; + playerTreeViewList << playerIDStr; + playerTreeViewList << playerName; + + QTreeWidgetItem *playerItem = new QTreeWidgetItem(playerTreeViewList); + ui->twPlayers->addTopLevelItem(playerItem); + playerItems.append(playerItem); + } + } + ui->twPlayers->sortItems(1, Qt::AscendingOrder); +} + +void OptionsDialog::setupLanguageBox() +{ + settings->beginGroup("Interface"); + currentLanguage = settings->value("Language","System").toString(); + settings->endGroup(); + + QStringList langList = QLocale::system().name().split("_"); + if (langList.length() > 0) + { + QString cbSysStr = tr("%1 (%2 if available)", "System like PC System = %1, System Language like Deutsch = %2").arg(tr("System", + "System like PC System"), QLocale::languageToString(QLocale(langList.at(0)).language())); + ui->cbLanguage->addItem(cbSysStr, "System"); + } + + QString cbEngStr = "English (English) [en]"; + ui->cbLanguage->addItem(QIcon::fromTheme("flag-us"), cbEngStr, "en"); + if (currentLanguage == "en") + { +#if QT_VERSION >= 0x050000 + ui->cbLanguage->setCurrentText(cbEngStr); +#else + int indexOfEnglish = ui->cbLanguage->findText(cbEngStr); + ui->cbLanguage->setCurrentIndex(indexOfEnglish); +#endif + } + + QDir langDir; + langDir.setNameFilters(QStringList("gta5sync_*.qm")); + langDir.setPath(AppEnv::getLangFolder()); + QStringList langFiles; + langFiles << langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort); + langDir.setPath(":/tr"); + langFiles << langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort); + langFiles.removeDuplicates(); + + foreach(const QString &langFile, langFiles) + { + QString lang = langFile; + lang.remove("gta5sync_"); + lang.remove(".qm"); + + QLocale langLocale(lang); + QString languageNameInternational = QLocale::languageToString(langLocale.language()); + QString languageNameNative = langLocale.nativeLanguageName(); + + QString cbLangStr = languageNameNative + " (" + languageNameInternational + ") [" + lang + "]"; + QString langIconStr = "flag-" + lang; + + ui->cbLanguage->addItem(QIcon::fromTheme(langIconStr), cbLangStr, lang); + if (currentLanguage == lang) + { +#if QT_VERSION >= 0x050000 + ui->cbLanguage->setCurrentText(cbLangStr); +#else + int indexOfLang = ui->cbLanguage->findText(cbLangStr); + ui->cbLanguage->setCurrentIndex(indexOfLang); +#endif + } + } +} + +void OptionsDialog::setupRadioButtons() +{ + bool contentModeOk; + settings->beginGroup("Profile"); + contentMode = settings->value("ContentMode", 0).toInt(&contentModeOk); + settings->endGroup(); + + if (contentModeOk) + { + if (contentMode == 0) + { + ui->rbOpenWithSC->setChecked(true); + } + else if (contentMode == 1) + { + ui->rbOpenWithDC->setChecked(true); + } + else if (contentMode == 2) + { + ui->rbSelectWithSC->setChecked(true); + } + } +} + +void OptionsDialog::on_cmdOK_clicked() +{ + applySettings(); + close(); +} + +void OptionsDialog::applySettings() +{ + settings->beginGroup("Interface"); +#if QT_VERSION >= 0x050000 + settings->setValue("Language", ui->cbLanguage->currentData()); +#else + settings->setValue("Language", ui->cbLanguage->itemData(ui->cbLanguage->currentIndex())); +#endif +#ifdef GTA5SYNC_WIN +#if QT_VERSION >= 0x050200 + settings->setValue("NavigationBar", ui->cbSnapmaticNavigationBar->isChecked()); +#endif +#endif + settings->endGroup(); + + settings->beginGroup("Profile"); + int newContentMode = 0; + if (ui->rbOpenWithSC->isChecked()) + { + newContentMode = 0; + } + else if (ui->rbOpenWithDC->isChecked()) + { + newContentMode = 1; + } + else if (ui->rbSelectWithSC->isChecked()) + { + newContentMode = 2; + } + settings->setValue("ContentMode", newContentMode); +#if QT_VERSION >= 0x050000 + settings->setValue("Default", ui->cbProfiles->currentData()); +#else + settings->setValue("Default", ui->cbProfiles->itemData(ui->cbProfiles->currentIndex())); +#endif + settings->endGroup(); + + settings->beginGroup("Pictures"); + if (ui->cbPicCustomQuality->isChecked()) + { + settings->setValue("CustomQuality", ui->hsPicQuality->value()); + } + settings->setValue("CustomQualityEnabled", ui->cbPicCustomQuality->isChecked()); + QString sizeMode = "Default"; + if (ui->rbPicDesktopRes->isChecked()) + { + sizeMode = "Desktop"; + } + else if (ui->rbPicCustomRes->isChecked()) + { + sizeMode = "Custom"; + settings->setValue("CustomSize", QSize(ui->sbPicExportWidth->value(), ui->sbPicExportHeight->value())); + } + settings->setValue("ExportSizeMode", sizeMode); + settings->setValue("AspectRatio", aspectRatio); + settings->endGroup(); + + bool forceCustomFolder = ui->cbForceCustomFolder->isChecked(); + settings->beginGroup("dir"); + settings->setValue("dir", ui->txtFolder->text()); + settings->setValue("force", forceCustomFolder); + settings->endGroup(); + +#if QT_VERSION >= 0x050000 + emit settingsApplied(newContentMode, ui->cbLanguage->currentData().toString()); +#else + emit settingsApplied(newContentMode, ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()).toString()); +#endif + +#if QT_VERSION >= 0x050000 + bool languageChanged = ui->cbLanguage->currentData().toString() != currentLanguage; +#else + bool languageChanged = ui->cbLanguage->itemData(ui->cbLanguage->currentIndex()).toString() != currentLanguage; +#endif + + if ((forceCustomFolder && ui->txtFolder->text() != currentCFolder) || (forceCustomFolder != currentFFolder && forceCustomFolder)) + { + QMessageBox::information(this, tr("%1", "%1").arg(GTA5SYNC_APPSTR), tr("The new Custom Folder will initialize after you restart %1.").arg(GTA5SYNC_APPSTR)); + } + if (languageChanged) + { + QMessageBox::information(this, tr("%1", "%1").arg(GTA5SYNC_APPSTR), tr("The language change will take effect after you restart %1.").arg(GTA5SYNC_APPSTR)); + } +} + +void OptionsDialog::setupDefaultProfile() +{ + settings->beginGroup("Profile"); + defaultProfile = settings->value("Default", "").toString(); + settings->endGroup(); + + QString cbNoneStr = tr("No Profile", "No Profile, as default"); + ui->cbProfiles->addItem(cbNoneStr, ""); +} + +void OptionsDialog::commitProfiles(QStringList profiles) +{ + foreach(const QString &profile, profiles) + { + ui->cbProfiles->addItem(tr("Profile: %1").arg(profile), profile); + if (defaultProfile == profile) + { +#if QT_VERSION >= 0x050000 + ui->cbProfiles->setCurrentText(tr("Profile: %1").arg(profile)); +#else + int indexOfProfile = ui->cbProfiles->findText(tr("Profile: %1").arg(profile)); + ui->cbProfiles->setCurrentIndex(indexOfProfile); +#endif + } + } +} + +void OptionsDialog::on_rbPicCustomRes_toggled(bool checked) +{ + ui->labPicCustomRes->setEnabled(checked); + ui->sbPicExportWidth->setEnabled(checked); + ui->sbPicExportHeight->setEnabled(checked); + ui->labPicXDescription->setEnabled(checked); +} + +void OptionsDialog::on_cbPicCustomQuality_toggled(bool checked) +{ + ui->hsPicQuality->setEnabled(checked); + ui->labPicQuality->setEnabled(checked); + ui->labPicQualityDescription->setEnabled(checked); +} + +void OptionsDialog::on_hsPicQuality_valueChanged(int value) +{ + customQuality = value; + ui->labPicQuality->setText(percentString.arg(QString::number(value))); +} + +void OptionsDialog::setupPictureSettings() +{ + settings->beginGroup("Pictures"); + + // Quality Settings + customQuality = settings->value("CustomQuality", defaultQuality).toInt(); + if (customQuality < 1 || customQuality > 100) + { + customQuality = 100; + } + ui->hsPicQuality->setValue(customQuality); + ui->cbPicCustomQuality->setChecked(settings->value("CustomQualityEnabled", false).toBool()); + + // Size Settings + cusExportSize = settings->value("CustomSize", defExportSize).toSize(); + if (cusExportSize.width() > 3840) + { + cusExportSize.setWidth(3840); + } + else if (cusExportSize.height() > 2160) + { + cusExportSize.setHeight(2160); + } + if (cusExportSize.width() < 1) + { + cusExportSize.setWidth(1); + } + else if (cusExportSize.height() < 1) + { + cusExportSize.setHeight(1); + } + ui->sbPicExportWidth->setValue(cusExportSize.width()); + ui->sbPicExportHeight->setValue(cusExportSize.height()); + + QString sizeMode = settings->value("ExportSizeMode", "Default").toString(); + if (sizeMode == "Desktop") + { + ui->rbPicDesktopRes->setChecked(true); + } + else if (sizeMode == "Custom") + { + ui->rbPicCustomRes->setChecked(true); + } + else + { + ui->rbPicDefaultRes->setChecked(true); + } + + aspectRatio = (Qt::AspectRatioMode)settings->value("AspectRatio", Qt::KeepAspectRatio).toInt(); + if (aspectRatio == Qt::IgnoreAspectRatio) + { + ui->cbIgnoreAspectRatio->setChecked(true); + } + + settings->endGroup(); +} + +void OptionsDialog::on_cbIgnoreAspectRatio_toggled(bool checked) +{ + if (checked) + { + aspectRatio = Qt::IgnoreAspectRatio; + } + else + { + aspectRatio = Qt::KeepAspectRatio; + } +} + +void OptionsDialog::setupCustomGTAFolder() +{ + bool ok; + QString defaultGameFolder = AppEnv::getGameFolder(&ok); + settings->beginGroup("dir"); + currentCFolder = settings->value("dir", "").toString(); + currentFFolder = settings->value("force", false).toBool(); + if (currentCFolder == "" && ok) + { + currentCFolder = defaultGameFolder; + } + ui->txtFolder->setText(currentCFolder); + ui->cbForceCustomFolder->setChecked(currentFFolder); + settings->endGroup(); +} + +void OptionsDialog::setupSnapmaticPictureViewer() +{ +#ifdef GTA5SYNC_WIN +#if QT_VERSION >= 0x050200 + settings->beginGroup("Interface"); + ui->cbSnapmaticNavigationBar->setChecked(settings->value("NavigationBar", false).toBool()); + settings->endGroup(); +#else + ui->cbSnapmaticNavigationBar->setVisible(false); + ui->gbSnapmaticPictureViewer->setVisible(false); +#endif +#else + ui->cbSnapmaticNavigationBar->setVisible(false); + ui->gbSnapmaticPictureViewer->setVisible(false); +#endif +} + +void OptionsDialog::on_cmdExploreFolder_clicked() +{ + QString GTAV_Folder = QFileDialog::getExistingDirectory(this, UserInterface::tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly); + if (QFileInfo(GTAV_Folder).exists()) + { + ui->txtFolder->setText(GTAV_Folder); + } +} diff --git a/OptionsDialog.h b/OptionsDialog.h old mode 100644 new mode 100755 index f53854e..7630dc2 --- a/OptionsDialog.h +++ b/OptionsDialog.h @@ -1,89 +1,79 @@ -/****************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef OPTIONSDIALOG_H -#define OPTIONSDIALOG_H - -#include -#include -#include -#include -#include -#include "ProfileDatabase.h" - -namespace Ui { -class OptionsDialog; -} - -class OptionsDialog : public QDialog -{ - Q_OBJECT - -public: - explicit OptionsDialog(ProfileDatabase *profileDB, QWidget *parent = 0); - void commitProfiles(const QStringList &profiles); - ~OptionsDialog(); - -private slots: - void on_cmdOK_clicked(); - void on_rbPicCustomRes_toggled(bool checked); - void on_cbPicCustomQuality_toggled(bool checked); - void on_hsPicQuality_valueChanged(int value); - void on_cbIgnoreAspectRatio_toggled(bool checked); - void on_cmdExploreFolder_clicked(); - void on_cbDefaultStyle_toggled(bool checked); - void on_cbDefaultFont_toggled(bool checked); - void on_cmdCopyStatsID_clicked(); - void on_cbFont_currentFontChanged(const QFont &font); - void on_cmdFont_clicked(); - -signals: - void settingsApplied(int contentMode, bool languageChanged); - -private: - ProfileDatabase *profileDB; - Ui::OptionsDialog *ui; - QList playerItems; - Qt::AspectRatioMode aspectRatio; - QString currentAreaLanguage; - QString currentLanguage; - QString currentCFolder; - QString defaultProfile; - QString percentString; - QSettings *settings; - bool withoutPlayers; - bool currentFFolder; - int contentMode; - int customQuality; - int defaultQuality; - QSize defExportSize; - QSize cusExportSize; - void setupTreeWidget(); - void setupLanguageBox(); - void setupRadioButtons(); - void setupDefaultProfile(); - void setupPictureSettings(); - void setupCustomGTAFolder(); - void setupInterfaceSettings(); - void setupStatisticsSettings(); - void setupSnapmaticPictureViewer(); - void setupWindowsGameSettings(); - void applySettings(); -}; - -#endif // OPTIONSDIALOG_H +/****************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef OPTIONSDIALOG_H +#define OPTIONSDIALOG_H + +#include +#include +#include +#include +#include +#include "ProfileDatabase.h" + +namespace Ui { +class OptionsDialog; +} + +class OptionsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit OptionsDialog(ProfileDatabase *profileDB, QWidget *parent = 0); + void commitProfiles(QStringList profiles); + ~OptionsDialog(); + +private slots: + void on_cmdOK_clicked(); + void on_rbPicCustomRes_toggled(bool checked); + void on_cbPicCustomQuality_toggled(bool checked); + void on_hsPicQuality_valueChanged(int value); + void on_cbIgnoreAspectRatio_toggled(bool checked); + void on_cmdExploreFolder_clicked(); + +signals: + void settingsApplied(int contentMode, QString language); + +private: + ProfileDatabase *profileDB; + Ui::OptionsDialog *ui; + QList playerItems; + Qt::AspectRatioMode aspectRatio; + QString currentLanguage; + QString currentCFolder; + QString defaultProfile; + QString percentString; + QSettings *settings; + bool currentFFolder; + int contentMode; + int customQuality; + int defaultQuality; + QSize defExportSize; + QSize cusExportSize; + void setupTreeWidget(); + void setupLanguageBox(); + void setupRadioButtons(); + void setupDefaultProfile(); + void setupPictureSettings(); + void setupCustomGTAFolder(); + void setupSnapmaticPictureViewer(); + void applySettings(); +}; + +#endif // OPTIONSDIALOG_H diff --git a/OptionsDialog.ui b/OptionsDialog.ui old mode 100644 new mode 100755 index 6c5e80b..c83a658 --- a/OptionsDialog.ui +++ b/OptionsDialog.ui @@ -1,832 +1,489 @@ - - - OptionsDialog - - - - 0 - 0 - 435 - 524 - - - - %1 - Settings - - - true - - - - - - 0 - - - - Profiles - - - - - - Content Open/Select Mode - - - - - - %1 1.9+ - - - true - - - - - - - %1 1.0-1.8 - - - - - - - Open with Doubleclick - - - - - - - - - - Default Profile - - - - - - - - - - - - Custom GTA V Folder - - - - - - Force using Custom Folder - - - - - - - - - - - - ... - - - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - Pictures - - - - - - Export Size - - - - - - Default: %1x%2 - - - true - - - - - - - Screen Resolution: %1x%2 - - - - - - - - - Custom Size: - - - - - - - false - - - Custom Size: - - - - - - - false - - - 1 - - - 3840 - - - 960 - - - - - - - false - - - x - - - - - - - false - - - 1 - - - 2160 - - - 536 - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - - - - Ignore Aspect Ratio - - - - - - - - - - - - Export Quality - - - - - - Enable Custom Quality - - - - - - - - - false - - - Quality: - - - - - - - false - - - 1 - - - 100 - - - 100 - - - Qt::Horizontal - - - - - - - false - - - %1% - - - true - - - - - - - - - - - - Picture Viewer - - - - - - Enable Navigation Bar - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - Players - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::ScrollPerPixel - - - true - - - true - - - - ID - - - - - Name - - - - - - - - - Game - - - - - - Social Club Version - - - - - - Found: %1 - - - - - - - Language: %1 - - - - - - - - - - Steam Version - - - - - - Found: %1 - - - - - - - Language: %1 - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - Feedback - - - - - - Participation - - - - - - Participate in %1 User Statistics - - - - - - - <a href="%2">%1</a> - - - true - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse - - - - - - - - - - Categories - - - - - - false - - - Hardware, Application and OS Specification - - - true - - - - - - - false - - - System Language Configuration - - - true - - - - - - - Application Configuration - - - - - - - Personal Usage Data - - - - - - - - - - Other - - - - - - - - - 0 - 0 - - - - Participation ID: %1 - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - &Copy - - - false - - - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - Interface - - - - - - Language for Interface - - - - - - - - - Current: %1 - - - true - - - - - - - - - - Language for Areas - - - - - - - - - Current: %1 - - - true - - - - - - - - - - Style - - - - - - Use Default Style (Restart) - - - true - - - - - - - - - false - - - Style: - - - - - - - false - - - - 0 - 0 - - - - - - - - - - - - - Font - - - - - - Use Default Font (Restart) - - - true - - - - - - - - - false - - - Font: - - - - - - - false - - - - 0 - 0 - - - - - - - - false - - - ... - - - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Apply changes - - - &OK - - - - - - - - 0 - 0 - - - - Discard changes - - - &Cancel - - - - - - - - - - - cmdCancel - clicked() - OptionsDialog - close() - - - 352 - 328 - - - 199 - 174 - - - - - + + + OptionsDialog + + + + 0 + 0 + 435 + 405 + + + + %1 - Settings + + + true + + + + + + 0 + + + + Profiles + + + + + + Content Open/Select Mode + + + + + + Open with Singleclick + + + true + + + + + + + Open with Doubleclick + + + + + + + Select with Singleclick + + + + + + + + + + Default Profile + + + + + + + + + + + + Custom GTA V Folder + + + + + + Force using Custom Folder + + + + + + + + + + + + ... + + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + Pictures + + + + + + Export Size + + + + + + Default: %1x%2 + + + true + + + + + + + Screen Resolution: %1x%2 + + + + + + + + + Custom Size: + + + + + + + false + + + Custom Size: + + + + + + + false + + + 1 + + + 3840 + + + 960 + + + + + + + false + + + x + + + + + + + false + + + 1 + + + 2160 + + + 536 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + + Ignore Aspect Ratio + + + + + + + + + + + + Export Quality + + + + + + Enable Custom Quality + + + + + + + + + false + + + Quality: + + + + + + + false + + + 1 + + + 100 + + + 100 + + + Qt::Horizontal + + + + + + + false + + + %1% + + + true + + + + + + + + + + + + Picture Viewer + + + + + + Enable Navigation Bar + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + Players + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::ScrollPerPixel + + + true + + + true + + + + ID + + + + + Name + + + + + + + + + Language + + + + + + Language + + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + &OK + + + + + + + + + + + 0 + 0 + + + + &Cancel + + + + + + + + + + + + + + cmdClose + clicked() + OptionsDialog + close() + + + 352 + 328 + + + 199 + 174 + + + + + diff --git a/PictureCopy.cpp b/PictureCopy.cpp new file mode 100755 index 0000000..de9a8c2 --- /dev/null +++ b/PictureCopy.cpp @@ -0,0 +1,109 @@ +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "PictureCopy.h" +#include "PictureDialog.h" +#include "StandardPaths.h" +#include "SidebarGenerator.h" +#include +#include +#include + +PictureCopy::PictureCopy() +{ + +} + +void PictureCopy::copyPicture(QWidget *parent, QString picPath) +{ + QSettings settings("Syping", "gta5sync"); + settings.beginGroup("FileDialogs"); + settings.beginGroup("PictureCopy"); + + QString adjustedPicPath = picPath; + if (adjustedPicPath.right(7) == ".hidden") // for the hidden file system + { + adjustedPicPath.remove(adjustedPicPath.length() - 7, 7); + } + +fileDialogPreSave: + QFileInfo sgdFileInfo(adjustedPicPath); + QFileDialog fileDialog(parent); + fileDialog.setFileMode(QFileDialog::AnyFile); + fileDialog.setViewMode(QFileDialog::Detail); + fileDialog.setAcceptMode(QFileDialog::AcceptSave); + fileDialog.setOption(QFileDialog::DontUseNativeDialog, false); + fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true); + fileDialog.setDefaultSuffix(""); + fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); + fileDialog.setWindowTitle(PictureDialog::tr("Export as GTA Snapmatic...")); + fileDialog.setLabelText(QFileDialog::Accept, PictureDialog::tr("&Export")); + + QStringList filters; + filters << PictureDialog::tr("Snapmatic pictures (PGTA*)"); + filters << PictureDialog::tr("All files (**)"); + fileDialog.setNameFilters(filters); + + QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); + + fileDialog.setSidebarUrls(sidebarUrls); + fileDialog.setDirectory(settings.value("Directory", StandardPaths::documentsLocation()).toString()); + fileDialog.selectFile(sgdFileInfo.fileName()); + fileDialog.restoreGeometry(settings.value(parent->objectName() + "+Geomtery", "").toByteArray()); + + if (fileDialog.exec()) + { + QStringList selectedFiles = fileDialog.selectedFiles(); + if (selectedFiles.length() == 1) + { + QString selectedFile = selectedFiles.at(0); + + if (QFile::exists(selectedFile)) + { + if (QMessageBox::Yes == QMessageBox::warning(parent, PictureDialog::tr("Export as GTA Snapmatic"), PictureDialog::tr("Overwrite %1 with current Snapmatic picture?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) + { + if (!QFile::remove(selectedFile)) + { + QMessageBox::warning(parent, PictureDialog::tr("Export as GTA Snapmatic"), PictureDialog::tr("Failed to overwrite %1 with current Snapmatic picture").arg("\""+selectedFile+"\"")); + goto fileDialogPreSave; + } + } + else + { + goto fileDialogPreSave; + } + } + + bool isCopied = QFile::copy(picPath, selectedFile); + if (!isCopied) + { + QMessageBox::warning(parent, PictureDialog::tr("Export as GTA Snapmatic"), PictureDialog::tr("Failed to copy current Snapmatic picture")); + goto fileDialogPreSave; + } + } + else + { + QMessageBox::warning(parent, PictureDialog::tr("Export as GTA Snapmatic"), PictureDialog::tr("No valid file is selected")); + goto fileDialogPreSave; + } + } + + settings.setValue(parent->objectName() + "+Geometry", fileDialog.saveGeometry()); + settings.setValue("Directory", fileDialog.directory().absolutePath()); + settings.endGroup(); +} diff --git a/wrapper.h b/PictureCopy.h old mode 100644 new mode 100755 similarity index 71% rename from wrapper.h rename to PictureCopy.h index 9ea0443..68b7ef2 --- a/wrapper.h +++ b/PictureCopy.h @@ -1,30 +1,32 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef WRAPPER_H -#define WRAPPER_H - -#if QT_VERSION < 0x050700 -#if __cplusplus > 201703L -#define qAsConst(x) std::as_const(x) -#else -#define qAsConst -#endif -#endif - -#endif // WRAPPER_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef PICTURECOPY_H +#define PICTURECOPY_H + +#include +#include + +class PictureCopy +{ +public: + PictureCopy(); + static void copyPicture(QWidget *parent, QString picPath); +}; + +#endif // PICTURECOPY_H diff --git a/PictureDialog.cpp b/PictureDialog.cpp old mode 100644 new mode 100755 index 99850f8..929b01b --- a/PictureDialog.cpp +++ b/PictureDialog.cpp @@ -1,928 +1,448 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "PictureDialog.h" -#include "PictureWidget.h" -#include "ProfileDatabase.h" -#include "ui_PictureDialog.h" -#include "SidebarGenerator.h" -#include "MapLocationDialog.h" -#include "JsonEditorDialog.h" -#include "SnapmaticEditor.h" -#include "StandardPaths.h" -#include "PictureExport.h" -#include "ImportDialog.h" -#include "StringParser.h" -#include "GlobalString.h" -#include "UiModLabel.h" -#include "AppEnv.h" -#include "config.h" - -#if QT_VERSION < 0x060000 -#include -#endif - -#ifdef Q_OS_WIN -#if QT_VERSION >= 0x050000 -#include "dwmapi.h" -#endif -#endif - -#ifdef Q_OS_MAC -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GTA5SYNC_TELEMETRY -#include "TelemetryClass.h" -#endif - -// Macros for better Overview + RAM -#define locX QString::number(picture->getSnapmaticProperties().location.x) -#define locY QString::number(picture->getSnapmaticProperties().location.y) -#define locZ QString::number(picture->getSnapmaticProperties().location.z) -#define crewID QString::number(picture->getSnapmaticProperties().crewID) -#define picArea picture->getSnapmaticProperties().location.area -#define picPath picture->getPictureFilePath() -#define picTitl StringParser::escapeString(picture->getPictureTitle()) -#define plyrsList picture->getSnapmaticProperties().playersList -#if QT_VERSION >= 0x060000 -#define created QLocale().toString(picture->getSnapmaticProperties().createdDateTime, QLocale::ShortFormat) -#else -#define created picture->getSnapmaticProperties().createdDateTime.toString(Qt::DefaultLocaleShortDate) -#endif - -PictureDialog::PictureDialog(ProfileDatabase *profileDB, CrewDatabase *crewDB, QWidget *parent) : - QDialog(parent), profileDB(profileDB), crewDB(crewDB), - ui(new Ui::PictureDialog) -{ - primaryWindow = false; - setupPictureDialog(); -} - -PictureDialog::PictureDialog(ProfileDatabase *profileDB, CrewDatabase *crewDB, QString profileName, QWidget *parent) : - QDialog(parent), profileDB(profileDB), crewDB(crewDB), profileName(profileName), - ui(new Ui::PictureDialog) -{ - primaryWindow = false; - setupPictureDialog(); -} - -PictureDialog::PictureDialog(bool primaryWindow, ProfileDatabase *profileDB, CrewDatabase *crewDB, QWidget *parent) : - QDialog(parent), primaryWindow(primaryWindow), profileDB(profileDB), crewDB(crewDB), - ui(new Ui::PictureDialog) -{ - setupPictureDialog(); -} - -PictureDialog::PictureDialog(bool primaryWindow, ProfileDatabase *profileDB, CrewDatabase *crewDB, QString profileName, QWidget *parent) : - QDialog(parent), primaryWindow(primaryWindow), profileDB(profileDB), crewDB(crewDB), profileName(profileName), - ui(new Ui::PictureDialog) -{ - setupPictureDialog(); -} - -void PictureDialog::setupPictureDialog() -{ - // Set Window Flags -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::WindowContextHelpButtonHint, false); - setWindowFlag(Qt::CustomizeWindowHint, true); -#else - setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::CustomizeWindowHint); -#endif -#ifdef Q_OS_LINUX - // for stupid Window Manager like GNOME -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::Dialog, false); - setWindowFlag(Qt::Window, true); -#else - setWindowFlags(windowFlags()^Qt::Dialog^Qt::Window); -#endif -#endif - - // Setup User Interface - ui->setupUi(this); - windowTitleStr = this->windowTitle(); - jsonDrawString = ui->labJSON->text(); - ui->cmdManage->setEnabled(false); - fullscreenWidget = nullptr; - rqFullscreen = false; - previewMode = false; - naviEnabled = false; - indexed = false; - smpic = nullptr; - crewStr = ""; - - // Get Snapmatic Resolution - const QSize snapmaticResolution = SnapmaticPicture::getSnapmaticResolution(); - - // Avatar area - qreal screenRatio = AppEnv::screenRatio(); - qreal screenRatioPR = AppEnv::screenRatioPR(); - if (screenRatio != 1 || screenRatioPR != 1) { - avatarAreaPicture = QImage(AppEnv::getImagesFolder() % "/avatararea.png").scaledToHeight(snapmaticResolution.height() * screenRatio * screenRatioPR, Qt::FastTransformation); - } - else { - avatarAreaPicture = QImage(AppEnv::getImagesFolder() % "/avatararea.png"); - } - avatarLocX = 145; - avatarLocY = 66; - avatarSize = 470; - - // DPI calculation (picture) - ui->labPicture->setFixedSize(snapmaticResolution.width() * screenRatio, snapmaticResolution.height() * screenRatio); - ui->labPicture->setFocusPolicy(Qt::StrongFocus); - ui->labPicture->setScaledContents(true); - - // Overlay area - renderOverlayPicture(); - overlayEnabled = true; - - // Manage menu - manageMenu = new QMenu(this); - manageMenu->addAction(tr("Export as &Picture..."), this, SLOT(exportSnapmaticPicture())); - manageMenu->addAction(tr("Export as &Snapmatic..."), this, SLOT(copySnapmaticPicture())); - manageMenu->addSeparator(); - manageMenu->addAction(tr("&Edit Properties..."), this, SLOT(editSnapmaticProperties())); - manageMenu->addAction(tr("&Overwrite Image..."), this, SLOT(editSnapmaticImage())); - manageMenu->addSeparator(); - QAction *openViewerAction = manageMenu->addAction(tr("Open &Map Viewer..."), this, SLOT(openPreviewMap())); - openViewerAction->setShortcut(Qt::Key_M); - manageMenu->addAction(tr("Open &JSON Editor..."), this, SLOT(editSnapmaticRawJson())); - ui->cmdManage->setMenu(manageMenu); - - // Global map - globalMap = GlobalString::getGlobalMap(); - - // Set Icon for Close Button - if (QIcon::hasThemeIcon("dialog-close")) { - ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) { - ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close")); - } - - installEventFilter(this); - - // 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 - const QSize windowSize(snapmaticResolution.width() * screenRatio, snapmaticResolution.height() * screenRatio); - setMinimumSize(windowSize); - setMaximumSize(windowSize); -} - -PictureDialog::~PictureDialog() -{ - delete ui; -} - -void PictureDialog::closeEvent(QCloseEvent *ev) -{ - Q_UNUSED(ev) - if (primaryWindow) - emit endDatabaseThread(); -} - -void PictureDialog::addPreviousNextButtons() -{ - QToolBar *uiToolbar = new QToolBar("Picture Toolbar", this); -#if QT_VERSION < 0x050600 - qreal screenRatio = AppEnv::screenRatio(); - if (screenRatio != 1) { - QSize iconSize = uiToolbar->iconSize(); - uiToolbar->setIconSize(QSize(iconSize.width() * screenRatio, iconSize.height() * screenRatio)); - } -#endif - uiToolbar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - uiToolbar->setObjectName("UiToolbar"); - uiToolbar->addAction(QIcon(AppEnv::getImagesFolder() % "/back.svgz"), "", this, SLOT(previousPictureRequestedSlot())); - uiToolbar->addAction(QIcon(AppEnv::getImagesFolder() % "/next.svgz"), "", this, SLOT(nextPictureRequestedSlot())); -#ifdef Q_OS_MAC -#if QT_VERSION >= 0x050000 - uiToolbar->setStyle(QStyleFactory::create("Fusion")); -#endif -#endif - layout()->setMenuBar(uiToolbar); - naviEnabled = true; -} - -void PictureDialog::adaptDialogSize() -{ - int newDialogHeight = (SnapmaticPicture::getSnapmaticResolution().height() * AppEnv::screenRatio()) + ui->jsonFrame->heightForWidth(width()); - if (naviEnabled) - newDialogHeight = newDialogHeight + layout()->menuBar()->height(); - const QSize windowSize(width(), newDialogHeight); - setMinimumSize(windowSize); - setMaximumSize(windowSize); -} - -void PictureDialog::styliseDialog() -{ -#ifdef Q_OS_WIN - BOOL isEnabled; - DwmIsCompositionEnabled(&isEnabled); - if (isEnabled == TRUE) { - MARGINS margins = {0, 0, qRound(layout()->menuBar()->height() * AppEnv::screenRatioPR()), 0}; - HRESULT hr = S_OK; - hr = DwmExtendFrameIntoClientArea(reinterpret_cast(winId()), &margins); - if (SUCCEEDED(hr)) { - setStyleSheet("PictureDialog{background:transparent}"); - } - } - else { - MARGINS margins = {0, 0, 0, 0}; - DwmExtendFrameIntoClientArea(reinterpret_cast(winId()), &margins); - bool colorOk = false; - QSettings dwmRegistry("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\DWM", QSettings::NativeFormat); - QRgb color = dwmRegistry.value("ColorizationColor").toUInt(&colorOk); - if (colorOk) { - setStyleSheet(QString("PictureDialog{background:%1}").arg(QColor::fromRgba(color).name())); - } - else { - HRESULT hr = S_OK; - BOOL isOpaqueBlend; - DWORD colorization; - hr = DwmGetColorizationColor(&colorization, &isOpaqueBlend); - if (SUCCEEDED(hr) && isOpaqueBlend == FALSE) { - color = colorization; - setStyleSheet(QString("PictureDialog{background:%1}").arg(QColor::fromRgba(color).name())); - } - else { - setStyleSheet("PictureDialog{background:palette(window)}"); - } - } - } - ui->jsonFrame->setStyleSheet("QFrame{background:palette(window)}"); -#endif -} - -#ifdef Q_OS_WIN -#if QT_VERSION >= 0x050000 -#if QT_VERSION >= 0x060000 -bool PictureDialog::nativeEvent(const QByteArray &eventType, void *message, qintptr *result) -#else -bool PictureDialog::nativeEvent(const QByteArray &eventType, void *message, long *result) -#endif -{ - MSG *msg = reinterpret_cast(message); - if (msg->message == 0x031e || msg->message == 0x0320) { - styliseDialog(); - } - return QWidget::nativeEvent(eventType, message, result); -} -#endif -#endif - -void PictureDialog::nextPictureRequestedSlot() -{ - emit nextPictureRequested(); -} - -void PictureDialog::previousPictureRequestedSlot() -{ - emit previousPictureRequested(); -} - -bool PictureDialog::eventFilter(QObject *obj, QEvent *ev) -{ - bool returnValue = false; - if (obj == this || obj == ui->labPicture) { - if (ev->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = dynamic_cast(ev); - switch (keyEvent->key()) { - case Qt::Key_Left: - emit previousPictureRequested(); - returnValue = true; - break; - case Qt::Key_Right: - emit nextPictureRequested(); - returnValue = true; - break; - case Qt::Key_1: - if (previewMode) { - previewMode = false; - renderPicture(); - } - else { - previewMode = true; - renderPicture(); - } - break; - case Qt::Key_2: - if (overlayEnabled) { - overlayEnabled = false; - if (!previewMode) renderPicture(); - } - else { - overlayEnabled = true; - if (!previewMode) renderPicture(); - } - break; - case Qt::Key_M: - openPreviewMap(); - returnValue = true; - break; -#if QT_VERSION >= 0x050300 - case Qt::Key_Exit: - ui->cmdClose->click(); - returnValue = true; - break; -#endif - case Qt::Key_Enter: case Qt::Key_Return: - on_labPicture_mouseDoubleClicked(Qt::LeftButton); - returnValue = true; - break; - case Qt::Key_Escape: - ui->cmdClose->click(); - returnValue = true; - break; - } - } -#ifdef Q_OS_WIN -#if QT_VERSION >= 0x050000 - if (obj != ui->labPicture && naviEnabled) { - if (ev->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = dynamic_cast(ev); - if (mouseEvent->pos().y() <= layout()->menuBar()->height()) { - if (mouseEvent->button() == Qt::LeftButton) { - dragPosition = mouseEvent->pos(); - dragStart = true; - } - } - } - if (ev->type() == QEvent::MouseButtonRelease) { - QMouseEvent *mouseEvent = dynamic_cast(ev); - if (mouseEvent->pos().y() <= layout()->menuBar()->height()) { - if (mouseEvent->button() == Qt::LeftButton) { - dragStart = false; - } - } - } - if (dragStart && ev->type() == QEvent::MouseMove) { - QMouseEvent *mouseEvent = dynamic_cast(ev); - if (mouseEvent->pos().y() <= layout()->menuBar()->height()) { - if (mouseEvent->buttons() & Qt::LeftButton) { - const QPoint diff = mouseEvent->pos() - dragPosition; - move(QPoint(pos() + diff)); - updateGeometry(); - } - } - } - } -#endif -#endif - } - return returnValue; -} - -void PictureDialog::triggerFullscreenDoubeClick() -{ - on_labPicture_mouseDoubleClicked(Qt::LeftButton); -} - -void PictureDialog::exportCustomContextMenuRequestedPrivate(const QPoint &pos, bool fullscreen) -{ - rqFullscreen = fullscreen; - manageMenu->popup(pos); -} - -void PictureDialog::exportCustomContextMenuRequested(const QPoint &pos) -{ - exportCustomContextMenuRequestedPrivate(pos, true); -} - -void PictureDialog::mousePressEvent(QMouseEvent *ev) -{ - QDialog::mousePressEvent(ev); -} - -void PictureDialog::dialogNextPictureRequested() -{ - emit nextPictureRequested(); -} - -void PictureDialog::dialogPreviousPictureRequested() -{ - emit previousPictureRequested(); -} - -void PictureDialog::renderOverlayPicture() -{ - // Generating Overlay Preview - qreal screenRatio = AppEnv::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"); - - QFont overlayPainterFont; - overlayPainterFont.setPixelSize(12 * screenRatio * screenRatioPR); - QFontMetrics fontMetrics(overlayPainterFont); - QRect overlaySpace = fontMetrics.boundingRect(preferedRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip | Qt::TextWordWrap, overlayText); - - int hOverlay = Qt::AlignTop; - if (overlaySpace.height() < 74 * screenRatio * screenRatioPR) { - hOverlay = Qt::AlignVCenter; - preferedRect.setHeight(71 * screenRatio * screenRatioPR); - overlaySpace.setHeight(80 * screenRatio * screenRatioPR); - } - else { - overlaySpace.setHeight(overlaySpace.height() + 6 * screenRatio * screenRatioPR); - } - - QImage overlayImage(overlaySpace.size(), QImage::Format_ARGB32_Premultiplied); - overlayImage.fill(Qt::transparent); - - QPainter overlayPainter(&overlayImage); - overlayPainter.setPen(QColor::fromRgb(255, 255, 255, 255)); - overlayPainter.setFont(overlayPainterFont); - overlayPainter.drawText(preferedRect, Qt::AlignLeft | hOverlay | Qt::TextDontClip | Qt::TextWordWrap, overlayText); - overlayPainter.end(); - - if (overlaySpace.width() < 194 * screenRatio * screenRatioPR) { - overlaySpace.setWidth(200 * screenRatio * screenRatioPR); - } - else { - overlaySpace.setWidth(overlaySpace.width() + 6 * screenRatio * screenRatioPR); - } - - QImage overlayBorderImage(overlaySpace.width(), overlaySpace.height(), QImage::Format_ARGB6666_Premultiplied); - overlayBorderImage.fill(QColor(15, 15, 15, 162)); - - overlayTempImage = QImage(overlaySpace.width(), overlaySpace.height(), QImage::Format_ARGB6666_Premultiplied); - overlayTempImage.fill(Qt::transparent); - QPainter overlayTempPainter(&overlayTempImage); - overlayTempPainter.drawImage(0, 0, overlayBorderImage); - overlayTempPainter.drawImage(3 * screenRatio * screenRatioPR, 3 * screenRatio * screenRatioPR, overlayImage); - overlayTempPainter.end(); -} - -void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, bool readOk, bool _indexed, int _index) -{ - if (smpic != nullptr) { - QObject::disconnect(smpic, SIGNAL(updated()), this, SLOT(updated())); - QObject::disconnect(smpic, SIGNAL(customSignal(QString)), this, SLOT(customSignal(QString))); - } - snapmaticPicture = QImage(); - indexed = _indexed; - index = _index; - smpic = picture; - if (!readOk) { - QMessageBox::warning(this, tr("Snapmatic Picture Viewer"), tr("Failed at %1").arg(picture->getLastStep())); - return; - } - if (picture->isPicOk()) { - snapmaticPicture = picture->getImage(); - renderPicture(); - ui->cmdManage->setEnabled(true); - } - if (picture->isJsonOk()) { - crewStr = crewDB->getCrewName(crewID); - if (globalMap.contains(picArea)) { - picAreaStr = globalMap.value(picArea); - } - else { - picAreaStr = picArea; - } - setWindowTitle(windowTitleStr.arg(picTitl)); - ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created)); - QTimer::singleShot(0, this, SLOT(adaptDialogSize())); - } - else { - ui->labJSON->setText(jsonDrawString.arg("0", "0", "0", tr("No Players"), tr("No Crew"), tr("Unknown Location"))); - QTimer::singleShot(0, this, SLOT(adaptDialogSize())); - } - QObject::connect(smpic, SIGNAL(updated()), this, SLOT(updated())); - QObject::connect(smpic, SIGNAL(customSignal(QString)), this, SLOT(customSignal(QString))); - emit newPictureCommited(snapmaticPicture); -} - -void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, bool readOk, int index) -{ - setSnapmaticPicture(picture, readOk, true, index); -} - -void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, bool readOk) -{ - setSnapmaticPicture(picture, readOk, false, 0); -} - -void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, int index) -{ - setSnapmaticPicture(picture, true, index); -} - -void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture) -{ - setSnapmaticPicture(picture, true); -} - -void PictureDialog::renderPicture() -{ - const qreal screenRatio = AppEnv::screenRatio(); - const qreal screenRatioPR = AppEnv::screenRatioPR(); - const QSize snapmaticResolution(SnapmaticPicture::getSnapmaticResolution()); - const QSize renderResolution(snapmaticResolution.width() * screenRatio * screenRatioPR, snapmaticResolution.height() * screenRatio * screenRatioPR); - QPixmap shownImagePixmap(renderResolution); - shownImagePixmap.fill(Qt::black); - QPainter shownImagePainter(&shownImagePixmap); - const QImage renderImage = snapmaticPicture.scaled(renderResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation); - if (renderImage.width() < renderResolution.width()) { - shownImagePainter.drawImage((renderResolution.width() - renderImage.width()) / 2, 0, renderImage, Qt::AutoColor); - } - else if (renderImage.height() < renderResolution.height()) { - shownImagePainter.drawImage(0, (renderResolution.height() - renderImage.height()) / 2, renderImage, Qt::AutoColor); - } - else { - shownImagePainter.drawImage(0, 0, renderImage, Qt::AutoColor); - } - if (previewMode) { - QFont shownImagePainterFont; - shownImagePainterFont.setPixelSize(12 * screenRatio * screenRatioPR); - shownImagePainter.drawImage(0, 0, avatarAreaPicture); - shownImagePainter.setPen(QColor::fromRgb(255, 255, 255, 255)); - shownImagePainter.setFont(shownImagePainterFont); - shownImagePainter.drawText(QRect(3 * screenRatio * screenRatioPR, 3 * screenRatio * screenRatioPR, 140 * screenRatio * screenRatioPR, snapmaticResolution.height() * screenRatio * screenRatioPR), Qt::AlignLeft | Qt::TextWordWrap, tr("Avatar Preview Mode\nPress 1 for Default View")); - } - else if (overlayEnabled) { - shownImagePainter.drawImage(3 * screenRatio * screenRatioPR, 3 * screenRatio * screenRatioPR, overlayTempImage, Qt::AutoColor); - } - shownImagePainter.end(); -#if QT_VERSION >= 0x050600 - shownImagePixmap.setDevicePixelRatio(screenRatioPR); -#endif - ui->labPicture->setPixmap(shownImagePixmap); -} - -void PictureDialog::crewNameUpdated() -{ - SnapmaticPicture *picture = smpic; // used by macro - QString crewIDStr = crewID; - if (crewIDStr == crewStr) { - crewStr = crewDB->getCrewName(crewIDStr); - ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created)); - QTimer::singleShot(0, this, SLOT(adaptDialogSize())); - } -} - -void PictureDialog::playerNameUpdated() -{ - SnapmaticPicture *picture = smpic; // used by macro - if (plyrsList.count() >= 1) { - ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created)); - QTimer::singleShot(0, this, SLOT(adaptDialogSize())); - } -} - -QString PictureDialog::generateCrewString() -{ - SnapmaticPicture *picture = smpic; // used by macro - const QString crewIDStr = crewID; // save operation time - if (crewIDStr != "0" && !crewIDStr.isEmpty()) { - if (crewIDStr != crewStr) { - return QString("" % crewStr % ""); - } - else { - return QString(crewIDStr); - } - } - return tr("No Crew"); -} - -QString PictureDialog::generatePlayersString() -{ - SnapmaticPicture *picture = smpic; // used by macro - const QStringList playersList = plyrsList; // save operation time - QString plyrsStr; - if (playersList.length() >= 1) { - for (const QString &player : playersList) { - const QString playerName = profileDB->getPlayerName(player); - if (player != playerName) { - plyrsStr += ", " % playerName % ""; - } - else { - plyrsStr += ", " % player; - } - } - plyrsStr.remove(0, 2); - } - else { - plyrsStr = tr("No Players"); - } - return plyrsStr; -} - -void PictureDialog::exportSnapmaticPicture() -{ - if (rqFullscreen && fullscreenWidget != nullptr) { - PictureExport::exportAsPicture(fullscreenWidget, smpic); - } - else { - PictureExport::exportAsPicture(this, smpic); - } -} - -void PictureDialog::copySnapmaticPicture() -{ - if (rqFullscreen && fullscreenWidget != nullptr) { - PictureExport::exportAsSnapmatic(fullscreenWidget, smpic); - } - else { - PictureExport::exportAsSnapmatic(this, smpic); - } -} - -void PictureDialog::on_labPicture_mouseDoubleClicked(Qt::MouseButton button) -{ - if (button == Qt::LeftButton) { -#if QT_VERSION >= 0x060000 - QRect desktopRect = QApplication::screenAt(pos())->geometry(); -#else - QRect desktopRect = QApplication::desktop()->screenGeometry(this); -#endif - PictureWidget *pictureWidget = new PictureWidget(this); // Work! - pictureWidget->setObjectName("PictureWidget"); -#if QT_VERSION >= 0x050900 - pictureWidget->setWindowFlag(Qt::FramelessWindowHint, true); - pictureWidget->setWindowFlag(Qt::MaximizeUsingFullscreenGeometryHint, true); -#elif QT_VERSION >= 0x050600 - pictureWidget->setWindowFlags(pictureWidget->windowFlags()^Qt::FramelessWindowHint^Qt::MaximizeUsingFullscreenGeometryHint); -#else - pictureWidget->setWindowFlags(pictureWidget->windowFlags()^Qt::FramelessWindowHint); -#endif - pictureWidget->setWindowTitle(windowTitle()); - pictureWidget->setStyleSheet("QLabel#pictureLabel{background-color:black;}"); - pictureWidget->setImage(smpic->getImage(), desktopRect); - pictureWidget->setModal(true); - - fullscreenWidget = pictureWidget; - QObject::connect(this, SIGNAL(newPictureCommited(QImage)), pictureWidget, SLOT(setImage(QImage))); - QObject::connect(pictureWidget, SIGNAL(nextPictureRequested()), this, SLOT(dialogNextPictureRequested())); - QObject::connect(pictureWidget, SIGNAL(previousPictureRequested()), this, SLOT(dialogPreviousPictureRequested())); - - pictureWidget->move(desktopRect.x(), desktopRect.y()); - pictureWidget->resize(desktopRect.width(), desktopRect.height()); - pictureWidget->showFullScreen(); - pictureWidget->setFocus(); - pictureWidget->raise(); - pictureWidget->exec(); - - fullscreenWidget = nullptr; // Work! - delete pictureWidget; // Work! - } -} - -void PictureDialog::on_labPicture_customContextMenuRequested(const QPoint &pos) -{ - exportCustomContextMenuRequestedPrivate(ui->labPicture->mapToGlobal(pos), false); -} - -bool PictureDialog::isIndexed() -{ - return indexed; -} - -int PictureDialog::getIndex() -{ - return index; -} - -void PictureDialog::openPreviewMap() -{ - SnapmaticPicture *picture = smpic; - SnapmaticProperties currentProperties = picture->getSnapmaticProperties(); - MapLocationDialog *mapLocDialog; - if (rqFullscreen && fullscreenWidget != nullptr) { - mapLocDialog = new MapLocationDialog(currentProperties.location.x, currentProperties.location.y, fullscreenWidget); - } - else { - mapLocDialog = new MapLocationDialog(currentProperties.location.x, currentProperties.location.y, this); - } - mapLocDialog->setCayoPerico(currentProperties.location.isCayoPerico); - mapLocDialog->setWindowIcon(windowIcon()); - mapLocDialog->setModal(true); -#ifndef Q_OS_ANDROID - mapLocDialog->show(); -#else - mapLocDialog->showMaximized(); -#endif - mapLocDialog->exec(); - if (mapLocDialog->propUpdated()) { - // Update Snapmatic Properties - currentProperties.location.x = mapLocDialog->getXpos(); - currentProperties.location.y = mapLocDialog->getYpos(); - currentProperties.location.z = 0; - - // Update Snapmatic Picture - QString currentFilePath = picture->getPictureFilePath(); - QString originalFilePath = picture->getOriginalPictureFilePath(); - QString backupFileName = originalFilePath % ".bak"; - if (!QFile::exists(backupFileName)) { - QFile::copy(currentFilePath, backupFileName); - } - SnapmaticProperties fallbackProperties = picture->getSnapmaticProperties(); - picture->setSnapmaticProperties(currentProperties); - if (!picture->exportPicture(currentFilePath)) { - QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error")); - picture->setSnapmaticProperties(fallbackProperties); - } - else { - 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()); -#if QT_VERSION >= 0x060000 - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } -#endif - } - } - delete mapLocDialog; -} - -void PictureDialog::editSnapmaticProperties() -{ - SnapmaticPicture *picture = smpic; - SnapmaticEditor *snapmaticEditor; - if (rqFullscreen && fullscreenWidget != nullptr) { - snapmaticEditor = new SnapmaticEditor(crewDB, profileDB, fullscreenWidget); - } - else { - snapmaticEditor = new SnapmaticEditor(crewDB, profileDB, this); - } - snapmaticEditor->setWindowIcon(windowIcon()); - snapmaticEditor->setSnapmaticPicture(picture); - snapmaticEditor->setModal(true); -#ifndef Q_OS_ANDROID - snapmaticEditor->show(); -#else - snapmaticEditor->showMaximized(); -#endif - snapmaticEditor->exec(); - delete snapmaticEditor; -} - -void PictureDialog::editSnapmaticImage() -{ - QImage *currentImage = new QImage(smpic->getImage()); - ImportDialog *importDialog; - if (rqFullscreen && fullscreenWidget != nullptr) { - importDialog = new ImportDialog(profileName, fullscreenWidget); - } - else { - importDialog = new ImportDialog(profileName, this); - } - importDialog->setWindowIcon(windowIcon()); - importDialog->setImage(currentImage); - importDialog->enableOverwriteMode(); - importDialog->setModal(true); - importDialog->exec(); - if (importDialog->isImportAgreed()) { - const QByteArray previousPicture = smpic->getPictureStream(); - bool success = smpic->setImage(importDialog->image(), importDialog->isUnlimitedBuffer()); - 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()); -#if QT_VERSION >= 0x060000 - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } -#endif - } - 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() -{ - SnapmaticPicture *picture = smpic; - JsonEditorDialog *jsonEditor; - if (rqFullscreen && fullscreenWidget != nullptr) { - jsonEditor = new JsonEditorDialog(picture, fullscreenWidget); - } - else { - jsonEditor = new JsonEditorDialog(picture, this); - } - jsonEditor->setWindowIcon(windowIcon()); - jsonEditor->setModal(true); -#ifndef Q_OS_ANDROID - jsonEditor->show(); -#else - jsonEditor->showMaximized(); -#endif - jsonEditor->exec(); - delete jsonEditor; -} - -void PictureDialog::updated() -{ - SnapmaticPicture *picture = smpic; // used by macro - crewStr = crewDB->getCrewName(crewID); - if (globalMap.contains(picArea)) { - picAreaStr = globalMap[picArea]; - } - else { - picAreaStr = picArea; - } - setWindowTitle(windowTitleStr.arg(picTitl)); - ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, generatePlayersString(), generateCrewString(), picTitl, picAreaStr, created)); - QTimer::singleShot(0, this, SLOT(adaptDialogSize())); -} - -void PictureDialog::customSignal(QString signal) -{ - SnapmaticPicture *picture = smpic; // used by macro - if (signal == "PictureUpdated") { - snapmaticPicture = picture->getImage(); - renderPicture(); - } -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "PictureDialog.h" +#include "PictureWidget.h" +#include "ProfileDatabase.h" +#include "ui_PictureDialog.h" +#include "SidebarGenerator.h" +#include "StandardPaths.h" +#include "PictureExport.h" +#include "GlobalString.h" +#include "PictureCopy.h" +#include "UiModLabel.h" + +#ifdef GTA5SYNC_WIN +#if QT_VERSION >= 0x050200 +#include +#include +#endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PictureDialog::PictureDialog(ProfileDatabase *profileDB, CrewDatabase *crewDB, QWidget *parent) : + QDialog(parent), profileDB(profileDB), crewDB(crewDB), + ui(new Ui::PictureDialog) +{ + ui->setupUi(this); + windowTitleStr = this->windowTitle(); + jsonDrawString = ui->labJSON->text(); + ui->cmdExport->setEnabled(0); + plyrsList = QStringList(); + fullscreenWidget = 0; + rqfullscreen = 0; + navienabled = 0; + indexed = 0; + picArea = ""; + picTitl = ""; + picPath = ""; + created = ""; + crewID = ""; + locX = ""; + locY = ""; + locZ = ""; + smpic = 0; + + // Export menu + exportMenu = new QMenu(this); + jpegExportAction = exportMenu->addAction(tr("Export as &JPG picture..."), this, SLOT(exportSnapmaticPicture())); + pgtaExportAction = exportMenu->addAction(tr("Export as >A Snapmatic..."), this, SLOT(copySnapmaticPicture())); + ui->cmdExport->setMenu(exportMenu); + + // Global map + globalMap = GlobalString::getGlobalMap(); + + // Event connects + connect(ui->labJSON, SIGNAL(resized(QSize)), this, SLOT(adaptNewDialogSize(QSize))); + + installEventFilter(this); + installEventFilter(ui->labPicture); + ui->labPicture->setFocusPolicy(Qt::StrongFocus); +} + +PictureDialog::~PictureDialog() +{ + delete jpegExportAction; + delete pgtaExportAction; + delete exportMenu; + delete ui; +} + +void PictureDialog::addPreviousNextButtons() +{ + // Windows Vista additions +#ifdef GTA5SYNC_WIN +#if QT_VERSION >= 0x050200 + QPalette palette; + QToolBar *uiToolbar = new QToolBar("Picture Toolbar", this); + layout()->setMenuBar(uiToolbar); + uiToolbar->addAction(QIcon(":/img/back.png"), "", this, SLOT(previousPictureRequestedSlot())); + uiToolbar->addAction(QIcon(":/img/next.png"), "", this, SLOT(nextPictureRequestedSlot())); + ui->jsonFrame->setStyleSheet(QString("QFrame { background: %1; }").arg(palette.window().color().name())); + navienabled = true; +#endif +#endif +} + +void PictureDialog::adaptNewDialogSize(QSize newLabelSize) +{ + Q_UNUSED(newLabelSize) + int newDialogHeight = ui->labPicture->pixmap()->height(); + newDialogHeight = newDialogHeight + ui->jsonFrame->height(); + setMinimumSize(width(), newDialogHeight); + setMaximumSize(width(), newDialogHeight); + resize(width(), newDialogHeight); + ui->labPicture->updateGeometry(); + ui->jsonFrame->updateGeometry(); +} + +void PictureDialog::stylizeDialog() +{ +#ifdef GTA5SYNC_WIN +#if QT_VERSION >= 0x050200 + if (QtWin::isCompositionEnabled()) + { + QtWin::extendFrameIntoClientArea(this, 0, this->layout()->menuBar()->height(), 0, 0); + setAttribute(Qt::WA_TranslucentBackground, true); + setAttribute(Qt::WA_NoSystemBackground, false); + setStyleSheet("PictureDialog { background: transparent; }"); + } + else + { + QtWin::resetExtendedFrame(this); + setAttribute(Qt::WA_TranslucentBackground, false); + setStyleSheet(QString("PictureDialog { background: %1; }").arg(QtWin::realColorizationColor().name())); + } +#endif +#endif +} + +bool PictureDialog::event(QEvent *event) +{ +#ifdef GTA5SYNC_WIN +#if QT_VERSION >= 0x050200 + if (navienabled) + { + if (event->type() == QWinEvent::CompositionChange || event->type() == QWinEvent::ColorizationChange) + { + stylizeDialog(); + } + } +#endif +#endif + return QDialog::event(event); +} + +void PictureDialog::nextPictureRequestedSlot() +{ + emit nextPictureRequested(); +} + +void PictureDialog::previousPictureRequestedSlot() +{ + emit previousPictureRequested(); +} + +bool PictureDialog::eventFilter(QObject *obj, QEvent *ev) +{ + bool returnValue = false; + if (obj == this || obj == ui->labPicture) + { + if (ev->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = (QKeyEvent*)ev; + switch (keyEvent->key()){ + case Qt::Key_Left: + emit previousPictureRequested(); + returnValue = true; + break; + case Qt::Key_Right: + emit nextPictureRequested(); + returnValue = true; + break; + case Qt::Key_E: case Qt::Key_S: case Qt::Key_Save: + ui->cmdExport->click(); + returnValue = true; + break; +#if QT_VERSION >= 0x050300 + case Qt::Key_Exit: + ui->cmdClose->click(); + returnValue = true; + break; +#endif + case Qt::Key_Enter: case Qt::Key_Return: + on_labPicture_mouseDoubleClicked(Qt::LeftButton); + returnValue = true; + break; + } + } + } + return returnValue; +} + +void PictureDialog::triggerFullscreenDoubeClick() +{ + on_labPicture_mouseDoubleClicked(Qt::LeftButton); +} + +void PictureDialog::exportCustomContextMenuRequestedPrivate(const QPoint &pos, bool fullscreen) +{ + rqfullscreen = fullscreen; + exportMenu->popup(pos); +} + +void PictureDialog::exportCustomContextMenuRequested(const QPoint &pos) +{ + exportCustomContextMenuRequestedPrivate(pos, true); +} + +void PictureDialog::mousePressEvent(QMouseEvent *ev) +{ + QDialog::mousePressEvent(ev); +} + +void PictureDialog::dialogNextPictureRequested() +{ + emit nextPictureRequested(); +} + +void PictureDialog::dialogPreviousPictureRequested() +{ + emit previousPictureRequested(); +} + +void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, QString picturePath, bool readOk, bool _indexed, int _index) +{ + snapmaticPicture = QImage(); + indexed = _indexed; + index = _index; + picPath = picturePath; + smpic = picture; + if (!readOk) + { + QMessageBox::warning(this, tr("Snapmatic Picture Viewer"), tr("Failed at %1").arg(picture->getLastStep())); + return; + } + if (picture->isPicOk()) + { + snapmaticPicture = picture->getPicture(); + ui->labPicture->setPixmap(QPixmap::fromImage(snapmaticPicture, Qt::AutoColor)); + ui->cmdExport->setEnabled(true); + } + if (picture->isJsonOk()) + { + locX = QString::number(picture->getSnapmaticProperties().location.x); + locY = QString::number(picture->getSnapmaticProperties().location.y); + locZ = QString::number(picture->getSnapmaticProperties().location.z); + crewID = crewDB->getCrewName(picture->getSnapmaticProperties().crewID); + created = picture->getSnapmaticProperties().createdDateTime.toString(Qt::DefaultLocaleShortDate); + plyrsList = picture->getSnapmaticProperties().playersList; + picTitl = picture->getPictureTitl(); + picArea = picture->getSnapmaticProperties().area; + if (globalMap.contains(picArea)) + { + picAreaStr = globalMap[picArea]; + } + else + { + picAreaStr = picArea; + } + + QString plyrsStr; + if (plyrsList.length() >= 1) + { + foreach (const QString &player, plyrsList) + { + QString playerName = profileDB->getPlayerName(player.toInt()); + plyrsStr.append(", "); + plyrsStr.append(playerName); + plyrsStr.append(""); + } + plyrsStr.remove(0,2); + } + else + { + plyrsStr = tr("No player"); + } + + if (crewID == "") { crewID = tr("No crew"); } + + this->setWindowTitle(windowTitleStr.arg(picture->getPictureStr())); + ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, plyrsStr, crewID, picTitl, picAreaStr, created)); + } + else + { + ui->labJSON->setText(jsonDrawString.arg("0.0", "0.0", "0.0", tr("No player"), tr("No crew"), tr("Unknown Location"))); + QMessageBox::warning(this,tr("Snapmatic Picture Viewer"),tr("Failed at %1").arg(picture->getLastStep())); + } + emit newPictureCommited(snapmaticPicture); +} + +void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, QString picPath, bool readOk) +{ + setSnapmaticPicture(picture, picPath, readOk, false, 0); +} + +void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, QString picPath) +{ + setSnapmaticPicture(picture, picPath, true); +} + +void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, bool readOk, int index) +{ + setSnapmaticPicture(picture, picture->getPictureFileName(), readOk, true, index); +} + +void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, bool readOk) +{ + setSnapmaticPicture(picture, picture->getPictureFileName(), readOk); +} + +void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture, int index) +{ + setSnapmaticPicture(picture, true, index); +} + +void PictureDialog::setSnapmaticPicture(SnapmaticPicture *picture) +{ + setSnapmaticPicture(picture, true); +} + +void PictureDialog::playerNameUpdated() +{ + if (plyrsList.count() >= 1) + { + QString plyrsStr; + foreach (const QString &player, plyrsList) + { + QString playerName = profileDB->getPlayerName(player.toInt()); + plyrsStr.append(", "); + plyrsStr.append(playerName); + plyrsStr.append(""); + } + plyrsStr.remove(0,2); + ui->labJSON->setText(jsonDrawString.arg(locX, locY, locZ, plyrsStr, crewID, picTitl, picAreaStr, created)); + } +} + +void PictureDialog::exportSnapmaticPicture() +{ + if (rqfullscreen && fullscreenWidget) + { + PictureExport::exportPicture(fullscreenWidget, smpic); + } + else + { + PictureExport::exportPicture(this, smpic); + } +} + +void PictureDialog::copySnapmaticPicture() +{ + if (rqfullscreen && fullscreenWidget) + { + PictureCopy::copyPicture(fullscreenWidget, picPath); + } + else + { + PictureCopy::copyPicture(this, picPath); + } +} + +void PictureDialog::on_labPicture_mouseDoubleClicked(Qt::MouseButton button) +{ + if (button == Qt::LeftButton) + { + QRect desktopRect = QApplication::desktop()->screenGeometry(this); + PictureWidget *pictureWidget = new PictureWidget(this); + pictureWidget->setObjectName("PictureWidget"); +#if QT_VERSION >= 0x050600 + pictureWidget->setWindowFlags(pictureWidget->windowFlags()^Qt::FramelessWindowHint^Qt::MaximizeUsingFullscreenGeometryHint); +#else + pictureWidget->setWindowFlags(pictureWidget->windowFlags()^Qt::FramelessWindowHint); +#endif + pictureWidget->setWindowTitle(this->windowTitle()); + pictureWidget->setStyleSheet("QLabel#pictureLabel{background-color: black;}"); + pictureWidget->setImage(snapmaticPicture, desktopRect); + pictureWidget->setModal(true); + + fullscreenWidget = pictureWidget; + QObject::connect(this, SIGNAL(newPictureCommited(QImage)), pictureWidget, SLOT(setImage(QImage))); + QObject::connect(pictureWidget, SIGNAL(nextPictureRequested()), this, SLOT(dialogNextPictureRequested())); + QObject::connect(pictureWidget, SIGNAL(previousPictureRequested()), this, SLOT(dialogPreviousPictureRequested())); + + pictureWidget->move(desktopRect.x(), desktopRect.y()); + pictureWidget->resize(desktopRect.width(), desktopRect.height()); + pictureWidget->showFullScreen(); + pictureWidget->setFocus(); + pictureWidget->raise(); + pictureWidget->exec(); + + fullscreenWidget = 0; + delete pictureWidget; + } +} + +void PictureDialog::on_labPicture_customContextMenuRequested(const QPoint &pos) +{ + exportCustomContextMenuRequestedPrivate(ui->labPicture->mapToGlobal(pos), false); +} + +bool PictureDialog::isIndexed() +{ + return indexed; +} + +int PictureDialog::getIndex() +{ + return index; +} diff --git a/PictureDialog.h b/PictureDialog.h old mode 100644 new mode 100755 index a35ebb4..a42883c --- a/PictureDialog.h +++ b/PictureDialog.h @@ -1,136 +1,108 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef PICTUREDIALOG_H -#define PICTUREDIALOG_H - -#include "SnapmaticPicture.h" -#include "ProfileDatabase.h" -#include "CrewDatabase.h" -#include -#include -#include -#include -#include -#include - -namespace Ui { -class PictureDialog; -} - -class PictureDialog : public QDialog -{ - Q_OBJECT -public: - explicit PictureDialog(ProfileDatabase *profileDB, CrewDatabase *crewDB, QWidget *parent = 0); - explicit PictureDialog(ProfileDatabase *profileDB, CrewDatabase *crewDB, QString profileName, QWidget *parent = 0); - explicit PictureDialog(bool primaryWindow, ProfileDatabase *profileDB, CrewDatabase *crewDB, QWidget *parent = 0); - explicit PictureDialog(bool primaryWindow, ProfileDatabase *profileDB, CrewDatabase *crewDB, QString profileName, QWidget *parent = 0); - void setupPictureDialog(); - void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk, bool indexed, int index); - void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk, int index); - void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk); - void setSnapmaticPicture(SnapmaticPicture *picture, int index); - void setSnapmaticPicture(SnapmaticPicture *picture); - void addPreviousNextButtons(); - void styliseDialog(); - bool isIndexed(); - int getIndex(); - ~PictureDialog(); - -public slots: - void adaptDialogSize(); - void crewNameUpdated(); - void playerNameUpdated(); - void dialogNextPictureRequested(); - void dialogPreviousPictureRequested(); - void exportCustomContextMenuRequested(const QPoint &pos); - -private slots: - void copySnapmaticPicture(); - void exportSnapmaticPicture(); - void triggerFullscreenDoubeClick(); - void on_labPicture_mouseDoubleClicked(Qt::MouseButton button); - void on_labPicture_customContextMenuRequested(const QPoint &pos); - void exportCustomContextMenuRequestedPrivate(const QPoint &pos, bool fullscreen); - void nextPictureRequestedSlot(); - void previousPictureRequestedSlot(); - void editSnapmaticProperties(); - void editSnapmaticRawJson(); - void editSnapmaticImage(); - void renderOverlayPicture(); - void renderPicture(); - void openPreviewMap(); - void updated(); - void customSignal(QString signal); - -signals: - void nextPictureRequested(); - void previousPictureRequested(); - void newPictureCommited(QImage picture); - void endDatabaseThread(); - -protected: - void closeEvent(QCloseEvent *ev); - bool eventFilter(QObject *obj, QEvent *ev); - void mousePressEvent(QMouseEvent *ev); -#ifdef Q_OS_WIN -#if QT_VERSION >= 0x060000 - bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result); -#elif QT_VERSION >= 0x050000 - bool nativeEvent(const QByteArray &eventType, void *message, long *result); -#endif -#endif - -private: - QString generateCrewString(); - QString generatePlayersString(); - bool primaryWindow; - ProfileDatabase *profileDB; - CrewDatabase *crewDB; - QString profileName; - Ui::PictureDialog *ui; - QMap globalMap; - SnapmaticPicture *smpic; - QWidget *fullscreenWidget; - QImage avatarAreaPicture; - QImage snapmaticPicture; - QImage overlayTempImage; - QString jsonDrawString; - QString windowTitleStr; - QString picAreaStr; - QString crewStr; - bool overlayEnabled; - bool rqFullscreen; - bool naviEnabled; - bool previewMode; - bool indexed; - int index; - int avatarLocX; - int avatarLocY; - int avatarSize; - QMenu *manageMenu; -#ifdef Q_OS_WIN -#if QT_VERSION >= 0x050000 - QPoint dragPosition; - bool dragStart; -#endif -#endif -}; - -#endif // PICTUREDIALOG_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef PICTUREDIALOG_H +#define PICTUREDIALOG_H + +#include "SnapmaticPicture.h" +#include "ProfileDatabase.h" +#include "CrewDatabase.h" +#include +#include +#include +#include + +namespace Ui { +class PictureDialog; +} + +class PictureDialog : public QDialog +{ + Q_OBJECT +public: + explicit PictureDialog(ProfileDatabase *profileDB, CrewDatabase *crewDB, QWidget *parent = 0); + void setSnapmaticPicture(SnapmaticPicture *picture, QString picPath, bool readOk, bool indexed, int index); + void setSnapmaticPicture(SnapmaticPicture *picture, QString picPath, bool readOk); + void setSnapmaticPicture(SnapmaticPicture *picture, QString picPath); + void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk, int index); + void setSnapmaticPicture(SnapmaticPicture *picture, bool readOk); + void setSnapmaticPicture(SnapmaticPicture *picture, int index); + void setSnapmaticPicture(SnapmaticPicture *picture); + void addPreviousNextButtons(); + void stylizeDialog(); + bool isIndexed(); + int getIndex(); + ~PictureDialog(); + +public slots: + void playerNameUpdated(); + void dialogNextPictureRequested(); + void dialogPreviousPictureRequested(); + void adaptNewDialogSize(QSize newLabelSize); + void exportCustomContextMenuRequested(const QPoint &pos); + +private slots: + void copySnapmaticPicture(); + void exportSnapmaticPicture(); + void triggerFullscreenDoubeClick(); + void on_labPicture_mouseDoubleClicked(Qt::MouseButton button); + void on_labPicture_customContextMenuRequested(const QPoint &pos); + void exportCustomContextMenuRequestedPrivate(const QPoint &pos, bool fullscreen); + void nextPictureRequestedSlot(); + void previousPictureRequestedSlot(); + +signals: + void nextPictureRequested(); + void previousPictureRequested(); + void newPictureCommited(QImage picture); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + void mousePressEvent(QMouseEvent *ev); + bool event(QEvent *event); + +private: + ProfileDatabase *profileDB; + CrewDatabase *crewDB; + Ui::PictureDialog *ui; + QMap globalMap; + SnapmaticPicture *smpic; + QWidget *fullscreenWidget; + QAction *jpegExportAction; + QAction *pgtaExportAction; + QImage snapmaticPicture; + QString jsonDrawString; + QString windowTitleStr; + QStringList plyrsList; + QString picAreaStr; + QString picArea; + QString picTitl; + QString picPath; + QString created; + QString crewID; + QString locX; + QString locY; + QString locZ; + bool rqfullscreen; + bool navienabled; + bool indexed; + int index; + QMenu *exportMenu; +}; + +#endif // PICTUREDIALOG_H diff --git a/PictureDialog.ui b/PictureDialog.ui old mode 100644 new mode 100755 index f324d84..ecf1214 --- a/PictureDialog.ui +++ b/PictureDialog.ui @@ -1,236 +1,244 @@ - - - PictureDialog - - - - 0 - 0 - 960 - 618 - - - - Snapmatic Picture Viewer - %1 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 1 - - - - Qt::CustomContextMenu - - - - - - Qt::AlignCenter - - - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 4 - - - 10 - - - 4 - - - 4 - - - - - - 0 - 0 - - - - <span style="font-weight:600">Title: </span>%6<br/> -<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Created: </span>%8 - - - true - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - 6 - - - 5 - - - 5 - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 0 - 0 - - - - - - - - 6 - - - - - - 0 - 0 - - - - Qt::NoFocus - - - Manage picture - - - &Manage - - - false - - - - - - - - 0 - 0 - - - - Qt::NoFocus - - - Close viewer - - - &Close - - - false - - - - - - - - - - - - - - - - - UiModLabel - QLabel -
uimod/UiModLabel.h
- - mouseMoved() - mouseReleased() - mousePressed() - mouseDoubleClicked() - -
-
- - - - cmdClose - clicked() - PictureDialog - close() - - - 912 - 514 - - - 479 - 267 - - - - -
+ + + PictureDialog + + + + 0 + 0 + 960 + 602 + + + + %1 - Snapmatic Picture Viewer + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 1 + + + + Qt::CustomContextMenu + + + + + + :/img/960x536.png + + + Qt::AlignCenter + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 4 + + + 10 + + + 4 + + + 4 + + + + + + 0 + 0 + + + + <span style=" font-weight:600;">Title: </span>%6<br/> +<span style=" font-weight:600;">Location: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Players: </span>%4 (Crew %5)<br/> +<span style=" font-weight:600;">Created: </span>%8 + + + true + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + 6 + + + 5 + + + 5 + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 0 + 0 + + + + + + + + 6 + + + + + + 0 + 0 + + + + Qt::NoFocus + + + Export picture + + + &Export + + + false + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + Close + + + &Close + + + + + + false + + + + + + + + + + + + + + + + + UiModLabel + QLabel +
uimod/UiModLabel.h
+ + mouseMoved() + mouseReleased() + mousePressed() + mouseDoubleClicked() + +
+
+ + + + + + cmdClose + clicked() + PictureDialog + close() + + + 912 + 514 + + + 479 + 267 + + + + +
diff --git a/PictureExport.cpp b/PictureExport.cpp old mode 100644 new mode 100755 index 8101ddd..2007c28 --- a/PictureExport.cpp +++ b/PictureExport.cpp @@ -1,308 +1,200 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2020 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "config.h" -#include "AppEnv.h" -#include "PictureExport.h" -#include "PictureDialog.h" -#include "StandardPaths.h" -#include "SidebarGenerator.h" -#include -#include -#include -#include -#include -#include - -#if QT_VERSION < 0x050000 -#include -#endif - -#if QT_VERSION >= 0x050000 -#include -#include -#endif - -PictureExport::PictureExport() -{ -} - -void PictureExport::exportAsPicture(QWidget *parent, SnapmaticPicture *picture) -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - - // Picture Settings - // Quality Settings - settings.beginGroup("Pictures"); - int defaultQuality = 100; - QSize defExportSize = SnapmaticPicture::getSnapmaticResolution(); - int customQuality = settings.value("CustomQuality", defaultQuality).toInt(); - if (customQuality < 1 || customQuality > 100) { - customQuality = 100; - } - bool useCustomQuality = settings.value("CustomQualityEnabled", false).toBool(); - - // Size Settings - QSize cusExportSize = settings.value("CustomSize", defExportSize).toSize(); - if (cusExportSize.width() > 3840) { - cusExportSize.setWidth(3840); - } - else if (cusExportSize.height() > 2160) { - cusExportSize.setHeight(2160); - } - if (cusExportSize.width() < 1) { - cusExportSize.setWidth(1); - } - else if (cusExportSize.height() < 1) { - cusExportSize.setHeight(1); - } - QString sizeMode = settings.value("ExportSizeMode", "Default").toString(); - Qt::AspectRatioMode aspectRatio = (Qt::AspectRatioMode)settings.value("AspectRatio", Qt::KeepAspectRatio).toInt(); - QString defaultExportFormat = settings.value("DefaultExportFormat", ".jpg").toString(); - settings.endGroup(); - // End Picture Settings - - settings.beginGroup("FileDialogs"); - bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool(); - settings.beginGroup("ExportAsPicture"); - -fileDialogPreSave: //Work? - QFileDialog fileDialog(parent); - fileDialog.setFileMode(QFileDialog::AnyFile); - fileDialog.setViewMode(QFileDialog::Detail); - fileDialog.setAcceptMode(QFileDialog::AcceptSave); - fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog); - fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true); - fileDialog.setDefaultSuffix("suffix"); - fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); - fileDialog.setWindowTitle(PictureDialog::tr("Export as Picture...")); - fileDialog.setLabelText(QFileDialog::Accept, PictureDialog::tr("Export")); - - QStringList filters; - filters << PictureDialog::tr("JPEG Graphics (*.jpg *.jpeg)"); - filters << PictureDialog::tr("Portable Network Graphics (*.png)"); - fileDialog.setNameFilters(filters); - - QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); - - fileDialog.setSidebarUrls(sidebarUrls); - fileDialog.setDirectory(settings.value("Directory", StandardPaths::picturesLocation()).toString()); - fileDialog.restoreGeometry(settings.value(parent->objectName() % "+Geometry", "").toByteArray()); - - QString newPictureFileName = getPictureFileName(picture) % defaultExportFormat; - fileDialog.selectFile(newPictureFileName); - - if (fileDialog.exec()) { - QStringList selectedFiles = fileDialog.selectedFiles(); - if (selectedFiles.length() == 1) { - QString saveFileFormat; - QString selectedFile = selectedFiles.at(0); - - if (selectedFile.right(4) == ".jpg") { - saveFileFormat = "JPEG"; - } - else if (selectedFile.right(4) == ".jpeg") { - saveFileFormat = "JPEG"; - } - else if (selectedFile.right(4) == ".png") { - saveFileFormat = "PNG"; - } - else if (selectedFile.right(7) == ".suffix") { - if (fileDialog.selectedNameFilter() == "JPEG picture (*.jpg)") { - selectedFile.replace(".suffix", ".jpg"); - } - else if (fileDialog.selectedNameFilter() == "Portable Network Graphics (*.png)") { - selectedFile.replace(".suffix", ".png"); - } - else { - selectedFile.replace(".suffix", ".jpg"); - } - } - - if (QFile::exists(selectedFile)) { - if (QMessageBox::No == QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Overwrite %1 with current Snapmatic picture?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) { - goto fileDialogPreSave; //Work? - } - } - - // Scale Picture - QImage exportPicture = picture->getImage(); - if (sizeMode == "Desktop") { -#if QT_VERSION >= 0x050000 - qreal screenRatioPR = AppEnv::screenRatioPR(); - QRect desktopResolution = QApplication::primaryScreen()->geometry(); - int desktopSizeWidth = qRound((double)desktopResolution.width() * screenRatioPR); - int desktopSizeHeight = qRound((double)desktopResolution.height() * screenRatioPR); -#else - QRect desktopResolution = QApplication::desktop()->screenGeometry(); - int desktopSizeWidth = desktopResolution.width(); - int desktopSizeHeight = desktopResolution.height(); -#endif - exportPicture = exportPicture.scaled(desktopSizeWidth, desktopSizeHeight, aspectRatio, Qt::SmoothTransformation); - } - else if (sizeMode == "Custom") { - exportPicture = exportPicture.scaled(cusExportSize, aspectRatio, Qt::SmoothTransformation); - } - - int errorId = 0; - bool isSaved = false; -#if QT_VERSION >= 0x050000 - QSaveFile *picFile = new QSaveFile(selectedFile); -#else - QFile *picFile = new QFile(selectedFile); -#endif - if (picFile->open(QIODevice::WriteOnly)) { - isSaved = exportPicture.save(picFile, saveFileFormat.toStdString().c_str(), useCustomQuality ? customQuality : defaultQuality); -#if QT_VERSION >= 0x050000 - if (isSaved) { - isSaved = picFile->commit(); - } - else { - errorId = 1; - } -#else - picFile->close(); -#endif - } - else { - errorId = 2; - } - delete picFile; - - if (!isSaved) { - switch (errorId) { - case 0: - QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Failed to export the picture because the system occurred a write failure")); - break; - case 1: - QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Failed to export the picture because the format detection failures")); - break; - case 2: - QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Failed to export the picture because the file can't be written")); - break; - default: - QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("Failed to export the picture because of an unknown reason")); - } - goto fileDialogPreSave; //Work? - } - } - else { - QMessageBox::warning(parent, PictureDialog::tr("Export as Picture"), PictureDialog::tr("No valid file is selected")); - goto fileDialogPreSave; //Work? - } - } - - settings.setValue(parent->objectName() % "+Geometry", fileDialog.saveGeometry()); - settings.setValue("Directory", fileDialog.directory().absolutePath()); - settings.endGroup(); - settings.endGroup(); -} - -void PictureExport::exportAsSnapmatic(QWidget *parent, SnapmaticPicture *picture) -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("FileDialogs"); - bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool(); - settings.beginGroup("ExportAsSnapmatic"); - - QString adjustedPicPath = picture->getOriginalPictureFileName(); - -fileDialogPreSave: //Work? - QFileInfo sgdFileInfo(adjustedPicPath); - QFileDialog fileDialog(parent); - fileDialog.setFileMode(QFileDialog::AnyFile); - fileDialog.setViewMode(QFileDialog::Detail); - fileDialog.setAcceptMode(QFileDialog::AcceptSave); - fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog); - fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true); - fileDialog.setDefaultSuffix(".rem"); - fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); - fileDialog.setWindowTitle(PictureDialog::tr("Export as Snapmatic...")); - fileDialog.setLabelText(QFileDialog::Accept, PictureDialog::tr("Export")); - - QStringList filters; - filters << PictureDialog::tr("GTA V Export (*.g5e)"); -#ifndef GTA5SYNC_FLATPAK - filters << PictureDialog::tr("GTA V Raw Export (*.auto)"); -#endif - filters << PictureDialog::tr("Snapmatic pictures (PGTA*)"); - fileDialog.setNameFilters(filters); - - QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); - - fileDialog.setSidebarUrls(sidebarUrls); - fileDialog.setDirectory(settings.value("Directory", StandardPaths::documentsLocation()).toString()); - fileDialog.restoreGeometry(settings.value(parent->objectName() % "+Geometry", "").toByteArray()); - fileDialog.selectFile(QString(picture->getExportPictureFileName() % ".g5e")); - - if (fileDialog.exec()) { - QStringList selectedFiles = fileDialog.selectedFiles(); - if (selectedFiles.length() == 1) { - QString selectedFile = selectedFiles.at(0); - bool isAutoExt = false; -#ifndef GTA5SYNC_FLATPAK - if (selectedFile.right(5) == ".auto") { - isAutoExt = true; - QString dirPath = QFileInfo(selectedFile).dir().path(); - QString stockFileName = sgdFileInfo.fileName(); - selectedFile = dirPath % "/" % stockFileName; - } -#endif - if (selectedFile.right(4) == ".rem") { - selectedFile.remove(selectedFile.length() - 4, 4); - } - - if (QFile::exists(selectedFile)) { - if (QMessageBox::No == QMessageBox::warning(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("Overwrite %1 with current Snapmatic picture?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) { - goto fileDialogPreSave; //Work? - } - } - - if (selectedFile.right(4) == ".g5e") { - bool isExported = picture->exportPicture(selectedFile, SnapmaticFormat::G5E_Format); - if (!isExported) { - QMessageBox::warning(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("Failed to export current Snapmatic picture")); - goto fileDialogPreSave; //Work? - } - } - else { - bool isCopied = picture->exportPicture(selectedFile, SnapmaticFormat::PGTA_Format); - if (!isCopied) { - QMessageBox::warning(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("Failed to export current Snapmatic picture")); - goto fileDialogPreSave; //Work? - } - else { - if (isAutoExt) QMessageBox::information(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("Exported Snapmatic to \"%1\" because of using the .auto extension.").arg(selectedFile)); - } - } - } - else { - QMessageBox::warning(parent, PictureDialog::tr("Export as Snapmatic"), PictureDialog::tr("No valid file is selected")); - goto fileDialogPreSave; //Work? - } - } - - settings.setValue(parent->objectName() % "+Geometry", fileDialog.saveGeometry()); - settings.setValue("Directory", fileDialog.directory().absolutePath()); - settings.endGroup(); -} - -QString PictureExport::getPictureFileName(SnapmaticPicture *picture) -{ - return picture->getExportPictureFileName(); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "config.h" +#include "PictureExport.h" +#include "PictureDialog.h" +#include "StandardPaths.h" +#include "SidebarGenerator.h" +#include +#include +#include +#include +#include +#include + +PictureExport::PictureExport() +{ + +} + +void PictureExport::exportPicture(QWidget *parent, SnapmaticPicture *picture) +{ + QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + + // Picture Settings + // Quality Settings + settings.beginGroup("Pictures"); + int defaultQuality = 100; + QSize defExportSize = QSize(960, 536); + int customQuality = settings.value("CustomQuality", defaultQuality).toInt(); + if (customQuality < 1 || customQuality > 100) + { + customQuality = 100; + } + bool useCustomQuality = settings.value("CustomQualityEnabled", false).toBool(); + + // Size Settings + QSize cusExportSize = settings.value("CustomSize", defExportSize).toSize(); + if (cusExportSize.width() > 3840) + { + cusExportSize.setWidth(3840); + } + else if (cusExportSize.height() > 2160) + { + cusExportSize.setHeight(2160); + } + if (cusExportSize.width() < 1) + { + cusExportSize.setWidth(1); + } + else if (cusExportSize.height() < 1) + { + cusExportSize.setHeight(1); + } + QString sizeMode = settings.value("ExportSizeMode", "Default").toString(); + Qt::AspectRatioMode aspectRatio = (Qt::AspectRatioMode)settings.value("AspectRatio", Qt::KeepAspectRatio).toInt(); + settings.endGroup(); + // End Picture Settings + + settings.beginGroup("FileDialogs"); + settings.beginGroup("ExportPicture"); + +fileDialogPreSave: + QFileDialog fileDialog(parent); + fileDialog.setFileMode(QFileDialog::AnyFile); + fileDialog.setViewMode(QFileDialog::Detail); + fileDialog.setAcceptMode(QFileDialog::AcceptSave); + fileDialog.setOption(QFileDialog::DontUseNativeDialog, false); + fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true); + fileDialog.setDefaultSuffix("suffix"); + fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); + fileDialog.setWindowTitle(PictureDialog::tr("Export as JPG picture...")); + fileDialog.setLabelText(QFileDialog::Accept, PictureDialog::tr("Export")); + + QStringList filters; + filters << PictureDialog::tr("JPEG picture (*.jpg)"); + filters << PictureDialog::tr("Portable Network Graphics (*.png)"); + fileDialog.setNameFilters(filters); + + QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); + + fileDialog.setSidebarUrls(sidebarUrls); + fileDialog.setDirectory(settings.value("Directory", StandardPaths::picturesLocation()).toString()); + fileDialog.restoreGeometry(settings.value(parent->objectName() + "+Geomtery", "").toByteArray()); + + QString newPictureFileName = getPictureFileName(picture); + fileDialog.selectFile(newPictureFileName); + + if (fileDialog.exec()) + { + QStringList selectedFiles = fileDialog.selectedFiles(); + if (selectedFiles.length() == 1) + { + QString saveFileFormat; + QString selectedFile = selectedFiles.at(0); + + if (selectedFile.right(4) == ".jpg") + { + saveFileFormat = "JPEG"; + } + else if (selectedFile.right(4) == ".jpeg") + { + saveFileFormat = "JPEG"; + } + else if (selectedFile.right(4) == ".png") + { + saveFileFormat = "PNG"; + } + else if (selectedFile.right(7) == ".suffix") + { + if (fileDialog.selectedNameFilter() == "JPEG picture (*.jpg)") + { + selectedFile.replace(".suffix", ".jpg"); + } + else if (fileDialog.selectedNameFilter() == "Portable Network Graphics (*.png)") + { + selectedFile.replace(".suffix", ".png"); + } + else + { + selectedFile.replace(".suffix", ".jpg"); + } + } + + if (QFile::exists(selectedFile)) + { + if (QMessageBox::Yes == QMessageBox::warning(parent, PictureDialog::tr("Export as JPG picture"), PictureDialog::tr("Overwrite %1 with current Snapmatic picture?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) + { + if (!QFile::remove(selectedFile)) + { + QMessageBox::warning(parent, PictureDialog::tr("Export as JPG picture"), PictureDialog::tr("Failed to overwrite %1 with current Snapmatic picture").arg("\""+selectedFile+"\"")); + goto fileDialogPreSave; + } + } + else + { + goto fileDialogPreSave; + } + } + + // Scale Picture + QImage exportPicture = picture->getPicture(); + if (sizeMode == "Desktop") + { + QRect desktopResolution = QApplication::desktop()->screenGeometry(); + exportPicture = exportPicture.scaled(desktopResolution.width(), desktopResolution.height(), aspectRatio, Qt::SmoothTransformation); + } + else if (sizeMode == "Custom") + { + exportPicture = exportPicture.scaled(cusExportSize, aspectRatio, Qt::SmoothTransformation); + } + + bool isSaved; + if (useCustomQuality) + { + isSaved = exportPicture.save(selectedFile, saveFileFormat.toStdString().c_str(), customQuality); + } + else + { + isSaved = exportPicture.save(selectedFile, saveFileFormat.toStdString().c_str(), 100); + } + + if (!isSaved) + { + QMessageBox::warning(parent, PictureDialog::tr("Export as JPG picture"), PictureDialog::tr("Failed to export current Snapmatic picture")); + goto fileDialogPreSave; + } + } + else + { + QMessageBox::warning(parent, PictureDialog::tr("Export as JPG picture"), PictureDialog::tr("No valid file is selected")); + goto fileDialogPreSave; + } + } + + settings.setValue(parent->objectName() + "+Geometry", fileDialog.saveGeometry()); + settings.setValue("Directory", fileDialog.directory().absolutePath()); + settings.endGroup(); + settings.endGroup(); +} + +QString PictureExport::getPictureFileName(SnapmaticPicture *picture) +{ + return picture->getExportPictureFileName(); +} diff --git a/PictureExport.h b/PictureExport.h old mode 100644 new mode 100755 index 623f093..76e224e --- a/PictureExport.h +++ b/PictureExport.h @@ -1,35 +1,34 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef PICTUREEXPORT_H -#define PICTUREEXPORT_H - -#include "SnapmaticPicture.h" -#include -#include - -class PictureExport -{ -public: - PictureExport(); - static void exportAsPicture(QWidget *parent, SnapmaticPicture *picture); - static void exportAsSnapmatic(QWidget *parent, SnapmaticPicture *picture); - static QString getPictureFileName(SnapmaticPicture *picture); -}; - -#endif // PICTUREEXPORT_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef PICTUREEXPORT_H +#define PICTUREEXPORT_H + +#include "SnapmaticPicture.h" +#include +#include + +class PictureExport +{ +public: + PictureExport(); + static void exportPicture(QWidget *parent, SnapmaticPicture *picture); + static QString getPictureFileName(SnapmaticPicture *picture); +}; + +#endif // PICTUREEXPORT_H diff --git a/PictureWidget.cpp b/PictureWidget.cpp index 49bdb8b..5811f0c 100644 --- a/PictureWidget.cpp +++ b/PictureWidget.cpp @@ -1,6 +1,6 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2020 Syping +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,12 +19,13 @@ #include "PictureDialog.h" #include "PictureWidget.h" #include "UiModLabel.h" -#include "AppEnv.h" +#include #include #include #include #include #include +#include PictureWidget::PictureWidget(QWidget *parent) : QDialog(parent) { @@ -43,6 +44,7 @@ PictureWidget::PictureWidget(QWidget *parent) : QDialog(parent) QObject::connect(pictureLabel, SIGNAL(mouseDoubleClicked(Qt::MouseButton)), this, SLOT(pictureDoubleClicked(Qt::MouseButton))); QObject::connect(pictureLabel, SIGNAL(customContextMenuRequested(QPoint)), parent, SLOT(exportCustomContextMenuRequested(QPoint))); + QObject::connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(updateWindowSize(int))); setLayout(widgetLayout); } @@ -56,10 +58,12 @@ PictureWidget::~PictureWidget() bool PictureWidget::eventFilter(QObject *obj, QEvent *ev) { - if (obj == this) { - if (ev->type() == QEvent::KeyPress) { + if (obj == this) + { + if (ev->type() == QEvent::KeyPress) + { QKeyEvent *keyEvent = (QKeyEvent*)ev; - switch (keyEvent->key()) { + switch (keyEvent->key()){ case Qt::Key_Left: emit previousPictureRequested(); break; @@ -74,29 +78,32 @@ bool PictureWidget::eventFilter(QObject *obj, QEvent *ev) void PictureWidget::pictureDoubleClicked(Qt::MouseButton button) { - if (button == Qt::LeftButton) { + if (button == Qt::LeftButton) + { close(); } } void PictureWidget::setImage(QImage image_, QRect rec) { - const qreal screenRatioPR = AppEnv::screenRatioPR(); image = image_; - QPixmap pixmap = QPixmap::fromImage(image.scaled(rec.width() * screenRatioPR, rec.height() * screenRatioPR, Qt::KeepAspectRatio, Qt::SmoothTransformation)); -#if QT_VERSION >= 0x050600 - pixmap.setDevicePixelRatio(AppEnv::screenRatioPR()); -#endif - pictureLabel->setPixmap(pixmap); + pictureLabel->setPixmap(QPixmap::fromImage(image.scaled(rec.width(), rec.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation))); } void PictureWidget::setImage(QImage image_) { - const qreal screenRatioPR = AppEnv::screenRatioPR(); image = image_; - QPixmap pixmap = QPixmap::fromImage(image.scaled(geometry().width() * screenRatioPR, geometry().height() * screenRatioPR, Qt::KeepAspectRatio, Qt::SmoothTransformation)); -#if QT_VERSION >= 0x050600 - pixmap.setDevicePixelRatio(screenRatioPR); -#endif - pictureLabel->setPixmap(pixmap); + pictureLabel->setPixmap(QPixmap::fromImage(image.scaled(geometry().width(), geometry().height(), Qt::KeepAspectRatio, Qt::SmoothTransformation))); +} + +void PictureWidget::updateWindowSize(int screenID) +{ + if (screenID == QApplication::desktop()->screenNumber(this)) + { + QRect desktopRect = QApplication::desktop()->screenGeometry(this); + this->move(desktopRect.x(), desktopRect.y()); + this->resize(desktopRect.width(), desktopRect.height()); + this->showFullScreen(); + pictureLabel->setPixmap(QPixmap::fromImage(image.scaled(desktopRect.width(), desktopRect.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation))); + } } diff --git a/PictureWidget.h b/PictureWidget.h index d2e64f3..f9066d9 100644 --- a/PictureWidget.h +++ b/PictureWidget.h @@ -1,6 +1,6 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,6 +46,7 @@ private: private slots: void pictureDoubleClicked(Qt::MouseButton button); + void updateWindowSize(int screenID); signals: void nextPictureRequested(); diff --git a/PlayerListDialog.cpp b/PlayerListDialog.cpp deleted file mode 100644 index 7c1b9a3..0000000 --- a/PlayerListDialog.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "PlayerListDialog.h" -#include "ui_PlayerListDialog.h" -#include "wrapper.h" -#include "AppEnv.h" -#include -#include -#include -#include -#include -#include -#include - -PlayerListDialog::PlayerListDialog(QStringList players, ProfileDatabase *profileDB, QWidget *parent) : - QDialog(parent), players(players), profileDB(profileDB), - ui(new Ui::PlayerListDialog) -{ - // Set Window Flags -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - - listUpdated = false; - ui->setupUi(this); - ui->cmdCancel->setDefault(true); - ui->cmdCancel->setFocus(); - - // Set Icon for Apply Button - if (QIcon::hasThemeIcon("dialog-ok-apply")) { - ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok-apply")); - } - else if (QIcon::hasThemeIcon("dialog-apply")) { - ui->cmdApply->setIcon(QIcon::fromTheme("dialog-apply")); - } - else if (QIcon::hasThemeIcon("gtk-apply")) { - ui->cmdApply->setIcon(QIcon::fromTheme("gtk-apply")); - } - else if (QIcon::hasThemeIcon("dialog-ok")) { - ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok")); - } - else if (QIcon::hasThemeIcon("gtk-ok")) { - ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok")); - } - - // Set Icon for Cancel Button - if (QIcon::hasThemeIcon("dialog-cancel")) { - ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel")); - } - else if (QIcon::hasThemeIcon("gtk-cancel")) { - ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel")); - } - - // Set Icon for Manage Buttons - if (QIcon::hasThemeIcon("go-previous") && QIcon::hasThemeIcon("go-next") && QIcon::hasThemeIcon("list-add")) { -#if QT_VERSION < 0x050600 - qreal screenRatio = AppEnv::screenRatio(); - if (screenRatio != 1) { - QSize iconSize = ui->cmdMakeAv->iconSize(); - iconSize = QSize(iconSize.width() * screenRatio, iconSize.height() * screenRatio); - ui->cmdMakeAv->setIconSize(iconSize); - ui->cmdMakeSe->setIconSize(iconSize); - ui->cmdMakeAd->setIconSize(iconSize); - } -#endif - ui->cmdMakeAv->setIcon(QIcon::fromTheme("go-previous")); - ui->cmdMakeSe->setIcon(QIcon::fromTheme("go-next")); - ui->cmdMakeAd->setIcon(QIcon::fromTheme("list-add")); - } - else { -#if QT_VERSION < 0x050600 - qreal screenRatio = AppEnv::screenRatio(); - if (screenRatio != 1) { - QSize iconSize = ui->cmdMakeAv->iconSize(); - iconSize = QSize(iconSize.width() * screenRatio, iconSize.height() * screenRatio); - ui->cmdMakeAv->setIconSize(iconSize); - ui->cmdMakeSe->setIconSize(iconSize); - ui->cmdMakeAd->setIconSize(iconSize); - } -#endif - ui->cmdMakeAv->setIcon(QIcon(AppEnv::getImagesFolder() % "/back.svgz")); - ui->cmdMakeSe->setIcon(QIcon(AppEnv::getImagesFolder() % "/next.svgz")); - ui->cmdMakeAd->setIcon(QIcon(AppEnv::getImagesFolder() % "/add.svgz")); - } - buildInterface(); - - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); - resize(500 * screenRatio, 350 * screenRatio); -} - -PlayerListDialog::~PlayerListDialog() -{ - for (QObject *object : ui->listAvPlayers->children()) { - delete object; - } - for (QObject *object : ui->listSePlayers->children()) { - delete object; - } - delete ui; -} - -void PlayerListDialog::on_cmdCancel_clicked() -{ - close(); -} - -void PlayerListDialog::buildInterface() -{ - const QStringList dbPlayers = profileDB->getPlayers(); - for (const QString &sePlayer : qAsConst(players)) { - QListWidgetItem *playerItem = new QListWidgetItem(profileDB->getPlayerName(sePlayer)); - playerItem->setData(Qt::UserRole, sePlayer); - ui->listSePlayers->addItem(playerItem); - } - for (const QString &dbPlayer : dbPlayers) { - if (!players.contains(dbPlayer)) { - QListWidgetItem *playerItem = new QListWidgetItem(profileDB->getPlayerName(dbPlayer)); - playerItem->setData(Qt::UserRole, dbPlayer); - ui->listAvPlayers->addItem(playerItem); - } - } - ui->listAvPlayers->sortItems(Qt::AscendingOrder); -} - -void PlayerListDialog::on_cmdMakeAv_clicked() -{ - for (QListWidgetItem *item : ui->listSePlayers->selectedItems()) { - QString playerName = item->text(); - int playerID = item->data(Qt::UserRole).toInt(); - delete item; - QListWidgetItem *playerItem = new QListWidgetItem(playerName); - playerItem->setData(Qt::UserRole, playerID); - ui->listAvPlayers->addItem(playerItem); - ui->listAvPlayers->sortItems(Qt::AscendingOrder); - } -} - -void PlayerListDialog::on_cmdMakeSe_clicked() -{ - int maxPlayers = 30; - if (maxPlayers < ui->listSePlayers->count() + ui->listAvPlayers->selectedItems().count()) { - QMessageBox::warning(this, tr("Add Players..."), tr("Failed to add more Players because the limit of Players are %1!").arg(QString::number(maxPlayers))); - return; - } - for (QListWidgetItem *item : ui->listAvPlayers->selectedItems()) { - QString playerName = item->text(); - int playerID = item->data(Qt::UserRole).toInt(); - delete item; - QListWidgetItem *playerItem = new QListWidgetItem(playerName); - playerItem->setData(Qt::UserRole, playerID); - ui->listSePlayers->addItem(playerItem); - } -} - -void PlayerListDialog::on_cmdMakeAd_clicked() -{ - bool playerOk; - int playerID = QInputDialog::getInt(this, tr("Add Player..."), tr("Enter Social Club Player ID"), 1, 1, 214783647, 1, &playerOk, windowFlags()); - if (playerOk) { - for (int i = 0; i < ui->listAvPlayers->count(); ++i) { - QListWidgetItem *item = ui->listAvPlayers->item(i); - QString itemPlayerName = item->text(); - int itemPlayerID = item->data(Qt::UserRole).toInt(); - if (itemPlayerID == playerID) { - delete item; - QListWidgetItem *playerItem = new QListWidgetItem(itemPlayerName); - playerItem->setData(Qt::UserRole, playerID); - ui->listSePlayers->addItem(playerItem); - return; - } - } - for (int i = 0; i < ui->listSePlayers->count(); ++i) { - QListWidgetItem *item = ui->listSePlayers->item(i); - int itemPlayerID = item->data(Qt::UserRole).toInt(); - if (itemPlayerID == playerID) - { - QMessageBox::warning(this, tr("Add Player..."), tr("Failed to add Player %1 because Player %1 is already added!").arg(QString::number(playerID))); - return; - } - } - QListWidgetItem *playerItem = new QListWidgetItem(QString::number(playerID)); - playerItem->setData(Qt::UserRole, playerID); - ui->listSePlayers->addItem(playerItem); - } -} - -void PlayerListDialog::on_cmdApply_clicked() -{ - players.clear(); - for (int i = 0; i < ui->listSePlayers->count(); ++i) { - players += ui->listSePlayers->item(i)->data(Qt::UserRole).toString(); - } - emit playerListUpdated(players); - listUpdated = true; - close(); -} - -QStringList PlayerListDialog::getPlayerList() const -{ - return players; -} - -bool PlayerListDialog::isListUpdated() -{ - return listUpdated; -} diff --git a/PlayerListDialog.h b/PlayerListDialog.h deleted file mode 100644 index c341a22..0000000 --- a/PlayerListDialog.h +++ /dev/null @@ -1,57 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef PLAYERLISTDIALOG_H -#define PLAYERLISTDIALOG_H - -#include "ProfileDatabase.h" -#include - -namespace Ui { -class PlayerListDialog; -} - -class PlayerListDialog : public QDialog -{ - Q_OBJECT - -public: - explicit PlayerListDialog(QStringList players, ProfileDatabase *profileDB, QWidget *parent = 0); - QStringList getPlayerList() const; - bool isListUpdated(); - ~PlayerListDialog(); - -private slots: - void on_cmdCancel_clicked(); - void on_cmdMakeAv_clicked(); - void on_cmdMakeSe_clicked(); - void on_cmdMakeAd_clicked(); - void on_cmdApply_clicked(); - -private: - QStringList players; - ProfileDatabase *profileDB; - Ui::PlayerListDialog *ui; - bool listUpdated; - void buildInterface(); - -signals: - void playerListUpdated(QStringList playerList); -}; - -#endif // PLAYERLISTDIALOG_H diff --git a/PlayerListDialog.ui b/PlayerListDialog.ui deleted file mode 100644 index 3bdda4c..0000000 --- a/PlayerListDialog.ui +++ /dev/null @@ -1,173 +0,0 @@ - - - PlayerListDialog - - - - 0 - 0 - 500 - 350 - - - - Edit Players... - - - - - - - - - - Available Players: - - - - - - - QAbstractItemView::ExtendedSelection - - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - Qt::NoFocus - - - false - - - - - - - Qt::NoFocus - - - - - - false - - - - - - - Qt::NoFocus - - - - - - false - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - - Selected Players: - - - - - - - QAbstractItemView::InternalMove - - - QAbstractItemView::ExtendedSelection - - - - - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - &Apply - - - - - - - - 0 - 0 - - - - &Cancel - - - - - - - - - - diff --git a/ProfileDatabase.cpp b/ProfileDatabase.cpp old mode 100644 new mode 100755 index 09ff581..a809c82 --- a/ProfileDatabase.cpp +++ b/ProfileDatabase.cpp @@ -1,85 +1,61 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "ProfileDatabase.h" -#include "StandardPaths.h" -#include "config.h" -#include -#include -#include -#include -#include - -ProfileDatabase::ProfileDatabase(QObject *parent) : QObject(parent) -{ - QDir dir; - dir.mkpath(StandardPaths::dataLocation()); - dir.setPath(StandardPaths::dataLocation()); - QString dirPath = dir.absolutePath(); - QString defaultConfPath = dirPath % "/players.ini"; - - QSettings confPathSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - confPathSettings.beginGroup("Database"); - QString confPathFile = confPathSettings.value("Players", defaultConfPath).toString(); - confPathSettings.endGroup(); - - profileDB = new QSettings(confPathFile, QSettings::IniFormat); - profileDB->beginGroup("Players"); -} - -ProfileDatabase::~ProfileDatabase() -{ - profileDB->endGroup(); - delete profileDB; -} - -QStringList ProfileDatabase::getPlayers() -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "getPlayers"; -#endif - return profileDB->childKeys(); -} - -QString ProfileDatabase::getPlayerName(QString playerID) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "getPlayerName" << playerID; -#endif - return profileDB->value(playerID, playerID).toString(); -} - -QString ProfileDatabase::getPlayerName(int playerID) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "getPlayerName" << playerID; -#endif - return profileDB->value(QString::number(playerID), playerID).toString(); -} - -void ProfileDatabase::setPlayerName(int playerID, QString playerName) -{ - QMutexLocker locker(&mutex); -#ifdef GTA5SYNC_DEBUG - qDebug() << "setPlayerName" << playerID << playerName; -#endif - profileDB->setValue(QString::number(playerID), playerName); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "ProfileDatabase.h" +#include "StandardPaths.h" +#include "config.h" +#include +#include + +ProfileDatabase::ProfileDatabase(QObject *parent) : QObject(parent) +{ + QDir dir; + dir.mkpath(StandardPaths::dataLocation()); + dir.setPath(StandardPaths::dataLocation()); + QString dirPath = dir.absolutePath(); + QString defaultConfPath = dirPath + QDir::separator() + "players.ini"; + + QSettings confPathSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + confPathSettings.beginGroup("Database"); + QString confPathFile = confPathSettings.value("Players", defaultConfPath).toString(); + confPathSettings.endGroup(); + + profileDB = new QSettings(confPathFile, QSettings::IniFormat); + profileDB->beginGroup("Players"); +} + +ProfileDatabase::~ProfileDatabase() +{ + profileDB->endGroup(); + delete profileDB; +} + +QStringList ProfileDatabase::getPlayers() +{ + return profileDB->childKeys(); +} + +QString ProfileDatabase::getPlayerName(int playerID) +{ + return profileDB->value(QString::number(playerID), playerID).toString(); +} + +void ProfileDatabase::setPlayerName(int playerID, QString playerName) +{ + profileDB->setValue(QString::number(playerID), playerName); +} diff --git a/ProfileDatabase.h b/ProfileDatabase.h old mode 100644 new mode 100755 index 99bfc80..e32b1c4 --- a/ProfileDatabase.h +++ b/ProfileDatabase.h @@ -1,46 +1,43 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef PROFILEDATABASE_H -#define PROFILEDATABASE_H - -#include -#include -#include -#include - -class ProfileDatabase : public QObject -{ - Q_OBJECT -public: - explicit ProfileDatabase(QObject *parent = 0); - QString getPlayerName(QString playerID); - QString getPlayerName(int playerID); - QStringList getPlayers(); - ~ProfileDatabase(); - -private: - mutable QMutex mutex; - QSettings *profileDB; - -public slots: - void setPlayerName(int playerID, QString playerName); - -}; - -#endif // PROFILEDATABASE_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef PROFILEDATABASE_H +#define PROFILEDATABASE_H + +#include +#include +#include + +class ProfileDatabase : public QObject +{ + Q_OBJECT +public: + explicit ProfileDatabase(QObject *parent = 0); + QString getPlayerName(int playerID); + QStringList getPlayers(); + ~ProfileDatabase(); + +private: + QSettings *profileDB; + +public slots: + void setPlayerName(int playerID, QString playerName); + +}; + +#endif // PROFILEDATABASE_H diff --git a/ProfileInterface.cpp b/ProfileInterface.cpp old mode 100644 new mode 100755 index 8eca40a..188dd87 --- a/ProfileInterface.cpp +++ b/ProfileInterface.cpp @@ -1,6 +1,6 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2022 Syping +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +18,6 @@ #include "ProfileInterface.h" #include "ui_ProfileInterface.h" -#include "PlayerListDialog.h" #include "SidebarGenerator.h" #include "SnapmaticWidget.h" #include "DatabaseThread.h" @@ -28,53 +27,26 @@ #include "StandardPaths.h" #include "ProfileLoader.h" #include "ExportThread.h" -#include "ImportDialog.h" -#include "UiModLabel.h" -#include "pcg_basic.h" -#include "wrapper.h" -#include "AppEnv.h" #include "config.h" -#include #include -#include -#include -#include -#include #include #include #include #include #include -#include #include -#include #include #include -#include #include -#include -#include +#include +#include #include #include #include -#include #include #include #include -#include -#include -#include - -#ifdef GTA5SYNC_TELEMETRY -#include "TelemetryClass.h" -#include -#include -#endif - -#define importTimeFormat "HHmmss" -#define findRetryLimit 500 - ProfileInterface::ProfileInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent) : QWidget(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), ui(new Ui::ProfileInterface) @@ -86,94 +58,38 @@ ProfileInterface::ProfileInterface(ProfileDatabase *profileDB, CrewDatabase *cre enabledPicStr = tr("Enabled pictures: %1 of %2"); selectedWidgts = 0; profileFolder = ""; - contextMenuOpened = false; - isProfileLoaded = false; - previousWidget = nullptr; - profileLoader = nullptr; - saSpacerItem = nullptr; + profileLoader = 0; + saSpacerItem = 0; - updatePalette(); - QString appVersion = QApplication::applicationVersion(); - const char* literalBuildType = GTA5SYNC_BUILDTYPE; -#ifdef GTA5SYNC_COMMIT - if ((strcmp(literalBuildType, REL_BUILDTYPE) != 0) && !appVersion.contains("-")) - appVersion = appVersion % "-" % GTA5SYNC_COMMIT; -#endif - ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion)); - ui->saProfileContent->setFilesDropEnabled(true); - ui->saProfileContent->setImageDropEnabled(true); - - // Set Icon for Close Button - if (QIcon::hasThemeIcon("dialog-close")) { - ui->cmdCloseProfile->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) { - ui->cmdCloseProfile->setIcon(QIcon::fromTheme("gtk-close")); - } - - // Set Icon for Import Button - if (QIcon::hasThemeIcon("document-import")) { - ui->cmdImport->setIcon(QIcon::fromTheme("document-import")); - } - else if (QIcon::hasThemeIcon("document-open")) { - ui->cmdImport->setIcon(QIcon::fromTheme("document-open")); - } - - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); -#ifndef Q_OS_MAC - ui->hlButtons->setSpacing(6 * screenRatio); - ui->hlButtons->setContentsMargins(9 * screenRatio, 9 * screenRatio, 9 * screenRatio, 9 * screenRatio); -#else -#if QT_VERSION >= 0x060000 - if (QApplication::style()->objectName() == "macos") { -#else - if (QApplication::style()->objectName() == "macintosh") { -#endif - ui->hlButtons->setSpacing(6 * screenRatio); - ui->hlButtons->setContentsMargins(9 * screenRatio, 15 * screenRatio, 15 * screenRatio, 17 * screenRatio); - } - else { - ui->hlButtons->setSpacing(6 * screenRatio); - ui->hlButtons->setContentsMargins(9 * screenRatio, 9 * screenRatio, 9 * screenRatio, 9 * screenRatio); - } -#endif - - // Seed RNG - pcg32_srandom_r(&rng, time(NULL), (intptr_t)&rng); - -#if QT_VERSION >= 0x050000 - // Register Metatypes - qRegisterMetaType>(); -#endif - - setMouseTracking(true); - installEventFilter(this); + QPalette palette; + QColor baseColor = palette.base().color(); + ui->labVersion->setText(ui->labVersion->text().arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER)); + 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()))); } ProfileInterface::~ProfileInterface() { - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - widget->removeEventFilter(this); - widget->disconnect(); - delete widget; - } + foreach(ProfileWidget *widget, widgets.keys()) + { + widgets.remove(widget); + widget->deleteLater(); + delete widget; } - widgets.clear(); - - for (SavegameData *savegame : qAsConst(savegames)) { + foreach(SavegameData *savegame, savegames) + { + savegames.removeAll(savegame); + savegame->deleteLater(); delete savegame; } - savegames.clear(); - - for (SnapmaticPicture *picture : qAsConst(pictures)) { + foreach(SnapmaticPicture *picture, pictures) + { + pictures.removeAll(picture); + picture->deleteLater(); delete picture; } - pictures.clear(); - + profileLoader->deleteLater(); delete profileLoader; + delete ui; } @@ -185,78 +101,57 @@ void ProfileInterface::setProfileFolder(QString folder, QString profile) void ProfileInterface::setupProfileInterface() { - fixedPictures.clear(); ui->labProfileLoading->setText(tr("Loading...")); profileLoader = new ProfileLoader(profileFolder, crewDB); -#if QT_VERSION >= 0x050000 - QObject::connect(profileLoader, SIGNAL(directoryScanned(QVector,QVector)), this, SLOT(directoryScanned(QVector,QVector))); -#endif - QObject::connect(profileLoader, SIGNAL(savegameLoaded(SavegameData*, QString)), this, SLOT(savegameLoaded_event(SavegameData*, QString))); - QObject::connect(profileLoader, SIGNAL(pictureLoaded(SnapmaticPicture*)), this, SLOT(pictureLoaded_event(SnapmaticPicture*))); - QObject::connect(profileLoader, SIGNAL(pictureFixed(SnapmaticPicture*)), this, SLOT(pictureFixed_event(SnapmaticPicture*))); + QObject::connect(profileLoader, SIGNAL(savegameLoaded(SavegameData*, QString)), this, SLOT(savegameLoaded(SavegameData*, QString))); + QObject::connect(profileLoader, SIGNAL(pictureLoaded(SnapmaticPicture*, QString)), this, SLOT(pictureLoaded(SnapmaticPicture*, QString))); QObject::connect(profileLoader, SIGNAL(loadingProgress(int,int)), this, SLOT(loadingProgress(int,int))); QObject::connect(profileLoader, SIGNAL(finished()), this, SLOT(profileLoaded_p())); profileLoader->start(); } -void ProfileInterface::savegameLoaded_event(SavegameData *savegame, QString savegamePath) +void ProfileInterface::savegameLoaded(SavegameData *savegame, QString savegamePath) { - savegameLoaded(savegame, savegamePath, false); + savegameLoaded_f(savegame, savegamePath, false); } -void ProfileInterface::savegameLoaded(SavegameData *savegame, QString savegamePath, bool inserted) +void ProfileInterface::savegameLoaded_f(SavegameData *savegame, QString savegamePath, bool inserted) { SavegameWidget *sgdWidget = new SavegameWidget(this); sgdWidget->setSavegameData(savegame, savegamePath); sgdWidget->setContentMode(contentMode); - sgdWidget->setMouseTracking(true); - sgdWidget->installEventFilter(this); - widgets[sgdWidget] = "SGD" % QFileInfo(savegamePath).fileName(); - savegames += savegame; - if (selectedWidgts != 0 || contentMode == 2) - sgdWidget->setSelectionMode(true); - QObject::connect(sgdWidget, SIGNAL(savegameDeleted()), this, SLOT(savegameDeleted_event())); + widgets[sgdWidget] = "SGD" + QFileInfo(savegamePath).fileName(); + savegames.append(savegame); + if (selectedWidgts != 0 || contentMode == 2) { sgdWidget->setSelectionMode(true); } + QObject::connect(sgdWidget, SIGNAL(savegameDeleted()), this, SLOT(savegameDeleted())); QObject::connect(sgdWidget, SIGNAL(widgetSelected()), this, SLOT(profileWidgetSelected())); QObject::connect(sgdWidget, SIGNAL(widgetDeselected()), this, SLOT(profileWidgetDeselected())); QObject::connect(sgdWidget, SIGNAL(allWidgetsSelected()), this, SLOT(selectAllWidgets())); QObject::connect(sgdWidget, SIGNAL(allWidgetsDeselected()), this, SLOT(deselectAllWidgets())); - QObject::connect(sgdWidget, SIGNAL(contextMenuTriggered(QContextMenuEvent*)), this, SLOT(contextMenuTriggeredSGD(QContextMenuEvent*))); - if (inserted) - insertSavegameIPI(sgdWidget); + if (inserted) { insertSavegameIPI(sgdWidget); } } -void ProfileInterface::pictureLoaded_event(SnapmaticPicture *picture) +void ProfileInterface::pictureLoaded(SnapmaticPicture *picture, QString picturePath) { - pictureLoaded(picture, false); + pictureLoaded_f(picture, picturePath, false); } -void ProfileInterface::pictureFixed_event(SnapmaticPicture *picture) +void ProfileInterface::pictureLoaded_f(SnapmaticPicture *picture, QString picturePath, bool inserted) { - QString fixedPicture = picture->getPictureStr() % " (" % picture->getPictureTitl() % ")"; - fixedPictures << fixedPicture; -} - -void ProfileInterface::pictureLoaded(SnapmaticPicture *picture, bool inserted) -{ - SnapmaticWidget *picWidget = new SnapmaticWidget(profileDB, crewDB, threadDB, profileName, this); - picWidget->setSnapmaticPicture(picture); + SnapmaticWidget *picWidget = new SnapmaticWidget(profileDB, crewDB, threadDB, this); + picWidget->setSnapmaticPicture(picture, picturePath); picWidget->setContentMode(contentMode); - picWidget->setMouseTracking(true); - picWidget->installEventFilter(this); - widgets[picWidget] = "PIC" % picture->getPictureSortStr(); - pictures += picture; - if (selectedWidgts != 0 || contentMode == 2) - picWidget->setSelectionMode(true); - QObject::connect(picWidget, SIGNAL(pictureDeleted()), this, SLOT(pictureDeleted_event())); + widgets[picWidget] = "PIC" + picture->getPictureSortStr(); + pictures.append(picture); + if (selectedWidgts != 0 || contentMode == 2) { picWidget->setSelectionMode(true); } + QObject::connect(picWidget, SIGNAL(pictureDeleted()), this, SLOT(pictureDeleted())); QObject::connect(picWidget, SIGNAL(widgetSelected()), this, SLOT(profileWidgetSelected())); QObject::connect(picWidget, SIGNAL(widgetDeselected()), this, SLOT(profileWidgetDeselected())); QObject::connect(picWidget, SIGNAL(allWidgetsSelected()), this, SLOT(selectAllWidgets())); QObject::connect(picWidget, SIGNAL(allWidgetsDeselected()), this, SLOT(deselectAllWidgets())); QObject::connect(picWidget, SIGNAL(nextPictureRequested(QWidget*)), this, SLOT(dialogNextPictureRequested(QWidget*))); QObject::connect(picWidget, SIGNAL(previousPictureRequested(QWidget*)), this, SLOT(dialogPreviousPictureRequested(QWidget*))); - QObject::connect(picWidget, SIGNAL(contextMenuTriggered(QContextMenuEvent*)), this, SLOT(contextMenuTriggeredPIC(QContextMenuEvent*))); - if (inserted) - insertSnapmaticIPI(picWidget); + if (inserted) { insertSnapmaticIPI(picWidget); } } void ProfileInterface::loadingProgress(int value, int maximum) @@ -266,168 +161,109 @@ void ProfileInterface::loadingProgress(int value, int maximum) ui->labProfileLoading->setText(loadingStr.arg(QString::number(value), QString::number(maximum))); } -#if QT_VERSION >= 0x050000 -void ProfileInterface::directoryChanged(const QString &path) -{ - Q_UNUSED(path) - - QDir dir(profileFolder); - QVector t_savegameFiles; - QVector t_snapmaticPics; - QVector n_savegameFiles; - QVector n_snapmaticPics; - - const QStringList files = dir.entryList(QDir::Files); - for (const QString &fileName : files) { - if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) { - t_savegameFiles << fileName; - if (!savegameFiles.contains(fileName)) { - n_savegameFiles << fileName; - } - } - if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) { - t_snapmaticPics << fileName; - if (fileName.endsWith(".hidden")) { - const QString originalFileName = fileName.left(fileName.length() - 7); - if (!snapmaticPics.contains(fileName) && !snapmaticPics.contains(originalFileName)) { - n_snapmaticPics << fileName; - } - } - else { - if (!snapmaticPics.contains(fileName) && !snapmaticPics.contains(fileName % ".hidden")) { - n_snapmaticPics << fileName; - } - } - } - } - savegameFiles = t_savegameFiles; - snapmaticPics = t_snapmaticPics; - - if (!n_savegameFiles.isEmpty() || !n_snapmaticPics.isEmpty()) { - QTimer::singleShot(1000, this, [=](){ - for (const QString &fileName : qAsConst(n_savegameFiles)) { - const QString filePath = profileFolder % "/" % fileName; - SavegameData *savegame = new SavegameData(filePath); - if (savegame->readingSavegame()) - savegameLoaded(savegame, filePath, true); - else - delete savegame; - } - for (const QString &fileName : qAsConst(n_snapmaticPics)) { - const QString filePath = profileFolder % "/" % fileName; - SnapmaticPicture *picture = new SnapmaticPicture(filePath); - if (picture->readingPicture(true)) - pictureLoaded(picture, true); - else - delete picture; - } - }); - } -} - -void ProfileInterface::directoryScanned(QVector savegameFiles_s, QVector snapmaticPics_s) -{ - savegameFiles = savegameFiles_s; - snapmaticPics = snapmaticPics_s; - fileSystemWatcher.addPath(profileFolder); - QObject::connect(&fileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &ProfileInterface::directoryChanged); -} -#endif - void ProfileInterface::insertSnapmaticIPI(QWidget *widget) { - ProfileWidget *proWidget = qobject_cast(widget); - const QString widgetKey = widgets.value(proWidget, QString()); - if (!widgetKey.isNull()) { + ProfileWidget *proWidget = (ProfileWidget*)widget; + if (widgets.contains(proWidget)) + { + QString widgetKey = widgets[proWidget]; QStringList widgetsKeyList = widgets.values(); QStringList pictureKeyList = widgetsKeyList.filter("PIC", Qt::CaseSensitive); #if QT_VERSION >= 0x050600 - std::sort(pictureKeyList.rbegin(), pictureKeyList.rend()); + qSort(pictureKeyList.rbegin(), pictureKeyList.rend()); #else qSort(pictureKeyList.begin(), pictureKeyList.end(), qGreater()); #endif - int picIndex = pictureKeyList.indexOf(widgetKey); + int picIndex = pictureKeyList.indexOf(QRegExp(widgetKey)); ui->vlSnapmatic->insertWidget(picIndex, proWidget); - QApplication::processEvents(); + qApp->processEvents(); ui->saProfile->ensureWidgetVisible(proWidget, 0, 0); } } void ProfileInterface::insertSavegameIPI(QWidget *widget) { - ProfileWidget *proWidget = qobject_cast(widget); - const QString widgetKey = widgets.value(proWidget, QString()); - if (!widgetKey.isNull()) { + ProfileWidget *proWidget = (ProfileWidget*)widget; + if (widgets.contains(proWidget)) + { + QString widgetKey = widgets[proWidget]; QStringList widgetsKeyList = widgets.values(); QStringList savegameKeyList = widgetsKeyList.filter("SGD", Qt::CaseSensitive); -#if QT_VERSION >= 0x050600 - std::sort(savegameKeyList.begin(), savegameKeyList.end()); -#else qSort(savegameKeyList.begin(), savegameKeyList.end()); -#endif - int sgdIndex = savegameKeyList.indexOf(widgetKey); + int sgdIndex = savegameKeyList.indexOf(QRegExp(widgetKey)); ui->vlSavegame->insertWidget(sgdIndex, proWidget); - QApplication::processEvents(); + qApp->processEvents(); ui->saProfile->ensureWidgetVisible(proWidget, 0, 0); } } void ProfileInterface::dialogNextPictureRequested(QWidget *dialog) { - PictureDialog *picDialog = qobject_cast(dialog); - ProfileWidget *proWidget = qobject_cast(sender()); - const QString widgetKey = widgets.value(proWidget, QString()); - if (!widgetKey.isNull()) { + PictureDialog *picDialog = (PictureDialog*)dialog; + ProfileWidget *proWidget = (ProfileWidget*)sender(); + if (widgets.contains(proWidget)) + { + QString widgetKey = widgets[proWidget]; QStringList widgetsKeyList = widgets.values(); QStringList pictureKeyList = widgetsKeyList.filter("PIC", Qt::CaseSensitive); #if QT_VERSION >= 0x050600 - std::sort(pictureKeyList.rbegin(), pictureKeyList.rend()); + qSort(pictureKeyList.rbegin(), pictureKeyList.rend()); #else qSort(pictureKeyList.begin(), pictureKeyList.end(), qGreater()); #endif int picIndex; - if (picDialog->isIndexed()) { + if (picDialog->isIndexed()) + { picIndex = picDialog->getIndex(); } - else { - picIndex = pictureKeyList.indexOf(widgetKey); + else + { + picIndex = pictureKeyList.indexOf(QRegExp(widgetKey)); } picIndex++; - if (pictureKeyList.length() > picIndex) { - const QString newWidgetKey = pictureKeyList.at(picIndex); - SnapmaticWidget *picWidget = static_cast(widgets.key(newWidgetKey)); + if (pictureKeyList.length() > picIndex) + { + QString newWidgetKey = pictureKeyList.at(picIndex); + SnapmaticWidget *picWidget = (SnapmaticWidget*)widgets.key(newWidgetKey); + picDialog->setMaximumSize(picDialog->width(), QWIDGETSIZE_MAX); picDialog->setSnapmaticPicture(picWidget->getPicture(), picIndex); + //picDialog->adaptNewDialogSize(); } } } void ProfileInterface::dialogPreviousPictureRequested(QWidget *dialog) { - PictureDialog *picDialog = qobject_cast(dialog); - ProfileWidget *proWidget = qobject_cast(sender()); - const QString widgetKey = widgets.value(proWidget, QString()); - if (!widgetKey.isNull()) { + PictureDialog *picDialog = (PictureDialog*)dialog; + ProfileWidget *proWidget = (ProfileWidget*)sender(); + if (widgets.contains(proWidget)) + { + QString widgetKey = widgets[proWidget]; QStringList widgetsKeyList = widgets.values(); QStringList pictureKeyList = widgetsKeyList.filter("PIC", Qt::CaseSensitive); #if QT_VERSION >= 0x050600 - std::sort(pictureKeyList.rbegin(), pictureKeyList.rend()); + qSort(pictureKeyList.rbegin(), pictureKeyList.rend()); #else qSort(pictureKeyList.begin(), pictureKeyList.end(), qGreater()); #endif int picIndex; - if (picDialog->isIndexed()) { + if (picDialog->isIndexed()) + { picIndex = picDialog->getIndex(); } - else { - picIndex = pictureKeyList.indexOf(widgetKey); + else + { + picIndex = pictureKeyList.indexOf(QRegExp(widgetKey)); } - if (picIndex > 0) { + if (picIndex > 0) + { picIndex--; - const QString newWidgetKey = pictureKeyList.at(picIndex); - SnapmaticWidget *picWidget = static_cast(widgets.key(newWidgetKey)); + QString newWidgetKey = pictureKeyList.at(picIndex ); + SnapmaticWidget *picWidget = (SnapmaticWidget*)widgets.key(newWidgetKey); picDialog->setSnapmaticPicture(picWidget->getPicture(), picIndex); + //picDialog->adaptNewDialogSize(); } } } @@ -438,19 +274,17 @@ void ProfileInterface::sortingProfileInterface() ui->vlSnapmatic->setEnabled(false); QStringList widgetsKeyList = widgets.values(); - -#if QT_VERSION >= 0x050600 - std::sort(widgetsKeyList.begin(), widgetsKeyList.end()); -#else qSort(widgetsKeyList.begin(), widgetsKeyList.end()); -#endif - for (const QString &widgetKey : qAsConst(widgetsKeyList)) { + foreach(QString widgetKey, widgetsKeyList) + { ProfileWidget *widget = widgets.key(widgetKey); - if (widget->getWidgetType() == "SnapmaticWidget") { + if (widget->getWidgetType() == "SnapmaticWidget") + { ui->vlSnapmatic->insertWidget(0, widget); } - else if (widget->getWidgetType() == "SavegameWidget") { + else if (widget->getWidgetType() == "SavegameWidget") + { ui->vlSavegame->addWidget(widget); } } @@ -458,7 +292,7 @@ void ProfileInterface::sortingProfileInterface() ui->vlSavegame->setEnabled(true); ui->vlSnapmatic->setEnabled(true); - QApplication::processEvents(); + qApp->processEvents(); } void ProfileInterface::profileLoaded_p() @@ -469,67 +303,39 @@ void ProfileInterface::profileLoaded_p() ui->swProfile->setCurrentWidget(ui->pageProfile); ui->cmdCloseProfile->setEnabled(true); ui->cmdImport->setEnabled(true); - isProfileLoaded = true; emit profileLoaded(); - - if (!fixedPictures.isEmpty()) { - int fixedInt = 0; - QString fixedStr; - for (const QString &fixedPicture : qAsConst(fixedPictures)) { - if (fixedInt != 0) { fixedStr += "
"; } - fixedStr += fixedPicture; - fixedInt++; - } - QMessageBox::information(this, tr("Snapmatic Loader"), tr("

Following Snapmatic Pictures got repaired

%1").arg(fixedStr)); - } } -void ProfileInterface::savegameDeleted_event() +void ProfileInterface::savegameDeleted() { - savegameDeleted(qobject_cast(sender()), true); + savegameDeleted_f((SavegameWidget*)sender()); } -void ProfileInterface::savegameDeleted(SavegameWidget *sgdWidget, bool isRemoteEmited) +void ProfileInterface::savegameDeleted_f(QWidget *sgdWidget_) { + SavegameWidget *sgdWidget = (SavegameWidget*)sgdWidget_; SavegameData *savegame = sgdWidget->getSavegame(); - if (sgdWidget->isSelected()) - sgdWidget->setSelected(false); + if (sgdWidget->isSelected()) { sgdWidget->setSelected(false); } widgets.remove(sgdWidget); - - sgdWidget->disconnect(); - sgdWidget->removeEventFilter(this); - if (sgdWidget == previousWidget) { - previousWidget = nullptr; - } - - // Deleting when the widget did send a event cause a crash - isRemoteEmited ? sgdWidget->deleteLater() : delete sgdWidget; - + sgdWidget->close(); + sgdWidget->deleteLater(); savegames.removeAll(savegame); delete savegame; } -void ProfileInterface::pictureDeleted_event() +void ProfileInterface::pictureDeleted() { - pictureDeleted(qobject_cast(sender()), true); + pictureDeleted_f((SnapmaticWidget*)sender()); } -void ProfileInterface::pictureDeleted(SnapmaticWidget *picWidget, bool isRemoteEmited) +void ProfileInterface::pictureDeleted_f(QWidget *picWidget_) { + SnapmaticWidget *picWidget = (SnapmaticWidget*)picWidget_; SnapmaticPicture *picture = picWidget->getPicture(); - if (picWidget->isSelected()) - picWidget->setSelected(false); + if (picWidget->isSelected()) { picWidget->setSelected(false); } widgets.remove(picWidget); - - picWidget->disconnect(); - picWidget->removeEventFilter(this); - if (picWidget == previousWidget) { - previousWidget = nullptr; - } - - // Deleting when the widget did send a event cause a crash - isRemoteEmited ? picWidget->deleteLater() : delete picWidget; - + picWidget->close(); + picWidget->deleteLater(); pictures.removeAll(picture); delete picture; } @@ -543,697 +349,177 @@ void ProfileInterface::on_cmdImport_clicked() { QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); settings.beginGroup("FileDialogs"); - bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool(); settings.beginGroup("ImportCopy"); -fileDialogPreOpen: //Work? +fileDialogPreOpen: QFileDialog fileDialog(this); fileDialog.setFileMode(QFileDialog::ExistingFiles); fileDialog.setViewMode(QFileDialog::Detail); fileDialog.setAcceptMode(QFileDialog::AcceptOpen); - fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog); + fileDialog.setOption(QFileDialog::DontUseNativeDialog, false); fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); fileDialog.setWindowTitle(tr("Import...")); - fileDialog.setLabelText(QFileDialog::Accept, tr("Import...")); - - // Getting readable Image formats - QString imageFormatsStr = " "; - for (const QByteArray &imageFormat : QImageReader::supportedImageFormats()) { - imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " "; - } - QString importableFormatsStr = QString("*.g5e SGTA* PGTA*"); - if (!imageFormatsStr.trimmed().isEmpty()) { - importableFormatsStr = QString("*.g5e%1SGTA* PGTA*").arg(imageFormatsStr); - } + fileDialog.setLabelText(QFileDialog::Accept, tr("Import")); QStringList filters; - filters << tr("Importable files (%1)").arg(importableFormatsStr); - filters << tr("GTA V Export (*.g5e)"); + filters << tr("All profile files (SGTA* PGTA*)"); filters << tr("Savegames files (SGTA*)"); filters << tr("Snapmatic pictures (PGTA*)"); - filters << tr("All image files (%1)").arg(imageFormatsStr.trimmed()); filters << tr("All files (**)"); fileDialog.setNameFilters(filters); QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); fileDialog.setSidebarUrls(sidebarUrls); - fileDialog.setDirectory(settings.value(profileName % "+Directory", StandardPaths::documentsLocation()).toString()); - fileDialog.restoreGeometry(settings.value(profileName % "+Geometry", "").toByteArray()); + fileDialog.setDirectory(settings.value(profileName + "+Directory", StandardPaths::documentsLocation()).toString()); + fileDialog.restoreGeometry(settings.value(profileName + "+Geometry", "").toByteArray()); - if (fileDialog.exec()) { + if (fileDialog.exec()) + { QStringList selectedFiles = fileDialog.selectedFiles(); - if (selectedFiles.length() == 1) { + if (selectedFiles.length() == 1) + { QString selectedFile = selectedFiles.at(0); - QDateTime importDateTime = QDateTime::currentDateTime(); - if (!importFile(selectedFile, importDateTime, true)) goto fileDialogPreOpen; //Work? + if (!importFile(selectedFile, true)) goto fileDialogPreOpen; } - else if (selectedFiles.length() > 1) { - importFilesProgress(selectedFiles); + else if (selectedFiles.length() > 1) + { + QString errorStr; + QStringList failedFiles; + foreach(const QString &selectedFile, selectedFiles) + { + if (!importFile(selectedFile, false)) + { + failedFiles << QFileInfo(selectedFile).fileName(); + } + } + foreach (const QString &curErrorStr, failedFiles) + { + errorStr.append(", " + curErrorStr); + } + if (errorStr != "") + { + errorStr.remove(0, 2); + QMessageBox::warning(this, tr("Import"), tr("Import failed with...\n\n%1").arg(errorStr)); + } } - else { - QMessageBox::warning(this, tr("Import..."), tr("No valid file is selected")); - goto fileDialogPreOpen; //Work? + else + { + QMessageBox::warning(this, tr("Import"), tr("No valid file is selected")); + goto fileDialogPreOpen; } } - settings.setValue(profileName % "+Geometry", fileDialog.saveGeometry()); - settings.setValue(profileName % "+Directory", fileDialog.directory().absolutePath()); + settings.setValue(profileName + "+Geometry", fileDialog.saveGeometry()); + settings.setValue(profileName + "+Directory", fileDialog.directory().absolutePath()); settings.endGroup(); settings.endGroup(); } -bool ProfileInterface::importFilesProgress(QStringList selectedFiles) -{ - int maximumId = selectedFiles.length(); - int overallId = 0; - QString errorStr; - QStringList failed; - - // Progress dialog - QProgressDialog pbDialog(this); - pbDialog.setWindowFlags(pbDialog.windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowCloseButtonHint); - pbDialog.setWindowTitle(tr("Import...")); - pbDialog.setLabelText(tr("Import file %1 of %2 files").arg(QString::number(1), QString::number(maximumId))); - pbDialog.setRange(1, maximumId); - pbDialog.setValue(1); - pbDialog.setModal(true); - QList pbBtn = pbDialog.findChildren(); - pbBtn.at(0)->setDisabled(true); - QList pbBar = pbDialog.findChildren(); - pbBar.at(0)->setTextVisible(false); - pbDialog.setAutoClose(false); - pbDialog.show(); - - // THREADING HERE PLEASE - QDateTime importDateTime = QDateTime::currentDateTime(); - for (const QString &selectedFile : selectedFiles) { - overallId++; - pbDialog.setValue(overallId); - pbDialog.setLabelText(tr("Import file %1 of %2 files").arg(QString::number(overallId), QString::number(maximumId))); - importDateTime = QDateTime::currentDateTime(); - if (!importFile(selectedFile, importDateTime, false)) { - failed << QFileInfo(selectedFile).fileName(); - } - } - - pbDialog.close(); - for (const QString &curErrorStr : qAsConst(failed)) { - errorStr += ", " % curErrorStr; - } - if (errorStr != "") { - errorStr.remove(0, 2); - 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, bool notMultiple) +bool ProfileInterface::importFile(QString selectedFile, bool warn) { QString selectedFileName = QFileInfo(selectedFile).fileName(); - if (QFile::exists(selectedFile)) { - if ((selectedFileName.left(4) == "PGTA" && !selectedFileName.contains('.')) || selectedFileName.right(4) == ".g5e") { + if (QFile::exists(selectedFile)) + { + if (selectedFileName.left(4) == "PGTA") + { SnapmaticPicture *picture = new SnapmaticPicture(selectedFile); - if (picture->readingPicture(true)) { - bool success = importSnapmaticPicture(picture, notMultiple); - 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()); -#if QT_VERSION >= 0x060000 - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonObject["ImportType"] = "Snapmatic"; - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } - } -#endif + if (picture->readingPicture()) + { + bool success = importSnapmaticPicture(picture, selectedFile, warn); + if (!success) delete picture; return success; } - else { - if (notMultiple) - QMessageBox::warning(this, tr("Import..."), tr("Failed to read Snapmatic picture")); + else + { + if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to read Snapmatic picture")); + picture->deleteLater(); delete picture; return false; } } - else if (selectedFileName.left(4) == "SGTA") { + else if (selectedFileName.left(4) == "SGTA") + { SavegameData *savegame = new SavegameData(selectedFile); - if (savegame->readingSavegame()) { - bool success = importSavegameData(savegame, selectedFile, notMultiple); - 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"; -#if QT_VERSION >= 0x060000 - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonObject["ImportType"] = "Savegame"; - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } - } -#endif + if (savegame->readingSavegame()) + { + bool success = importSavegameData(savegame, selectedFile, warn); + if (!success) delete savegame; return success; } - else { - if (notMultiple) QMessageBox::warning(this, tr("Import..."), tr("Failed to read Savegame file")); + else + { + if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to read Savegame file")); + savegame->deleteLater(); delete savegame; return false; } } - else if (isSupportedImageFile(selectedFileName)) { - SnapmaticPicture *picture = new SnapmaticPicture(":/template/template.g5e"); - if (picture->readingPicture(false)) { - if (!notMultiple) { - QFile snapmaticFile(selectedFile); - if (!snapmaticFile.open(QFile::ReadOnly)) { - delete picture; - return false; - } - QImage snapmaticImage; - QImageReader snapmaticImageReader; - snapmaticImageReader.setDecideFormatFromContent(true); - snapmaticImageReader.setDevice(&snapmaticFile); - if (!snapmaticImageReader.read(&snapmaticImage)) { - delete picture; - return false; - } - QString customImageTitle; - QPixmap snapmaticPixmap(960, 536); - snapmaticPixmap.fill(Qt::black); - QPainter snapmaticPainter(&snapmaticPixmap); - if (snapmaticImage.height() == snapmaticImage.width()) { - // Avatar mode - int diffWidth = 0; - int diffHeight = 0; - snapmaticImage = snapmaticImage.scaled(470, 470, Qt::KeepAspectRatio, Qt::SmoothTransformation); - if (snapmaticImage.width() > snapmaticImage.height()) { - diffHeight = 470 - snapmaticImage.height(); - diffHeight = diffHeight / 2; - } - else if (snapmaticImage.width() < snapmaticImage.height()) { - diffWidth = 470 - snapmaticImage.width(); - diffWidth = diffWidth / 2; - } - snapmaticPainter.drawImage(145 + diffWidth, 66 + diffHeight, snapmaticImage); - customImageTitle = ImportDialog::tr("Custom Avatar", "Custom Avatar Description in SC, don't use Special Character!"); - } - else { - // Picture mode - int diffWidth = 0; - int diffHeight = 0; - snapmaticImage = snapmaticImage.scaled(960, 536, Qt::KeepAspectRatio, Qt::SmoothTransformation); - if (snapmaticImage.width() != 960) { - diffWidth = 960 - snapmaticImage.width(); - diffWidth = diffWidth / 2; - } - else if (snapmaticImage.height() != 536) { - diffHeight = 536 - snapmaticImage.height(); - diffHeight = diffHeight / 2; - } - snapmaticPainter.drawImage(0 + diffWidth, 0 + diffHeight, snapmaticImage); - customImageTitle = ImportDialog::tr("Custom Picture", "Custom Picture Description in SC, don't use Special Character!"); - } - snapmaticPainter.end(); - if (!picture->setImage(snapmaticPixmap.toImage())) { - delete picture; - return false; - } - 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; -#if QT_VERSION >= 0x060000 - quint64 timestamp = spJson.createdDateTime.toSecsSinceEpoch(); - if (timestamp > UINT32_MAX) { - timestamp = UINT32_MAX; - } - spJson.createdTimestamp = (quint32)timestamp; -#else - spJson.createdTimestamp = spJson.createdDateTime.toTime_t(); -#endif - picture->setSnapmaticProperties(spJson); - const QString picFileName = QString("PGTA5%1").arg(QString::number(spJson.uid)); - picture->setPicFileName(picFileName); - picture->setPictureTitle(customImageTitle); - picture->updateStrings(); - bool success = importSnapmaticPicture(picture, notMultiple); - if (!success) - delete picture; - return success; - } - else { - bool success = false; - QFile snapmaticFile(selectedFile); - if (!snapmaticFile.open(QFile::ReadOnly)) { - QMessageBox::warning(this, tr("Import..."), tr("Can't import %1 because file can't be open").arg("\""+selectedFileName+"\"")); - delete picture; - return false; - } - QImage *snapmaticImage = new QImage(); - QImageReader snapmaticImageReader; - snapmaticImageReader.setDecideFormatFromContent(true); - snapmaticImageReader.setDevice(&snapmaticFile); - if (!snapmaticImageReader.read(snapmaticImage)) { - QMessageBox::warning(this, tr("Import..."), tr("Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\"")); - delete snapmaticImage; - delete picture; - return 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(), importDialog->isUnlimitedBuffer())) { - 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; -#if QT_VERSION >= 0x060000 - quint64 timestamp = spJson.createdDateTime.toSecsSinceEpoch(); - if (timestamp > UINT32_MAX) { - timestamp = UINT32_MAX; - } - spJson.createdTimestamp = (quint32)timestamp; -#else - spJson.createdTimestamp = spJson.createdDateTime.toTime_t(); -#endif - picture->setSnapmaticProperties(spJson); - const QString picFileName = QString("PGTA5%1").arg(QString::number(spJson.uid)); - picture->setPicFileName(picFileName); - picture->setPictureTitle(importDialog->getImageTitle()); - picture->updateStrings(); - 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()); -#if QT_VERSION >= 0x060000 - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonObject["ImportType"] = "Image"; - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } - } -#endif - } - } - else { - delete picture; - success = true; - } - delete importDialog; - if (!success) - delete picture; - return success; - } - } - else { - delete picture; - return false; - } - } - else { + else + { SnapmaticPicture *picture = new SnapmaticPicture(selectedFile); SavegameData *savegame = new SavegameData(selectedFile); - if (picture->readingPicture()) { - bool success = importSnapmaticPicture(picture, notMultiple); + if (picture->readingPicture()) + { + bool success = importSnapmaticPicture(picture, selectedFile, warn); delete savegame; - 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()); -#if QT_VERSION >= 0x060000 - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonObject["ImportType"] = "Snapmatic"; - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } - } -#endif + if (!success) delete picture; return success; } - else if (savegame->readingSavegame()) { - bool success = importSavegameData(savegame, selectedFile, notMultiple); + else if (savegame->readingSavegame()) + { + bool success = importSavegameData(savegame, selectedFile, warn); delete picture; - 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"; -#if QT_VERSION >= 0x060000 - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["ImportTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonObject["ImportType"] = "Savegame"; - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } - } -#endif + if (!success) delete savegame; return success; } - else { -#ifdef GTA5SYNC_DEBUG - qDebug() << "ImportError SnapmaticPicture" << picture->getLastStep(); - qDebug() << "ImportError SavegameData" << savegame->getLastStep(); -#endif - delete picture; + else + { + savegame->deleteLater(); + picture->deleteLater(); delete savegame; - if (notMultiple) QMessageBox::warning(this, tr("Import..."), tr("Can't import %1 because file format can't be detected").arg("\""+selectedFileName+"\"")); + delete picture; + if (warn) QMessageBox::warning(this, tr("Import"), tr("Can't import %1 because of not valid file format").arg("\""+selectedFileName+"\"")); return false; } } } - if (notMultiple) - QMessageBox::warning(this, tr("Import..."), tr("No valid file is selected")); + if (warn) QMessageBox::warning(this, tr("Import"), tr("No valid file is selected")); return false; } -bool ProfileInterface::importUrls(const QMimeData *mimeData) +bool ProfileInterface::importSnapmaticPicture(SnapmaticPicture *picture, QString picPath, bool warn) { - QStringList pathList; - - for (const QUrl ¤tUrl : mimeData->urls()) { - if (currentUrl.isLocalFile()) - pathList += currentUrl.toLocalFile(); + QFileInfo picFileInfo(picPath); + QString picFileName = picFileInfo.fileName(); + QString adjustedFileName = picFileName; + if (adjustedFileName.right(7) == ".hidden") // for the hidden file system + { + adjustedFileName.remove(adjustedFileName.length() - 7, 7); } - - if (pathList.length() == 1) { - QString selectedFile = pathList.at(0); - return importFile(selectedFile, QDateTime::currentDateTime(), true); + if (adjustedFileName.right(4) == ".bak") // for the backup file system + { + adjustedFileName.remove(adjustedFileName.length() - 4, 4); } - 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(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(), importDialog->isUnlimitedBuffer())) { - 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; -#if QT_VERSION >= 0x060000 - quint64 timestamp = spJson.createdDateTime.toSecsSinceEpoch(); - if (timestamp > UINT32_MAX) { - timestamp = UINT32_MAX; - } - spJson.createdTimestamp = (quint32)timestamp; -#else - spJson.createdTimestamp = spJson.createdDateTime.toTime_t(); -#endif - picture->setSnapmaticProperties(spJson); - const QString picFileName = QString("PGTA5%1").arg(QString::number(spJson.uid)); - picture->setPicFileName(picFileName); - 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; + if (picFileName.left(4) != "PGTA") + { + if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Snapmatic picture, file not begin with PGTA")); return false; } -} - -bool ProfileInterface::importSnapmaticPicture(SnapmaticPicture *picture, bool warn) -{ - QString picFileName = picture->getPictureFileName(); - QString adjustedFileName = picture->getOriginalPictureFileName(); - if (!picFileName.startsWith("PGTA5")) { - if (warn) - QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e")); + else if (QFile::exists(profileFolder + QDir::separator() + adjustedFileName) || QFile::exists(profileFolder + QDir::separator() + adjustedFileName + ".hidden")) + { + if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Snapmatic picture, the picture is already in the game")); return false; } - else if (QFile::exists(profileFolder % "/" % adjustedFileName) || QFile::exists(profileFolder % "/" % adjustedFileName % ".hidden")) { - SnapmaticProperties snapmaticProperties = picture->getSnapmaticProperties(); - 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(); -#if QT_VERSION >= 0x060000 - quint64 timestamp = snapmaticProperties.createdDateTime.toSecsSinceEpoch(); - if (timestamp > UINT32_MAX) { - timestamp = UINT32_MAX; - } - snapmaticProperties.createdTimestamp = (quint32)timestamp; -#else - snapmaticProperties.createdTimestamp = snapmaticProperties.createdDateTime.toTime_t(); -#endif - 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(); -#if QT_VERSION >= 0x060000 - quint64 timestamp = snapmaticProperties.createdDateTime.toSecsSinceEpoch(); - if (timestamp > UINT32_MAX) { - timestamp = UINT32_MAX; - } - snapmaticProperties.createdTimestamp = (quint32)timestamp; -#else - snapmaticProperties.createdTimestamp = snapmaticProperties.createdDateTime.toTime_t(); -#endif - 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(); - } - } - if (picture->exportPicture(profileFolder % "/" % adjustedFileName, SnapmaticFormat::PGTA_Format)) { - picture->setSnapmaticFormat(SnapmaticFormat::PGTA_Format); - picture->setPicFilePath(profileFolder % "/" % adjustedFileName); -#if QT_VERSION >= 0x050000 - snapmaticPics << picture->getPictureFileName(); -#endif - pictureLoaded(picture, true); + else if (QFile::copy(picPath, profileFolder + QDir::separator() + adjustedFileName)) + { + picture->setPicFileName(profileFolder + QDir::separator() + adjustedFileName); + pictureLoaded_f(picture, profileFolder + QDir::separator() + adjustedFileName, true); return true; } - else { - if (warn) - QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Snapmatic picture, can't copy the file into profile")); + else + { + if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Snapmatic picture, can't copy the file into profile")); return false; } } @@ -1244,49 +530,50 @@ bool ProfileInterface::importSavegameData(SavegameData *savegame, QString sgdPat bool foundFree = 0; int currentSgd = 0; - while (currentSgd < 15 && !foundFree) { + while (currentSgd < 15 && !foundFree) + { QString sgdNumber = QString::number(currentSgd); - if (sgdNumber.length() == 1) { + if (sgdNumber.length() == 1) + { sgdNumber.insert(0, "0"); } - sgdFileName = "SGTA500" % sgdNumber; + sgdFileName = "SGTA500" + sgdNumber; - if (!QFile::exists(profileFolder % "/" % sgdFileName)) { + if (!QFile::exists(profileFolder + QDir::separator() + sgdFileName)) + { foundFree = true; } currentSgd++; } - if (foundFree) { - const QString newSgdPath = profileFolder % "/" % sgdFileName; - if (QFile::copy(sgdPath, newSgdPath)) { - savegame->setSavegameFileName(newSgdPath); -#if QT_VERSION >= 0x050000 - savegameFiles << newSgdPath; -#endif - savegameLoaded(savegame, newSgdPath, true); + if (foundFree) + { + if (QFile::copy(sgdPath, profileFolder + QDir::separator() + sgdFileName)) + { + savegame->setSavegameFileName(profileFolder + QDir::separator() + sgdFileName); + savegameLoaded_f(savegame, profileFolder + QDir::separator() + sgdFileName, true); return true; } - else { - if (warn) - QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Savegame, can't copy the file into profile")); + else + { + if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Savegame, can't copy the file into profile")); return false; } } - else { - if (warn) - QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Savegame, no Savegame slot is left")); + else + { + if (warn) QMessageBox::warning(this, tr("Import"), tr("Failed to import the Savegame, no Savegame slot is left")); return false; } } void ProfileInterface::profileWidgetSelected() { - if (selectedWidgts == 0) { - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) - widget->setSelectionMode(true); + if (selectedWidgts == 0) + { + foreach(ProfileWidget *widget, widgets.keys()) + { + widget->setSelectionMode(true); } } selectedWidgts++; @@ -1294,11 +581,13 @@ void ProfileInterface::profileWidgetSelected() void ProfileInterface::profileWidgetDeselected() { - if (selectedWidgts == 1) { + if (selectedWidgts == 1) + { int scrollBarValue = ui->saProfile->verticalScrollBar()->value(); - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr && contentMode != 2) { + foreach(ProfileWidget *widget, widgets.keys()) + { + if (contentMode != 2) + { widget->setSelectionMode(false); } } @@ -1309,25 +598,24 @@ void ProfileInterface::profileWidgetDeselected() void ProfileInterface::selectAllWidgets() { - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) - widget->setSelected(true); + foreach(ProfileWidget *widget, widgets.keys()) + { + widget->setSelected(true); } } void ProfileInterface::deselectAllWidgets() { - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) - widget->setSelected(false); + foreach(ProfileWidget *widget, widgets.keys()) + { + widget->setSelected(false); } } void ProfileInterface::exportSelected() { - if (selectedWidgts != 0) { + if (selectedWidgts != 0) + { int exportCount = 0; int exportPictures = 0; int exportSavegames = 0; @@ -1336,26 +624,28 @@ void ProfileInterface::exportSelected() QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); settings.beginGroup("FileDialogs"); - //bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool(); settings.beginGroup("ExportDirectory"); - QString exportDirectory = QFileDialog::getExistingDirectory(this, tr("Export selected..."), settings.value(profileName, profileFolder).toString()); - if (exportDirectory != "") { + QString exportDirectory = QFileDialog::getExistingDirectory(this, tr("Export selected"), settings.value(profileName, profileFolder).toString()); + if (exportDirectory != "") + { settings.setValue(profileName, exportDirectory); - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - if (widget->isSelected()) { - if (widget->getWidgetType() == "SnapmaticWidget") { - exportPictures++; - } - else if (widget->getWidgetType() == "SavegameWidget") { - exportSavegames++; - } + foreach (ProfileWidget *widget, widgets.keys()) + { + if (widget->isSelected()) + { + if (widget->getWidgetType() == "SnapmaticWidget") + { + exportPictures++; + } + else if (widget->getWidgetType() == "SavegameWidget") + { + exportSavegames++; } } } - if (exportPictures != 0) { + if (exportPictures != 0) + { QInputDialog inputDialog; QStringList inputDialogItems; inputDialogItems << tr("JPG pictures and GTA Snapmatic"); @@ -1364,54 +654,60 @@ void ProfileInterface::exportSelected() QString ExportPreSpan; QString ExportPostSpan; -#ifdef Q_OS_WIN - ExportPreSpan = ""; +#ifdef GTA5SYNC_WIN + ExportPreSpan = ""; ExportPostSpan = ""; #else - ExportPreSpan = ""; + ExportPreSpan = ""; ExportPostSpan = ""; #endif bool itemSelected = false; - QString selectedItem = inputDialog.getItem(this, tr("Export selected..."), tr("%1Export Snapmatic pictures%2

JPG pictures make it possible to open the picture with a Image Viewer
GTA Snapmatic make it possible to import the picture into the game

Export as:").arg(ExportPreSpan, ExportPostSpan), inputDialogItems, 0, false, &itemSelected, inputDialog.windowFlags()^Qt::WindowContextHelpButtonHint); - if (itemSelected) { - if (selectedItem == tr("JPG pictures and GTA Snapmatic")) { + QString selectedItem = inputDialog.getItem(this, tr("Export selected"), tr("%1Export Snapmatic pictures%2

JPG pictures make it possible to open the picture with a Image Viewer
GTA Snapmatic make it possible to import the picture into the game

Export as:").arg(ExportPreSpan, ExportPostSpan), inputDialogItems, 0, false, &itemSelected, inputDialog.windowFlags()^Qt::WindowContextHelpButtonHint); + if (itemSelected) + { + if (selectedItem == tr("JPG pictures and GTA Snapmatic")) + { pictureExportEnabled = true; pictureCopyEnabled = true; } - else if (selectedItem == tr("JPG pictures only")) { + else if (selectedItem == tr("JPG pictures only")) + { pictureExportEnabled = true; } - else if (selectedItem == tr("GTA Snapmatic only")) { + else if (selectedItem == tr("GTA Snapmatic only")) + { pictureCopyEnabled = true; } - else { + else + { pictureExportEnabled = true; pictureCopyEnabled = true; } } - else { - // Don't export anymore when any Cancel button got clicked - settings.endGroup(); - settings.endGroup(); - return; + else + { + pictureExportEnabled = true; + pictureCopyEnabled = true; } } // Counting the exports together exportCount = exportCount + exportSavegames; - if (pictureExportEnabled && pictureCopyEnabled) { + if (pictureExportEnabled && pictureCopyEnabled) + { int exportPictures2 = exportPictures * 2; exportCount = exportCount + exportPictures2; } - else { + else + { exportCount = exportCount + exportPictures; } QProgressDialog pbDialog(this); pbDialog.setWindowFlags(pbDialog.windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowCloseButtonHint); pbDialog.setWindowTitle(tr("Export selected...")); - pbDialog.setLabelText(tr("Initialising export...")); + pbDialog.setLabelText(tr("Initializing export...")); pbDialog.setRange(0, exportCount); QList pbBtn = pbDialog.findChildren(); @@ -1426,7 +722,6 @@ void ProfileInterface::exportSelected() QObject::connect(exportThread, SIGNAL(exportFinished()), &pbDialog, SLOT(close())); exportThread->start(); - pbDialog.setAutoClose(false); pbDialog.exec(); QStringList getFailedSavegames = exportThread->getFailedSavegames(); QStringList getFailedCopyPictures = exportThread->getFailedCopyPictures(); @@ -1438,95 +733,80 @@ void ProfileInterface::exportSelected() errorList << getFailedCopyPictures; errorList << getFailedSavegames; - for (const QString &curErrorStr : qAsConst(errorList)) { - errorStr += ", " % curErrorStr; + foreach (const QString &curErrorStr, errorList) + { + errorStr.append(", " + curErrorStr); } - if (errorStr != "") { + if (errorStr != "") + { errorStr.remove(0, 2); - QMessageBox::warning(this, tr("Export selected..."), tr("Export failed with...\n\n%1").arg(errorStr)); + QMessageBox::warning(this, tr("Export selected"), tr("Export failed with...\n\n%1").arg(errorStr)); } - if (exportThread->isFinished()) { + if (exportThread->isFinished()) + { + exportThread->deleteLater(); delete exportThread; } - else { + else + { QEventLoop threadFinishLoop; QObject::connect(exportThread, SIGNAL(finished()), &threadFinishLoop, SLOT(quit())); threadFinishLoop.exec(); + exportThread->deleteLater(); delete exportThread; } } settings.endGroup(); settings.endGroup(); } - else { - QMessageBox::information(this, tr("Export selected..."), tr("No Snapmatic pictures or Savegames files are selected")); - } -} - -void ProfileInterface::deleteSelectedL(bool isRemoteEmited) -{ - if (selectedWidgts != 0) { - if (QMessageBox::Yes == QMessageBox::warning(this, tr("Remove selected"), tr("You really want remove the selected Snapmatic picutres and Savegame files?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) { - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - if (widget->isSelected()) { - if (widget->getWidgetType() == "SnapmaticWidget") { - SnapmaticWidget *picWidget = qobject_cast(widget); - if (picWidget->getPicture()->deletePictureFile()) { - pictureDeleted(picWidget, isRemoteEmited); - } - } - else if (widget->getWidgetType() == "SavegameWidget") { - SavegameWidget *sgdWidget = qobject_cast(widget); - SavegameData *savegame = sgdWidget->getSavegame(); - QString fileName = savegame->getSavegameFileName(); - if (!QFile::exists(fileName) || QFile::remove(fileName)) { - savegameDeleted(sgdWidget, isRemoteEmited); - } - } - } - } - } - if (selectedWidgts != 0) { - QMessageBox::warning(this, tr("Remove selected"), tr("Failed to remove all selected Snapmatic pictures and/or Savegame files")); - } - } - } - else { - QMessageBox::information(this, tr("Remove selected"), tr("No Snapmatic pictures or Savegames files are selected")); + else + { + QMessageBox::information(this, tr("Export selected"), tr("No Snapmatic pictures or Savegames files are selected")); } } void ProfileInterface::deleteSelected() { - deleteSelectedL(false); -} - -void ProfileInterface::deleteSelectedR() -{ - deleteSelectedL(true); -} - -void ProfileInterface::massToolQualify() -{ - massTool(MassTool::Qualify); -} - -void ProfileInterface::massToolPlayers() -{ - massTool(MassTool::Players); -} - -void ProfileInterface::massToolCrew() -{ - massTool(MassTool::Crew); -} - -void ProfileInterface::massToolTitle() -{ - massTool(MassTool::Title); + if (selectedWidgts != 0) + { + if (QMessageBox::Yes == QMessageBox::warning(this, tr("Remove selected"), tr("You really want remove the selected Snapmatic picutres and Savegame files?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) + { + foreach (ProfileWidget *widget, widgets.keys()) + { + if (widget->isSelected()) + { + if (widget->getWidgetType() == "SnapmaticWidget") + { + SnapmaticWidget *picWidget = (SnapmaticWidget*)widget; + QString fileName = picWidget->getPicturePath(); + if (!QFile::exists(fileName) || QFile::remove(fileName)) + { + pictureDeleted_f(picWidget); + } + } + else if (widget->getWidgetType() == "SavegameWidget") + { + SavegameWidget *sgdWidget = (SavegameWidget*)widget; + SavegameData *savegame = sgdWidget->getSavegame(); + QString fileName = savegame->getSavegameFileName(); + if (!QFile::exists(fileName) || QFile::remove(fileName)) + { + savegameDeleted_f(sgdWidget); + } + } + } + } + if (selectedWidgts != 0) + { + QMessageBox::warning(this, tr("Remove selected"), tr("Failed at remove the complete selected Snapmatic pictures and/or Savegame files")); + } + } + } + else + { + QMessageBox::information(this, tr("Remove selected"), tr("No Snapmatic pictures or Savegames files are selected")); + } } void ProfileInterface::importFiles() @@ -1534,865 +814,71 @@ void ProfileInterface::importFiles() on_cmdImport_clicked(); } -void ProfileInterface::settingsApplied(int _contentMode, bool languageChanged) +void ProfileInterface::settingsApplied(int _contentMode, QString language) { - if (languageChanged) - retranslateUi(); + Q_UNUSED(language) contentMode = _contentMode; - if (contentMode == 2) { - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - widget->setSelectionMode(true); - widget->setContentMode(contentMode); - if (languageChanged) - widget->retranslate(); - } + + if (contentMode == 2) + { + foreach(ProfileWidget *widget, widgets.keys()) + { + widget->setSelectionMode(true); + widget->setContentMode(contentMode); } } - else { - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - if (selectedWidgts == 0) { - widget->setSelectionMode(false); - } - widget->setContentMode(contentMode); - if (languageChanged) - widget->retranslate(); + else + { + foreach(ProfileWidget *widget, widgets.keys()) + { + if (selectedWidgts == 0) + { + widget->setSelectionMode(false); } + widget->setContentMode(contentMode); } } -#ifdef Q_OS_MAC - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); -#if QT_VERSION >= 0x060000 - if (QApplication::style()->objectName() == "macos") { -#else - if (QApplication::style()->objectName() == "macintosh") { -#endif - ui->hlButtons->setSpacing(6 * screenRatio); - ui->hlButtons->setContentsMargins(9 * screenRatio, 15 * screenRatio, 15 * screenRatio, 17 * screenRatio); - } - else { - ui->hlButtons->setSpacing(6 * screenRatio); - ui->hlButtons->setContentsMargins(9 * screenRatio, 9 * screenRatio, 9 * screenRatio, 9 * screenRatio); - } -#endif } void ProfileInterface::enableSelected() { - QList snapmaticWidgets; - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - if (widget->isSelected()) { - if (widget->getWidgetType() == "SnapmaticWidget") { - SnapmaticWidget *snapmaticWidget = qobject_cast(widget); - snapmaticWidgets += snapmaticWidget; + int fails = 0; + foreach (ProfileWidget *widget, widgets.keys()) + { + if (widget->isSelected()) + { + if (widget->getWidgetType() == "SnapmaticWidget") + { + SnapmaticWidget *snapmaticWidget = (SnapmaticWidget*)widget; + if (!snapmaticWidget->makePictureVisible()) + { + fails++; } } } } - if (snapmaticWidgets.isEmpty()) { - QMessageBox::information(this, QApplication::translate("UserInterface", "Show In-game"), QApplication::translate("ProfileInterface", "No Snapmatic pictures are selected")); - return; - } - QStringList fails; - for (SnapmaticWidget *widget : qAsConst(snapmaticWidgets)) { - SnapmaticPicture *picture = widget->getPicture(); - if (!widget->makePictureVisible()) { - fails << QString("%1 [%2]").arg(picture->getPictureTitle(), picture->getPictureString()); - } - } - if (!fails.isEmpty()) { - QMessageBox::warning(this, QApplication::translate("UserInterface", "Show In-game"), QApplication::translate("ProfileInterface", "%1 failed with...\n\n%2", "Action failed with...").arg(QApplication::translate("UserInterface", "Show In-game"), fails.join(", "))); - } } void ProfileInterface::disableSelected() { - QList snapmaticWidgets; - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - if (widget->isSelected()) { - if (widget->getWidgetType() == "SnapmaticWidget") { - SnapmaticWidget *snapmaticWidget = qobject_cast(widget); - snapmaticWidgets += snapmaticWidget; + int fails = 0; + foreach (ProfileWidget *widget, widgets.keys()) + { + if (widget->isSelected()) + { + if (widget->getWidgetType() == "SnapmaticWidget") + { + SnapmaticWidget *snapmaticWidget = (SnapmaticWidget*)widget; + if (!snapmaticWidget->makePictureHidden()) + { + fails++; } } } } - if (snapmaticWidgets.isEmpty()) { - QMessageBox::information(this, QApplication::translate("UserInterface", "Hide In-game"), QApplication::translate("ProfileInterface", "No Snapmatic pictures are selected")); - return; - } - QStringList fails; - for (SnapmaticWidget *widget : qAsConst(snapmaticWidgets)) { - SnapmaticPicture *picture = widget->getPicture(); - if (!widget->makePictureHidden()) { - fails << QString("%1 [%2]").arg(picture->getPictureTitle(), picture->getPictureString()); - } - } - if (!fails.isEmpty()) { - QMessageBox::warning(this, QApplication::translate("UserInterface", "Hide In-game"), QApplication::translate("ProfileInterface", "%1 failed with...\n\n%2", "Action failed with...").arg(QApplication::translate("UserInterface", "Hide In-game"), fails.join(", "))); - } } int ProfileInterface::selectedWidgets() { return selectedWidgts; } - -void ProfileInterface::contextMenuTriggeredPIC(QContextMenuEvent *ev) -{ - SnapmaticWidget *picWidget = qobject_cast(sender()); - if (picWidget != previousWidget) { - if (previousWidget != nullptr) { - previousWidget->setStyleSheet(QLatin1String("")); - } - picWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}")); - previousWidget = picWidget; - } - QMenu contextMenu(picWidget); - const int selectedCount = selectedWidgets(); - if (contentMode < 20 || selectedCount == 0) { - QMenu editMenu(SnapmaticWidget::tr("Edi&t"), picWidget); - if (picWidget->isHidden()) { - editMenu.addAction(SnapmaticWidget::tr("Show &In-game"), picWidget, SLOT(makePictureVisibleSlot())); - } - else { - editMenu.addAction(SnapmaticWidget::tr("Hide &In-game"), picWidget, SLOT(makePictureHiddenSlot())); - } - editMenu.addAction(PictureDialog::tr("&Edit Properties..."), picWidget, SLOT(editSnapmaticProperties())); - editMenu.addAction(PictureDialog::tr("&Overwrite Image..."), picWidget, SLOT(editSnapmaticImage())); - editMenu.addSeparator(); - editMenu.addAction(PictureDialog::tr("Open &Map Viewer..."), picWidget, SLOT(openMapViewer())); - editMenu.addAction(PictureDialog::tr("Open &JSON Editor..."), picWidget, SLOT(editSnapmaticRawJson())); - QMenu exportMenu(SnapmaticWidget::tr("&Export"), this); - exportMenu.addAction(PictureDialog::tr("Export as &Picture..."), picWidget, SLOT(on_cmdExport_clicked())); - exportMenu.addAction(PictureDialog::tr("Export as &Snapmatic..."), picWidget, SLOT(on_cmdCopy_clicked())); - contextMenu.addAction(SnapmaticWidget::tr("&View"), picWidget, SLOT(on_cmdView_clicked())); - contextMenu.addMenu(&editMenu); - contextMenu.addMenu(&exportMenu); - contextMenu.addAction(SnapmaticWidget::tr("&Remove"), picWidget, SLOT(on_cmdDelete_clicked())); - contextMenu.addSeparator(); - if (!picWidget->isSelected()) - contextMenu.addAction(SnapmaticWidget::tr("&Select"), picWidget, SLOT(pictureSelected())); - else { - contextMenu.addAction(SnapmaticWidget::tr("&Deselect"), picWidget, SLOT(pictureSelected())); - } - if (selectedCount != widgets.count()) { - contextMenu.addAction(SnapmaticWidget::tr("Select &All"), picWidget, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A")); - } - if (selectedCount != 0) { - contextMenu.addAction(SnapmaticWidget::tr("&Deselect All"), picWidget, SLOT(deselectAllWidgets()), QKeySequence::fromString("Ctrl+D")); - } - contextMenuOpened = true; - contextMenu.exec(ev->globalPos()); - contextMenuOpened = false; - QTimer::singleShot(0, this, SLOT(hoverProfileWidgetCheck())); - } - else { - QMenu editMenu(SnapmaticWidget::tr("Edi&t"), picWidget); - editMenu.addAction(QApplication::translate("UserInterface", "&Qualify as Avatar"), this, SLOT(massToolQualify()), QKeySequence::fromString("Shift+Q")); - editMenu.addAction(QApplication::translate("UserInterface", "Change &Players..."), this, SLOT(massToolPlayers()), QKeySequence::fromString("Shift+P")); - editMenu.addAction(QApplication::translate("UserInterface", "Change &Crew..."), this, SLOT(massToolCrew()), QKeySequence::fromString("Shift+C")); - editMenu.addAction(QApplication::translate("UserInterface", "Change &Title..."), this, SLOT(massToolTitle()), QKeySequence::fromString("Shift+T")); - editMenu.addSeparator(); - editMenu.addAction(SnapmaticWidget::tr("Show &In-game"), this, SLOT(enableSelected()), QKeySequence::fromString("Shift+E")); - editMenu.addAction(SnapmaticWidget::tr("Hide &In-game"), this, SLOT(disableSelected()), QKeySequence::fromString("Shift+D")); - contextMenu.addMenu(&editMenu); - contextMenu.addAction(SavegameWidget::tr("&Export"), this, SLOT(exportSelected()), QKeySequence::fromString("Ctrl+E")); - contextMenu.addAction(SavegameWidget::tr("&Remove"), this, SLOT(deleteSelectedR()), QKeySequence::fromString("Ctrl+Del")); - contextMenu.addSeparator(); - if (!picWidget->isSelected()) { - contextMenu.addAction(SnapmaticWidget::tr("&Select"), picWidget, SLOT(pictureSelected())); - } - else { - contextMenu.addAction(SnapmaticWidget::tr("&Deselect"), picWidget, SLOT(pictureSelected())); - } - if (selectedCount != widgets.count()) { - contextMenu.addAction(SnapmaticWidget::tr("Select &All"), picWidget, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A")); - } - if (selectedCount != 0) { - contextMenu.addAction(SnapmaticWidget::tr("&Deselect All"), picWidget, SLOT(deselectAllWidgets()), QKeySequence::fromString("Ctrl+D")); - } - contextMenuOpened = true; - contextMenu.exec(ev->globalPos()); - contextMenuOpened = false; - QTimer::singleShot(0, this, SLOT(hoverProfileWidgetCheck())); - } -} - -void ProfileInterface::contextMenuTriggeredSGD(QContextMenuEvent *ev) -{ - SavegameWidget *sgdWidget = qobject_cast(sender()); - if (sgdWidget != previousWidget) { - if (previousWidget != nullptr) { - previousWidget->setStyleSheet(QLatin1String("")); - } - sgdWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color:palette(highlight)}QLabel#labSavegameStr{color:palette(highlighted-text)}")); - previousWidget = sgdWidget; - } - QMenu contextMenu(sgdWidget); - const int selectedCount = selectedWidgets(); - if (contentMode < 20 || selectedCount == 0) { - contextMenu.addAction(SavegameWidget::tr("&View"), sgdWidget, SLOT(on_cmdView_clicked())); - contextMenu.addAction(SavegameWidget::tr("&Export"), sgdWidget, SLOT(on_cmdCopy_clicked())); - contextMenu.addAction(SavegameWidget::tr("&Remove"), sgdWidget, SLOT(on_cmdDelete_clicked())); - contextMenu.addSeparator(); - if (!sgdWidget->isSelected()) { - contextMenu.addAction(SavegameWidget::tr("&Select"), sgdWidget, SLOT(savegameSelected())); - } - else { - contextMenu.addAction(SavegameWidget::tr("&Deselect"), sgdWidget, SLOT(savegameSelected())); - } - if (selectedCount != widgets.count()) { - contextMenu.addAction(SavegameWidget::tr("Select &All"), sgdWidget, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A")); - } - if (selectedCount != 0) { - contextMenu.addAction(SavegameWidget::tr("&Deselect All"), sgdWidget, SLOT(deselectAllWidgets()), QKeySequence::fromString("Ctrl+D")); - } - contextMenuOpened = true; - contextMenu.exec(ev->globalPos()); - contextMenuOpened = false; - QTimer::singleShot(0, this, SLOT(hoverProfileWidgetCheck())); - } - else { - QMenu editMenu(SnapmaticWidget::tr("Edi&t"), sgdWidget); - editMenu.addAction(QApplication::translate("UserInterface", "&Qualify as Avatar"), this, SLOT(massToolQualify()), QKeySequence::fromString("Shift+Q")); - editMenu.addAction(QApplication::translate("UserInterface", "Change &Players..."), this, SLOT(massToolPlayers()), QKeySequence::fromString("Shift+P")); - editMenu.addAction(QApplication::translate("UserInterface", "Change &Crew..."), this, SLOT(massToolCrew()), QKeySequence::fromString("Shift+C")); - editMenu.addAction(QApplication::translate("UserInterface", "Change &Title..."), this, SLOT(massToolTitle()), QKeySequence::fromString("Shift+T")); - editMenu.addSeparator(); - editMenu.addAction(SnapmaticWidget::tr("Show &In-game"), this, SLOT(enableSelected()), QKeySequence::fromString("Shift+E")); - editMenu.addAction(SnapmaticWidget::tr("Hide &In-game"), this, SLOT(disableSelected()), QKeySequence::fromString("Shift+D")); - contextMenu.addMenu(&editMenu); - contextMenu.addAction(SavegameWidget::tr("&Export"), this, SLOT(exportSelected()), QKeySequence::fromString("Ctrl+E")); - contextMenu.addAction(SavegameWidget::tr("&Remove"), this, SLOT(deleteSelectedR()), QKeySequence::fromString("Ctrl+Del")); - contextMenu.addSeparator(); - if (!sgdWidget->isSelected()) - contextMenu.addAction(SavegameWidget::tr("&Select"), sgdWidget, SLOT(savegameSelected())); - else { - contextMenu.addAction(SavegameWidget::tr("&Deselect"), sgdWidget, SLOT(savegameSelected())); - } - if (selectedCount != widgets.count()) { - contextMenu.addAction(SavegameWidget::tr("Select &All"), sgdWidget, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A")); - } - if (selectedCount != 0) { - contextMenu.addAction(SavegameWidget::tr("&Deselect All"), sgdWidget, SLOT(deselectAllWidgets()), QKeySequence::fromString("Ctrl+D")); - } - contextMenuOpened = true; - contextMenu.exec(ev->globalPos()); - contextMenuOpened = false; - QTimer::singleShot(0, this, SLOT(hoverProfileWidgetCheck())); - } -} - -void ProfileInterface::on_saProfileContent_dropped(const QMimeData *mimeData) -{ - if (!mimeData) - return; - if (mimeData->hasImage()) { - QImage *snapmaticImage = new QImage(qvariant_cast(mimeData->imageData())); - importImage(snapmaticImage, QDateTime::currentDateTime()); - } - else if (mimeData->hasUrls()) { - importUrls(mimeData); - } -} - -void ProfileInterface::retranslateUi() -{ - ui->retranslateUi(this); - QString appVersion = QApplication::applicationVersion(); - const char* literalBuildType = GTA5SYNC_BUILDTYPE; -#ifdef GTA5SYNC_COMMIT - if ((strcmp(literalBuildType, REL_BUILDTYPE) != 0) && !appVersion.contains("-")) - appVersion = appVersion % "-" % GTA5SYNC_COMMIT; -#endif - ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion)); -} - -bool ProfileInterface::eventFilter(QObject *watched, QEvent *event) -{ - if (event->type() == QEvent::KeyPress) { - if (isProfileLoaded) { - QKeyEvent *keyEvent = dynamic_cast(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(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) { - ProfileWidget *pWidget = qobject_cast(watched); - if (pWidget->underMouse()) { - bool styleSheetChanged = false; - if (pWidget->getWidgetType() == "SnapmaticWidget") { - if (pWidget != previousWidget) { - pWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}")); - styleSheetChanged = true; - } - } - else if (pWidget->getWidgetType() == "SavegameWidget") { - if (pWidget != previousWidget) { - pWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color:palette(highlight)}QLabel#labSavegameStr{color:palette(highlighted-text)}")); - styleSheetChanged = true; - } - } - if (styleSheetChanged) { - if (previousWidget != nullptr) { - previousWidget->setStyleSheet(QLatin1String("")); - } - previousWidget = pWidget; - } - } - return true; - } - } - else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) { - if ((watched->objectName() == "SavegameWidget" || watched->objectName() == "SnapmaticWidget") && isProfileLoaded) { - ProfileWidget *pWidget = nullptr; - for (auto it = widgets.constBegin(); it != widgets.constEnd(); it++) { - ProfileWidget *widget = it.key(); - QPoint mousePos = widget->mapFromGlobal(QCursor::pos()); - if (widget->rect().contains(mousePos)) { - pWidget = widget; - break; - } - } - if (pWidget != nullptr) { - bool styleSheetChanged = false; - if (pWidget->getWidgetType() == "SnapmaticWidget") { - if (pWidget != previousWidget) { - pWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}")); - styleSheetChanged = true; - } - } - else if (pWidget->getWidgetType() == "SavegameWidget") { - if (pWidget != previousWidget) { - pWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color:palette(highlight)}QLabel#labSavegameStr{color:palette(highlighted-text)}")); - styleSheetChanged = true; - } - } - if (styleSheetChanged) { - if (previousWidget != nullptr) { - previousWidget->setStyleSheet(QLatin1String("")); - } - previousWidget = pWidget; - } - } - } - } - else if (event->type() == QEvent::WindowDeactivate && isProfileLoaded) { - if (previousWidget != nullptr && watched == previousWidget) { - previousWidget->setStyleSheet(QLatin1String("")); - previousWidget = nullptr; - } - } - else if (event->type() == QEvent::Leave && isProfileLoaded && !contextMenuOpened) { - if (watched->objectName() == "SavegameWidget" || watched->objectName() == "SnapmaticWidget") { - ProfileWidget *pWidget = qobject_cast(watched); - QPoint mousePos = pWidget->mapFromGlobal(QCursor::pos()); - if (!pWidget->geometry().contains(mousePos)) { - if (previousWidget != nullptr) { - previousWidget->setStyleSheet(QLatin1String("")); - previousWidget = nullptr; - } - } - } - else if (watched->objectName() == "ProfileInterface") { - if (previousWidget != nullptr) { - previousWidget->setStyleSheet(QLatin1String("")); - previousWidget = nullptr; - } - } - } - return false; -} - -void ProfileInterface::hoverProfileWidgetCheck() -{ - ProfileWidget *pWidget = nullptr; - for (auto it = widgets.constBegin(); it != widgets.constEnd(); it++) { - ProfileWidget *widget = it.key(); - if (widget->underMouse()) { - pWidget = widget; - break; - } - } - if (pWidget != nullptr) { - bool styleSheetChanged = false; - if (pWidget->getWidgetType() == "SnapmaticWidget") { - if (pWidget != previousWidget) { - pWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}")); - styleSheetChanged = true; - } - } - else if (pWidget->getWidgetType() == "SavegameWidget") { - if (pWidget != previousWidget) { - pWidget->setStyleSheet(QString("QFrame#SavegameFrame{background-color:palette(highlight)}QLabel#labSavegameStr{color:palette(highlighted-text)}")); - styleSheetChanged = true; - } - } - if (styleSheetChanged) { - if (previousWidget != nullptr) { - previousWidget->setStyleSheet(QLatin1String("")); - } - previousWidget = pWidget; - } - } - else { - if (previousWidget != nullptr) { - previousWidget->setStyleSheet(QLatin1String("")); - previousWidget = nullptr; - } - } -} - -void ProfileInterface::updatePalette() -{ - ui->saProfile->setStyleSheet(QString("QWidget#saProfileContent{background-color:palette(base)}")); - if (previousWidget != nullptr) { - if (previousWidget->getWidgetType() == "SnapmaticWidget") { - previousWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}")); - } - else if (previousWidget->getWidgetType() == "SavegameWidget") { - previousWidget->setStyleSheet(QString("QFrame#SnapmaticFrame{background-color:palette(highlight)}QLabel#labPicStr{color:palette(highlighted-text)}")); - } - } -} - -bool ProfileInterface::isSupportedImageFile(QString selectedFileName) -{ - for (const QByteArray &imageFormat : QImageReader::supportedImageFormats()) { - QString imageFormatStr = QString(".") % QString::fromUtf8(imageFormat).toLower(); - if (selectedFileName.length() >= imageFormatStr.length() && selectedFileName.toLower().right(imageFormatStr.length()) == imageFormatStr) { - return true; - } - } - return false; -} - -void ProfileInterface::massTool(MassTool tool) -{ - switch(tool) { - case MassTool::Qualify: { - QList snapmaticWidgets; - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - if (widget->isSelected()) { - if (widget->getWidgetType() == "SnapmaticWidget") { - SnapmaticWidget *snapmaticWidget = qobject_cast(widget); - snapmaticWidgets += snapmaticWidget; - } - } - } - } - - if (snapmaticWidgets.isEmpty()) { - QMessageBox::information(this, tr("Qualify as Avatar"), tr("No Snapmatic pictures are selected")); - return; - } - - // Prepare Progress - - int maximumId = snapmaticWidgets.length(); - int overallId = 0; - - QProgressDialog pbDialog(this); - pbDialog.setWindowFlags(pbDialog.windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowCloseButtonHint); - pbDialog.setWindowTitle(tr("Patch selected...")); - pbDialog.setLabelText(tr("Patch file %1 of %2 files").arg(QString::number(1), QString::number(maximumId))); - pbDialog.setRange(1, maximumId); - pbDialog.setValue(1); - pbDialog.setModal(true); - QList pbBtn = pbDialog.findChildren(); - pbBtn.at(0)->setDisabled(true); - QList pbBar = pbDialog.findChildren(); - pbBar.at(0)->setTextVisible(false); - pbDialog.setAutoClose(false); - pbDialog.show(); - - // Begin Progress - - QStringList fails; - for (SnapmaticWidget *snapmaticWidget : qAsConst(snapmaticWidgets)) { - // Update Progress - overallId++; - pbDialog.setValue(overallId); - pbDialog.setLabelText(tr("Patch file %1 of %2 files").arg(QString::number(overallId), QString::number(maximumId))); - - SnapmaticPicture *picture = snapmaticWidget->getPicture(); - - SnapmaticProperties snapmaticProperties = picture->getSnapmaticProperties(); - snapmaticProperties.isSelfie = true; - snapmaticProperties.isMug = false; - snapmaticProperties.isFromRSEditor = false; - snapmaticProperties.isFromDirector = false; - snapmaticProperties.isMeme = false; - - QString currentFilePath = picture->getPictureFilePath(); - QString originalFilePath = picture->getOriginalPictureFilePath(); - QString backupFileName = originalFilePath % ".bak"; - if (!QFile::exists(backupFileName)) { - QFile::copy(currentFilePath, backupFileName); - } - SnapmaticProperties fallbackProperties = picture->getSnapmaticProperties(); - picture->setSnapmaticProperties(snapmaticProperties); - if (!picture->exportPicture(currentFilePath)) { - picture->setSnapmaticProperties(fallbackProperties); - fails << QString("%1 [%2]").arg(picture->getPictureTitle(), picture->getPictureString()); - } - else { - picture->emitUpdate(); - QApplication::processEvents(); - } - } - pbDialog.close(); - if (!fails.isEmpty()) { - QMessageBox::warning(this, tr("Qualify as Avatar"), tr("%1 failed with...\n\n%2", "Action failed with...").arg(tr("Qualify", "%1 failed with..."), fails.join(", "))); - } - } - break; - case MassTool::Players: { - QList snapmaticWidgets; - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - if (widget->isSelected()) { - if (widget->getWidgetType() == "SnapmaticWidget") { - SnapmaticWidget *snapmaticWidget = qobject_cast(widget); - snapmaticWidgets += snapmaticWidget; - } - } - } - } - - if (snapmaticWidgets.isEmpty()) { - QMessageBox::information(this, tr("Change Players..."), tr("No Snapmatic pictures are selected")); - return; - } - - QStringList players; - if (snapmaticWidgets.length() == 1) { - players = snapmaticWidgets.at(0)->getPicture()->getSnapmaticProperties().playersList; - } - - PlayerListDialog *playerListDialog = new PlayerListDialog(players, profileDB, this); - playerListDialog->setModal(true); - playerListDialog->show(); - playerListDialog->exec(); - if (!playerListDialog->isListUpdated()) - return; - players = playerListDialog->getPlayerList(); - delete playerListDialog; - - // Prepare Progress - - int maximumId = snapmaticWidgets.length(); - int overallId = 0; - - QProgressDialog pbDialog(this); - pbDialog.setWindowFlags(pbDialog.windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowCloseButtonHint); - pbDialog.setWindowTitle(tr("Patch selected...")); - pbDialog.setLabelText(tr("Patch file %1 of %2 files").arg(QString::number(1), QString::number(maximumId))); - pbDialog.setRange(1, maximumId); - pbDialog.setValue(1); - pbDialog.setModal(true); - QList pbBtn = pbDialog.findChildren(); - pbBtn.at(0)->setDisabled(true); - QList pbBar = pbDialog.findChildren(); - pbBar.at(0)->setTextVisible(false); - pbDialog.setAutoClose(false); - pbDialog.show(); - - // Begin Progress - - QStringList fails; - for (SnapmaticWidget *snapmaticWidget : qAsConst(snapmaticWidgets)) { - // Update Progress - overallId++; - pbDialog.setValue(overallId); - pbDialog.setLabelText(tr("Patch file %1 of %2 files").arg(QString::number(overallId), QString::number(maximumId))); - - SnapmaticPicture *picture = snapmaticWidget->getPicture(); - - SnapmaticProperties snapmaticProperties = picture->getSnapmaticProperties(); - snapmaticProperties.playersList = players; - - QString currentFilePath = picture->getPictureFilePath(); - QString originalFilePath = picture->getOriginalPictureFilePath(); - QString backupFileName = originalFilePath % ".bak"; - if (!QFile::exists(backupFileName)) { - QFile::copy(currentFilePath, backupFileName); - } - SnapmaticProperties fallbackProperties = picture->getSnapmaticProperties(); - picture->setSnapmaticProperties(snapmaticProperties); - if (!picture->exportPicture(currentFilePath)) { - picture->setSnapmaticProperties(fallbackProperties); - fails << QString("%1 [%2]").arg(picture->getPictureTitle(), picture->getPictureString()); - } - else { - picture->emitUpdate(); - QApplication::processEvents(); - } - } - pbDialog.close(); - if (!fails.isEmpty()) { - QMessageBox::warning(this, tr("Change Players..."), tr("%1 failed with...\n\n%2", "Action failed with...").arg(tr("Change Players", "%1 failed with..."), fails.join(", "))); - } - } - break; - case MassTool::Crew: { - QList snapmaticWidgets; - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - if (widget->isSelected()) { - if (widget->getWidgetType() == "SnapmaticWidget") { - SnapmaticWidget *snapmaticWidget = qobject_cast(widget); - snapmaticWidgets += snapmaticWidget; - } - } - } - } - - if (snapmaticWidgets.isEmpty()) { - QMessageBox::information(this, tr("Change Crew..."), tr("No Snapmatic pictures are selected")); - return; - } - - int crewID = 0; - if (snapmaticWidgets.length() == 1) { - crewID = snapmaticWidgets.at(0)->getPicture()->getSnapmaticProperties().crewID; - } - { -preSelectionCrewID: - bool ok; - int indexNum = 0; - QStringList itemList; - QStringList crewList = crewDB->getCrews(); - if (!crewList.contains(QLatin1String("0"))) { - crewList += QLatin1String("0"); - } - crewList.sort(); - for (QString crew : qAsConst(crewList)) { - itemList += QString("%1 (%2)").arg(crew, crewDB->getCrewName(crew.toInt())); - } - if (crewList.contains(QString::number(crewID))) { - indexNum = crewList.indexOf(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 (newCrew.contains(" ")) newCrew = newCrew.split(" ").at(0); - if (newCrew.length() > 10) return; - for (const QChar &crewChar : qAsConst(newCrew)) { - if (!crewChar.isNumber()) { - QMessageBox::warning(this, tr("Change Crew..."), tr("Failed to enter a valid Snapmatic Crew ID")); - goto preSelectionCrewID; - } - } - if (!crewList.contains(newCrew)) { - crewDB->addCrew(crewID); - } - crewID = newCrew.toInt(); - } - else { - return; - } - } - - // Prepare Progress - - int maximumId = snapmaticWidgets.length(); - int overallId = 0; - - QProgressDialog pbDialog(this); - pbDialog.setWindowFlags(pbDialog.windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowCloseButtonHint); - pbDialog.setWindowTitle(tr("Patch selected...")); - pbDialog.setLabelText(tr("Patch file %1 of %2 files").arg(QString::number(1), QString::number(maximumId))); - pbDialog.setRange(1, maximumId); - pbDialog.setValue(1); - pbDialog.setModal(true); - QList pbBtn = pbDialog.findChildren(); - pbBtn.at(0)->setDisabled(true); - QList pbBar = pbDialog.findChildren(); - pbBar.at(0)->setTextVisible(false); - pbDialog.setAutoClose(false); - pbDialog.show(); - - // Begin Progress - - QStringList fails; - for (SnapmaticWidget *snapmaticWidget : qAsConst(snapmaticWidgets)) { - // Update Progress - overallId++; - pbDialog.setValue(overallId); - pbDialog.setLabelText(tr("Patch file %1 of %2 files").arg(QString::number(overallId), QString::number(maximumId))); - - SnapmaticPicture *picture = snapmaticWidget->getPicture(); - - SnapmaticProperties snapmaticProperties = picture->getSnapmaticProperties(); - snapmaticProperties.crewID = crewID; - - QString currentFilePath = picture->getPictureFilePath(); - QString originalFilePath = picture->getOriginalPictureFilePath(); - QString backupFileName = originalFilePath % ".bak"; - if (!QFile::exists(backupFileName)) { - QFile::copy(currentFilePath, backupFileName); - } - SnapmaticProperties fallbackProperties = picture->getSnapmaticProperties(); - picture->setSnapmaticProperties(snapmaticProperties); - if (!picture->exportPicture(currentFilePath)) { - picture->setSnapmaticProperties(fallbackProperties); - fails << QString("%1 [%2]").arg(picture->getPictureTitle(), picture->getPictureString()); - } - else { - picture->emitUpdate(); - QApplication::processEvents(); - } - } - pbDialog.close(); - if (!fails.isEmpty()) { - QMessageBox::warning(this, tr("Change Crew..."), tr("%1 failed with...\n\n%2", "Action failed with...").arg(tr("Change Crew", "%1 failed with..."), fails.join(", "))); - } - } - break; - case MassTool::Title: { - QList snapmaticWidgets; - for (const QString &widgetStr : qAsConst(widgets)) { - ProfileWidget *widget = widgets.key(widgetStr, nullptr); - if (widget != nullptr) { - if (widget->isSelected()) { - if (widget->getWidgetType() == "SnapmaticWidget") { - SnapmaticWidget *snapmaticWidget = qobject_cast(widget); - snapmaticWidgets += snapmaticWidget; - } - } - } - } - - if (snapmaticWidgets.isEmpty()) { - QMessageBox::information(this, tr("Change Title..."), tr("No Snapmatic pictures are selected")); - return; - } - - QString snapmaticTitle; - if (snapmaticWidgets.length() == 1) { - snapmaticTitle = snapmaticWidgets.at(0)->getPicture()->getPictureTitle(); - } - { -preSelectionTitle: - bool ok; - QString newTitle = QInputDialog::getText(this, QApplication::translate("SnapmaticEditor", "Snapmatic Title"), QApplication::translate("SnapmaticEditor", "New Snapmatic title:"), QLineEdit::Normal, snapmaticTitle, &ok, windowFlags()^Qt::Dialog^Qt::WindowMinMaxButtonsHint); - if (ok && !newTitle.isEmpty()) { - if (!SnapmaticPicture::verifyTitle(newTitle)) { - QMessageBox::warning(this, tr("Change Title..."), tr("Failed to enter a valid Snapmatic title")); - goto preSelectionTitle; - } - snapmaticTitle = newTitle; - } - else { - return; - } - } - - // Prepare Progress - - int maximumId = snapmaticWidgets.length(); - int overallId = 0; - - QProgressDialog pbDialog(this); - pbDialog.setWindowFlags(pbDialog.windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowCloseButtonHint); - pbDialog.setWindowTitle(tr("Patch selected...")); - pbDialog.setLabelText(tr("Patch file %1 of %2 files").arg(QString::number(overallId), QString::number(maximumId))); - pbDialog.setRange(1, maximumId); - pbDialog.setValue(1); - pbDialog.setModal(true); - QList pbBtn = pbDialog.findChildren(); - pbBtn.at(0)->setDisabled(true); - QList pbBar = pbDialog.findChildren(); - pbBar.at(0)->setTextVisible(false); - pbDialog.setAutoClose(false); - pbDialog.show(); - - // Begin Progress - - QStringList fails; - for (SnapmaticWidget *snapmaticWidget : qAsConst(snapmaticWidgets)) { - // Update Progress - overallId++; - pbDialog.setValue(overallId); - pbDialog.setLabelText(tr("Patch file %1 of %2 files").arg(QString::number(overallId), QString::number(maximumId))); - - SnapmaticPicture *picture = snapmaticWidget->getPicture(); - - QString currentFilePath = picture->getPictureFilePath(); - QString originalFilePath = picture->getOriginalPictureFilePath(); - QString backupFileName = originalFilePath % ".bak"; - if (!QFile::exists(backupFileName)) { - QFile::copy(currentFilePath, backupFileName); - } - QString fallbackTitle = picture->getPictureTitle(); - picture->setPictureTitle(snapmaticTitle); - if (!picture->exportPicture(currentFilePath)) { - picture->setPictureTitle(fallbackTitle); - fails << QString("%1 [%2]").arg(picture->getPictureTitle(), picture->getPictureString()); - } - else { - picture->emitUpdate(); - QApplication::processEvents(); - } - } - pbDialog.close(); - if (!fails.isEmpty()) { - QMessageBox::warning(this, tr("Change Title..."), tr("%1 failed with...\n\n%2", "Action failed with...").arg(tr("Change Title", "%1 failed with..."), fails.join(", "))); - } - } - break; - } -} - -int ProfileInterface::getRandomUid() -{ - int random_int = pcg32_boundedrand_r(&rng, 2147483647); - return random_int; -} diff --git a/ProfileInterface.h b/ProfileInterface.h old mode 100644 new mode 100755 index a3297ae..692d888 --- a/ProfileInterface.h +++ b/ProfileInterface.h @@ -1,153 +1,110 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef PROFILEINTERFACE_H -#define PROFILEINTERFACE_H - -#include "SnapmaticPicture.h" -#include "SnapmaticWidget.h" -#include "ProfileDatabase.h" -#include "DatabaseThread.h" -#include "SavegameWidget.h" -#include "ProfileLoader.h" -#include "ProfileWidget.h" -#include "ExportThread.h" -#include "SavegameData.h" -#include "CrewDatabase.h" -#include "pcg_basic.h" -#include -#include -#include -#include -#include -#include -#include - -namespace Ui { -class ProfileInterface; -} - -enum class MassTool : int { Qualify = 0, Players = 1, Crew = 2, Title = 3 }; - -class ProfileInterface : public QWidget -{ - Q_OBJECT -public: - explicit ProfileInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent = 0); - void setProfileFolder(QString folder, QString profile); - void settingsApplied(int contentMode, bool languageChanged); - void setupProfileInterface(); - void massTool(MassTool tool); - int selectedWidgets(); - void retranslateUi(); - ~ProfileInterface(); - -public slots: - void contextMenuTriggeredPIC(QContextMenuEvent* ev); - void contextMenuTriggeredSGD(QContextMenuEvent* ev); - void hoverProfileWidgetCheck(); - void selectAllWidgets(); - void deselectAllWidgets(); - void disableSelected(); - void enableSelected(); - void exportSelected(); - void deleteSelected(); - void deleteSelectedR(); - void updatePalette(); - void importFiles(); - -private slots: - void on_cmdCloseProfile_clicked(); - void on_cmdImport_clicked(); - void pictureLoaded_event(SnapmaticPicture *picture); - void pictureFixed_event(SnapmaticPicture *picture); - void savegameLoaded_event(SavegameData *savegame, QString savegamePath); - void loadingProgress(int value, int maximum); - void pictureDeleted_event(); - void savegameDeleted_event(); - void profileLoaded_p(); - void profileWidgetSelected(); - void profileWidgetDeselected(); - void massToolQualify(); - void massToolPlayers(); - void massToolCrew(); - void massToolTitle(); - void dialogNextPictureRequested(QWidget *dialog); - void dialogPreviousPictureRequested(QWidget *dialog); - void on_saProfileContent_dropped(const QMimeData *mimeData); -#if QT_VERSION >= 0x050000 - void directoryChanged(const QString &path); - void directoryScanned(QVector savegameFiles, QVector snapmaticPics); -#endif - -protected: - bool eventFilter(QObject *watched, QEvent *event); - -private: - ProfileDatabase *profileDB; - CrewDatabase *crewDB; - DatabaseThread *threadDB; - Ui::ProfileInterface *ui; - - ProfileLoader *profileLoader; - ProfileWidget *previousWidget; - QList savegames; - QList pictures; - QMap widgets; -#if QT_VERSION >= 0x050000 - QFileSystemWatcher fileSystemWatcher; - QVector savegameFiles; - QVector snapmaticPics; -#endif - QSpacerItem *saSpacerItem; - QStringList fixedPictures; - QString enabledPicStr; - QString profileFolder; - QString profileName; - QString loadingStr; - QString language; - pcg32_random_t rng; - bool contextMenuOpened; - bool isProfileLoaded; - int selectedWidgts; - int contentMode; - - bool isSupportedImageFile(QString selectedFileName); - bool importFile(QString selectedFile, QDateTime importDateTime, bool notMultiple); - bool importUrls(const QMimeData *mimeData); - bool importRemote(QUrl remoteUrl); - bool importImage(QImage *snapmaticImage, QDateTime importDateTime); - bool importFilesProgress(QStringList selectedFiles); - bool importSnapmaticPicture(SnapmaticPicture *picture, bool warn = true); - bool importSavegameData(SavegameData *savegame, QString sgdPath, bool warn = true); - void pictureLoaded(SnapmaticPicture *picture, bool inserted); - void savegameLoaded(SavegameData *savegame, QString savegamePath, bool inserted); - void savegameDeleted(SavegameWidget *sgdWidget, bool isRemoteEmited = false); - void pictureDeleted(SnapmaticWidget *picWidget, bool isRemoteEmited = false); - void deleteSelectedL(bool isRemoteEmited = false); - void insertSnapmaticIPI(QWidget *widget); - void insertSavegameIPI(QWidget *widget); - void sortingProfileInterface(); - int getRandomUid(); - -signals: - void profileLoaded(); - void profileClosed(); -}; - -#endif // PROFILEINTERFACE_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef PROFILEINTERFACE_H +#define PROFILEINTERFACE_H + +#include "SnapmaticPicture.h" +#include "SnapmaticWidget.h" +#include "ProfileDatabase.h" +#include "DatabaseThread.h" +#include "SavegameWidget.h" +#include "ProfileLoader.h" +#include "ProfileWidget.h" +#include "ExportThread.h" +#include "SavegameData.h" +#include "CrewDatabase.h" +#include +#include +#include +#include +#include + +namespace Ui { +class ProfileInterface; +} + +class ProfileInterface : public QWidget +{ + Q_OBJECT +public: + explicit ProfileInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent = 0); + void setProfileFolder(QString folder, QString profile); + void settingsApplied(int contentMode, QString language); + void setupProfileInterface(); + void disableSelected(); + void enableSelected(); + int selectedWidgets(); + ~ProfileInterface(); + +public slots: + void selectAllWidgets(); + void deselectAllWidgets(); + void exportSelected(); + void deleteSelected(); + void importFiles(); + +private slots: + void on_cmdCloseProfile_clicked(); + void on_cmdImport_clicked(); + void pictureLoaded(SnapmaticPicture *picture, QString picturePath); + void savegameLoaded(SavegameData *savegame, QString savegamePath); + void loadingProgress(int value, int maximum); + void pictureDeleted(); + void savegameDeleted(); + void profileLoaded_p(); + void profileWidgetSelected(); + void profileWidgetDeselected(); + void dialogNextPictureRequested(QWidget *dialog); + void dialogPreviousPictureRequested(QWidget *dialog); + +private: + ProfileDatabase *profileDB; + CrewDatabase *crewDB; + DatabaseThread *threadDB; + Ui::ProfileInterface *ui; + + ProfileLoader *profileLoader; + QList savegames; + QList pictures; + QMap widgets; + QSpacerItem *saSpacerItem; + QString enabledPicStr; + QString profileFolder; + QString profileName; + QString loadingStr; + int selectedWidgts; + int contentMode; + + bool importFile(QString selectedFile, bool warn); + bool importSnapmaticPicture(SnapmaticPicture *picture, QString picPath, bool warn = true); + bool importSavegameData(SavegameData *savegame, QString sgdPath, bool warn = true); + void pictureLoaded_f(SnapmaticPicture *picture, QString picturePath, bool inserted); + void savegameLoaded_f(SavegameData *savegame, QString savegamePath, bool inserted); + void savegameDeleted_f(QWidget *sgdWidget); + void pictureDeleted_f(QWidget *picWidget); + void insertSnapmaticIPI(QWidget *widget); + void insertSavegameIPI(QWidget *widget); + void sortingProfileInterface(); + +signals: + void profileLoaded(); + void profileClosed(); +}; + +#endif // PROFILEINTERFACE_H diff --git a/ProfileInterface.ui b/ProfileInterface.ui old mode 100644 new mode 100755 index 066e636..65f7ce9 --- a/ProfileInterface.ui +++ b/ProfileInterface.ui @@ -1,244 +1,233 @@ - - - ProfileInterface - - - - 0 - 0 - 400 - 300 - - - - Profile Interface - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - Loading file %1 of %2 files - - - Qt::AlignCenter - - - - - - - 0 - - - false - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - - 0 - 0 - 398 - 257 - - - - true - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - - - - - - - - - - - - - - - - 6 - - - 9 - - - 9 - - - 9 - - - 9 - - - - - %1 %2 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Import file - - - &Import... - - - true - - - - - - - - 0 - 0 - - - - Close profile - - - &Close - - - true - - - - - - - - - - UiModWidget - QWidget -
UiModWidget.h
- 1 - - dropped(QMimeData*) - -
-
- - -
+ + + ProfileInterface + + + + 0 + 0 + 400 + 300 + + + + Profile Interface + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + Loading file %1 of %2 files + + + Qt::AlignCenter + + + + + + + 0 + + + false + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + + + + + + + + + + + + + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + %1 %2 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Import exported file + + + &Import... + + + true + + + + + + + + 0 + 0 + + + + Close profile + + + &Close + + + + + + true + + + + + + + + + + diff --git a/ProfileLoader.cpp b/ProfileLoader.cpp old mode 100644 new mode 100755 index a4e4318..d8e4f15 --- a/ProfileLoader.cpp +++ b/ProfileLoader.cpp @@ -1,133 +1,93 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SnapmaticPicture.h" -#include "ProfileLoader.h" -#include "SavegameData.h" -#include "CrewDatabase.h" -#include "wrapper.h" -#include -#include -#include -#include -#ifdef Q_OS_WIN -#include -#include -#else -#include "sys/types.h" -#include "sys/stat.h" -#include "dirent.h" -#endif - -ProfileLoader::ProfileLoader(QString profileFolder, CrewDatabase *crewDB, QObject *parent) : QThread(parent), profileFolder(profileFolder), crewDB(crewDB) -{ -} - -void ProfileLoader::run() -{ - int curFile = 1; - int maximumV = 0; - QVector crewList; - QVector savegameFiles; - QVector snapmaticPics; - -#ifdef Q_OS_WIN - QDir dir(profileFolder); - const QStringList files = dir.entryList(QDir::Files); - for (const QString &fileName : files) { - if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) { - savegameFiles << fileName; - maximumV++; - } - if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) { - snapmaticPics << fileName; - maximumV++; - } - } -#else - DIR *dirp = opendir(profileFolder.toUtf8().constData()); - struct dirent *dp; - while ((dp = readdir(dirp)) != 0) { - const QString fileName = QString::fromUtf8(dp->d_name); - const QString filePath = profileFolder % "/" % fileName; - struct stat fileStat; - stat(filePath.toUtf8().constData(), &fileStat); - if (S_ISREG(fileStat.st_mode) != 0) { - if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) { - savegameFiles << fileName; - maximumV++; - } - if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) { - snapmaticPics << fileName; - maximumV++; - } - } - } - closedir(dirp); -#endif - - // Directory successfully scanned - emit directoryScanned(savegameFiles, snapmaticPics); - - // Loading pictures and savegames - emit loadingProgress(curFile, maximumV); - for (const QString &SavegameFile : qAsConst(savegameFiles)) { - emit loadingProgress(curFile, maximumV); - const QString sgdPath = profileFolder % "/" % SavegameFile; - SavegameData *savegame = new SavegameData(sgdPath); - if (savegame->readingSavegame()) { - emit savegameLoaded(savegame, sgdPath); - } - curFile++; - } - for (const QString &SnapmaticPic : qAsConst(snapmaticPics)) { - emit loadingProgress(curFile, maximumV); - const QString picturePath = profileFolder % "/" % SnapmaticPic; - SnapmaticPicture *picture = new SnapmaticPicture(picturePath); - if (picture->readingPicture(true)) { - if (picture->isFormatSwitched()) { - picture->setSnapmaticFormat(SnapmaticFormat::PGTA_Format); - if (picture->exportPicture(picturePath, SnapmaticFormat::PGTA_Format)) { - emit pictureFixed(picture); - } - } - emit pictureLoaded(picture); - int crewNumber = picture->getSnapmaticProperties().crewID; - if (!crewList.contains(crewNumber)) { - crewList += crewNumber; - } - } - curFile++; - } - - // adding found crews - crewDB->setAddingCrews(true); - for (int crewID : qAsConst(crewList)) { - crewDB->addCrew(crewID); - } - crewDB->setAddingCrews(false); -} - -void ProfileLoader::preloaded() -{ -} - -void ProfileLoader::loaded() -{ -} - +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "ProfileLoader.h" +#include "SnapmaticPicture.h" +#include "SavegameData.h" +#include "CrewDatabase.h" +#include +#include +#include +#include + +ProfileLoader::ProfileLoader(QString profileFolder, CrewDatabase *crewDB, QObject *parent) : QThread(parent), profileFolder(profileFolder), crewDB(crewDB) +{ + +} + +void ProfileLoader::run() +{ + int curFile = 1; + QDir profileDir; + QList crewList; + profileDir.setPath(profileFolder); + + // Seek pictures and savegames + profileDir.setNameFilters(QStringList("SGTA*")); + QStringList SavegameFiles = profileDir.entryList(QDir::Files | QDir::NoDot, QDir::NoSort); + QStringList BackupFiles = SavegameFiles.filter(".bak", Qt::CaseInsensitive); + profileDir.setNameFilters(QStringList("PGTA*")); + QStringList SnapmaticPics = profileDir.entryList(QDir::Files | QDir::NoDot, QDir::NoSort); + BackupFiles.append(SnapmaticPics.filter(".bak", Qt::CaseInsensitive)); + + SavegameFiles.removeDuplicates(); + SnapmaticPics.removeDuplicates(); + foreach(const QString &BackupFile, BackupFiles) + { + SavegameFiles.removeAll(BackupFile); + SnapmaticPics.removeAll(BackupFile); + } + + int maximumV = SavegameFiles.length() + SnapmaticPics.length(); + + // Loading pictures and savegames + emit loadingProgress(curFile, maximumV); + foreach(const QString &SavegameFile, SavegameFiles) + { + emit loadingProgress(curFile, maximumV); + QString sgdPath = profileFolder + QDir::separator() + SavegameFile; + SavegameData *savegame = new SavegameData(sgdPath); + if (savegame->readingSavegame()) + { + emit savegameLoaded(savegame, sgdPath); + } + curFile++; + } + foreach(const QString &SnapmaticPic, SnapmaticPics) + { + emit loadingProgress(curFile, maximumV); + QString picturePath = profileFolder + QDir::separator() + SnapmaticPic; + SnapmaticPicture *picture = new SnapmaticPicture(picturePath); + if (picture->readingPicture()) + { + emit pictureLoaded(picture, picturePath); + int crewNumber = picture->getSnapmaticProperties().crewID; + if (!crewList.contains(crewNumber)) + { + crewList.append(crewNumber); + } + } + curFile++; + } + + // adding found crews + foreach(int crewID, crewList) + { + crewDB->addCrew(crewID); + } +} diff --git a/ProfileLoader.h b/ProfileLoader.h old mode 100644 new mode 100755 index 6bde0ed..c0ed9b4 --- a/ProfileLoader.h +++ b/ProfileLoader.h @@ -1,54 +1,48 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef PROFILELOADER_H -#define PROFILELOADER_H - -#include "SnapmaticPicture.h" -#include "SavegameData.h" -#include "CrewDatabase.h" -#include -#include - -class ProfileLoader : public QThread -{ - Q_OBJECT -public: - explicit ProfileLoader(QString profileFolder, CrewDatabase *crewDB, QObject *parent = 0); - -protected: - void run(); - -private: - QString profileFolder; - CrewDatabase *crewDB; - ProfileLoader *profileLoader; - -private slots: - void preloaded(); - void loaded(); - -signals: - void pictureLoaded(SnapmaticPicture *picture); - void pictureFixed(SnapmaticPicture *picture); - void savegameLoaded(SavegameData *savegame, QString savegamePath); - void loadingProgress(int value, int maximum); - void directoryScanned(QVector savegameFiles, QVector snapmaticPics); -}; - -#endif // PROFILELOADER_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef PROFILELOADER_H +#define PROFILELOADER_H + +#include "SnapmaticPicture.h" +#include "SavegameData.h" +#include "CrewDatabase.h" +#include +#include + +class ProfileLoader : public QThread +{ + Q_OBJECT +public: + explicit ProfileLoader(QString profileFolder, CrewDatabase *crewDB, QObject *parent = 0); + +protected: + void run(); + +private: + QString profileFolder; + CrewDatabase *crewDB; + ProfileLoader *profileLoader; + +signals: + void pictureLoaded(SnapmaticPicture *picture, QString picturePath); + void savegameLoaded(SavegameData *savegame, QString savegamePath); + void loadingProgress(int value, int maximum); +}; + +#endif // PROFILELOADER_H diff --git a/ProfileWidget.cpp b/ProfileWidget.cpp old mode 100644 new mode 100755 index a325d92..1b208e2 --- a/ProfileWidget.cpp +++ b/ProfileWidget.cpp @@ -1,66 +1,61 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "ProfileWidget.h" -#include - -ProfileWidget::ProfileWidget(QWidget *parent) : QWidget(parent) -{ - contentMode = 0; -} - -ProfileWidget::~ProfileWidget() -{ -} - -void ProfileWidget::retranslate() -{ - qDebug() << "ProfileWidget::retranslate got used without overwrite"; -} - -bool ProfileWidget::isSelected() -{ - qDebug() << "ProfileWidget::isSelected got used without overwrite"; - return false; -} - -void ProfileWidget::setSelected(bool isSelected) -{ - qDebug() << "ProfileWidget::setSelected got used without overwrite, result" << isSelected; -} - -void ProfileWidget::setSelectionMode(bool selectionMode) -{ - qDebug() << "ProfileWidget::setSelectionMode got used without overwrite, result:" << selectionMode; -} - -QString ProfileWidget::getWidgetType() -{ - qDebug() << "ProfileWidget::getWidgetType got used without overwrite"; - return "ProfileWidget"; -} - -int ProfileWidget::getContentMode() -{ - return contentMode; -} - -void ProfileWidget::setContentMode(int _contentMode) -{ - contentMode = _contentMode; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "ProfileWidget.h" +#include + +ProfileWidget::ProfileWidget(QWidget *parent) : QWidget(parent) +{ + contentMode = 0; +} + +ProfileWidget::~ProfileWidget() +{ +} + +bool ProfileWidget::isSelected() +{ + qDebug() << "ProfileWidget::isSelected got used without overwrite"; + return false; +} + +void ProfileWidget::setSelected(bool isSelected) +{ + qDebug() << "ProfileWidget::setSelected got used without overwrite, result" << isSelected; +} + +void ProfileWidget::setSelectionMode(bool selectionMode) +{ + qDebug() << "ProfileWidget::setSelectionMode got used without overwrite, result:" << selectionMode; +} + +QString ProfileWidget::getWidgetType() +{ + qDebug() << "ProfileWidget::getWidgetType got used without overwrite"; + return "ProfileWidget"; +} + +int ProfileWidget::getContentMode() +{ + return contentMode; +} + +void ProfileWidget::setContentMode(int _contentMode) +{ + contentMode = _contentMode; +} diff --git a/ProfileWidget.h b/ProfileWidget.h old mode 100644 new mode 100755 index b7d2f77..cde3218 --- a/ProfileWidget.h +++ b/ProfileWidget.h @@ -1,46 +1,45 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef PROFILEWIDGET_H -#define PROFILEWIDGET_H - -#include - -class ProfileWidget : public QWidget -{ - Q_OBJECT -public: - explicit ProfileWidget(QWidget *parent = 0); - virtual void setSelectionMode(bool selectionMode); - virtual void setContentMode(int contentMode); - virtual void setSelected(bool isSelected); - virtual bool isSelected(); - virtual QString getWidgetType(); - virtual int getContentMode(); - virtual void retranslate(); - ~ProfileWidget(); - -private: - int contentMode; - -signals: - -public slots: -}; - -#endif // PROFILEWIDGET_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef PROFILEWIDGET_H +#define PROFILEWIDGET_H + +#include + +class ProfileWidget : public QWidget +{ + Q_OBJECT +public: + explicit ProfileWidget(QWidget *parent = 0); + virtual void setSelectionMode(bool selectionMode); + virtual void setContentMode(int contentMode); + virtual void setSelected(bool isSelected); + virtual bool isSelected(); + virtual QString getWidgetType(); + virtual int getContentMode(); + ~ProfileWidget(); + +private: + int contentMode; + +signals: + +public slots: +}; + +#endif // PROFILEWIDGET_H diff --git a/README.md b/README.md index 8831699..397d79a 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,30 @@ ## gta5view -Open Source Snapmatic and Savegame viewer/editor for GTA V +Grand Theft Auto V Savegame and Snapmatic viewer -- View Snapmatics with the ability to disable them in-game -- Edit Snapmatic pictures and properties in multiple ways -- Import/Export Snapmatics, Savegames and pictures -- Choose between multiple Social Club accounts as GTA V profiles IDs +- Viewing Snapmatics and giving the ability to disable them in-game +- Import/Export Snapmatics and Savegames +- Choosing between multiple Social Club accounts as GTA V profiles IDs #### Screenshots -![Snapmatic Picture Viewer](res/src/picture.png) -![User Interface](res/src/mainui.png) -![Snapmatic Properties](res/src/prop.png) + + -#### Build gta5view for Windows +#### Build gta5view Debian/Ubuntu - # Note: Install Docker Community Edition and Git before continuing - docker pull sypingauto/gta5view-build:1.10-static - git clone https://gitlab.com/Syping/gta5view - docker run --rm -v "$PWD/gta5view:/gta5view" -it sypingauto/gta5view-build:1.10-static - mingw64-qt-cmake -B /gta5view/build /gta5view - cmake --build /gta5view/build + apt-get install git gcc g++ qtbase5-dev qt5-qmake make checkinstall + git clone https://github.com/SyDevTeam/gta5view + mkdir build && cd build + qmake -qt=5 ../gta5view.pro # or just qmake ../gta5view.pro + make + INSTALL_ROOT=/usr checkinstall --pkgname=gta5view --pkggroup=utility --requires=libqt5core5a,libqt5gui5,libqt5network5,libqt5widgets5 -#### Build gta5view for Debian/Ubuntu +#### Build gta5view Windows - sudo apt-get install cmake git gcc g++ libqt5svg5-dev make qtbase5-dev qttranslations5-l10n - git clone https://gitlab.com/Syping/gta5view - cmake -B gta5view-build gta5view - cmake --build gta5view-build - sudo cmake --install gta5view-build +Downloading Qt Framework and install it.
+Take the Online Installer and choose the MinGW version or install Microsoft Visual Studio 2013/2015 Community
+Downloading Source Code over GitHub or with your Git client.
+Open the gta5view.pro file with Qt Creator and build it over Qt Creator.
-#### Build gta5view for Arch/Manjaro +#### Download Binary Releases - sudo pacman -S cmake gcc git make qt5-base qt5-svg qt5-tools qt5-translations - git clone https://gitlab.com/Syping/gta5view - cmake -B gta5view-build gta5view - cmake --build gta5view-build - sudo cmake --install gta5view-build - -#### Build gta5view for Fedora/RHEL - - sudo dnf install cmake git gcc gcc-c++ make qt5-qtbase-devel qt5-qtsvg-devel qt5-qttranslations - git clone https://gitlab.com/Syping/gta5view - cmake -B gta5view-build gta5view - cmake --build gta5view-build - sudo cmake --install gta5view-build +Go to gta5view release and download the .exe file for Windows, .deb file for Debian/Ubuntu and .rpm file for Red Hat/openSuSE/Fedora. diff --git a/RagePhoto.cpp b/RagePhoto.cpp deleted file mode 100644 index ba03159..0000000 --- a/RagePhoto.cpp +++ /dev/null @@ -1,893 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2020-2022 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "RagePhoto.h" -#include -#include -#include -#if QT_VERSION < 0x060000 -#include -#else -#include -#include -#endif -#ifdef RAGEPHOTO_BENCHMARK -#include -#include -#endif - -inline quint32 joaatFromSI(const char *data, size_t size) -{ - quint32 val = 0xE47AB81CUL; - for (size_t i = 0; i != size; i++) { - val += data[i]; - val += (val << 10); - val ^= (val >> 6); - } - val += (val << 3); - val ^= (val >> 11); - val += (val << 15); - return val; -} - -RagePhoto::RagePhoto() -{ - p_photoFormat = PhotoFormat::Undefined; - p_isLoaded = false; - p_inputMode = -1; -} - -RagePhoto::RagePhoto(const QByteArray &data) : p_fileData(data) -{ - p_photoFormat = PhotoFormat::Undefined; - p_isLoaded = false; - p_inputMode = 0; -} - -RagePhoto::RagePhoto(const QString &filePath) : p_filePath(filePath) -{ - p_photoFormat = PhotoFormat::Undefined; - p_isLoaded = false; - p_inputMode = 1; -} - -RagePhoto::RagePhoto(QIODevice *ioDevice) : p_ioDevice(ioDevice) -{ - p_photoFormat = PhotoFormat::Undefined; - p_isLoaded = false; - p_inputMode = 2; -} - -bool RagePhoto::isLoaded() -{ - return p_isLoaded; -} - -bool RagePhoto::load() -{ - if (p_inputMode == -1) - return false; - - if (p_isLoaded) - clear(); - - if (p_inputMode == 1) { - QFile pictureFile(p_filePath); - if (pictureFile.open(QIODevice::ReadOnly)) { - p_fileData = pictureFile.readAll(); - } - pictureFile.close(); - } - else if (p_inputMode == 2) { - if (!p_ioDevice->isOpen()) { - if (!p_ioDevice->open(QIODevice::ReadOnly)) - return false; - } - p_fileData = p_ioDevice->readAll(); - } - - QBuffer dataBuffer(&p_fileData); - dataBuffer.open(QIODevice::ReadOnly); - -#ifdef RAGEPHOTO_BENCHMARK - auto benchmark_parse_start = std::chrono::high_resolution_clock::now(); -#endif - - char uInt32Buffer[4]; - qint64 size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - quint32 format = charToUInt32LE(uInt32Buffer); - - if (format == static_cast(PhotoFormat::GTA5)) { - char photoHeader[256]; - size = dataBuffer.read(photoHeader, 256); - if (size != 256) { - return false; - } - for (const QChar &photoChar : utf16LEToString(photoHeader, 256)) { - if (photoChar.isNull()) - break; - p_photoString += photoChar; - } - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_headerSum = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_endOfFile = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_jsonOffset = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_titlOffset = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_descOffset = charToUInt32LE(uInt32Buffer); - - char markerBuffer[4]; - size = dataBuffer.read(markerBuffer, 4); - if (size != 4) - return false; - if (strncmp(markerBuffer, "JPEG", 4) != 0) - return false; - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_photoBuffer = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - quint32 t_photoSize = charToUInt32LE(uInt32Buffer); - - char *photoData = static_cast(malloc(t_photoSize)); - if (!photoData) - return false; - size = dataBuffer.read(photoData, t_photoSize); - if (size != t_photoSize) { - free(photoData); - return false; - } - p_photoData = QByteArray(photoData, t_photoSize); - free(photoData); - - dataBuffer.seek(p_jsonOffset + 264); - size = dataBuffer.read(markerBuffer, 4); - if (size != 4) - return false; - if (strncmp(markerBuffer, "JSON", 4) != 0) - return false; - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_jsonBuffer = charToUInt32LE(uInt32Buffer); - - char *jsonBytes = static_cast(malloc(p_jsonBuffer)); - if (!jsonBytes) - return false; - size = dataBuffer.read(jsonBytes, p_jsonBuffer); - if (size != p_jsonBuffer) { - free(jsonBytes); - return false; - } - quint32 i; - for (i = 0; i != p_jsonBuffer; i++) { - if (jsonBytes[i] == '\x00') - break; - } - p_jsonData = QByteArray(jsonBytes, i); - free(jsonBytes); - QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData); - if (t_jsonDocument.isNull()) - return false; - p_jsonObject = t_jsonDocument.object(); - - dataBuffer.seek(p_titlOffset + 264); - size = dataBuffer.read(markerBuffer, 4); - if (size != 4) - return false; - if (strncmp(markerBuffer, "TITL", 4) != 0) - return false; - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_titlBuffer = charToUInt32LE(uInt32Buffer); - - char *titlBytes = static_cast(malloc(p_titlBuffer)); - if (!titlBytes) - return false; - size = dataBuffer.read(titlBytes, p_titlBuffer); - if (size != p_titlBuffer){ - free(titlBytes); - return false; - } - for (i = 0; i != p_titlBuffer; i++) { - if (titlBytes[i] == '\x00') - break; - } - p_titleString = QString::fromUtf8(titlBytes, i); - free(titlBytes); - - dataBuffer.seek(p_descOffset + 264); - size = dataBuffer.read(markerBuffer, 4); - if (size != 4) - return false; - if (strncmp(markerBuffer, "DESC", 4) != 0) - return false; - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_descBuffer = charToUInt32LE(uInt32Buffer); - - char *descBytes = static_cast(malloc(p_descBuffer)); - if (!descBytes) - return false; - size = dataBuffer.read(descBytes, p_descBuffer); - if (size != p_descBuffer) { - free(descBytes); - return false; - } - for (i = 0; i != p_descBuffer; i++) { - if (descBytes[i] == '\x00') - break; - } - p_descriptionString = QString::fromUtf8(descBytes, i); - free(descBytes); - - dataBuffer.seek(p_endOfFile + 260); - size = dataBuffer.read(markerBuffer, 4); - if (size != 4) - return false; - if (strncmp(markerBuffer, "JEND", 4) != 0) - return false; - -#ifdef RAGEPHOTO_BENCHMARK - auto benchmark_parse_end = std::chrono::high_resolution_clock::now(); - auto benchmark_ns = std::chrono::duration_cast(benchmark_parse_end - benchmark_parse_start); - if (p_inputMode == 1) { - QTextStream(stdout) << QFileInfo(p_filePath).fileName() << ": " << benchmark_ns.count() << "ns" << Qt::endl; - } - else { - QTextStream(stdout) << "PGTA5" << p_jsonObject.value("uid").toInt() << ": " << benchmark_ns.count() << "ns" << Qt::endl; - } -#endif - - if (p_photoFormat != PhotoFormat::G5EX) - p_photoFormat = PhotoFormat::GTA5; - - p_fileData.clear(); - p_isLoaded = true; - return true; - } - else if (format == static_cast(PhotoFormat::G5EX)) { - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - format = charToUInt32LE(uInt32Buffer); - if (format == static_cast(ExportFormat::G5E3P)) { - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - quint32 compressedSize = charToUInt32LE(uInt32Buffer); - - char *compressedPhotoHeader = static_cast(malloc(compressedSize)); - if (!compressedPhotoHeader) - return false; - size = dataBuffer.read(compressedPhotoHeader, compressedSize); - if (size != compressedSize) { - free(compressedPhotoHeader); - return false; - } - QByteArray t_photoHeader = QByteArray::fromRawData(compressedPhotoHeader, compressedSize); - t_photoHeader = qUncompress(t_photoHeader); - free(compressedPhotoHeader); - if (t_photoHeader.isEmpty()) - return false; - p_photoString = QString::fromUtf8(t_photoHeader); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_headerSum = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_photoBuffer = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - compressedSize = charToUInt32LE(uInt32Buffer); - - char *compressedPhoto = static_cast(malloc(compressedSize)); - if (!compressedPhoto) - return false; - size = dataBuffer.read(compressedPhoto, compressedSize); - if (size != compressedSize) { - free(compressedPhoto); - return false; - } - QByteArray t_photoData = QByteArray::fromRawData(compressedPhoto, compressedSize); - p_photoData = qUncompress(t_photoData); - free(compressedPhoto); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_jsonOffset = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_jsonBuffer = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - compressedSize = charToUInt32LE(uInt32Buffer); - - char *compressedJson = static_cast(malloc(compressedSize)); - if (!compressedJson) - return false; - size = dataBuffer.read(compressedJson, compressedSize); - if (size != compressedSize) { - free(compressedJson); - return false; - } - QByteArray t_jsonBytes = QByteArray::fromRawData(compressedJson, compressedSize); - p_jsonData = qUncompress(t_jsonBytes); - free(compressedJson); - if (p_jsonData.isEmpty()) - return false; - QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData); - if (t_jsonDocument.isNull()) - return false; - p_jsonObject = t_jsonDocument.object(); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_titlOffset = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_titlBuffer = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - compressedSize = charToUInt32LE(uInt32Buffer); - - char *compressedTitl = static_cast(malloc(compressedSize)); - if (!compressedTitl) - return false; - size = dataBuffer.read(compressedTitl, compressedSize); - if (size != compressedSize) { - free(compressedTitl); - return false; - } - QByteArray t_titlBytes = QByteArray::fromRawData(compressedTitl, compressedSize); - t_titlBytes = qUncompress(t_titlBytes); - free(compressedTitl); - p_titleString = QString::fromUtf8(t_titlBytes); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_descOffset = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_descBuffer = charToUInt32LE(uInt32Buffer); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - compressedSize = charToUInt32LE(uInt32Buffer); - - char *compressedDesc = static_cast(malloc(compressedSize)); - if (!compressedDesc) - return false; - size = dataBuffer.read(compressedDesc, compressedSize); - if (size != compressedSize) { - free(compressedDesc); - return false; - } - QByteArray t_descBytes = QByteArray::fromRawData(compressedDesc, compressedSize); - t_descBytes = qUncompress(t_descBytes); - free(compressedDesc); - p_descriptionString = QString::fromUtf8(t_descBytes); - - size = dataBuffer.read(uInt32Buffer, 4); - if (size != 4) - return false; - p_endOfFile = charToUInt32LE(uInt32Buffer); - -#ifdef RAGEPHOTO_BENCHMARK - auto benchmark_parse_end = std::chrono::high_resolution_clock::now(); - auto benchmark_ns = std::chrono::duration_cast(benchmark_parse_end - benchmark_parse_start); - if (p_inputMode == 1) { - QTextStream(stdout) << QFileInfo(p_filePath).fileName() << ": " << benchmark_ns.count() << "ns" << Qt::endl; - } - else { - QTextStream(stdout) << "PGTA5" << p_jsonObject.value("uid").toInt() << ": " << benchmark_ns.count() << "ns" << Qt::endl; - } -#endif - - p_photoFormat = PhotoFormat::G5EX; - - p_fileData.clear(); - p_isLoaded = true; - return true; - } - else if (format == static_cast(ExportFormat::G5E2P)) { - p_photoFormat = PhotoFormat::G5EX; - p_fileData = qUncompress(dataBuffer.readAll()); - if (p_fileData.isEmpty()) - return false; - p_inputMode = 0; - return load(); - } - else if (format == static_cast(ExportFormat::G5E1P)) { -#if QT_VERSION >= 0x050A00 - size = dataBuffer.skip(1); - if (size != 1) - return false; -#else - if (!dataBuffer.seek(dataBuffer.pos() + 1)) - return false; -#endif - - char length[1]; - size = dataBuffer.read(length, 1); - if (size != 1) - return false; - int i_length = QByteArray::number(static_cast(length[0]), 16).toInt() + 6; - -#if QT_VERSION >= 0x050A00 - size = dataBuffer.skip(i_length); - if (size != i_length) - return false; -#else - if (!dataBuffer.seek(dataBuffer.pos() + i_length)) - return false; -#endif - - p_photoFormat = PhotoFormat::G5EX; - p_fileData = qUncompress(dataBuffer.readAll()); - if (p_fileData.isEmpty()) - return false; - p_inputMode = 0; - return load(); - } - else { - return false; - } - } - else { - return false; - } -} - -void RagePhoto::clear() -{ - p_photoFormat = PhotoFormat::Undefined; - p_jsonObject = QJsonObject(); - p_descriptionString.clear(); - p_jsonData.clear(); - p_photoData.clear(); - p_photoString.clear(); - p_titleString.clear(); - p_headerSum = 0; - p_isLoaded = false; -} - -void RagePhoto::setDescription(const QString &description) -{ - p_descriptionString = description; -} - -void RagePhoto::setFileData(const QByteArray &data) -{ - p_fileData = data; - p_inputMode = 0; -} - -void RagePhoto::setFilePath(const QString &filePath) -{ - p_filePath = filePath; - p_inputMode = 1; -} - -void RagePhoto::setIODevice(QIODevice *ioDevice) -{ - p_ioDevice = ioDevice; - p_inputMode = 2; -} - -bool RagePhoto::setJsonData(const QByteArray &data) -{ - QJsonDocument t_jsonDocument = QJsonDocument::fromJson(data); - if (t_jsonDocument.isNull()) - return false; - p_jsonObject = t_jsonDocument.object(); - // serializer band-aid - QJsonObject t_jsonObject = p_jsonObject; - t_jsonObject["sign"] = "__gta5view.sign"; - t_jsonDocument.setObject(t_jsonObject); - p_jsonData = t_jsonDocument.toJson(QJsonDocument::Compact); - char sign_char[24]; - sprintf(sign_char, "%llu", (0x100000000000000ULL | joaatFromSI(p_photoData.constData(), p_photoData.size()))); - p_jsonData.replace("\"__gta5view.sign\"", sign_char); - return true; -} - -bool RagePhoto::setPhotoBuffer(quint32 size, bool moveOffsets) -{ - if (size < static_cast(p_photoData.size())) - return false; - p_photoBuffer = size; - if (moveOffsets) { - p_jsonOffset = size + 28; - p_titlOffset = p_jsonOffset + p_jsonBuffer + 8; - p_descOffset = p_titlOffset + p_titlBuffer + 8; - p_endOfFile = p_descOffset + p_descBuffer + 12; - } - return true; -} - -bool RagePhoto::setPhotoData(const QByteArray &data) -{ - quint32 size = data.size(); - if (size > p_photoBuffer) - return false; - p_photoData = data; - // serializer band-aid - setJsonData(p_jsonData); - return true; -} - -bool RagePhoto::setPhotoData(const char *data, int size) -{ - if (static_cast(size) > p_photoBuffer) - return false; - p_photoData = QByteArray(data, size); - // serializer band-aid - setJsonData(p_jsonData); - return true; -} - -void RagePhoto::setPhotoFormat(PhotoFormat photoFormat) -{ - p_photoFormat = photoFormat; -} - -void RagePhoto::setTitle(const QString &title) -{ - p_titleString = title; -} - -const QByteArray RagePhoto::jsonData(JsonFormat jsonFormat) -{ - if (jsonFormat == JsonFormat::Compact) { - return QJsonDocument(p_jsonObject).toJson(QJsonDocument::Compact); - } - else if (jsonFormat == JsonFormat::Indented) { - return QJsonDocument(p_jsonObject).toJson(QJsonDocument::Indented); - } - else { - return p_jsonData; - } -} - -const QJsonObject RagePhoto::jsonObject() -{ - return p_jsonObject; -} - -const QByteArray RagePhoto::photoData() -{ - return p_photoData; -} - -const QString RagePhoto::description() -{ - return p_descriptionString; -} - -const QString RagePhoto::photoString() -{ - return p_photoString; -} - -const QString RagePhoto::title() -{ - return p_titleString; -} - -quint32 RagePhoto::photoBuffer() -{ - return p_photoBuffer; -} - -quint32 RagePhoto::photoSize() -{ - return p_photoData.size(); -} - -RagePhoto::PhotoFormat RagePhoto::photoFormat() -{ - return p_photoFormat; -} - -QByteArray RagePhoto::save(PhotoFormat photoFormat) -{ - QByteArray data; - QBuffer dataBuffer(&data); - dataBuffer.open(QIODevice::WriteOnly); - save(&dataBuffer, photoFormat); - return data; -} - -void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat) -{ - // serializer band-aid - setJsonData(p_jsonData); - - if (photoFormat == PhotoFormat::G5EX) { - char uInt32Buffer[4]; - quint32 format = static_cast(PhotoFormat::G5EX); - uInt32ToCharLE(format, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - format = static_cast(ExportFormat::G5E3P); - uInt32ToCharLE(format, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - QByteArray compressedData = qCompress(p_photoString.toUtf8(), 9); - quint32 compressedSize = compressedData.size(); - uInt32ToCharLE(compressedSize, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - ioDevice->write(compressedData); - - uInt32ToCharLE(p_headerSum, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - uInt32ToCharLE(p_photoBuffer, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - compressedData = qCompress(p_photoData, 9); - compressedSize = compressedData.size(); - uInt32ToCharLE(compressedSize, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - ioDevice->write(compressedData); - - uInt32ToCharLE(p_jsonOffset, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - uInt32ToCharLE(p_jsonBuffer, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - compressedData = qCompress(p_jsonData, 9); - compressedSize = compressedData.size(); - uInt32ToCharLE(compressedSize, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - ioDevice->write(compressedData); - - uInt32ToCharLE(p_titlOffset, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - uInt32ToCharLE(p_titlBuffer, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - compressedData = qCompress(p_titleString.toUtf8(), 9); - compressedSize = compressedData.size(); - uInt32ToCharLE(compressedSize, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - ioDevice->write(compressedData); - - uInt32ToCharLE(p_descOffset, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - uInt32ToCharLE(p_descBuffer, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - compressedData = qCompress(p_descriptionString.toUtf8(), 9); - compressedSize = compressedData.size(); - uInt32ToCharLE(compressedSize, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - ioDevice->write(compressedData); - - uInt32ToCharLE(p_endOfFile, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - } - else if (photoFormat == PhotoFormat::GTA5) { - char uInt32Buffer[4]; - quint32 format = static_cast(PhotoFormat::GTA5); - uInt32ToCharLE(format, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - QByteArray photoHeader = stringToUtf16LE(p_photoString); - if (photoHeader.startsWith("\xFF\xFE")) { - photoHeader.remove(0, 2); - } - qint64 photoHeaderSize = photoHeader.size(); - if (photoHeaderSize > 256) { - photoHeader = photoHeader.left(256); - photoHeaderSize = 256; - } - ioDevice->write(photoHeader); - for (qint64 size = photoHeaderSize; size < 256; size++) { - ioDevice->write("\x00", 1); - } - - uInt32ToCharLE(p_headerSum, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - uInt32ToCharLE(p_endOfFile, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - uInt32ToCharLE(p_jsonOffset, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - uInt32ToCharLE(p_titlOffset, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - uInt32ToCharLE(p_descOffset, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - ioDevice->write("JPEG", 4); - - uInt32ToCharLE(p_photoBuffer, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - quint32 t_photoSize = p_photoData.size(); - uInt32ToCharLE(t_photoSize, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - ioDevice->write(p_photoData); - for (qint64 size = t_photoSize; size < p_photoBuffer; size++) { - ioDevice->write("\x00", 1); - } - - ioDevice->seek(p_jsonOffset + 264); - ioDevice->write("JSON", 4); - - uInt32ToCharLE(p_jsonBuffer, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - qint64 dataSize = p_jsonData.size(); - ioDevice->write(p_jsonData); - for (qint64 size = dataSize; size < p_jsonBuffer; size++) { - ioDevice->write("\x00", 1); - } - - ioDevice->seek(p_titlOffset + 264); - ioDevice->write("TITL", 4); - - uInt32ToCharLE(p_titlBuffer, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - QByteArray data = p_titleString.toUtf8(); - dataSize = data.size(); - ioDevice->write(data); - for (qint64 size = dataSize; size < p_titlBuffer; size++) { - ioDevice->write("\x00", 1); - } - - ioDevice->seek(p_descOffset + 264); - ioDevice->write("DESC", 4); - - uInt32ToCharLE(p_descBuffer, uInt32Buffer); - ioDevice->write(uInt32Buffer, 4); - - data = p_descriptionString.toUtf8(); - dataSize = data.size(); - ioDevice->write(data); - for (qint64 size = dataSize; size < p_descBuffer; size++) { - ioDevice->write("\x00", 1); - } - - ioDevice->seek(p_endOfFile + 260); - ioDevice->write("JEND", 4); - } -} - -RagePhoto* RagePhoto::loadFile(const QString &filePath) -{ - RagePhoto *ragePhoto = new RagePhoto(filePath); - ragePhoto->load(); - return ragePhoto; -} - -quint32 RagePhoto::charToUInt32BE(char *x) -{ - return (static_cast(x[0]) << 24 | - static_cast(x[1]) << 16 | - static_cast(x[2]) << 8 | - static_cast(x[3])); -} - -quint32 RagePhoto::charToUInt32LE(char *x) -{ - return (static_cast(x[3]) << 24 | - static_cast(x[2]) << 16 | - static_cast(x[1]) << 8 | - static_cast(x[0])); -} - -void RagePhoto::uInt32ToCharBE(quint32 x, char *y) -{ - y[0] = x >> 24; - y[1] = x >> 16; - y[2] = x >> 8; - y[3] = x; -} - -void RagePhoto::uInt32ToCharLE(quint32 x, char *y) -{ - y[0] = x; - y[1] = x >> 8; - y[2] = x >> 16; - y[3] = x >> 24; -} - -const QByteArray RagePhoto::stringToUtf16LE(const QString &string) -{ -#if QT_VERSION >= 0x060000 - return QStringEncoder(QStringEncoder::Utf16LE)(string); -#else - return QTextCodec::codecForName("UTF-16LE")->fromUnicode(string); -#endif -} - -const QString RagePhoto::utf16LEToString(const QByteArray &data) -{ -#if QT_VERSION >= 0x060000 - return QStringDecoder(QStringDecoder::Utf16LE)(data); -#else - return QTextCodec::codecForName("UTF-16LE")->toUnicode(data); -#endif -} - -const QString RagePhoto::utf16LEToString(const char *data, int size) -{ -#if QT_VERSION >= 0x060000 - return QStringDecoder(QStringDecoder::Utf16LE)(QByteArray::fromRawData(data, size)); -#else - return QTextCodec::codecForName("UTF-16LE")->toUnicode(data, size); -#endif -} diff --git a/RagePhoto.h b/RagePhoto.h deleted file mode 100644 index 4f7a5ba..0000000 --- a/RagePhoto.h +++ /dev/null @@ -1,110 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2020 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef RAGEPHOTO_H -#define RAGEPHOTO_H - -#include -#include -#include - -class RagePhoto : public QObject -{ - Q_OBJECT -public: - enum class JsonFormat : quint8 { - Original = 0, - Compact = 1, - Indented = 2, - }; - enum class ExportFormat : quint32 { - G5E1P = 0x454C0010U, - G5E2P = 0x01000032U, - G5E2S = 0x02000032U, - G5E3P = 0x01000033U, - G5E3S = 0x02000033U, - Undefined = 0, - }; - enum class PhotoFormat : quint32 { - G5EX = 0x45354700U, - GTA5 = 0x01000000U, - RDR2 = 0x04000000U, - Undefined = 0, - }; - explicit RagePhoto(); - explicit RagePhoto(const QByteArray &data); - explicit RagePhoto(const QString &filePath); - explicit RagePhoto(QIODevice *ioDevice); - bool isLoaded(); - bool load(); - void clear(); - void setDescription(const QString &description); - void setFileData(const QByteArray &data); - void setFilePath(const QString &filePath); - void setIODevice(QIODevice *ioDevice); - bool setJsonData(const QByteArray &data); - bool setPhotoBuffer(quint32 size, bool moveOffsets = true); - bool setPhotoData(const QByteArray &data); - bool setPhotoData(const char *data, int size); - void setPhotoFormat(PhotoFormat photoFormat); - void setTitle(const QString &title); - const QJsonObject jsonObject(); - const QByteArray jsonData(JsonFormat jsonFormat = JsonFormat::Original); - const QByteArray photoData(); - const QString description(); - const QString photoString(); - const QString title(); - quint32 photoBuffer(); - quint32 photoSize(); - PhotoFormat photoFormat(); - QByteArray save(PhotoFormat photoFormat); - void save(QIODevice *ioDevice, PhotoFormat photoFormat); - static RagePhoto* loadFile(const QString &filePath); - -private: - inline quint32 charToUInt32BE(char *x); - inline quint32 charToUInt32LE(char *x); - inline void uInt32ToCharBE(quint32 x, char *y); - inline void uInt32ToCharLE(quint32 x, char *y); - inline const QByteArray stringToUtf16LE(const QString &string); - inline const QString utf16LEToString(const QByteArray &data); - inline const QString utf16LEToString(const char *data, int size); - PhotoFormat p_photoFormat; - QJsonObject p_jsonObject; - QByteArray p_fileData; - QByteArray p_jsonData; - QByteArray p_photoData; - QIODevice *p_ioDevice; - QString p_descriptionString; - QString p_filePath; - QString p_photoString; - QString p_titleString; - quint32 p_descBuffer; - quint32 p_descOffset; - quint32 p_endOfFile; - quint32 p_headerSum; - quint32 p_jsonBuffer; - quint32 p_jsonOffset; - quint32 p_photoBuffer; - quint32 p_titlBuffer; - quint32 p_titlOffset; - bool p_isLoaded; - int p_inputMode; -}; - -#endif // RAGEPHOTO_H diff --git a/SavegameCopy.cpp b/SavegameCopy.cpp old mode 100644 new mode 100755 index 9ebbe66..c08a604 --- a/SavegameCopy.cpp +++ b/SavegameCopy.cpp @@ -1,108 +1,100 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SidebarGenerator.h" -#include "SavegameWidget.h" -#include "StandardPaths.h" -#include "SavegameCopy.h" -#include "config.h" -#include -#include -#include -#include - -SavegameCopy::SavegameCopy() -{ - -} - -void SavegameCopy::copySavegame(QWidget *parent, QString sgdPath) -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - - settings.beginGroup("FileDialogs"); - bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool(); - settings.beginGroup("SavegameCopy"); - -fileDialogPreSave: //Work? - QFileInfo sgdFileInfo(sgdPath); - QFileDialog fileDialog(parent); - fileDialog.setFileMode(QFileDialog::AnyFile); - fileDialog.setViewMode(QFileDialog::Detail); - fileDialog.setAcceptMode(QFileDialog::AcceptSave); - fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog); - fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true); - fileDialog.setDefaultSuffix(""); - fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); - fileDialog.setWindowTitle(SavegameWidget::tr(("Export Savegame..."))); - fileDialog.setLabelText(QFileDialog::Accept, SavegameWidget::tr("Export")); - - QStringList filters; - filters << SavegameWidget::tr("Savegame files (SGTA*)"); - filters << SavegameWidget::tr("All files (**)"); - fileDialog.setNameFilters(filters); - - QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); - - fileDialog.setSidebarUrls(sidebarUrls); - fileDialog.setDirectory(settings.value("Directory", StandardPaths::picturesLocation()).toString()); - fileDialog.restoreGeometry(settings.value(parent->objectName() % "+Geometry", "").toByteArray()); - fileDialog.selectFile(sgdFileInfo.fileName()); - - if (fileDialog.exec()) - { - QStringList selectedFiles = fileDialog.selectedFiles(); - if (selectedFiles.length() == 1) - { - QString selectedFile = selectedFiles.at(0); - - if (QFile::exists(selectedFile)) - { - if (QMessageBox::Yes == QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Overwrite %1 with current Savegame?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) - { - if (!QFile::remove(selectedFile)) - { - QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Failed to overwrite %1 with current Savegame").arg("\""+selectedFile+"\"")); - goto fileDialogPreSave; //Work? - } - } - else - { - goto fileDialogPreSave; //Work? - } - } - - bool isCopied = QFile::copy(sgdPath, selectedFile); - if (!isCopied) - { - QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Failed to export current Savegame")); - goto fileDialogPreSave; //Work? - } - } - else - { - QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("No valid file is selected")); - goto fileDialogPreSave; //Work? - } - } - - settings.setValue(parent->objectName() % "+Geometry", fileDialog.saveGeometry()); - settings.setValue("Directory", fileDialog.directory().absolutePath()); - settings.endGroup(); - settings.endGroup(); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "SidebarGenerator.h" +#include "SavegameWidget.h" +#include "SavegameCopy.h" +#include "config.h" +#include +#include +#include + +SavegameCopy::SavegameCopy() +{ + +} + +void SavegameCopy::copySavegame(QWidget *parent, QString sgdPath) +{ + QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + settings.beginGroup("FileDialogs"); + +fileDialogPreSave: + QFileInfo sgdFileInfo(sgdPath); + QFileDialog fileDialog(parent); + fileDialog.setFileMode(QFileDialog::AnyFile); + fileDialog.setViewMode(QFileDialog::Detail); + fileDialog.setAcceptMode(QFileDialog::AcceptSave); + fileDialog.setOption(QFileDialog::DontUseNativeDialog, false); + fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true); + fileDialog.setDefaultSuffix(""); + fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); + fileDialog.setWindowTitle(SavegameWidget::tr(("Export Savegame..."))); + fileDialog.setLabelText(QFileDialog::Accept, SavegameWidget::tr("&Export")); + + QStringList filters; + filters << SavegameWidget::tr("Savegame files (SGTA*)"); + filters << SavegameWidget::tr("All files (**)"); + fileDialog.setNameFilters(filters); + + QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); + + fileDialog.setSidebarUrls(sidebarUrls); + fileDialog.restoreState(settings.value("CopySavegame","").toByteArray()); + fileDialog.selectFile(sgdFileInfo.fileName()); + + if (fileDialog.exec()) + { + QStringList selectedFiles = fileDialog.selectedFiles(); + if (selectedFiles.length() == 1) + { + QString selectedFile = selectedFiles.at(0); + + if (QFile::exists(selectedFile)) + { + if (QMessageBox::Yes == QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Overwrite %1 with current Savegame?").arg("\""+selectedFile+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) + { + if (!QFile::remove(selectedFile)) + { + QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Failed to overwrite %1 with current Savegame").arg("\""+selectedFile+"\"")); + goto fileDialogPreSave; + } + } + else + { + goto fileDialogPreSave; + } + } + + bool isCopied = QFile::copy(sgdPath, selectedFile); + if (!isCopied) + { + QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("Failed to export current Savegame")); + goto fileDialogPreSave; + } + } + else + { + QMessageBox::warning(parent, SavegameWidget::tr("Export Savegame"), SavegameWidget::tr("No valid file is selected")); + goto fileDialogPreSave; + } + } + + settings.setValue("CopySavegame", fileDialog.saveState()); + settings.endGroup(); +} diff --git a/SavegameCopy.h b/SavegameCopy.h old mode 100644 new mode 100755 index f5550ba..c60edfd --- a/SavegameCopy.h +++ b/SavegameCopy.h @@ -1,32 +1,32 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef SAVEGAMECOPY_H -#define SAVEGAMECOPY_H - -#include -#include - -class SavegameCopy -{ -public: - SavegameCopy(); - static void copySavegame(QWidget *parent, QString sgdPath); -}; - -#endif // SAVEGAMECOPY_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef SAVEGAMECOPY_H +#define SAVEGAMECOPY_H + +#include +#include + +class SavegameCopy +{ +public: + SavegameCopy(); + static void copySavegame(QWidget *parent, QString sgdPath); +}; + +#endif // SAVEGAMECOPY_H diff --git a/SavegameData.cpp b/SavegameData.cpp old mode 100644 new mode 100755 index 42a9ae3..ac3feb8 --- a/SavegameData.cpp +++ b/SavegameData.cpp @@ -1,120 +1,119 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SnapmaticPicture.h" -#include "StringParser.h" -#include "SavegameData.h" -#include -#include -#include -#include - -#define savegameHeaderLength 260 -#define verificationValue QByteArray::fromHex("00000001") - -SavegameData::SavegameData(const QString &fileName, QObject *parent) : QObject(parent), savegameFileName(fileName) -{ - // INIT SAVEGAME - savegameStr = ""; - savegameOk = 0; -} - -bool SavegameData::readingSavegame() -{ - // Start opening file - // lastStep is like currentStep - - QFile *saveFile = new QFile(savegameFileName); - if (!saveFile->open(QFile::ReadOnly)) - { - lastStep = "1;/1,OpenFile," % SnapmaticPicture::convertDrawStringForLog(savegameFileName); - saveFile->deleteLater(); - delete saveFile; - return false; - } - - // Reading Savegame Header - if (!saveFile->isReadable()) - { - lastStep = "2;/3,ReadingFile," % SnapmaticPicture::convertDrawStringForLog(savegameFileName) % ",1,NOHEADER"; - saveFile->close(); - saveFile->deleteLater(); - delete saveFile; - return false; - } - QByteArray savegameHeaderLine = saveFile->read(savegameHeaderLength); - if (savegameHeaderLine.left(4) == verificationValue) - { - savegameStr = getSavegameDataString(savegameHeaderLine); - if (savegameStr.length() >= 1) - { - savegameOk = true; - } - } - saveFile->close(); - saveFile->deleteLater(); - delete saveFile; - return savegameOk; -} - -QString SavegameData::getSavegameDataString(const QByteArray &savegameHeader) -{ - QByteArray savegameBytes = savegameHeader.left(savegameHeaderLength); - QList savegameBytesList = savegameBytes.split(char(0x01)); - savegameBytes = savegameBytesList.at(1); - savegameBytesList.clear(); - return SnapmaticPicture::parseTitleString(savegameBytes, savegameBytes.length()); -} - -bool SavegameData::readingSavegameFromFile(const QString &fileName) -{ - if (fileName != "") - { - savegameFileName = fileName; - return readingSavegame(); - } - else - { - return false; - } -} - -bool SavegameData::isSavegameOk() -{ - return savegameOk; -} - -QString SavegameData::getSavegameFileName() -{ - return savegameFileName; -} - -QString SavegameData::getSavegameStr() -{ - return savegameStr; -} - -QString SavegameData::getLastStep() -{ - return lastStep; -} - -void SavegameData::setSavegameFileName(QString savegameFileName_) -{ - savegameFileName = savegameFileName_; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "StringParser.h" +#include "SavegameData.h" +#include +#include +#include + +SavegameData::SavegameData(const QString &fileName, QObject *parent) : QObject(parent), savegameFileName(fileName) +{ + // PARSE INT INIT - DO NOT CHANGE THIS VALUES + savegameHeaderLength = 260; + verificationValue = QByteArray::fromHex("00000001"); + + // INIT SAVEGAME + savegameStr = ""; + savegameOk = 0; +} + +bool SavegameData::readingSavegame() +{ + // Start opening file + // lastStep is like currentStep + + QFile *saveFile = new QFile(savegameFileName); + if (!saveFile->open(QFile::ReadOnly)) + { + lastStep = "1;/1,OpenFile," + StringParser::convertDrawStringForLog(savegameFileName); + saveFile->deleteLater(); + delete saveFile; + return false; + } + + // Reading Savegame Header + if (!saveFile->isReadable()) + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(savegameFileName) + ",1,NOHEADER"; + saveFile->close(); + saveFile->deleteLater(); + delete saveFile; + return false; + } + QByteArray savegameHeaderLine = saveFile->read(savegameHeaderLength); + if (savegameHeaderLine.left(4) == verificationValue) + { + savegameStr = getSavegameDataString(savegameHeaderLine); + if (savegameStr.length() >= 1) + { + savegameOk = true; + } + } + saveFile->close(); + saveFile->deleteLater(); + delete saveFile; + return savegameOk; +} + +QString SavegameData::getSavegameDataString(const QByteArray &savegameHeader) +{ + QByteArray savegameBytes = savegameHeader.left(savegameHeaderLength); + QList savegameBytesList = savegameBytes.split(char(0x01)); + savegameBytes = savegameBytesList.at(1); + savegameBytesList.clear(); + return StringParser::parseTitleString(savegameBytes, savegameBytes.length()); +} + +bool SavegameData::readingSavegameFromFile(const QString &fileName) +{ + if (fileName != "") + { + savegameFileName = fileName; + return readingSavegame(); + } + else + { + return false; + } +} + +bool SavegameData::isSavegameOk() +{ + return savegameOk; +} + +QString SavegameData::getSavegameFileName() +{ + return savegameFileName; +} + +QString SavegameData::getSavegameStr() +{ + return savegameStr; +} + +QString SavegameData::getLastStep() +{ + return lastStep; +} + +void SavegameData::setSavegameFileName(QString savegameFileName_) +{ + savegameFileName = savegameFileName_; +} diff --git a/SavegameData.h b/SavegameData.h old mode 100644 new mode 100755 index bedb57c..46c64fd --- a/SavegameData.h +++ b/SavegameData.h @@ -1,45 +1,49 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef SAVEGAMEDATA_H -#define SAVEGAMEDATA_H - -#include - -class SavegameData : public QObject -{ - Q_OBJECT -public: - explicit SavegameData(const QString &fileName = "", QObject *parent = 0); - bool readingSavegameFromFile(const QString &fileName); - bool readingSavegame(); - bool isSavegameOk(); - QString getLastStep(); - QString getSavegameStr(); - QString getSavegameFileName(); - void setSavegameFileName(QString savegameFileName); - -private: - QString getSavegameDataString(const QByteArray &savegameHeader); - QString savegameFileName; - QString savegameStr; - QString lastStep; - bool savegameOk; -}; - -#endif // SAVEGAMEDATA_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef SAVEGAMEDATA_H +#define SAVEGAMEDATA_H + +#include + +class SavegameData : public QObject +{ + Q_OBJECT +public: + explicit SavegameData(const QString &fileName = "", QObject *parent = 0); + bool readingSavegameFromFile(const QString &fileName); + bool readingSavegame(); + bool isSavegameOk(); + QString getLastStep(); + QString getSavegameStr(); + QString getSavegameFileName(); + void setSavegameFileName(QString savegameFileName); + +private: + QString getSavegameDataString(const QByteArray &savegameHeader); + QString savegameFileName; + QString savegameStr; + QString lastStep; + bool savegameOk; + + // PARSE INT + QByteArray verificationValue; + int savegameHeaderLength; +}; + +#endif // SAVEGAMEDATA_H diff --git a/SavegameDialog.cpp b/SavegameDialog.cpp old mode 100644 new mode 100755 index 27b0229..c4a74aa --- a/SavegameDialog.cpp +++ b/SavegameDialog.cpp @@ -1,104 +1,39 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2018 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SavegameDialog.h" -#include "ui_SavegameDialog.h" -#include "SavegameCopy.h" -#include "AppEnv.h" -#include -#include - -SavegameDialog::SavegameDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::SavegameDialog) -{ - // Set Window Flags -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - - // Setup User Interface - ui->setupUi(this); - ui->cmdClose->setFocus(); - savegameLabStr = ui->labSavegameText->text(); - - // Set Icon for Close Button - if (QIcon::hasThemeIcon("dialog-close")) - { - ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) - { - ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close")); - } - - // Set Icon for Export Button - if (QIcon::hasThemeIcon("document-export")) - { - ui->cmdCopy->setIcon(QIcon::fromTheme("document-export")); - } - else if (QIcon::hasThemeIcon("document-save")) - { - ui->cmdCopy->setIcon(QIcon::fromTheme("document-save")); - } - - refreshWindowSize(); -} - -SavegameDialog::~SavegameDialog() -{ - delete ui; -} - -void SavegameDialog::refreshWindowSize() -{ - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); - int dpiWindowWidth = 400 * screenRatio; - int dpiWindowHeight = 105 * screenRatio; - if (dpiWindowHeight < heightForWidth(dpiWindowWidth)) - { - dpiWindowHeight = heightForWidth(dpiWindowWidth); - } - resize(dpiWindowWidth, dpiWindowHeight); -} - -void SavegameDialog::setSavegameData(SavegameData *savegame, QString savegamePath, bool readOk) -{ - // Showing error if reading error - if (!readOk) - { - QMessageBox::warning(this,tr("Savegame Viewer"),tr("Failed at %1").arg(savegame->getLastStep())); - return; - } - sgdPath = savegamePath; - ui->labSavegameText->setText(savegameLabStr.arg(savegame->getSavegameStr())); - refreshWindowSize(); -} - -void SavegameDialog::on_cmdClose_clicked() -{ - this->close(); -} - -void SavegameDialog::on_cmdCopy_clicked() -{ - SavegameCopy::copySavegame(this, sgdPath); -} +#include "SavegameDialog.h" +#include "ui_SavegameDialog.h" +#include "SavegameCopy.h" +#include + +SavegameDialog::SavegameDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SavegameDialog) +{ + ui->setupUi(this); + savegameLabStr = ui->labSavegameText->text(); +} + +SavegameDialog::~SavegameDialog() +{ + delete ui; +} + +void SavegameDialog::setSavegameData(SavegameData *savegame, QString savegamePath, bool readOk) +{ + // Showing error if reading error + if (!readOk) + { + QMessageBox::warning(this,tr("Savegame Viewer"),tr("Failed at %1").arg(savegame->getLastStep())); + return; + } + sgdPath = savegamePath; + ui->labSavegameText->setText(savegameLabStr.arg(savegame->getSavegameStr())); +} + +void SavegameDialog::on_cmdClose_clicked() +{ + this->close(); +} + +void SavegameDialog::on_cmdCopy_clicked() +{ + SavegameCopy::copySavegame(this, sgdPath); +} diff --git a/SavegameDialog.h b/SavegameDialog.h old mode 100644 new mode 100755 index 4abbba4..0b3a900 --- a/SavegameDialog.h +++ b/SavegameDialog.h @@ -1,48 +1,29 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2018 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef SAVEGAMEDIALOG_H -#define SAVEGAMEDIALOG_H - -#include "SavegameData.h" -#include - -namespace Ui { -class SavegameDialog; -} - -class SavegameDialog : public QDialog -{ - Q_OBJECT -public: - explicit SavegameDialog(QWidget *parent = 0); - void setSavegameData(SavegameData *savegame, QString sgdPath, bool readOk); - ~SavegameDialog(); - -private slots: - void on_cmdClose_clicked(); - void on_cmdCopy_clicked(); - void refreshWindowSize(); - -private: - Ui::SavegameDialog *ui; - QString savegameLabStr; - QString sgdPath; -}; - -#endif // SAVEGAMEDIALOG_H +#ifndef SAVEGAMEDIALOG_H +#define SAVEGAMEDIALOG_H + +#include "SavegameData.h" +#include + +namespace Ui { +class SavegameDialog; +} + +class SavegameDialog : public QDialog +{ + Q_OBJECT +public: + explicit SavegameDialog(QWidget *parent = 0); + void setSavegameData(SavegameData *savegame, QString sgdPath, bool readOk); + ~SavegameDialog(); + +private slots: + void on_cmdClose_clicked(); + void on_cmdCopy_clicked(); + +private: + Ui::SavegameDialog *ui; + QString savegameLabStr; + QString sgdPath; +}; + +#endif // SAVEGAMEDIALOG_H diff --git a/SavegameDialog.ui b/SavegameDialog.ui old mode 100644 new mode 100755 index ac9481e..035b5f9 --- a/SavegameDialog.ui +++ b/SavegameDialog.ui @@ -1,93 +1,86 @@ - - - SavegameDialog - - - - 0 - 0 - 400 - 112 - - - - Savegame Viewer - - - true - - - - - - <span style="font-weight:600">Savegame</span><br><br>%1 - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - &Export - - - - - - - - 0 - 0 - - - - &Close - - - - - - - - - - + + + SavegameDialog + + + + 0 + 0 + 400 + 104 + + + + Savegame Viewer + + + + + + + 0 + 0 + + + + <span style=" font-weight:600;">Savegame</span><br><br>%1 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + &Export + + + + + + + + 0 + 0 + + + + &Close + + + + + + + + + + + + + diff --git a/SavegameWidget.cpp b/SavegameWidget.cpp old mode 100644 new mode 100755 index cede630..ef58f21 --- a/SavegameWidget.cpp +++ b/SavegameWidget.cpp @@ -1,314 +1,275 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SavegameWidget.h" -#include "ui_SavegameWidget.h" -#include "SidebarGenerator.h" -#include "SavegameDialog.h" -#include "StandardPaths.h" -#include "SavegameData.h" -#include "SavegameCopy.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GTA5SYNC_TELEMETRY -#include "TelemetryClass.h" -#include -#include -#include -#endif - -SavegameWidget::SavegameWidget(QWidget *parent) : - ProfileWidget(parent), - ui(new Ui::SavegameWidget) -{ - ui->setupUi(this); - ui->cmdCopy->setVisible(false); - ui->cmdView->setVisible(false); - ui->cmdDelete->setVisible(false); - ui->cbSelected->setVisible(false); - - qreal screenRatio = AppEnv::screenRatio(); - ui->labSavegamePic->setFixedSize(48 * screenRatio, 27 * screenRatio); - - ui->labSavegamePic->setScaledContents(true); - ui->labSavegamePic->setPixmap(QPixmap(AppEnv::getImagesFolder() % "/savegame.svgz")); - - QString exportSavegameStr = tr("Export Savegame..."); - Q_UNUSED(exportSavegameStr) - - labelAutosaveStr = tr("AUTOSAVE - %1\n%2"); - labelSaveStr = tr("SAVE %3 - %1\n%2"); - - ui->SavegameFrame->setMouseTracking(true); - ui->labSavegamePic->setMouseTracking(true); - ui->labSavegameStr->setMouseTracking(true); - ui->cbSelected->setMouseTracking(true); - sgdata = nullptr; -} - -SavegameWidget::~SavegameWidget() -{ - delete ui; -} - -void SavegameWidget::setSavegameData(SavegameData *savegame, QString savegamePath) -{ - // BETA CODE - QString savegameString = savegame->getSavegameStr(); - QString fileName = QFileInfo(savegame->getSavegameFileName()).fileName(); - renderString(savegameString, fileName); - sgdStr = savegameString; - sgdPath = savegamePath; - sgdata = savegame; -} - -void SavegameWidget::renderString(const QString &savegameString, const QString &fileName) -{ - bool validNumber; - QString savegameName = tr("WRONG FORMAT"); - QString savegameDate = tr("WRONG FORMAT"); - QStringList savegameNDL = QString(savegameString).split(" - "); - if (savegameNDL.length() >= 2) - { - savegameDate = savegameNDL.at(savegameNDL.length() - 1); - savegameName = QString(savegameString).remove(savegameString.length() - savegameDate.length() - 3, savegameDate.length() + 3); - } - int savegameNumber = QString(fileName).remove(0,5).toInt(&validNumber) + 1; - if (validNumber) - { - if (savegameNumber == 16) - { - ui->labSavegameStr->setText(labelAutosaveStr.arg(savegameDate, savegameName)); - } - else - { - ui->labSavegameStr->setText(labelSaveStr.arg(savegameDate, savegameName, QString::number(savegameNumber))); - } - } - else - { - ui->labSavegameStr->setText(labelSaveStr.arg(savegameDate, savegameName, tr("UNKNOWN"))); - } -} - -void SavegameWidget::retranslate() -{ - labelAutosaveStr = tr("AUTOSAVE - %1\n%2"); - labelSaveStr = tr("SAVE %3 - %1\n%2"); - - QString fileName = QFileInfo(sgdata->getSavegameFileName()).fileName(); - renderString(sgdStr, fileName); -} - -void SavegameWidget::on_cmdCopy_clicked() -{ - SavegameCopy::copySavegame(this, sgdPath); -} - -void SavegameWidget::on_cmdDelete_clicked() -{ - int uchoice = QMessageBox::question(this, tr("Delete Savegame"), tr("Are you sure to delete %1 from your savegames?").arg("\""+sgdStr+"\""), QMessageBox::No | QMessageBox::Yes, QMessageBox::No); - if (uchoice == QMessageBox::Yes) - { - if (!QFile::exists(sgdPath)) - { - emit savegameDeleted(); -#ifdef GTA5SYNC_TELEMETRY - QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - telemetrySettings.beginGroup("Telemetry"); - bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool(); - telemetrySettings.endGroup(); - if (pushUsageData && Telemetry->canPush()) - { - QJsonDocument jsonDocument; - QJsonObject jsonObject; - jsonObject["Type"] = "DeleteSuccess"; - jsonObject["ExtraFlags"] = "Savegame"; -#if QT_VERSION >= 0x060000 - jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } -#endif - } - else if (QFile::remove(sgdPath)) - { -#ifdef GTA5SYNC_TELEMETRY - QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - telemetrySettings.beginGroup("Telemetry"); - bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool(); - telemetrySettings.endGroup(); - if (pushUsageData && Telemetry->canPush()) - { - QJsonDocument jsonDocument; - QJsonObject jsonObject; - jsonObject["Type"] = "DeleteSuccess"; - jsonObject["ExtraFlags"] = "Savegame"; -#if QT_VERSION >= 0x060000 - jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } -#endif - emit savegameDeleted(); - } - else - { - QMessageBox::warning(this, tr("Delete Savegame"), tr("Failed at deleting %1 from your savegames").arg("\""+sgdStr+"\"")); - } - } -} - -void SavegameWidget::on_cmdView_clicked() -{ - SavegameDialog *savegameDialog = new SavegameDialog(this); - savegameDialog->setSavegameData(sgdata, sgdPath, true); - savegameDialog->setModal(true); -#ifdef Q_OS_ANDROID - // Android ... - savegameDialog->showMaximized(); -#else - savegameDialog->show(); -#endif - savegameDialog->exec(); - delete savegameDialog; -} - -void SavegameWidget::mousePressEvent(QMouseEvent *ev) -{ - ProfileWidget::mousePressEvent(ev); -} - -void SavegameWidget::mouseReleaseEvent(QMouseEvent *ev) -{ - ProfileWidget::mouseReleaseEvent(ev); - if (ui->cbSelected->isVisible()) - { - if (rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) - { - ui->cbSelected->setChecked(!ui->cbSelected->isChecked()); - } - } - else - { - const int contentMode = getContentMode(); - if ((contentMode == 0 || contentMode == 10 || contentMode == 20) && rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) - { - if (ev->modifiers().testFlag(Qt::ShiftModifier)) - { - ui->cbSelected->setChecked(!ui->cbSelected->isChecked()); - } - else - { - on_cmdView_clicked(); - } - } - else if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton && ev->modifiers().testFlag(Qt::ShiftModifier)) - { - ui->cbSelected->setChecked(!ui->cbSelected->isChecked()); - } - } -} - -void SavegameWidget::mouseDoubleClickEvent(QMouseEvent *ev) -{ - ProfileWidget::mouseDoubleClickEvent(ev); - - const int contentMode = getContentMode(); - if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton) - { - on_cmdView_clicked(); - } -} - -void SavegameWidget::setSelected(bool isSelected) -{ - ui->cbSelected->setChecked(isSelected); -} - -void SavegameWidget::savegameSelected() -{ - setSelected(!ui->cbSelected->isChecked()); -} - -void SavegameWidget::contextMenuEvent(QContextMenuEvent *ev) -{ - emit contextMenuTriggered(ev); -} - -void SavegameWidget::on_cbSelected_stateChanged(int arg1) -{ - if (arg1 == Qt::Checked) - { - emit widgetSelected(); - } - else if (arg1 == Qt::Unchecked) - { - emit widgetDeselected(); - } -} - -bool SavegameWidget::isSelected() -{ - return ui->cbSelected->isChecked(); -} - -void SavegameWidget::setSelectionMode(bool selectionMode) -{ - ui->cbSelected->setVisible(selectionMode); -} - -void SavegameWidget::selectAllWidgets() -{ - emit allWidgetsSelected(); -} - -void SavegameWidget::deselectAllWidgets() -{ - emit allWidgetsDeselected(); -} - -SavegameData* SavegameWidget::getSavegame() -{ - return sgdata; -} - -QString SavegameWidget::getWidgetType() -{ - return "SavegameWidget"; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "SavegameWidget.h" +#include "ui_SavegameWidget.h" +#include "SidebarGenerator.h" +#include "ProfileInterface.h" +#include "SavegameDialog.h" +#include "StandardPaths.h" +#include "SavegameData.h" +#include "SavegameCopy.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +SavegameWidget::SavegameWidget(QWidget *parent) : + ProfileWidget(parent), + ui(new Ui::SavegameWidget) +{ + ui->setupUi(this); + ui->cmdCopy->setVisible(false); + ui->cmdView->setVisible(false); + ui->cmdDelete->setVisible(false); + ui->cbSelected->setVisible(false); + + QString exportSavegameStr = tr("Export Savegame..."); + Q_UNUSED(exportSavegameStr) + + QPalette palette; + highlightBackColor = palette.highlight().color(); + highlightTextColor = palette.highlightedText().color(); + + labelAutosaveStr = tr("AUTOSAVE - %1\n%2"); + labelSaveStr = tr("SAVE %3 - %1\n%2"); + snwgt = parent; + sgdPath = ""; + sgdStr = ""; + sgdata = 0; + + installEventFilter(this); +} + +SavegameWidget::~SavegameWidget() +{ + delete ui; +} + +bool SavegameWidget::eventFilter(QObject *obj, QEvent *ev) +{ + if (obj == this) + { + if (ev->type() == QEvent::Enter) + { + setStyleSheet(QString("QFrame#SavegameFrame{background-color: rgb(%1, %2, %3)}QLabel#labSavegameStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); + return true; + } + else if(ev->type() == QEvent::Leave) + { + setStyleSheet(""); + return true; + } + } + return false; +} + +void SavegameWidget::setSavegameData(SavegameData *savegame, QString savegamePath) +{ + // BETA CODE + bool validNumber; + QString savegameName = tr("WRONG FORMAT"); + QString savegameDate = tr("WRONG FORMAT"); + QString savegameString = savegame->getSavegameStr(); + QString fileName = QFileInfo(savegame->getSavegameFileName()).fileName(); + QStringList savegameNDL = QString(savegameString).split(" - "); + if (savegameNDL.length() >= 2) + { + savegameDate = savegameNDL.at(savegameNDL.length() - 1); + savegameName = QString(savegameString).remove(savegameString.length() - savegameDate.length() - 3, savegameDate.length() + 3); + } + int savegameNumber = QString(fileName).remove(0,5).toInt(&validNumber) + 1; + if (validNumber) + { + if (savegameNumber == 16) + { + ui->labSavegameStr->setText(labelAutosaveStr.arg(savegameDate, savegameName)); + } + else + { + ui->labSavegameStr->setText(labelSaveStr.arg(savegameDate, savegameName, QString::number(savegameNumber))); + } + } + else + { + ui->labSavegameStr->setText(labelSaveStr.arg(savegameDate, savegameName, tr("UNKNOWN"))); + } + sgdStr = savegameString; + sgdPath = savegamePath; + sgdata = savegame; +} + +void SavegameWidget::on_cmdCopy_clicked() +{ + SavegameCopy::copySavegame(this, sgdPath); +} + +void SavegameWidget::on_cmdDelete_clicked() +{ + int uchoice = QMessageBox::question(this, tr("Delete savegame"), tr("Are you sure to delete %1 from your savegames?").arg("\""+sgdStr+"\""), QMessageBox::No | QMessageBox::Yes, QMessageBox::No); + if (uchoice == QMessageBox::Yes) + { + if (!QFile::exists(sgdPath)) + { + emit savegameDeleted(); + } + else if(QFile::remove(sgdPath)) + { + emit savegameDeleted(); + } + else + { + QMessageBox::warning(this, tr("Delete savegame"), tr("Failed at deleting %1 from your savegames").arg("\""+sgdStr+"\"")); + } + } +} + +void SavegameWidget::on_cmdView_clicked() +{ + SavegameDialog *savegameDialog = new SavegameDialog(this); + savegameDialog->setWindowFlags(savegameDialog->windowFlags()^Qt::WindowContextHelpButtonHint); + savegameDialog->setSavegameData(sgdata, sgdPath, true); + savegameDialog->setModal(true); + savegameDialog->show(); + savegameDialog->exec(); + savegameDialog->deleteLater(); + delete savegameDialog; +} + +void SavegameWidget::mousePressEvent(QMouseEvent *ev) +{ + ProfileWidget::mousePressEvent(ev); +} + +void SavegameWidget::mouseReleaseEvent(QMouseEvent *ev) +{ + ProfileWidget::mouseReleaseEvent(ev); + if (ui->cbSelected->isVisible()) + { + if (rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) + { + ui->cbSelected->setChecked(!ui->cbSelected->isChecked()); + } + } + else + { + if (getContentMode() == 0 && rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) + { + on_cmdView_clicked(); + } + } +} + +void SavegameWidget::mouseDoubleClickEvent(QMouseEvent *ev) +{ + ProfileWidget::mouseDoubleClickEvent(ev); + + if (!ui->cbSelected->isVisible() && getContentMode() == 1 && ev->button() == Qt::LeftButton) + { + on_cmdView_clicked(); + } +} + +void SavegameWidget::setSelected(bool isSelected) +{ + ui->cbSelected->setChecked(isSelected); +} + +void SavegameWidget::savegameSelected() +{ + setSelected(!ui->cbSelected->isChecked()); +} + +void SavegameWidget::contextMenuEvent(QContextMenuEvent *ev) +{ + QMenu contextMenu(this); + contextMenu.addAction(tr("&View"), this, SLOT(on_cmdView_clicked())); + contextMenu.addAction(tr("&Export"), this, SLOT(on_cmdCopy_clicked())); + contextMenu.addAction(tr("&Remove"), this, SLOT(on_cmdDelete_clicked())); + if (ui->cbSelected->isVisible()) + { + contextMenu.addSeparator(); + if (!ui->cbSelected->isChecked()) { contextMenu.addAction(tr("&Select"), this, SLOT(savegameSelected())); } + if (ui->cbSelected->isChecked()) { contextMenu.addAction(tr("&Deselect"), this, SLOT(savegameSelected())); } + contextMenu.addAction(tr("Select &All"), this, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A")); + ProfileInterface *profileInterface = (ProfileInterface*)snwgt; + if (profileInterface->selectedWidgets() != 0) + { + contextMenu.addAction(tr("&Deselect All"), this, SLOT(deselectAllWidgets()), QKeySequence::fromString("Ctrl+D")); + } + } + else + { + contextMenu.addSeparator(); + contextMenu.addAction(tr("&Select"), this, SLOT(savegameSelected())); + contextMenu.addAction(tr("Select &All"), this, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A")); + } + //ui->SavegameFrame->setStyleSheet(QString("QFrame#SavegameFrame{background-color: rgb(%1, %2, %3)}QLabel#labSavegameStr{color: rgb(%4, %5, %6)}").arg(QString::number(highlightBackColor.red()), QString::number(highlightBackColor.green()), QString::number(highlightBackColor.blue()), QString::number(highlightTextColor.red()), QString::number(highlightTextColor.green()), QString::number(highlightTextColor.blue()))); + contextMenu.exec(ev->globalPos()); + //ui->SavegameFrame->setStyleSheet(""); +} + +void SavegameWidget::on_cbSelected_stateChanged(int arg1) +{ + if (arg1 == Qt::Checked) + { + emit widgetSelected(); + } + else if (arg1 == Qt::Unchecked) + { + emit widgetDeselected(); + } +} + +bool SavegameWidget::isSelected() +{ + return ui->cbSelected->isChecked(); +} + +void SavegameWidget::setSelectionMode(bool selectionMode) +{ + ui->cbSelected->setVisible(selectionMode); +} + +void SavegameWidget::selectAllWidgets() +{ + emit allWidgetsSelected(); +} + +void SavegameWidget::deselectAllWidgets() +{ + emit allWidgetsDeselected(); +} + +SavegameData* SavegameWidget::getSavegame() +{ + return sgdata; +} + +QString SavegameWidget::getWidgetType() +{ + return "SavegameWidget"; +} diff --git a/SavegameWidget.h b/SavegameWidget.h old mode 100644 new mode 100755 index 103fa55..85e8fb2 --- a/SavegameWidget.h +++ b/SavegameWidget.h @@ -1,80 +1,83 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef SAVEGAMEWIDGET_H -#define SAVEGAMEWIDGET_H -#include "ProfileWidget.h" -#include "SavegameData.h" -#include -#include -#include -#include - -namespace Ui { -class SavegameWidget; -} - -class SavegameWidget : public ProfileWidget -{ - Q_OBJECT - -public: - SavegameWidget(QWidget *parent = 0); - void setSavegameData(SavegameData *savegame, QString savegamePath); - void setSelectionMode(bool selectionMode); - void setSelected(bool isSelected); - SavegameData* getSavegame(); - QString getWidgetType(); - bool isSelected(); - void retranslate(); - ~SavegameWidget(); - -private slots: - void on_cmdView_clicked(); - void on_cmdCopy_clicked(); - void on_cmdDelete_clicked(); - void on_cbSelected_stateChanged(int arg1); - void savegameSelected(); - void selectAllWidgets(); - void deselectAllWidgets(); - -protected: - void mouseDoubleClickEvent(QMouseEvent *ev); - void mouseReleaseEvent(QMouseEvent *ev); - void mousePressEvent(QMouseEvent *ev); - void contextMenuEvent(QContextMenuEvent *ev); - -private: - Ui::SavegameWidget *ui; - SavegameData *sgdata; - QString labelAutosaveStr; - QString labelSaveStr; - QString sgdPath; - QString sgdStr; - void renderString(const QString &savegameString, const QString &fileName); - -signals: - void savegameDeleted(); - void widgetSelected(); - void widgetDeselected(); - void allWidgetsSelected(); - void allWidgetsDeselected(); - void contextMenuTriggered(QContextMenuEvent *ev); -}; - -#endif // SAVEGAMEWIDGET_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef SAVEGAMEWIDGET_H +#define SAVEGAMEWIDGET_H + +#include "ProfileInterface.h" +#include "ProfileWidget.h" +#include "SavegameData.h" +#include +#include +#include +#include + +namespace Ui { +class SavegameWidget; +} + +class SavegameWidget : public ProfileWidget +{ + Q_OBJECT + +public: + SavegameWidget(QWidget *parent = 0); + void setSavegameData(SavegameData *savegame, QString savegamePath); + void setSelectionMode(bool selectionMode); + void setSelected(bool isSelected); + SavegameData* getSavegame(); + QString getWidgetType(); + bool isSelected(); + ~SavegameWidget(); + +private slots: + void on_cmdView_clicked(); + void on_cmdCopy_clicked(); + void on_cmdDelete_clicked(); + void on_cbSelected_stateChanged(int arg1); + void savegameSelected(); + void selectAllWidgets(); + void deselectAllWidgets(); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + void mouseDoubleClickEvent(QMouseEvent *ev); + void mouseReleaseEvent(QMouseEvent *ev); + void mousePressEvent(QMouseEvent *ev); + void contextMenuEvent(QContextMenuEvent *ev); + +private: + Ui::SavegameWidget *ui; + SavegameData *sgdata; + QColor highlightBackColor; + QColor highlightTextColor; + QString labelAutosaveStr; + QString labelSaveStr; + QString sgdPath; + QString sgdStr; + QWidget *snwgt; + +signals: + void savegameDeleted(); + void widgetSelected(); + void widgetDeselected(); + void allWidgetsSelected(); + void allWidgetsDeselected(); +}; + +#endif // SAVEGAMEWIDGET_H diff --git a/SavegameWidget.ui b/SavegameWidget.ui old mode 100644 new mode 100755 index ea5e3c6..d148f66 --- a/SavegameWidget.ui +++ b/SavegameWidget.ui @@ -1,135 +1,137 @@ - - - SavegameWidget - - - - 0 - 0 - 405 - 46 - - - - Savegame Widget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - - - - Qt::NoFocus - - - - - - - - - - - - - - - - - - 0 - 0 - - - - SAVE %3 - %1<br>%2 - - - true - - - - - - - - 0 - 0 - - - - View savegame - - - View - - - - - - - - 0 - 0 - - - - Copy savegame - - - Export - - - true - - - - - - - - 0 - 0 - - - - Delete savegame - - - Delete - - - true - - - - - - - - - - - + + + SavegameWidget + + + + 0 + 0 + 405 + 46 + + + + Savegame Widget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + + + + + + + + + + + + + + :/img/savegame.png + + + + + + + + 0 + 0 + + + + SAVE %3 - %1<br>%2 + + + true + + + + + + + + 0 + 0 + + + + View savegame + + + View + + + + + + + + 0 + 0 + + + + Copy savegame + + + Export + + + true + + + + + + + + 0 + 0 + + + + Delete savegame + + + Delete + + + true + + + + + + + + + + + + + diff --git a/SidebarGenerator.cpp b/SidebarGenerator.cpp old mode 100644 new mode 100755 index e93474c..c2eecdc --- a/SidebarGenerator.cpp +++ b/SidebarGenerator.cpp @@ -1,61 +1,61 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SidebarGenerator.h" -#include "StandardPaths.h" -#include "AppEnv.h" -#include -#include -#include - -SidebarGenerator::SidebarGenerator() -{ - -} - -QList SidebarGenerator::generateSidebarUrls(QList sidebarUrls) -{ - QDir dir; - - dir.setPath(StandardPaths::picturesLocation()); - if (dir.exists()) - { - sidebarUrls += QUrl::fromLocalFile(dir.absolutePath()); - } - - dir.setPath(StandardPaths::documentsLocation()); - if (dir.exists()) - { - sidebarUrls += QUrl::fromLocalFile(dir.absolutePath()); - } - - bool gameFolderExists; - QString gameFolder = AppEnv::getGameFolder(&gameFolderExists); - if (gameFolderExists) - { - sidebarUrls += QUrl::fromLocalFile(gameFolder); - } - - dir.setPath(StandardPaths::desktopLocation()); - if (dir.exists()) - { - sidebarUrls += QUrl::fromLocalFile(dir.absolutePath()); - } - - return sidebarUrls; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "SidebarGenerator.h" +#include "StandardPaths.h" +#include "AppEnv.h" +#include +#include +#include + +SidebarGenerator::SidebarGenerator() +{ + +} + +QList SidebarGenerator::generateSidebarUrls(QList sidebarUrls) +{ + QDir dir; + + dir.setPath(StandardPaths::picturesLocation()); + if (dir.exists()) + { + sidebarUrls << QUrl::fromLocalFile(dir.absolutePath()); + } + + dir.setPath(StandardPaths::documentsLocation()); + if (dir.exists()) + { + sidebarUrls << QUrl::fromLocalFile(dir.absolutePath()); + } + + bool gameFolderExists; + QString gameFolder = AppEnv::getGameFolder(&gameFolderExists); + if (gameFolderExists) + { + sidebarUrls << QUrl::fromLocalFile(gameFolder); + } + + dir.setPath(StandardPaths::desktopLocation()); + if (dir.exists()) + { + sidebarUrls << QUrl::fromLocalFile(dir.absolutePath()); + } + + return sidebarUrls; +} diff --git a/SidebarGenerator.h b/SidebarGenerator.h old mode 100644 new mode 100755 index 446f73c..d01bba0 --- a/SidebarGenerator.h +++ b/SidebarGenerator.h @@ -1,32 +1,32 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef SIDEBARGENERATOR_H -#define SIDEBARGENERATOR_H - -#include -#include - -class SidebarGenerator -{ -public: - SidebarGenerator(); - static QList generateSidebarUrls(QList sidebarUrls); -}; - -#endif // SIDEBARGENERATOR_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef SIDEBARGENERATOR_H +#define SIDEBARGENERATOR_H + +#include +#include + +class SidebarGenerator +{ +public: + SidebarGenerator(); + static QList generateSidebarUrls(QList sidebarUrls); +}; + +#endif // SIDEBARGENERATOR_H diff --git a/SnapmaticEditor.cpp b/SnapmaticEditor.cpp index f07346e..a959ccb 100644 --- a/SnapmaticEditor.cpp +++ b/SnapmaticEditor.cpp @@ -1,427 +1,243 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SnapmaticEditor.h" -#include "ui_SnapmaticEditor.h" -#include "SnapmaticPicture.h" -#include "PlayerListDialog.h" -#include "StringParser.h" -#include "wrapper.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include - -#ifdef GTA5SYNC_TELEMETRY -#include "TelemetryClass.h" -#include -#include -#endif - -SnapmaticEditor::SnapmaticEditor(CrewDatabase *crewDB, ProfileDatabase *profileDB, QWidget *parent) : - QDialog(parent), crewDB(crewDB), profileDB(profileDB), - ui(new Ui::SnapmaticEditor) -{ - // Set Window Flags -#if QT_VERSION >= 0x050900 - setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - - ui->setupUi(this); - ui->cmdCancel->setDefault(true); - ui->cmdCancel->setFocus(); - - // Set Icon for Apply Button - if (QIcon::hasThemeIcon("dialog-ok-apply")) { - ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok-apply")); - } - else if (QIcon::hasThemeIcon("dialog-apply")) { - ui->cmdApply->setIcon(QIcon::fromTheme("dialog-apply")); - } - else if (QIcon::hasThemeIcon("gtk-apply")) { - ui->cmdApply->setIcon(QIcon::fromTheme("gtk-apply")); - } - else if (QIcon::hasThemeIcon("dialog-ok")) { - ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok")); - } - else if (QIcon::hasThemeIcon("gtk-ok")) { - ui->cmdApply->setIcon(QIcon::fromTheme("dialog-ok")); - } - - // Set Icon for Cancel Button - if (QIcon::hasThemeIcon("dialog-cancel")) { - ui->cmdCancel->setIcon(QIcon::fromTheme("dialog-cancel")); - } - else if (QIcon::hasThemeIcon("gtk-cancel")) { - ui->cmdCancel->setIcon(QIcon::fromTheme("gtk-cancel")); - } - - snapmaticTitle = QString(); - smpic = 0; - -#ifndef Q_OS_ANDROID - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); - resize(400 * screenRatio, 360 * screenRatio); -#endif -} - -SnapmaticEditor::~SnapmaticEditor() -{ - delete ui; -} - -void SnapmaticEditor::selfie_toggled(bool checked) -{ - isSelfie = checked; -} - - -void SnapmaticEditor::mugshot_toggled(bool checked) -{ - if (checked) { - isMugshot = true; - ui->cbDirector->setEnabled(false); - ui->cbDirector->setChecked(false); - } - else { - isMugshot = false; - ui->cbDirector->setEnabled(true); - } -} - -void SnapmaticEditor::editor_toggled(bool checked) -{ - if (checked) { - isEditor = true; - ui->cbDirector->setEnabled(false); - ui->cbDirector->setChecked(false); - } - else { - isEditor = false; - ui->cbDirector->setEnabled(true); - } -} - -void SnapmaticEditor::on_rbSelfie_toggled(bool checked) -{ - if (checked) { - mugshot_toggled(false); - editor_toggled(false); - selfie_toggled(true); - } -} - -void SnapmaticEditor::on_rbMugshot_toggled(bool checked) -{ - if (checked) { - selfie_toggled(false); - editor_toggled(false); - mugshot_toggled(true); - } -} - -void SnapmaticEditor::on_rbEditor_toggled(bool checked) -{ - if (checked) { - selfie_toggled(false); - mugshot_toggled(false); - editor_toggled(true); - } -} - -void SnapmaticEditor::on_rbCustom_toggled(bool checked) -{ - if (checked) { - selfie_toggled(false); - mugshot_toggled(false); - editor_toggled(false); - } -} - -void SnapmaticEditor::setSnapmaticPicture(SnapmaticPicture *picture) -{ - smpic = picture; - snapmaticProperties = smpic->getSnapmaticProperties(); - ui->rbCustom->setChecked(true); - crewID = snapmaticProperties.crewID; - isSelfie = snapmaticProperties.isSelfie; - isMugshot = snapmaticProperties.isMug; - isEditor = snapmaticProperties.isFromRSEditor; - playersList = snapmaticProperties.playersList; - ui->cbDirector->setChecked(snapmaticProperties.isFromDirector); - ui->cbMeme->setChecked(snapmaticProperties.isMeme); - if (isSelfie) { - ui->rbSelfie->setChecked(true); - } - else if (isMugshot) { - ui->rbMugshot->setChecked(true); - } - else if (isEditor) { - ui->rbEditor->setChecked(true); - } - else { - ui->rbCustom->setChecked(true); - } - setSnapmaticCrew(returnCrewName(crewID)); - setSnapmaticTitle(picture->getPictureTitle()); - setSnapmaticPlayers(insertPlayerNames(playersList)); -} - -void SnapmaticEditor::insertPlayerNames(QStringList *players) -{ - for (int i = 0; i < players->size(); ++i) { - players->replace(i, profileDB->getPlayerName(players->at(i))); - } -} - -QStringList SnapmaticEditor::insertPlayerNames(const QStringList &players) -{ - QStringList playersWI = players; - insertPlayerNames(&playersWI); - return playersWI; -} - -void SnapmaticEditor::setSnapmaticPlayers(const QStringList &players) -{ - QString editStr = QString("%1").arg(tr("Edit")); - QString playersStr; - if (players.length() != 1) { - playersStr = tr("Players: %1 (%2)", "Multiple Player are inserted here"); - } - else { - playersStr = tr("Player: %1 (%2)", "One Player is inserted here"); - } - if (players.length() != 0) { - ui->labPlayers->setText(playersStr.arg(players.join(", "), editStr)); - } - else { - ui->labPlayers->setText(playersStr.arg(QApplication::translate("PictureDialog", "No Players"), editStr)); - } -#ifndef Q_OS_ANDROID - ui->gbValues->resize(ui->gbValues->width(), ui->gbValues->heightForWidth(ui->gbValues->width())); - ui->frameWidget->resize(ui->gbValues->width(), ui->frameWidget->heightForWidth(ui->frameWidget->width())); - if (heightForWidth(width()) > height()) - resize(width(), heightForWidth(width())); -#endif -} - -void SnapmaticEditor::setSnapmaticTitle(const QString &title) -{ - if (title.length() > 39) { - snapmaticTitle = title.left(39); - } - else { - snapmaticTitle = title; - } - QString editStr = QString("%1").arg(tr("Edit")); - QString titleStr = tr("Title: %1 (%2)").arg(StringParser::escapeString(snapmaticTitle), editStr); - ui->labTitle->setText(titleStr); - if (SnapmaticPicture::verifyTitle(snapmaticTitle)) { - ui->labAppropriate->setText(tr("Appropriate: %1").arg(QString("%1").arg(tr("Yes", "Yes, should work fine")))); - } - else { - ui->labAppropriate->setText(tr("Appropriate: %1").arg(QString("%1").arg(tr("No", "No, could lead to issues")))); - } -#ifndef Q_OS_ANDROID - ui->gbValues->resize(ui->gbValues->width(), ui->gbValues->heightForWidth(ui->gbValues->width())); - ui->frameWidget->resize(ui->gbValues->width(), ui->frameWidget->heightForWidth(ui->frameWidget->width())); - if (heightForWidth(width()) > height()) - resize(width(), heightForWidth(width())); -#endif -} - -void SnapmaticEditor::setSnapmaticCrew(const QString &crew) -{ - QString editStr = QString("%1").arg(tr("Edit")); - QString crewStr = tr("Crew: %1 (%2)").arg(StringParser::escapeString(crew), editStr); - ui->labCrew->setText(crewStr); -#ifndef Q_OS_ANDROID - ui->gbValues->resize(ui->gbValues->width(), ui->gbValues->heightForWidth(ui->gbValues->width())); - ui->frameWidget->resize(ui->gbValues->width(), ui->frameWidget->heightForWidth(ui->frameWidget->width())); - if (heightForWidth(width()) > height()) - resize(width(), heightForWidth(width())); -#endif -} - -QString SnapmaticEditor::returnCrewName(int crewID_) -{ - return crewDB->getCrewName(crewID_); -} - -void SnapmaticEditor::on_cmdCancel_clicked() -{ - close(); -} - -void SnapmaticEditor::on_cmdApply_clicked() -{ - if (ui->cbQualify->isChecked()) { - qualifyAvatar(); - } - snapmaticProperties.crewID = crewID; - snapmaticProperties.isSelfie = isSelfie; - snapmaticProperties.isMug = isMugshot; - snapmaticProperties.isFromRSEditor = isEditor; - snapmaticProperties.isFromDirector = ui->cbDirector->isChecked(); - snapmaticProperties.isMeme = ui->cbMeme->isChecked(); - snapmaticProperties.playersList = playersList; - if (smpic) { - QString currentFilePath = smpic->getPictureFilePath(); - QString originalFilePath = smpic->getOriginalPictureFilePath(); - QString backupFileName = originalFilePath % ".bak"; - if (!QFile::exists(backupFileName)) { - QFile::copy(currentFilePath, backupFileName); - } - SnapmaticProperties fallbackProperties = smpic->getSnapmaticProperties(); - QString fallbackTitle = smpic->getPictureTitle(); - smpic->setSnapmaticProperties(snapmaticProperties); - smpic->setPictureTitle(snapmaticTitle); - if (!smpic->exportPicture(currentFilePath)) { - QMessageBox::warning(this, tr("Snapmatic Properties"), tr("Patching of Snapmatic Properties failed because of I/O Error")); - smpic->setSnapmaticProperties(fallbackProperties); - smpic->setPictureTitle(fallbackTitle); - } - else { - smpic->updateStrings(); - smpic->emitUpdate(); -#ifdef GTA5SYNC_TELEMETRY - QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - telemetrySettings.beginGroup("Telemetry"); - bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool(); - telemetrySettings.endGroup(); - if (pushUsageData && Telemetry->canPush()) { - QJsonDocument jsonDocument; - QJsonObject jsonObject; - jsonObject["Type"] = "PropertyEdited"; - jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength()); -#if QT_VERSION >= 0x060000 - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } -#endif - } - } - close(); -} - -void SnapmaticEditor::qualifyAvatar() -{ - ui->rbSelfie->setChecked(true); - ui->cbDirector->setChecked(false); - ui->cbMeme->setChecked(false); - ui->cmdApply->setDefault(true); -} - -void SnapmaticEditor::on_cbQualify_toggled(bool checked) -{ - if (checked) { - ui->cbMeme->setEnabled(false); - ui->cbDirector->setEnabled(false); - ui->rbCustom->setEnabled(false); - ui->rbSelfie->setEnabled(false); - ui->rbEditor->setEnabled(false); - ui->rbMugshot->setEnabled(false); - } - else { - ui->cbMeme->setEnabled(true); - ui->rbCustom->setEnabled(true); - ui->rbSelfie->setEnabled(true); - ui->rbEditor->setEnabled(true); - ui->rbMugshot->setEnabled(true); - if (ui->rbSelfie->isChecked() || ui->rbCustom->isChecked()) { - ui->cbDirector->setEnabled(true); - } - } -} - -void SnapmaticEditor::on_labPlayers_linkActivated(const QString &link) -{ - if (link == "g5e://editplayers") { - PlayerListDialog *playerListDialog = new PlayerListDialog(playersList, profileDB, this); - connect(playerListDialog, SIGNAL(playerListUpdated(QStringList)), this, SLOT(playerListUpdated(QStringList))); - playerListDialog->setModal(true); - playerListDialog->show(); - playerListDialog->exec(); - delete playerListDialog; - } -} - -void SnapmaticEditor::on_labTitle_linkActivated(const QString &link) -{ - if (link == "g5e://edittitle") { - bool ok; - QString newTitle = QInputDialog::getText(this, tr("Snapmatic Title"), tr("New Snapmatic title:"), QLineEdit::Normal, snapmaticTitle, &ok, windowFlags()); - if (ok && !newTitle.isEmpty()) { - setSnapmaticTitle(newTitle); - } - } -} - -void SnapmaticEditor::on_labCrew_linkActivated(const QString &link) -{ - if (link == "g5e://editcrew") { - bool ok; - int indexNum = 0; - QStringList itemList; - QStringList crewList = crewDB->getCrews(); - if (!crewList.contains(QLatin1String("0"))) { - crewList += QLatin1String("0"); - } - crewList.sort(); - for (const QString &crew : crewList) { - itemList += QString("%1 (%2)").arg(crew, returnCrewName(crew.toInt())); - } - if (crewList.contains(QString::number(crewID))) { - indexNum = crewList.indexOf(QString::number(crewID)); - } - QString newCrew = QInputDialog::getItem(this, tr("Snapmatic Crew"), tr("New Snapmatic crew:"), itemList, indexNum, true, &ok, windowFlags()); - if (ok && !newCrew.isEmpty()) { - if (newCrew.contains(" ")) - newCrew = newCrew.split(" ").at(0); - if (newCrew.length() > 10) - return; - for (const QChar &crewChar : qAsConst(newCrew)) { - if (!crewChar.isNumber()) { - return; - } - } - if (!crewList.contains(newCrew)) { - crewDB->addCrew(crewID); - } - crewID = newCrew.toInt(); - setSnapmaticCrew(returnCrewName(crewID)); - } - } -} - -void SnapmaticEditor::playerListUpdated(QStringList playerList) -{ - playersList = playerList; - setSnapmaticPlayers(insertPlayerNames(playerList)); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "SnapmaticEditor.h" +#include "ui_SnapmaticEditor.h" +#include "SnapmaticPicture.h" +#include +#include +#include + +SnapmaticEditor::SnapmaticEditor(QWidget *parent) : + QDialog(parent), + ui(new Ui::SnapmaticEditor) +{ + ui->setupUi(this); + ui->cbSelfie->setVisible(false); + ui->cbMugshot->setVisible(false); + ui->cbEditor->setVisible(false); + ui->cmdApply->setDefault(true); + smpic = 0; +} + +SnapmaticEditor::~SnapmaticEditor() +{ + delete ui; +} + +void SnapmaticEditor::on_cbSelfie_toggled(bool checked) +{ + if (checked) + { + ui->cbMugshot->setEnabled(false); + ui->cbEditor->setEnabled(false); + } + else if (!ui->cbDirector->isChecked()) + { + ui->cbMugshot->setEnabled(true); + ui->cbEditor->setEnabled(true); + } +} + + +void SnapmaticEditor::on_cbMugshot_toggled(bool checked) +{ + if (checked) + { + ui->cbSelfie->setEnabled(false); + ui->cbEditor->setEnabled(false); + ui->cbDirector->setEnabled(false); + } + else + { + ui->cbSelfie->setEnabled(true); + ui->cbEditor->setEnabled(true); + ui->cbDirector->setEnabled(true); + } +} + +void SnapmaticEditor::on_cbDirector_toggled(bool checked) +{ + if (checked) + { + ui->cbMugshot->setEnabled(false); + ui->cbEditor->setEnabled(false); + } + else if (!ui->cbSelfie->isChecked()) + { + ui->cbMugshot->setEnabled(true); + ui->cbEditor->setEnabled(true); + } +} + +void SnapmaticEditor::on_cbEditor_toggled(bool checked) +{ + if (checked) + { + ui->cbSelfie->setEnabled(false); + ui->cbMugshot->setEnabled(false); + ui->cbDirector->setEnabled(false); + } + else + { + ui->cbSelfie->setEnabled(true); + ui->cbMugshot->setEnabled(true); + ui->cbDirector->setEnabled(true); + } +} + +void SnapmaticEditor::on_rbSelfie_toggled(bool checked) +{ + if (checked) + { + ui->cbMugshot->setChecked(false); + ui->cbEditor->setChecked(false); + ui->cbSelfie->setChecked(true); + } +} + +void SnapmaticEditor::on_rbMugshot_toggled(bool checked) +{ + if (checked) + { + ui->cbSelfie->setChecked(false); + ui->cbEditor->setChecked(false); + ui->cbDirector->setChecked(false); + ui->cbMugshot->setChecked(true); + } +} + +void SnapmaticEditor::on_rbEditor_toggled(bool checked) +{ + if (checked) + { + ui->cbSelfie->setChecked(false); + ui->cbMugshot->setChecked(false); + ui->cbDirector->setChecked(false); + ui->cbEditor->setChecked(true); + } +} + +void SnapmaticEditor::on_rbCustom_toggled(bool checked) +{ + if (checked) + { + ui->cbSelfie->setChecked(false); + ui->cbMugshot->setChecked(false); + ui->cbEditor->setChecked(false); + } +} + +void SnapmaticEditor::setSnapmaticPicture(SnapmaticPicture *picture) +{ + smpic = picture; + localSpJson = smpic->getSnapmaticProperties(); + ui->rbCustom->setChecked(true); + ui->cbSelfie->setChecked(localSpJson.isSelfie); + ui->cbMugshot->setChecked(localSpJson.isMug); + ui->cbEditor->setChecked(localSpJson.isFromRSEditor); + ui->cbDirector->setChecked(localSpJson.isFromDirector); + ui->cbMeme->setChecked(localSpJson.isMeme); + if (ui->cbSelfie->isChecked()) + { + ui->rbSelfie->setChecked(true); + } + else if (ui->cbMugshot->isChecked()) + { + ui->rbMugshot->setChecked(true); + } + else if (ui->cbEditor->isChecked()) + { + ui->rbEditor->setChecked(true); + } + else + { + ui->rbCustom->setChecked(true); + } +} + +void SnapmaticEditor::on_cmdCancel_clicked() +{ + close(); +} + +void SnapmaticEditor::on_cmdApply_clicked() +{ + if (ui->cbQualify->isChecked()) + { + qualifyAvatar(); + } + localSpJson.isSelfie = ui->cbSelfie->isChecked(); + localSpJson.isMug = ui->cbMugshot->isChecked(); + localSpJson.isFromRSEditor = ui->cbEditor->isChecked(); + localSpJson.isFromDirector = ui->cbDirector->isChecked(); + localSpJson.isMeme = ui->cbMeme->isChecked(); + if (smpic) + { + QString originalFileName = smpic->getPictureFileName(); + QString adjustedFileName = originalFileName; + if (adjustedFileName.right(7) == ".hidden") // for the hidden file system + { + adjustedFileName.remove(adjustedFileName.length() - 7, 7); + } + QString backupFileName = adjustedFileName + ".bak"; + if (!QFile::exists(backupFileName)) + { + QFile::copy(adjustedFileName, backupFileName); + } + smpic->setSnapmaticProperties(localSpJson); + if (!smpic->exportPicture(originalFileName)) + { + QMessageBox::warning(this, tr("Snapmatic Properties"), tr("Patching of Snapmatic Properties failed because of I/O Error")); + } + } + close(); +} + +void SnapmaticEditor::qualifyAvatar() +{ + ui->rbSelfie->setChecked(true); + ui->cbDirector->setChecked(false); + ui->cbMeme->setChecked(false); + ui->cmdApply->setDefault(true); +} + +void SnapmaticEditor::on_cbQualify_toggled(bool checked) +{ + if (checked) + { + ui->cbMeme->setEnabled(false); + ui->cbDirector->setEnabled(false); + ui->rbCustom->setEnabled(false); + ui->rbSelfie->setEnabled(false); + ui->rbEditor->setEnabled(false); + ui->rbMugshot->setEnabled(false); + } + else + { + ui->cbMeme->setEnabled(true); + ui->rbCustom->setEnabled(true); + ui->rbSelfie->setEnabled(true); + ui->rbEditor->setEnabled(true); + ui->rbMugshot->setEnabled(true); + if (ui->rbSelfie->isChecked() || ui->rbCustom->isChecked()) + { + ui->cbDirector->setEnabled(true); + } + } +} diff --git a/SnapmaticEditor.h b/SnapmaticEditor.h index 98ed2d6..e22960c 100644 --- a/SnapmaticEditor.h +++ b/SnapmaticEditor.h @@ -1,77 +1,59 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef SNAPMATICEDITOR_H -#define SNAPMATICEDITOR_H - -#include -#include "CrewDatabase.h" -#include "ProfileDatabase.h" -#include "SnapmaticPicture.h" - -namespace Ui { -class SnapmaticEditor; -} - -class SnapmaticEditor : public QDialog -{ - Q_OBJECT - -public: - explicit SnapmaticEditor(CrewDatabase *crewDB, ProfileDatabase *profileDB, QWidget *parent = 0); - void setSnapmaticPicture(SnapmaticPicture *picture); - void setSnapmaticPlayers(const QStringList &players); - void setSnapmaticTitle(const QString &title); - void setSnapmaticCrew(const QString &crew = ""); - QString returnCrewName(int crewID); - ~SnapmaticEditor(); - -private slots: - void on_rbSelfie_toggled(bool checked); - void on_rbMugshot_toggled(bool checked); - void on_rbEditor_toggled(bool checked); - void on_rbCustom_toggled(bool checked); - void on_cmdCancel_clicked(); - void on_cmdApply_clicked(); - void on_cbQualify_toggled(bool checked); - void on_labPlayers_linkActivated(const QString &link); - void on_labTitle_linkActivated(const QString &link); - void on_labCrew_linkActivated(const QString &link); - void playerListUpdated(QStringList playerList); - -private: - CrewDatabase *crewDB; - ProfileDatabase *profileDB; - Ui::SnapmaticEditor *ui; - SnapmaticProperties snapmaticProperties; - SnapmaticPicture *smpic; - QStringList playersList; - QString snapmaticTitle; - int crewID; - bool isSelfie; - bool isMugshot; - bool isEditor; - void selfie_toggled(bool checked); - void mugshot_toggled(bool checked); - void editor_toggled(bool checked); - void qualifyAvatar(); - void insertPlayerNames(QStringList *players); - QStringList insertPlayerNames(const QStringList &players); -}; - -#endif // SNAPMATICEDITOR_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef SNAPMATICEDITOR_H +#define SNAPMATICEDITOR_H + +#include +#include "SnapmaticPicture.h" + +namespace Ui { +class SnapmaticEditor; +} + +class SnapmaticEditor : public QDialog +{ + Q_OBJECT + +public: + explicit SnapmaticEditor(QWidget *parent = 0); + void setSnapmaticPicture(SnapmaticPicture *picture); + ~SnapmaticEditor(); + +private slots: + void on_cbSelfie_toggled(bool checked); + void on_cbMugshot_toggled(bool checked); + void on_cbDirector_toggled(bool checked); + void on_cbEditor_toggled(bool checked); + void on_rbSelfie_toggled(bool checked); + void on_rbMugshot_toggled(bool checked); + void on_rbEditor_toggled(bool checked); + void on_rbCustom_toggled(bool checked); + void on_cmdCancel_clicked(); + void on_cmdApply_clicked(); + + void on_cbQualify_toggled(bool checked); + +private: + Ui::SnapmaticEditor *ui; + SnapmaticProperties localSpJson; + SnapmaticPicture *smpic; + void qualifyAvatar(); +}; + +#endif // SNAPMATICEDITOR_H diff --git a/SnapmaticEditor.ui b/SnapmaticEditor.ui index fc9ede9..fda63ed 100644 --- a/SnapmaticEditor.ui +++ b/SnapmaticEditor.ui @@ -1,276 +1,178 @@ - - - SnapmaticEditor - - - - 0 - 0 - 400 - 381 - - - - Snapmatic Properties - - - true - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Snapmatic Type - - - - - - Editor - - - - - - - Selfie - - - - - - - Regular - - - - - - - Mugshot - - - - - - - - - - Snapmatic Properties - - - - - - Meme - - - - - - - Director - - - - - - - - - - Snapmatic Values - - - - - - Qt::NoContextMenu - - - - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse - - - - - - - Qt::NoContextMenu - - - - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse - - - - - - - Qt::NoContextMenu - - - - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse - - - - - - - - - - true - - - - - - - - - - Extras - - - - - - Qualify as Avatar automatically at apply - - - - - - - - 0 - 0 - - - - Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture - - - true - - - - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Apply changes - - - &Apply - - - - - - - - 0 - 0 - - - - Discard changes - - - &Cancel - - - - - - - - - - UiModLabel - QLabel -
UiModLabel.h
-
-
- - -
+ + + SnapmaticEditor + + + + 0 + 0 + 375 + 305 + + + + Snapmatic Properties + + + + + + Snapmatic Type + + + + + + Editor + + + + + + + Selfie + + + + + + + Regular + + + + + + + Mugshot + + + + + + + + + + Snapmatic Properties + + + + + + Editor + + + + + + + Meme + + + + + + + Director + + + + + + + Selfie + + + + + + + Mugshot + + + + + + + + + + Extras + + + + + + Qualify as Avatar automatically at apply + + + + + + + Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture + + + true + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + &Apply + + + + + + + + + + &Cancel + + + + + + + + + + + + + diff --git a/SnapmaticPicture.cpp b/SnapmaticPicture.cpp old mode 100644 new mode 100755 index c3664fd..2109d48 --- a/SnapmaticPicture.cpp +++ b/SnapmaticPicture.cpp @@ -1,836 +1,647 @@ -/***************************************************************************** -* gta5spv Grand Theft Auto Snapmatic Picture Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SnapmaticPicture.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if QT_VERSION < 0x060000 -#include -#else -#include -#endif - -#if QT_VERSION >= 0x050000 -#include -#else -#include "StandardPaths.h" -#endif - -// IMAGES VALUES -#define snapmaticResolutionW 960 -#define snapmaticResolutionH 536 -#define snapmaticResolution QSize(snapmaticResolutionW, snapmaticResolutionH) - -SnapmaticPicture::SnapmaticPicture(const QString &fileName, QObject *parent) : QObject(parent), picFilePath(fileName) -{ - reset(); -} - -SnapmaticPicture::~SnapmaticPicture() -{ -} - -void SnapmaticPicture::reset() -{ - // INIT PIC - p_ragePhoto.clear(); - cachePicture = QImage(); - picExportFileName = QString(); - pictureStr = QString(); - lastStep = QString(); - sortStr = QString(); - - // INIT PIC BOOLS - isFormatSwitch = false; - picOk = false; - - // INIT JSON - jsonOk = false; - - // SNAPMATIC PROPERTIES - localProperties = {}; -} - -bool SnapmaticPicture::preloadFile() -{ - QFile *picFile = new QFile(picFilePath); - picFileName = QFileInfo(picFilePath).fileName(); - - isFormatSwitch = false; - - if (!picFile->open(QFile::ReadOnly)) { - lastStep = "1;/1,OpenFile," % convertDrawStringForLog(picFilePath); - delete picFile; - return false; - } - - p_ragePhoto.setIODevice(picFile); - bool ok = p_ragePhoto.load(); - picFile->close(); - delete picFile; - if (!ok) - return false; - - if (picFilePath.right(4) != QLatin1String(".g5e")) { - if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) - isFormatSwitch = true; - } - emit preloaded(); - return ok; -} - -bool SnapmaticPicture::readingPicture(bool cacheEnabled_) -{ - // Start opening file - // lastStep is like currentStep - - // Set boolean values - cacheEnabled = cacheEnabled_; - - bool ok = true; - if (!p_ragePhoto.isLoaded()) - ok = preloadFile(); - - if (!ok) - return false; - - if (cacheEnabled) - picOk = cachePicture.loadFromData(p_ragePhoto.photoData(), "JPEG"); - if (!cacheEnabled) { - QImage tempPicture; - picOk = tempPicture.loadFromData(p_ragePhoto.photoData(), "JPEG"); - } - - parseJsonContent(); // JSON parsing is own function - updateStrings(); - - emit loaded(); - return picOk; -} - -void SnapmaticPicture::updateStrings() -{ - QString cmpPicTitl = p_ragePhoto.title(); - cmpPicTitl.replace('\"', "''"); - cmpPicTitl.replace(' ', '_'); - cmpPicTitl.replace(':', '-'); - cmpPicTitl.remove('\\'); - cmpPicTitl.remove('{'); - cmpPicTitl.remove('}'); - cmpPicTitl.remove('/'); - cmpPicTitl.remove('<'); - cmpPicTitl.remove('>'); - cmpPicTitl.remove('*'); - cmpPicTitl.remove('?'); - cmpPicTitl.remove('.'); - pictureStr = tr("PHOTO - %1").arg(localProperties.createdDateTime.toString("MM/dd/yy HH:mm:ss")); - sortStr = localProperties.createdDateTime.toString("yyMMddHHmmss") % QString::number(localProperties.uid); - QString exportStr = localProperties.createdDateTime.toString("yyyyMMdd") % "-" % QString::number(localProperties.uid); - if (getSnapmaticFormat() == SnapmaticFormat::G5E_Format) - picFileName = "PGTA5" % QString::number(localProperties.uid); - picExportFileName = exportStr % "_" % cmpPicTitl; -} - -bool SnapmaticPicture::readingPictureFromFile(const QString &fileName, bool cacheEnabled_) -{ - if (!fileName.isEmpty()) { - picFilePath = fileName; - return readingPicture(cacheEnabled_); - } - else { - return false; - } -} - -bool SnapmaticPicture::setImage(const QImage &picture, bool eXtendMode) -{ -#ifdef GTA5SYNC_DYNAMIC_PHOTOBUFFER - quint32 jpegPicStreamLength = p_ragePhoto.photoBuffer(); -#else - quint32 jpegPicStreamLength = 524288U; -#endif - QByteArray picByteArray; - int comLvl = 100; - bool saveSuccess = false; - while (comLvl != 0 && !saveSuccess) { - QByteArray picByteArrayT; - QBuffer picStreamT(&picByteArrayT); - picStreamT.open(QIODevice::WriteOnly); - saveSuccess = picture.save(&picStreamT, "JPEG", comLvl); - picStreamT.close(); - if (saveSuccess) { - quint32 size = picByteArrayT.length(); - if (size > jpegPicStreamLength) { - if (!eXtendMode) { - comLvl--; - saveSuccess = false; - } - else { - p_ragePhoto.setPhotoBuffer(size, true); - picByteArray = picByteArrayT; - } - } - else { -#ifndef GTA5SYNC_DYNAMIC_PHOTOBUFFER - if (p_ragePhoto.photoBuffer() != jpegPicStreamLength) - p_ragePhoto.setPhotoData(QByteArray()); // avoid buffer set fail - p_ragePhoto.setPhotoBuffer(jpegPicStreamLength, true); -#endif - picByteArray = picByteArrayT; - } - } - } - if (saveSuccess) - return setPictureStream(picByteArray); - return false; -} - -bool SnapmaticPicture::setPictureStream(const QByteArray &streamArray) // clean method -{ - bool success = p_ragePhoto.setPhotoData(streamArray); - if (success) { - if (cacheEnabled) { - QImage replacedPicture; - replacedPicture.loadFromData(streamArray); - cachePicture = replacedPicture; - } - return true; - } - else { - return false; - } -} - -bool SnapmaticPicture::setPictureTitl(const QString &newTitle_) -{ - QString newTitle = newTitle_; - if (newTitle.length() > 39) { - newTitle = newTitle.left(39); - } - p_ragePhoto.setTitle(newTitle); - return true; -} - -int SnapmaticPicture::getContentMaxLength() -{ - return p_ragePhoto.photoBuffer(); -} - -QString SnapmaticPicture::getExportPictureFileName() -{ - return picExportFileName; -} - -QString SnapmaticPicture::getOriginalPictureFileName() -{ - QString newPicFileName = picFileName; - if (picFileName.right(4) == ".bak") { - newPicFileName = QString(picFileName).remove(picFileName.length() - 4, 4); - } - if (picFileName.right(7) == ".hidden") { - newPicFileName = QString(picFileName).remove(picFileName.length() - 7, 7); - } - return newPicFileName; -} - -QString SnapmaticPicture::getOriginalPictureFilePath() -{ - QString newPicFilePath = picFilePath; - if (picFilePath.right(4) == ".bak") { - newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 4, 4); - } - if (picFilePath.right(7) == ".hidden") { - newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7); - } - return newPicFilePath; -} - -QString SnapmaticPicture::getPictureFileName() -{ - return picFileName; -} - -QString SnapmaticPicture::getPictureFilePath() -{ - return picFilePath; -} - -QString SnapmaticPicture::getPictureSortStr() -{ - return sortStr; -} - -QString SnapmaticPicture::getPictureTitl() -{ - return p_ragePhoto.title(); -} - -QString SnapmaticPicture::getPictureStr() -{ - return pictureStr; -} - -QString SnapmaticPicture::getLastStep(bool readable) -{ - if (readable) { - QStringList lastStepList = lastStep.split(";/"); - if (lastStepList.length() < 2) - return lastStep; - bool intOk; - QStringList descStepList = lastStepList.at(1).split(","); - if (descStepList.length() < 1) - return lastStep; - int argsCount = descStepList.at(0).toInt(&intOk); - if (!intOk) { return lastStep; } - if (argsCount == 1) { - QString currentAction = descStepList.at(1); - QString actionFile = descStepList.at(2); - if (currentAction == "OpenFile") { - return tr("open file %1").arg(actionFile); - } - } - else if (argsCount == 3 || argsCount == 4) { - QString currentAction = descStepList.at(1); - QString actionFile = descStepList.at(2); - QString actionError = descStepList.at(4); - QString actionError2; - if (argsCount == 4) { actionError2 = descStepList.at(5); } - if (currentAction == "ReadingFile") { - QString readableError = actionError; - if (actionError == "NOHEADER") { - readableError = tr("header not exists"); - } - else if (actionError == "MALFORMEDHEADER") { - readableError = tr("header is malformed"); - } - else if (actionError == "NOJPEG" || actionError == "NOPIC") { - readableError = tr("picture not exists (%1)").arg(actionError); - } - else if (actionError == "NOJSON" || actionError == "CTJSON") { - readableError = tr("JSON not exists (%1)").arg(actionError); - } - else if (actionError == "NOTITL" || actionError == "CTTITL") { - readableError = tr("title not exists (%1)").arg(actionError); - } - else if (actionError == "NODESC" || actionError == "CTDESC") { - readableError = tr("description not exists (%1)").arg(actionError); - } - else if (actionError == "JSONINCOMPLETE" && actionError2 == "JSONERROR") { - readableError = tr("JSON is incomplete and malformed"); - } - else if (actionError == "JSONINCOMPLETE") { - readableError = tr("JSON is incomplete"); - } - else if (actionError == "JSONERROR") { - readableError = tr("JSON is malformed"); - } - return tr("reading file %1 because of %2", "Example for %2: JSON is malformed error").arg(actionFile, readableError); - } - else { - return lastStep; - } - } - else { - return lastStep; - } - } - return lastStep; - -} - -QImage SnapmaticPicture::getImage() -{ - if (cacheEnabled) { - return cachePicture; - } - else { - return QImage::fromData(p_ragePhoto.photoData(), "JPEG"); - } - return QImage(); -} - -QByteArray SnapmaticPicture::getPictureStream() -{ - return p_ragePhoto.photoData(); -} - -bool SnapmaticPicture::isPicOk() -{ - return picOk; -} - -void SnapmaticPicture::clearCache() -{ - cacheEnabled = false; - cachePicture = QImage(); -} - -void SnapmaticPicture::emitUpdate() -{ - emit updated(); -} - -void SnapmaticPicture::emitCustomSignal(const QString &signal) -{ - emit customSignal(signal); -} - -// JSON part - -bool SnapmaticPicture::isJsonOk() -{ - return jsonOk; -} - -QString SnapmaticPicture::getJsonStr() -{ - return QString::fromUtf8(p_ragePhoto.jsonData()); -} - -SnapmaticProperties SnapmaticPicture::getSnapmaticProperties() -{ - return localProperties; -} - -void SnapmaticPicture::parseJsonContent() -{ - QJsonObject jsonObject = p_ragePhoto.jsonObject(); - QVariantMap jsonMap = jsonObject.toVariantMap(); - - bool jsonIncomplete = false; - bool jsonError = false; - if (jsonObject.contains("loc")) { - if (jsonObject["loc"].isObject()) { - QJsonObject locObject = jsonObject["loc"].toObject(); - if (locObject.contains("x")) { - if (locObject["x"].isDouble()) { localProperties.location.x = locObject["x"].toDouble(); } - else { jsonError = true; } - } - else { jsonIncomplete = true; } - if (locObject.contains("y")) { - if (locObject["y"].isDouble()) { localProperties.location.y = locObject["y"].toDouble(); } - else { jsonError = true; } - } - else { jsonIncomplete = true; } - if (locObject.contains("z")) { - if (locObject["z"].isDouble()) { localProperties.location.z = locObject["z"].toDouble(); } - else { jsonError = true; } - } - else { jsonIncomplete = true; } - } - else { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("uid")) { - bool uidOk; - localProperties.uid = jsonMap["uid"].toInt(&uidOk); - if (!uidOk) { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("area")) { - if (jsonObject["area"].isString()) { localProperties.location.area = jsonObject["area"].toString(); } - else { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("crewid")) { - bool crewIDOk; - localProperties.crewID = jsonMap["crewid"].toInt(&crewIDOk); - if (!crewIDOk) { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("street")) { - bool streetIDOk; - localProperties.streetID = jsonMap["street"].toInt(&streetIDOk); - if (!streetIDOk) { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("creat")) { - bool timestampOk; - QDateTime createdTimestamp; - localProperties.createdTimestamp = jsonMap["creat"].toUInt(×tampOk); -#if QT_VERSION >= 0x060000 - createdTimestamp.setSecsSinceEpoch(localProperties.createdTimestamp); -#else - createdTimestamp.setTime_t(localProperties.createdTimestamp); -#endif - localProperties.createdDateTime = createdTimestamp; - if (!timestampOk) { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("plyrs")) { - if (jsonObject["plyrs"].isArray()) { localProperties.playersList = jsonMap["plyrs"].toStringList(); } - else { jsonError = true; } - } - // else { jsonIncomplete = true; } // 2016 Snapmatic pictures left out plyrs when none are captured, so don't force exists on that one - if (jsonObject.contains("meme")) { - if (jsonObject["meme"].isBool()) { localProperties.isMeme = jsonObject["meme"].toBool(); } - else { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("mug")) { - if (jsonObject["mug"].isBool()) { localProperties.isMug = jsonObject["mug"].toBool(); } - else { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("slf")) { - if (jsonObject["slf"].isBool()) { localProperties.isSelfie = jsonObject["slf"].toBool(); } - else { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("drctr")) { - if (jsonObject["drctr"].isBool()) { localProperties.isFromDirector = jsonObject["drctr"].toBool(); } - else { jsonError = true; } - } - else { jsonIncomplete = true; } - if (jsonObject.contains("rsedtr")) { - if (jsonObject["rsedtr"].isBool()) { localProperties.isFromRSEditor = jsonObject["rsedtr"].toBool(); } - else { jsonError = true; } - } - else { localProperties.isFromRSEditor = false; } - if (jsonObject.contains("onislandx")) { - if (jsonObject["onislandx"].isBool()) { localProperties.location.isCayoPerico = jsonObject["onislandx"].toBool(); } - else { jsonError = true; } - } - else { localProperties.location.isCayoPerico = false; } - - if (!jsonIncomplete && !jsonError) { - jsonOk = true; - } - else { - if (jsonIncomplete && jsonError) { - lastStep = "2;/4,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE,JSONERROR"; - } - else if (jsonIncomplete) { - lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE"; - } - else if (jsonError) { - lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONERROR"; - } - jsonOk = false; - } -} - -bool SnapmaticPicture::setSnapmaticProperties(SnapmaticProperties properties) -{ - QJsonObject jsonObject = p_ragePhoto.jsonObject(); - - QJsonObject locObject; - locObject["x"] = properties.location.x; - locObject["y"] = properties.location.y; - locObject["z"] = properties.location.z; - - jsonObject["loc"] = locObject; - jsonObject["uid"] = properties.uid; - jsonObject["area"] = properties.location.area; - jsonObject["crewid"] = properties.crewID; - jsonObject["street"] = properties.streetID; - jsonObject["creat"] = QJsonValue::fromVariant(properties.createdTimestamp); - jsonObject["plyrs"] = QJsonValue::fromVariant(properties.playersList); - jsonObject["meme"] = properties.isMeme; - jsonObject["mug"] = properties.isMug; - jsonObject["slf"] = properties.isSelfie; - jsonObject["drctr"] = properties.isFromDirector; - jsonObject["rsedtr"] = properties.isFromRSEditor; - jsonObject["onislandx"] = properties.location.isCayoPerico; - - QJsonDocument jsonDocument(jsonObject); - if (setJsonStr(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Compact)))) { - localProperties = properties; - return true; - } - return false; -} - -bool SnapmaticPicture::setJsonStr(const QString &newJsonStr, bool updateProperties) -{ - if (p_ragePhoto.setJsonData(newJsonStr.toUtf8())) { - if (updateProperties) - parseJsonContent(); - return true; - } - else { - return false; - } -} - -// FILE MANAGEMENT - -bool SnapmaticPicture::exportPicture(const QString &fileName, SnapmaticFormat format_) -{ - // Keep current format when Auto_Format is used - SnapmaticFormat format = format_; - if (format_ == SnapmaticFormat::Auto_Format) { - if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) { - format = SnapmaticFormat::G5E_Format; - } - else { - format = SnapmaticFormat::PGTA_Format; - } - } - - bool saveSuccess = false; -#if QT_VERSION >= 0x050000 - QSaveFile *picFile = new QSaveFile(fileName); -#else - QFile *picFile = new QFile(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp"); -#endif - if (picFile->open(QIODevice::WriteOnly)) { - if (format == SnapmaticFormat::G5E_Format) { - p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::G5EX); -#if QT_VERSION >= 0x050000 - saveSuccess = picFile->commit(); -#else - saveSuccess = true; - picFile->close(); -#endif - delete picFile; - } - else if (format == SnapmaticFormat::JPEG_Format) { - picFile->write(p_ragePhoto.photoData()); -#if QT_VERSION >= 0x050000 - saveSuccess = picFile->commit(); -#else - saveSuccess = true; - picFile->close(); -#endif - delete picFile; - } - else { - p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::GTA5); -#if QT_VERSION >= 0x050000 - saveSuccess = picFile->commit(); -#else - saveSuccess = true; - picFile->close(); -#endif - delete picFile; - } -#if QT_VERSION <= 0x050000 - if (saveSuccess) { - bool tempBakCreated = false; - if (QFile::exists(fileName)) { - if (!QFile::rename(fileName, fileName % ".tmp")) { - QFile::remove(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp"); - return false; - } - tempBakCreated = true; - } - if (!QFile::rename(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp", fileName)) { - QFile::remove(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp"); - if (tempBakCreated) - QFile::rename(fileName % ".tmp", fileName); - return false; - } - if (tempBakCreated) - QFile::remove(fileName % ".tmp"); - } -#endif - return saveSuccess; - } - else { - delete picFile; - return saveSuccess; - } -} - -void SnapmaticPicture::setPicFileName(const QString &picFileName_) -{ - picFileName = picFileName_; -} - -void SnapmaticPicture::setPicFilePath(const QString &picFilePath_) -{ - picFilePath = picFilePath_; -} - -bool SnapmaticPicture::deletePicFile() -{ - bool success = false; - if (!QFile::exists(picFilePath)) { - success = true; - } - else if (QFile::remove(picFilePath)) { - success = true; - } - if (isHidden()) { - const QString picBakPath = QString(picFilePath).remove(picFilePath.length() - 7, 7) % ".bak"; - if (QFile::exists(picBakPath)) QFile::remove(picBakPath); - } - else { - const QString picBakPath = picFilePath % ".bak"; - if (QFile::exists(picBakPath)) QFile::remove(picBakPath); - } - return success; -} - -// VISIBILITY - -bool SnapmaticPicture::isHidden() -{ - if (picFilePath.right(7) == QLatin1String(".hidden")) { - return true; - } - return false; -} - -bool SnapmaticPicture::isVisible() -{ - if (picFilePath.right(7) == QLatin1String(".hidden")) { - return false; - } - return true; -} - -bool SnapmaticPicture::setPictureHidden() -{ - if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) { - return false; - } - if (!isHidden()) { - QString newPicFilePath = QString(picFilePath % ".hidden"); - if (QFile::rename(picFilePath, newPicFilePath)) { - picFilePath = newPicFilePath; - return true; - } - return false; - } - return true; -} - -bool SnapmaticPicture::setPictureVisible() -{ - if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) { - return false; - } - if (isHidden()) { - QString newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7); - if (QFile::rename(picFilePath, newPicFilePath)) { - picFilePath = newPicFilePath; - return true; - } - return false; - } - return true; -} - -// PREDEFINED PROPERTIES - -QSize SnapmaticPicture::getSnapmaticResolution() -{ - return snapmaticResolution; -} - -// SNAPMATIC FORMAT - -SnapmaticFormat SnapmaticPicture::getSnapmaticFormat() -{ - if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) { - return SnapmaticFormat::G5E_Format; - } - return SnapmaticFormat::PGTA_Format; -} - -void SnapmaticPicture::setSnapmaticFormat(SnapmaticFormat format) -{ - if (format == SnapmaticFormat::G5E_Format) { - p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::G5EX); - return; - } - else if (format == SnapmaticFormat::PGTA_Format) { - p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::GTA5); - return; - } - qDebug() << "setSnapmaticFormat: Invalid SnapmaticFormat defined, valid SnapmaticFormats are G5E_Format and PGTA_Format"; -} - -bool SnapmaticPicture::isFormatSwitched() -{ - return isFormatSwitch; -} - -// VERIFY CONTENT - -bool SnapmaticPicture::verifyTitle(const QString &title) -{ - // VERIFY TITLE FOR BE A VALID SNAPMATIC TITLE - if (title.length() <= 39 && title.length() > 0) { - for (const QChar &titleChar : title) { - if (!verifyTitleChar(titleChar)) return false; - } - return true; - } - return false; -} - -bool SnapmaticPicture::verifyTitleChar(const QChar &titleChar) -{ - // VERIFY CHAR FOR BE A VALID SNAPMATIC CHARACTER - if (titleChar.isLetterOrNumber() || titleChar.isPrint()) { - if (titleChar == '<' || titleChar == '>' || titleChar == '\\') return false; - return true; - } - return false; -} - -// STRING OPERATIONS - -QString SnapmaticPicture::parseTitleString(const QByteArray &commitBytes, int maxLength) -{ - Q_UNUSED(maxLength) -#if QT_VERSION >= 0x060000 - QStringDecoder strDecoder = QStringDecoder(QStringDecoder::Utf16LE); - QString retStr = strDecoder(commitBytes); - retStr = retStr.trimmed(); -#else - QString retStr = QTextCodec::codecForName("UTF-16LE")->toUnicode(commitBytes).trimmed(); -#endif - retStr.remove(QChar('\x00')); - return retStr; -} - -QString SnapmaticPicture::convertDrawStringForLog(const QString &inputStr) -{ - QString outputStr = inputStr; - return outputStr.replace("&","&u;").replace(",", "&c;"); -} - -QString SnapmaticPicture::convertLogStringForDraw(const QString &inputStr) -{ - QString outputStr = inputStr; - return outputStr.replace("&c;",",").replace("&u;", "&"); -} - -// RAGEPHOTO - -RagePhoto* SnapmaticPicture::ragePhoto() -{ - return &p_ragePhoto; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "SnapmaticPicture.h" +#include "StringParser.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +SnapmaticPicture::SnapmaticPicture(const QString &fileName, QObject *parent) : QObject(parent), picFileName(fileName) +{ + // PARSE INT INIT - DO NOT CHANGE THIS VALUES + snapmaticHeaderLength = 278; + snapmaticUsefulLength = 260; + snapmaticFileMaxSize = 528192; + jpegHeaderLineDifStr = 2; + jpegPreHeaderLength = 14; + jpegPicStreamLength = 524288; + jsonStreamLength = 3076; + tideStreamLength = 260; + + // PARSE EDITOR INIT + jpegStreamEditorBegin = 292; + jsonStreamEditorBegin = 524588; + jsonStreamEditorLength = 3072; + rawPicContent = ""; + + // INIT PIC + cachePicture = QImage(0, 0, QImage::Format_RGB32); + picExportFileName = ""; + pictureStr = ""; + lastStep = ""; + sortStr = ""; + titlStr = ""; + descStr = ""; + picOk = 0; + + // INIT JSON + jsonOk = 0; + jsonStr = ""; +} + +SnapmaticPicture::~SnapmaticPicture() +{ +} + +bool SnapmaticPicture::readingPicture(bool writeEnabled_, bool cacheEnabled_) +{ + // Start opening file + // lastStep is like currentStep + + // Set boolean values + writeEnabled = writeEnabled_; + cacheEnabled = cacheEnabled_; + + QFile *picFile = new QFile(picFileName); + QIODevice *picStream; + + if (!picFile->open(QFile::ReadOnly)) + { + lastStep = "1;/1,OpenFile," + StringParser::convertDrawStringForLog(picFileName); + picFile->deleteLater(); + delete picFile; + return false; + } + rawPicContent = picFile->read(snapmaticFileMaxSize); + picFile->close(); + delete picFile; + + picStream = new QBuffer(&rawPicContent); + picStream->open(QIODevice::ReadWrite); + + // Reading Snapmatic Header + if (!picStream->isReadable()) + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",1,NOHEADER"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return false; + } + QByteArray snapmaticHeaderLine = picStream->read(snapmaticHeaderLength); + pictureStr = getSnapmaticPictureString(snapmaticHeaderLine); + + // Reading JPEG Header Line + if (!picStream->isReadable()) + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",2,NOHEADER"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return false; + } + QByteArray jpegHeaderLine = picStream->read(jpegPreHeaderLength); + + // Checking for JPEG + jpegHeaderLine.remove(0, jpegHeaderLineDifStr); + if (jpegHeaderLine.left(4) != "JPEG") + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",2,NOJPEG"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return false; + } + + // Read JPEG Stream + if (!picStream->isReadable()) + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",2,NOPIC"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return false; + } + QByteArray jpegRawContent = picStream->read(jpegPicStreamLength); + if (cacheEnabled) picOk = cachePicture.loadFromData(jpegRawContent, "JPEG"); + if (!cacheEnabled) + { + QImage tempPicture; + picOk = tempPicture.loadFromData(jpegRawContent, "JPEG"); + } + + // Read JSON Stream + if (!picStream->isReadable()) + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",3,NOJSON"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return picOk; + } + else if (picStream->read(4) != "JSON") + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",3,CTJSON"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return picOk; + } + QByteArray jsonRawContent = picStream->read(jsonStreamLength); + jsonStr = getSnapmaticJSONString(jsonRawContent); + parseJsonContent(); // JSON parsing is own function + + if (!picStream->isReadable()) + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",4,NOTITL"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return picOk; + } + else if (picStream->read(4) != "TITL") + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",4,CTTITL"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return picOk; + } + QByteArray titlRawContent = picStream->read(tideStreamLength); + titlStr = getSnapmaticTIDEString(titlRawContent); + + if (!picStream->isReadable()) + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",5,NODESC"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return picOk; + } + else if (picStream->read(4) != "DESC") + { + lastStep = "2;/3,ReadingFile," + StringParser::convertDrawStringForLog(picFileName) + ",5,CTDESC"; + picStream->close(); + picStream->deleteLater(); + delete picStream; + return picOk; + } + QByteArray descRawContent = picStream->read(tideStreamLength); + descStr = getSnapmaticTIDEString(descRawContent); + + parseSnapmaticExportAndSortString(); + + picStream->close(); + picStream->deleteLater(); + delete picStream; + if (!writeEnabled) { rawPicContent.clear(); } + return picOk; +} + +QString SnapmaticPicture::getSnapmaticPictureString(const QByteArray &snapmaticHeader) +{ + QByteArray snapmaticBytes = snapmaticHeader.left(snapmaticUsefulLength); + QList snapmaticBytesList = snapmaticBytes.split(char(0x01)); + snapmaticBytes = snapmaticBytesList.at(1); + snapmaticBytesList.clear(); + return StringParser::parseTitleString(snapmaticBytes, snapmaticBytes.length()); +} + +QString SnapmaticPicture::getSnapmaticJSONString(const QByteArray &jsonBytes) +{ + QByteArray jsonUsefulBytes = jsonBytes; + jsonUsefulBytes.replace((char)0x00, ""); + jsonUsefulBytes.replace((char)0x0c, ""); + return QString::fromUtf8(jsonUsefulBytes).trimmed(); +} + +QString SnapmaticPicture::getSnapmaticTIDEString(const QByteArray &tideBytes) +{ + QByteArray tideUsefulBytes = tideBytes; + tideUsefulBytes.remove(0,4); + QList tideUsefulBytesList = tideUsefulBytes.split(char(0x00)); + return QString::fromUtf8(tideUsefulBytesList.at(0)).trimmed(); +} + +void SnapmaticPicture::parseSnapmaticExportAndSortString() +{ + QStringList pictureStrList = pictureStr.split(" - "); + if (pictureStrList.length() <= 2) + { + QString dtStr = pictureStrList.at(1); + QStringList dtStrList = dtStr.split(" "); + if (dtStrList.length() <= 2) + { + QString dayStr; + QString yearStr; + QString monthStr; + QString dateStr = dtStrList.at(0); + QString timeStr = dtStrList.at(1); + timeStr.replace(":",""); + QStringList dateStrList = dateStr.split("/"); + if (dateStrList.length() <= 3) + { + dayStr = dateStrList.at(1); + yearStr = dateStrList.at(2); + monthStr = dateStrList.at(0); + } + QString cmpPicTitl = titlStr; + cmpPicTitl.replace("\"", "''"); + cmpPicTitl.replace(" ", "_"); + cmpPicTitl.replace(":", "-"); + cmpPicTitl.replace("\\", ""); + cmpPicTitl.replace("/", ""); + cmpPicTitl.replace("<", ""); + cmpPicTitl.replace(">", ""); + cmpPicTitl.replace("*", ""); + cmpPicTitl.replace("?", ""); + cmpPicTitl.replace(".", ""); + sortStr = yearStr + monthStr + dayStr + timeStr; + picExportFileName = sortStr + "_" + cmpPicTitl + ".jpg"; + } + } +} + +bool SnapmaticPicture::readingPictureFromFile(const QString &fileName, bool writeEnabled_, bool cacheEnabled_) +{ + if (fileName != "") + { + picFileName = fileName; + return readingPicture(writeEnabled_, cacheEnabled_); + } + else + { + return false; + } +} + +bool SnapmaticPicture::setPicture(const QImage &picture) +{ + if (writeEnabled) + { + QByteArray picByteArray; + QBuffer snapmaticStream(&rawPicContent); + snapmaticStream.open(QIODevice::ReadWrite); + if (snapmaticStream.seek(jpegStreamEditorBegin)) + { + bool saveSuccess; + Q_UNUSED(saveSuccess) + QByteArray picByteArray1; + QBuffer picStream1(&picByteArray1); + picStream1.open(QIODevice::WriteOnly); + saveSuccess = picture.save(&picStream1, "JPEG", 95); + picStream1.close(); + + if (picByteArray1.length() > jpegPicStreamLength) + { + QByteArray picByteArray2; + QBuffer picStream2(&picByteArray2); + picStream2.open(QIODevice::WriteOnly); + saveSuccess = picture.save(&picStream2, "JPEG", 80); + picStream2.close(); + if (picByteArray2.length() > jpegPicStreamLength) + { + snapmaticStream.close(); + return false; + } + picByteArray = picByteArray2; + } + else + { + picByteArray = picByteArray1; + } + } + while (picByteArray.length() != jpegPicStreamLength) + { + picByteArray.append((char)0x00); + } + int result = snapmaticStream.write(picByteArray); + if (result != 0) + { + if (cacheEnabled) + { + cachePicture = picture; + } + return true; + } + return false; + } + return false; +} + +bool SnapmaticPicture::exportPicture(const QString &fileName) +{ + QFile *picFile = new QFile(fileName); + if (picFile->open(QIODevice::WriteOnly)) + { + picFile->write(rawPicContent); + picFile->close(); + picFile->deleteLater(); + return true; + } + else + { + return false; + } +} + +QString SnapmaticPicture::getExportPictureFileName() +{ + return picExportFileName; +} + +QString SnapmaticPicture::getPictureFileName() +{ + return picFileName; +} + +QString SnapmaticPicture::getPictureSortStr() +{ + return sortStr; +} + +QString SnapmaticPicture::getPictureDesc() +{ + return descStr; +} + +QString SnapmaticPicture::getPictureTitl() +{ + return titlStr; +} + +QString SnapmaticPicture::getPictureStr() +{ + return pictureStr; +} + +QString SnapmaticPicture::getLastStep() +{ + return lastStep; +} + +QImage SnapmaticPicture::getPicture() +{ + if (cacheEnabled) + { + return cachePicture; + } + else if (writeEnabled) + { + bool returnOk = 0; + QImage returnPicture; + + QBuffer snapmaticStream(&rawPicContent); + snapmaticStream.open(QIODevice::ReadOnly); + if (snapmaticStream.seek(jpegStreamEditorBegin)) + { + QByteArray jpegRawContent = snapmaticStream.read(jpegPicStreamLength); + returnOk = returnPicture.loadFromData(jpegRawContent, "JPEG"); + } + snapmaticStream.close(); + + if (returnOk) + { + return returnPicture; + } + } + else + { + bool returnOk = 0; + QImage returnPicture; + QIODevice *picStream; + + QFile *picFile = new QFile(picFileName); + if (!picFile->open(QFile::ReadOnly)) + { + lastStep = "1;/1,OpenFile," + StringParser::convertDrawStringForLog(picFileName); + picFile->deleteLater(); + delete picFile; + return QImage(0, 0, QImage::Format_RGB32); + } + rawPicContent = picFile->read(snapmaticFileMaxSize); + picFile->close(); + delete picFile; + + picStream = new QBuffer(&rawPicContent); + picStream->open(QIODevice::ReadWrite); + if (picStream->seek(jpegStreamEditorBegin)) + { + QByteArray jpegRawContent = picStream->read(jpegPicStreamLength); + returnOk = returnPicture.loadFromData(jpegRawContent, "JPEG"); + } + picStream->close(); + delete picStream; + + if (returnOk) + { + return returnPicture; + } + } + return QImage(0, 0, QImage::Format_RGB32); +} + +bool SnapmaticPicture::isPicOk() +{ + return picOk; +} + +void SnapmaticPicture::setPicFileName(QString picFileName_) +{ + picFileName = picFileName_; +} + +void SnapmaticPicture::clearCache() +{ + cacheEnabled = false; + cachePicture = QImage(0, 0, QImage::Format_RGB32); +} + +// JSON part + +void SnapmaticPicture::parseJsonContent() +{ + QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonStr.toUtf8()); + QJsonObject jsonObject = jsonDocument.object(); + QVariantMap jsonMap = jsonObject.toVariantMap(); // backward compatibility + + if (jsonObject.contains("loc")) + { + QJsonObject locObject = jsonObject["loc"].toObject(); + if (locObject.contains("x")) { localSpJson.location.x = locObject["x"].toDouble(); } + if (locObject.contains("y")) { localSpJson.location.y = locObject["y"].toDouble(); } + if (locObject.contains("z")) { localSpJson.location.z = locObject["z"].toDouble(); } + } + if (jsonObject.contains("area")) + { + localSpJson.area = jsonObject["area"].toString(); + } + if (jsonObject.contains("crewid")) + { + localSpJson.crewID = jsonObject["crewid"].toInt(); + } + if (jsonObject.contains("creat")) + { + QDateTime createdTimestamp; + localSpJson.createdTimestamp = jsonMap["creat"].toUInt(); + createdTimestamp.setTime_t(localSpJson.createdTimestamp); + localSpJson.createdDateTime = createdTimestamp; + } + if (jsonObject.contains("plyrs")) + { + localSpJson.playersList = jsonMap["plyrs"].toStringList(); + } + if (jsonObject.contains("meme")) + { + localSpJson.isMeme = jsonObject["meme"].toBool(); + } + if (jsonObject.contains("mug")) + { + localSpJson.isMug = jsonObject["mug"].toBool(); + } + if (jsonObject.contains("slf")) + { + localSpJson.isSelfie = jsonObject["slf"].toBool(); + } + if (jsonObject.contains("drctr")) + { + localSpJson.isFromDirector = jsonObject["drctr"].toBool(); + } + if (jsonObject.contains("rsedtr")) + { + localSpJson.isFromRSEditor = jsonObject["rsedtr"].toBool(); + } + + jsonOk = true; +} + +bool SnapmaticPicture::isJsonOk() +{ + return jsonOk; +} + +QString SnapmaticPicture::getJsonStr() +{ + return jsonStr; +} + +SnapmaticProperties SnapmaticPicture::getSnapmaticProperties() +{ + return localSpJson; +} + +bool SnapmaticPicture::setSnapmaticProperties(SnapmaticProperties newSpJson) +{ + QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonStr.toUtf8()); + QJsonObject jsonObject = jsonDocument.object(); + + QJsonObject locObject; + locObject["x"] = newSpJson.location.x; + locObject["y"] = newSpJson.location.y; + locObject["z"] = newSpJson.location.z; + + jsonObject["loc"] = locObject; + jsonObject["area"] = newSpJson.area; + jsonObject["crewid"] = newSpJson.crewID; + jsonObject["creat"] = QJsonValue::fromVariant(newSpJson.createdTimestamp); + jsonObject["plyrs"] = QJsonValue::fromVariant(newSpJson.playersList); + jsonObject["meme"] = newSpJson.isMeme; + jsonObject["mug"] = newSpJson.isMug; + jsonObject["slf"] = newSpJson.isSelfie; + jsonObject["drctr"] = newSpJson.isFromDirector; + jsonObject["rsedtr"] = newSpJson.isFromRSEditor; + + jsonDocument.setObject(jsonObject); + + QString newJsonStr = QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Compact)); + if (newJsonStr.length() < jsonStreamEditorLength) + { + if (writeEnabled) + { + QByteArray jsonByteArray = newJsonStr.toUtf8(); + while (jsonByteArray.length() != jsonStreamEditorLength) + { + jsonByteArray.append((char)0x00); + } + QBuffer snapmaticStream(&rawPicContent); + snapmaticStream.open(QIODevice::ReadWrite); + if (!snapmaticStream.seek(jsonStreamEditorBegin)) + { + snapmaticStream.close(); + return false; + } + int result = snapmaticStream.write(jsonByteArray); + snapmaticStream.close(); + if (result != 0) + { + localSpJson = newSpJson; + jsonStr = newJsonStr; + return true; + } + } + else + { + return false; + } + } + else + { + return false; + } + + return true; +} + +// VISIBILITY + +bool SnapmaticPicture::isHidden() +{ + if (picFileName.right(7) == ".hidden") + { + return true; + } + return false; +} + +bool SnapmaticPicture::setPictureHidden() +{ + if (!isHidden()) + { + QString newPicFileName = QString(picFileName + ".hidden"); + if (QFile::rename(picFileName, newPicFileName)) + { + picFileName = newPicFileName; + return true; + } + return false; + } + return true; +} + +bool SnapmaticPicture::setPictureVisible() +{ + if (isHidden()) + { + QString newPicFileName = QString(picFileName).remove(picFileName.length() - 7, 7); + if (QFile::rename(picFileName, newPicFileName)) + { + picFileName = newPicFileName; + return true; + } + return false; + } + return true; +} diff --git a/SnapmaticPicture.h b/SnapmaticPicture.h old mode 100644 new mode 100755 index 8113cdc..cc1b215 --- a/SnapmaticPicture.h +++ b/SnapmaticPicture.h @@ -1,172 +1,126 @@ -/***************************************************************************** -* gta5spv Grand Theft Auto Snapmatic Picture Viewer -* Copyright (C) 2016-2020 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef SNAPMATICPICTURE_H -#define SNAPMATICPICTURE_H - -#include "RagePhoto.h" -#include -#include -#include -#include -#include -#include - -enum class SnapmaticFormat : int { Auto_Format = 0, PGTA_Format = 1, JPEG_Format = 2, G5E_Format = 3 }; - -struct SnapmaticProperties { - struct SnapmaticLocation { - QString area; - double x; - double y; - double z; - bool isCayoPerico; - }; - int uid; - int crewID; - int streetID; - QStringList playersList; - uint createdTimestamp; - QDateTime createdDateTime; - bool isMeme; - bool isMug; - bool isSelfie; - bool isFromDirector; - bool isFromRSEditor; - SnapmaticLocation location; -}; - -class SnapmaticPicture : public QObject -{ - Q_OBJECT -public: - explicit SnapmaticPicture(const QString &fileName = "", QObject *parent = 0); - ~SnapmaticPicture(); - void reset(); - bool preloadFile(); - bool readingPictureFromFile(const QString &fileName, bool cacheEnabled = false); - bool readingPicture(bool cacheEnabled = false); - bool isPicOk(); // Please use isPictureOk instead - void clearCache(); - QImage getImage(); - QByteArray getPictureStream(); - QString getLastStep(bool readable = true); - QString getPictureStr(); - QString getPictureTitl(); - QString getPictureSortStr(); - QString getPictureFileName(); - QString getPictureFilePath(); - QString getExportPictureFileName(); - QString getOriginalPictureFileName(); - QString getOriginalPictureFilePath(); - int getContentMaxLength(); - bool setImage(const QImage &picture, bool eXtendMode = false); - bool setPictureTitl(const QString &newTitle); // Please use setPictureTitle instead - bool setPictureStream(const QByteArray &streamArray); - void updateStrings(); - void emitUpdate(); - void emitCustomSignal(const QString &signal); - - // FILE MANAGEMENT - bool exportPicture(const QString &fileName, SnapmaticFormat format = SnapmaticFormat::Auto_Format); - void setPicFileName(const QString &picFileName); // Please use setPictureFileName instead - void setPicFilePath(const QString &picFilePath); // Please use setPictureFilePath instead - bool deletePicFile(); // Please use deletePictureFile instead - - // JSON - bool isJsonOk(); - QString getJsonStr(); // Please use getPictureJson instead - SnapmaticProperties getSnapmaticProperties(); - bool setSnapmaticProperties(SnapmaticProperties properties); - bool setJsonStr(const QString &jsonStr, bool updateProperties = false); // Please use setPictureJson instead - - // VISIBILITY - bool isHidden(); // Please use isPictureHidden instead - bool isVisible(); // Please use isPictureVisible instead - bool setPictureHidden(); - bool setPictureVisible(); - - // ALTERNATIVES (MORE DEVELOPER FRIENDLY FUNCTION CALLS) - QString getJsonString() { return getJsonStr(); } // Please use getPictureJson instead - QString getPictureJson() { return getJsonStr(); } - QString getPictureTitle() { return getPictureTitl(); } - QString getPictureString() { return getPictureStr(); } - bool setJsonString(const QString &jsonString, bool updateProperties = false) { return setJsonStr(jsonString, updateProperties); } // Please use setPictureJson instead - bool setPictureJson(const QString &json, bool updateProperties = false) { return setJsonStr(json, updateProperties); } - bool setPictureTitle(const QString &title) { return setPictureTitl(title); } - void setPictureFileName(const QString &fileName) { return setPicFileName(fileName); } - void setPictureFilePath(const QString &filePath) { return setPicFilePath(filePath); } - bool deletePictureFile() { return deletePicFile(); } - bool isPictureOk() { return isPicOk(); } - bool isPictureHidden() { return isHidden(); } - bool isPictureVisible() { return isVisible(); } - bool setHidden() { return setPictureHidden(); } // Please use setPictureHidden instead - bool setVisible() { return setPictureVisible(); } // Please use setPictureVisible instead - - // PREDEFINED PROPERTIES - static QSize getSnapmaticResolution(); - - // SNAPMATIC FORMAT - SnapmaticFormat getSnapmaticFormat(); - void setSnapmaticFormat(SnapmaticFormat format); - bool isFormatSwitched(); - - // VERIFY CONTENT - 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); - - // RAGEPHOTO - RagePhoto* ragePhoto(); - -private: - QImage cachePicture; - QString picExportFileName; - QString picFileName; - QString picFilePath; - QString pictureStr; - QString lastStep; - QString sortStr; - bool picOk; - bool cacheEnabled; - bool isFormatSwitch; - - // JSON - void parseJsonContent(); - bool jsonOk; - SnapmaticProperties localProperties; - - // VERIFY CONTENT - static bool verifyTitleChar(const QChar &titleChar); - - // RAGEPHOTO - RagePhoto p_ragePhoto; - -signals: - void customSignal(QString signal); - void preloaded(); - void updated(); - void loaded(); - -public slots: -}; - -#endif // SNAPMATICPICTURE_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef SNAPMATICPICTURE_H +#define SNAPMATICPICTURE_H + +#include +#include +#include +#include +#include +#include + +struct SnapmaticProperties { + struct SnapmaticLocation { + double x; + double y; + double z; + }; + int crewID; + QString area; + QStringList playersList; + uint createdTimestamp; + QDateTime createdDateTime; + bool isMeme; + bool isMug; + bool isSelfie; + bool isFromDirector; + bool isFromRSEditor; + SnapmaticLocation location; +}; + +class SnapmaticPicture : public QObject +{ + Q_OBJECT +public: + explicit SnapmaticPicture(const QString &fileName = "", QObject *parent = 0); + ~SnapmaticPicture(); + bool readingPictureFromFile(const QString &fileName, bool writeEnabled = true, bool cacheEnabled = true); + bool readingPicture(bool writeEnabled = true, bool cacheEnabled = true); + bool isPicOk(); + void clearCache(); + QImage getPicture(); + QString getLastStep(); + QString getPictureStr(); + QString getPictureTitl(); + QString getPictureDesc(); + QString getPictureSortStr(); + QString getPictureFileName(); + QString getExportPictureFileName(); + QDateTime getCreatedDateTime(); + bool setPicture(const QImage &picture); + bool exportPicture(const QString &fileName); + void setPicFileName(QString picFileName_); + + // JSON + bool isJsonOk(); + QString getJsonStr(); + SnapmaticProperties getSnapmaticProperties(); + bool setSnapmaticProperties(SnapmaticProperties newSpJson); + + // VISIBILITY + bool isHidden(); + bool setPictureHidden(); + bool setPictureVisible(); + +private: + QString getSnapmaticPictureString(const QByteArray &snapmaticHeader); + QString getSnapmaticJSONString(const QByteArray &jsonBytes); + QString getSnapmaticTIDEString(const QByteArray &tideBytes); + void parseSnapmaticExportAndSortString(); + QImage cachePicture; + QString picExportFileName; + QString picFileName; + QString pictureStr; + QString lastStep; + QString sortStr; + QString titlStr; + QString descStr; + bool picOk; + bool writeEnabled; + bool cacheEnabled; + + // PARSE INT + int snapmaticHeaderLength; + int snapmaticUsefulLength; + int snapmaticFileMaxSize; + int jpegHeaderLineDifStr; + int jpegPreHeaderLength; + int jpegPicStreamLength; + int jsonStreamLength; + int tideStreamLength; + + // PARSE EDITOR + int jpegStreamEditorBegin; + int jsonStreamEditorBegin; + int jsonStreamEditorLength; + QByteArray rawPicContent; + + // JSON + void parseJsonContent(); + bool jsonOk; + QString jsonStr; + SnapmaticProperties localSpJson; + +signals: + +public slots: +}; + +#endif // SNAPMATICPICTURE_H diff --git a/SnapmaticWidget.cpp b/SnapmaticWidget.cpp old mode 100644 new mode 100755 index db718a7..560881a --- a/SnapmaticWidget.cpp +++ b/SnapmaticWidget.cpp @@ -1,495 +1,369 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "SnapmaticWidget.h" -#include "ui_SnapmaticWidget.h" -#include "MapLocationDialog.h" -#include "JsonEditorDialog.h" -#include "SnapmaticPicture.h" -#include "SnapmaticEditor.h" -#include "DatabaseThread.h" -#include "PictureDialog.h" -#include "PictureExport.h" -#include "StringParser.h" -#include "ImportDialog.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include - -#ifdef GTA5SYNC_TELEMETRY -#include "TelemetryClass.h" -#include -#include -#endif - -SnapmaticWidget::SnapmaticWidget(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QString profileName, QWidget *parent) : - ProfileWidget(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), profileName(profileName), - ui(new Ui::SnapmaticWidget) -{ - ui->setupUi(this); - ui->cmdView->setVisible(false); - ui->cmdCopy->setVisible(false); - ui->cmdExport->setVisible(false); - ui->cmdDelete->setVisible(false); - ui->cbSelected->setVisible(false); - - QPalette palette; - palette.setCurrentColorGroup(QPalette::Disabled); - highlightHiddenColor = palette.text().color(); - - ui->SnapmaticFrame->setMouseTracking(true); - ui->labPicture->setMouseTracking(true); - ui->labPicStr->setMouseTracking(true); - ui->cbSelected->setMouseTracking(true); - smpic = nullptr; -} - -SnapmaticWidget::~SnapmaticWidget() -{ - delete ui; -} - -void SnapmaticWidget::setSnapmaticPicture(SnapmaticPicture *picture) -{ - smpic = picture; - QObject::connect(picture, SIGNAL(updated()), this, SLOT(snapmaticUpdated())); - QObject::connect(picture, SIGNAL(customSignal(QString)), this, SLOT(customSignal(QString))); - - const qreal screenRatio = AppEnv::screenRatio(); - const qreal screenRatioPR = AppEnv::screenRatioPR(); - const QSize renderResolution(48 * screenRatio * screenRatioPR, 27 * screenRatio * screenRatioPR); - ui->labPicture->setFixedSize(48 * screenRatio, 27 * screenRatio); - ui->labPicture->setScaledContents(true); - - QPixmap renderPixmap(renderResolution); - renderPixmap.fill(Qt::transparent); - QPainter renderPainter(&renderPixmap); - const QImage originalImage = picture->getImage(); - const QImage renderImage = originalImage.scaled(renderResolution, Qt::KeepAspectRatio, Qt::SmoothTransformation); // Stack smash - if (renderImage.width() < renderResolution.width()) { - renderPainter.drawImage((renderResolution.width() - renderImage.width()) / 2, 0, renderImage, Qt::AutoColor); - } - else if (renderImage.height() < renderResolution.height()) { - renderPainter.drawImage(0, (renderResolution.height() - renderImage.height()) / 2, renderImage, Qt::AutoColor); - } - else { - renderPainter.drawImage(0, 0, renderImage, Qt::AutoColor); - } - renderPainter.end(); -#if QT_VERSION >= 0x050600 - renderPixmap.setDevicePixelRatio(screenRatioPR); -#endif - - ui->labPicStr->setText(smpic->getPictureStr() % "\n" % smpic->getPictureTitl()); - ui->labPicture->setPixmap(renderPixmap); - - picture->clearCache(); - - adjustTextColor(); -} - -void SnapmaticWidget::snapmaticUpdated() -{ - ui->labPicStr->setText(smpic->getPictureStr() % "\n" % smpic->getPictureTitl()); -} - -void SnapmaticWidget::customSignal(QString signal) -{ - if (signal == "PictureUpdated") { - QPixmap SnapmaticPixmap = QPixmap::fromImage(smpic->getImage().scaled(ui->labPicture->width(), ui->labPicture->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::AutoColor); - ui->labPicture->setPixmap(SnapmaticPixmap); - } -} - -void SnapmaticWidget::retranslate() -{ - smpic->updateStrings(); - ui->labPicStr->setText(smpic->getPictureStr() % "\n" % smpic->getPictureTitl()); -} - -void SnapmaticWidget::on_cmdView_clicked() -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Interface"); - bool navigationBar = settings.value("NavigationBar", true).toBool(); - settings.endGroup(); - - PictureDialog *picDialog = new PictureDialog(profileDB, crewDB, profileName, this); - picDialog->setSnapmaticPicture(smpic, true); - picDialog->setModal(true); - - // be ready for crewName and playerName updated - QObject::connect(threadDB, SIGNAL(crewNameUpdated()), picDialog, SLOT(crewNameUpdated())); - QObject::connect(threadDB, SIGNAL(playerNameUpdated()), picDialog, SLOT(playerNameUpdated())); - QObject::connect(picDialog, SIGNAL(nextPictureRequested()), this, SLOT(dialogNextPictureRequested())); - QObject::connect(picDialog, SIGNAL(previousPictureRequested()), this, SLOT(dialogPreviousPictureRequested())); - - // add previous next buttons - if (navigationBar) - picDialog->addPreviousNextButtons(); - - // show picture dialog -#ifdef Q_OS_ANDROID - // Android ... - picDialog->showMaximized(); -#else - picDialog->show(); - if (navigationBar) picDialog->styliseDialog(); - //picDialog->adaptNewDialogSize(); - picDialog->setMinimumSize(picDialog->size()); - picDialog->setMaximumSize(picDialog->size()); -#endif - picDialog->exec(); - delete picDialog; -} - -void SnapmaticWidget::on_cmdCopy_clicked() -{ - PictureExport::exportAsSnapmatic(this, smpic); -} - -void SnapmaticWidget::on_cmdExport_clicked() -{ - PictureExport::exportAsPicture(this, smpic); -} - -void SnapmaticWidget::on_cmdDelete_clicked() -{ - if (deletePicture()) - emit pictureDeleted(); -} - -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); - if (uchoice == QMessageBox::Yes) { - 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()); -#if QT_VERSION >= 0x060000 - jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["DeletedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } -#endif - return true; - } - else { - QMessageBox::warning(this, tr("Delete picture"), tr("Failed at deleting %1 from your Snapmatic pictures").arg("\""+smpic->getPictureTitle()+"\"")); - } - } - return false; -} - -void SnapmaticWidget::mousePressEvent(QMouseEvent *ev) -{ - ProfileWidget::mousePressEvent(ev); -} - -void SnapmaticWidget::mouseReleaseEvent(QMouseEvent *ev) -{ - ProfileWidget::mouseReleaseEvent(ev); - if (ui->cbSelected->isVisible()) { - if (rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) { - ui->cbSelected->setChecked(!ui->cbSelected->isChecked()); - } - } - else { - const int contentMode = getContentMode(); - if ((contentMode == 0 || contentMode == 10 || contentMode == 20) && rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) { - if (ev->modifiers().testFlag(Qt::ShiftModifier)) { - ui->cbSelected->setChecked(!ui->cbSelected->isChecked()); - } - else { - on_cmdView_clicked(); - } - } - else if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton && ev->modifiers().testFlag(Qt::ShiftModifier)) { - ui->cbSelected->setChecked(!ui->cbSelected->isChecked()); - } - } -} - -void SnapmaticWidget::mouseDoubleClickEvent(QMouseEvent *ev) -{ - ProfileWidget::mouseDoubleClickEvent(ev); - - const int contentMode = getContentMode(); - if (!ui->cbSelected->isVisible() && (contentMode == 1 || contentMode == 11 || contentMode == 21) && ev->button() == Qt::LeftButton) { - on_cmdView_clicked(); - } -} - -void SnapmaticWidget::setSelected(bool isSelected) -{ - ui->cbSelected->setChecked(isSelected); -} - -void SnapmaticWidget::pictureSelected() -{ - setSelected(!ui->cbSelected->isChecked()); -} - -void SnapmaticWidget::contextMenuEvent(QContextMenuEvent *ev) -{ - emit contextMenuTriggered(ev); -} - -void SnapmaticWidget::dialogNextPictureRequested() -{ - emit nextPictureRequested((QWidget*)sender()); -} - -void SnapmaticWidget::dialogPreviousPictureRequested() -{ - emit previousPictureRequested((QWidget*)sender()); -} - -void SnapmaticWidget::on_cbSelected_stateChanged(int arg1) -{ - if (arg1 == Qt::Checked) { - emit widgetSelected(); - } - else if (arg1 == Qt::Unchecked) { - emit widgetDeselected(); - } -} - -void SnapmaticWidget::adjustTextColor() -{ - if (isHidden()) { - ui->labPicStr->setStyleSheet(QString("QLabel{color: rgb(%1, %2, %3);}").arg(QString::number(highlightHiddenColor.red()), QString::number(highlightHiddenColor.green()), QString::number(highlightHiddenColor.blue()))); - } - else { - ui->labPicStr->setStyleSheet(""); - } -} - -bool SnapmaticWidget::makePictureHidden() -{ - if (smpic->setPictureHidden()) { - adjustTextColor(); - return true; - } - return false; -} - -bool SnapmaticWidget::makePictureVisible() -{ - if (smpic->setPictureVisible()) { - adjustTextColor(); - return true; - } - return false; -} - -void SnapmaticWidget::makePictureHiddenSlot() -{ - if (!makePictureHidden()) - QMessageBox::warning(this, QApplication::translate("UserInterface", "Hide In-game"), QApplication::translate("SnapmaticWidget", "Failed to hide %1 In-game from your Snapmatic pictures").arg("\""+smpic->getPictureTitle()+"\"")); -} - -void SnapmaticWidget::makePictureVisibleSlot() -{ - if (!makePictureVisible()) - QMessageBox::warning(this, QApplication::translate("UserInterface", "Show In-game"), QApplication::translate("SnapmaticWidget", "Failed to show %1 In-game from your Snapmatic pictures").arg("\""+smpic->getPictureTitle()+"\"")); -} - -void SnapmaticWidget::editSnapmaticProperties() -{ - SnapmaticEditor *snapmaticEditor = new SnapmaticEditor(crewDB, profileDB, this); - snapmaticEditor->setSnapmaticPicture(smpic); - snapmaticEditor->setModal(true); - snapmaticEditor->show(); - snapmaticEditor->exec(); - delete snapmaticEditor; -} - -void SnapmaticWidget::editSnapmaticRawJson() -{ - JsonEditorDialog *jsonEditor = new JsonEditorDialog(smpic, this); - jsonEditor->setModal(true); - jsonEditor->show(); - jsonEditor->exec(); - delete jsonEditor; -} - -void SnapmaticWidget::editSnapmaticImage() -{ - QImage *currentImage = new QImage(smpic->getImage()); - ImportDialog *importDialog = new ImportDialog(profileName, this); - importDialog->setImage(currentImage); - importDialog->enableOverwriteMode(); - importDialog->setModal(true); - importDialog->exec(); - if (importDialog->isImportAgreed()) { - const QByteArray previousPicture = smpic->getPictureStream(); - bool success = smpic->setImage(importDialog->image(), importDialog->isUnlimitedBuffer()); - 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()); -#if QT_VERSION >= 0x060000 - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } -#endif - } - 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() -{ - SnapmaticPicture *picture = smpic; - SnapmaticProperties currentProperties = picture->getSnapmaticProperties(); - MapLocationDialog *mapLocDialog = new MapLocationDialog(currentProperties.location.x, currentProperties.location.y, this); - mapLocDialog->setCayoPerico(currentProperties.location.isCayoPerico); - mapLocDialog->setModal(true); - mapLocDialog->show(); - mapLocDialog->exec(); - if (mapLocDialog->propUpdated()) { - // Update Snapmatic Properties - currentProperties.location.x = mapLocDialog->getXpos(); - currentProperties.location.y = mapLocDialog->getYpos(); - currentProperties.location.z = 0; - - // Update Snapmatic Picture - QString currentFilePath = picture->getPictureFilePath(); - QString originalFilePath = picture->getOriginalPictureFilePath(); - QString backupFileName = originalFilePath % ".bak"; - if (!QFile::exists(backupFileName)) { - QFile::copy(currentFilePath, backupFileName); - } - SnapmaticProperties fallbackProperties = picture->getSnapmaticProperties(); - picture->setSnapmaticProperties(currentProperties); - if (!picture->exportPicture(currentFilePath)) { - QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error")); - 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()); -#if QT_VERSION >= 0x060000 - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); -#else - jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); -#endif - jsonDocument.setObject(jsonObject); - Telemetry->push(TelemetryCategory::PersonalData, jsonDocument); - } - } -#endif - } - delete mapLocDialog; -} - -bool SnapmaticWidget::isSelected() -{ - return ui->cbSelected->isChecked(); -} - -bool SnapmaticWidget::isHidden() -{ - return smpic->isHidden(); -} - -void SnapmaticWidget::setSelectionMode(bool selectionMode) -{ - ui->cbSelected->setVisible(selectionMode); -} - -void SnapmaticWidget::selectAllWidgets() -{ - emit allWidgetsSelected(); -} - -void SnapmaticWidget::deselectAllWidgets() -{ - emit allWidgetsDeselected(); -} - -SnapmaticPicture* SnapmaticWidget::getPicture() -{ - return smpic; -} - -QString SnapmaticWidget::getPicturePath() -{ - return smpic->getPictureFilePath(); -} - -QString SnapmaticWidget::getWidgetType() -{ - return "SnapmaticWidget"; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "SnapmaticWidget.h" +#include "ui_SnapmaticWidget.h" +#include "SnapmaticPicture.h" +#include "SnapmaticEditor.h" +#include "DatabaseThread.h" +#include "PictureDialog.h" +#include "PictureExport.h" +#include "PictureCopy.h" +#include "config.h" +#include +#include +#include +#include +#include +#include + +SnapmaticWidget::SnapmaticWidget(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent) : + ProfileWidget(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), + ui(new Ui::SnapmaticWidget) +{ + ui->setupUi(this); + ui->cmdView->setVisible(false); + ui->cmdCopy->setVisible(false); + ui->cmdExport->setVisible(false); + ui->cmdDelete->setVisible(false); + ui->cbSelected->setVisible(false); + + QPalette palette; + highlightBackColor = palette.highlight().color(); + highlightTextColor = palette.highlightedText().color(); + palette.setCurrentColorGroup(QPalette::Disabled); + highlightHiddenColor = palette.text().color(); + + snwgt = parent; + picPath = ""; + picStr = ""; + smpic = 0; + + installEventFilter(this); +} + +SnapmaticWidget::~SnapmaticWidget() +{ + delete ui; +} + +bool SnapmaticWidget::eventFilter(QObject *obj, QEvent *ev) +{ + if (obj == this) + { + if (ev->type() == QEvent::Enter) + { + 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()))); + return true; + } + else if(ev->type() == QEvent::Leave) + { + setStyleSheet(""); + return true; + } + } + return false; +} + +void SnapmaticWidget::setSnapmaticPicture(SnapmaticPicture *picture, QString picturePath) +{ + smpic = picture; + picPath = picturePath; + picStr = picture->getPictureStr(); + picTitl = picture->getPictureTitl(); + + QPixmap SnapmaticPixmap = QPixmap::fromImage(picture->getPicture().scaled(ui->labPicture->width(), ui->labPicture->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::AutoColor); + ui->labPicStr->setText(picStr + "\n" + picTitl + ""); + ui->labPicture->setPixmap(SnapmaticPixmap); + + picture->clearCache(); + + adjustTextColor(); +} + +void SnapmaticWidget::setSnapmaticPicture(SnapmaticPicture *picture) +{ + setSnapmaticPicture(picture, picture->getPictureFileName()); +} + +void SnapmaticWidget::on_cmdView_clicked() +{ + QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + settings.beginGroup("Interface"); + bool navigationBar = settings.value("NavigationBar", false).toBool(); + settings.endGroup(); + + PictureDialog *picDialog = new PictureDialog(profileDB, crewDB, this); + picDialog->setWindowFlags(picDialog->windowFlags()^Qt::WindowContextHelpButtonHint); + picDialog->setSnapmaticPicture(smpic, picPath, true); + picDialog->setModal(true); + + // be ready for playerName updated + QObject::connect(threadDB, SIGNAL(playerNameUpdated()), picDialog, SLOT(playerNameUpdated())); + QObject::connect(picDialog, SIGNAL(nextPictureRequested()), this, SLOT(dialogNextPictureRequested())); + QObject::connect(picDialog, SIGNAL(previousPictureRequested()), this, SLOT(dialogPreviousPictureRequested())); + + // add previous next buttons + if (navigationBar) picDialog->addPreviousNextButtons(); + + // show picture dialog + picDialog->show(); + if (navigationBar) picDialog->stylizeDialog(); + //picDialog->adaptNewDialogSize(); + picDialog->setMinimumSize(picDialog->size()); + picDialog->setMaximumSize(picDialog->size()); + picDialog->exec(); + delete picDialog; +} + +void SnapmaticWidget::on_cmdCopy_clicked() +{ + PictureCopy::copyPicture(this, picPath); +} + +void SnapmaticWidget::on_cmdExport_clicked() +{ + PictureExport::exportPicture(this, smpic); +} + +void SnapmaticWidget::on_cmdDelete_clicked() +{ + int uchoice = QMessageBox::question(this, tr("Delete picture"), tr("Are you sure to delete %1 from your Snapmatic pictures?").arg("\""+picStr+"\""), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + if (uchoice == QMessageBox::Yes) + { + if (!QFile::exists(picPath)) + { + emit pictureDeleted(); + } + else if(QFile::remove(picPath)) + { + emit pictureDeleted(); + } + else + { + QMessageBox::warning(this, tr("Delete picture"), tr("Failed at deleting %1 from your Snapmatic pictures").arg("\""+picStr+"\"")); + } + } +} + +void SnapmaticWidget::mousePressEvent(QMouseEvent *ev) +{ + ProfileWidget::mousePressEvent(ev); +} + +void SnapmaticWidget::mouseReleaseEvent(QMouseEvent *ev) +{ + ProfileWidget::mouseReleaseEvent(ev); + if (ui->cbSelected->isVisible()) + { + if (rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) + { + ui->cbSelected->setChecked(!ui->cbSelected->isChecked()); + } + } + else + { + if (getContentMode() == 0 && rect().contains(ev->pos()) && ev->button() == Qt::LeftButton) + { + on_cmdView_clicked(); + } + } +} + +void SnapmaticWidget::mouseDoubleClickEvent(QMouseEvent *ev) +{ + ProfileWidget::mouseDoubleClickEvent(ev); + + if (!ui->cbSelected->isVisible() && getContentMode() == 1 && ev->button() == Qt::LeftButton) + { + on_cmdView_clicked(); + } +} + +void SnapmaticWidget::setSelected(bool isSelected) +{ + ui->cbSelected->setChecked(isSelected); +} + +void SnapmaticWidget::pictureSelected() +{ + setSelected(!ui->cbSelected->isChecked()); +} + +void SnapmaticWidget::contextMenuEvent(QContextMenuEvent *ev) +{ + QMenu contextMenu(this); + QMenu editMenu(tr("Edi&t"), this); + if (isHidden()) + { + editMenu.addAction(tr("Show &In-game"), this, SLOT(makePictureVisibleSlot())); + } + else + { + editMenu.addAction(tr("Hide &In-game"), this, SLOT(makePictureHiddenSlot())); + } + editMenu.addAction(tr("&Edit Properties..."), this, SLOT(editSnapmaticProperties())); + QMenu exportMenu(tr("&Export"), this); + exportMenu.addAction(tr("Export as &JPG picture..."), this, SLOT(on_cmdExport_clicked())); + exportMenu.addAction(tr("Export as >A Snapmatic..."), this, SLOT(on_cmdCopy_clicked())); + contextMenu.addAction(tr("&View"), this, SLOT(on_cmdView_clicked())); + contextMenu.addMenu(&editMenu); + contextMenu.addMenu(&exportMenu); + contextMenu.addAction(tr("&Remove"), this, SLOT(on_cmdDelete_clicked())); + if (ui->cbSelected->isVisible()) + { + contextMenu.addSeparator(); + if (!ui->cbSelected->isChecked()) { contextMenu.addAction(tr("&Select"), this, SLOT(pictureSelected())); } + if (ui->cbSelected->isChecked()) { contextMenu.addAction(tr("&Deselect"), this, SLOT(pictureSelected())); } + contextMenu.addAction(tr("Select &All"), this, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A")); + ProfileInterface *profileInterface = (ProfileInterface*)snwgt; + if (profileInterface->selectedWidgets() != 0) + { + contextMenu.addAction(tr("&Deselect All"), this, SLOT(deselectAllWidgets()), QKeySequence::fromString("Ctrl+D")); + } + } + else + { + contextMenu.addSeparator(); + contextMenu.addAction(tr("&Select"), this, SLOT(pictureSelected())); + contextMenu.addAction(tr("Select &All"), this, SLOT(selectAllWidgets()), QKeySequence::fromString("Ctrl+A")); + } + contextMenu.exec(ev->globalPos()); +} + +void SnapmaticWidget::dialogNextPictureRequested() +{ + emit nextPictureRequested((QWidget*)sender()); +} + +void SnapmaticWidget::dialogPreviousPictureRequested() +{ + emit previousPictureRequested((QWidget*)sender()); +} + +void SnapmaticWidget::on_cbSelected_stateChanged(int arg1) +{ + if (arg1 == Qt::Checked) + { + emit widgetSelected(); + } + else if (arg1 == Qt::Unchecked) + { + emit widgetDeselected(); + } +} + +void SnapmaticWidget::adjustTextColor() +{ + if (isHidden()) + { + ui->labPicStr->setStyleSheet(QString("QLabel{color: rgb(%1, %2, %3);}").arg(QString::number(highlightHiddenColor.red()), QString::number(highlightHiddenColor.green()), QString::number(highlightHiddenColor.blue()))); + } + else + { + ui->labPicStr->setStyleSheet(""); + } +} + +bool SnapmaticWidget::makePictureHidden() +{ + SnapmaticPicture *picture = (SnapmaticPicture*)smpic; + if (picture->setPictureHidden()) + { + picPath = picture->getPictureFileName(); + adjustTextColor(); + return true; + } + return false; +} + +bool SnapmaticWidget::makePictureVisible() +{ + SnapmaticPicture *picture = (SnapmaticPicture*)smpic; + if (picture->setPictureVisible()) + { + picPath = picture->getPictureFileName(); + adjustTextColor(); + return true; + } + return false; +} + +void SnapmaticWidget::makePictureHiddenSlot() +{ + makePictureHidden(); +} + +void SnapmaticWidget::makePictureVisibleSlot() +{ + makePictureVisible(); +} + +void SnapmaticWidget::editSnapmaticProperties() +{ + SnapmaticEditor *snapmaticEditor = new SnapmaticEditor(this); + snapmaticEditor->setWindowFlags(snapmaticEditor->windowFlags()^Qt::WindowContextHelpButtonHint); + snapmaticEditor->setSnapmaticPicture(smpic); + snapmaticEditor->setModal(true); + snapmaticEditor->exec(); + delete snapmaticEditor; +} + +bool SnapmaticWidget::isSelected() +{ + return ui->cbSelected->isChecked(); +} + +bool SnapmaticWidget::isHidden() +{ + if (picPath.right(7) == ".hidden") + { + return true; + } + return false; +} + +void SnapmaticWidget::setSelectionMode(bool selectionMode) +{ + ui->cbSelected->setVisible(selectionMode); +} + +void SnapmaticWidget::selectAllWidgets() +{ + emit allWidgetsSelected(); +} + +void SnapmaticWidget::deselectAllWidgets() +{ + emit allWidgetsDeselected(); +} + +SnapmaticPicture* SnapmaticWidget::getPicture() +{ + return smpic; +} + +QString SnapmaticWidget::getPicturePath() +{ + return picPath; +} + +QString SnapmaticWidget::getWidgetType() +{ + return "SnapmaticWidget"; +} diff --git a/SnapmaticWidget.h b/SnapmaticWidget.h old mode 100644 new mode 100755 index 8c28f12..d4b8eaf --- a/SnapmaticWidget.h +++ b/SnapmaticWidget.h @@ -1,103 +1,103 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef SNAPMATICWIDGET_H -#define SNAPMATICWIDGET_H - -#include "SnapmaticPicture.h" -#include "ProfileDatabase.h" -#include "DatabaseThread.h" -#include "ProfileWidget.h" -#include "CrewDatabase.h" -#include -#include -#include -#include - -namespace Ui { -class SnapmaticWidget; -} - -class SnapmaticWidget : public ProfileWidget -{ - Q_OBJECT - -public: - SnapmaticWidget(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QString profileName, QWidget *parent = 0); - void setSnapmaticPicture(SnapmaticPicture *picture); - void setSelectionMode(bool selectionMode); - void setSelected(bool isSelected); - bool deletePicture(); - bool makePictureVisible(); - bool makePictureHidden(); - SnapmaticPicture *getPicture(); - QString getPicturePath(); - QString getWidgetType(); - bool isSelected(); - bool isHidden(); - void retranslate(); - ~SnapmaticWidget(); - -private slots: - void on_cmdView_clicked(); - void on_cmdCopy_clicked(); - void on_cmdExport_clicked(); - void on_cmdDelete_clicked(); - void on_cbSelected_stateChanged(int arg1); - void adjustTextColor(); - void pictureSelected(); - void selectAllWidgets(); - void deselectAllWidgets(); - void dialogNextPictureRequested(); - void dialogPreviousPictureRequested(); - void makePictureVisibleSlot(); - void makePictureHiddenSlot(); - void editSnapmaticProperties(); - void editSnapmaticRawJson(); - void editSnapmaticImage(); - void openMapViewer(); - void snapmaticUpdated(); - void customSignal(QString signal); - -protected: - void mouseDoubleClickEvent(QMouseEvent *ev); - void mouseReleaseEvent(QMouseEvent *ev); - void mousePressEvent(QMouseEvent *ev); - void contextMenuEvent(QContextMenuEvent *ev); - -private: - ProfileDatabase *profileDB; - CrewDatabase *crewDB; - DatabaseThread *threadDB; - QString profileName; - Ui::SnapmaticWidget *ui; - SnapmaticPicture *smpic; - QColor highlightHiddenColor; - -signals: - void pictureDeleted(); - void widgetSelected(); - void widgetDeselected(); - void allWidgetsSelected(); - void allWidgetsDeselected(); - void nextPictureRequested(QWidget *dialog); - void previousPictureRequested(QWidget *dialog); - void contextMenuTriggered(QContextMenuEvent *ev); -}; - -#endif // SNAPMATICWIDGET_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef SNAPMATICWIDGET_H +#define SNAPMATICWIDGET_H + +#include "SnapmaticPicture.h" +#include "ProfileInterface.h" +#include "ProfileDatabase.h" +#include "DatabaseThread.h" +#include "ProfileWidget.h" +#include "CrewDatabase.h" +#include +#include +#include +#include + +namespace Ui { +class SnapmaticWidget; +} + +class SnapmaticWidget : public ProfileWidget +{ + Q_OBJECT + +public: + SnapmaticWidget(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent = 0); + void setSnapmaticPicture(SnapmaticPicture *picture, QString picturePath); + void setSnapmaticPicture(SnapmaticPicture *picture); + void setSelectionMode(bool selectionMode); + void setSelected(bool isSelected); + bool makePictureVisible(); + bool makePictureHidden(); + SnapmaticPicture *getPicture(); + QString getPicturePath(); + QString getWidgetType(); + bool isSelected(); + bool isHidden(); + ~SnapmaticWidget(); + +private slots: + void on_cmdView_clicked(); + void on_cmdCopy_clicked(); + void on_cmdExport_clicked(); + void on_cmdDelete_clicked(); + void on_cbSelected_stateChanged(int arg1); + void adjustTextColor(); + void pictureSelected(); + void selectAllWidgets(); + void deselectAllWidgets(); + void dialogNextPictureRequested(); + void dialogPreviousPictureRequested(); + void makePictureVisibleSlot(); + void makePictureHiddenSlot(); + void editSnapmaticProperties(); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + void mouseDoubleClickEvent(QMouseEvent *ev); + void mouseReleaseEvent(QMouseEvent *ev); + void mousePressEvent(QMouseEvent *ev); + void contextMenuEvent(QContextMenuEvent *ev); + +private: + ProfileDatabase *profileDB; + CrewDatabase *crewDB; + DatabaseThread *threadDB; + Ui::SnapmaticWidget *ui; + SnapmaticPicture *smpic; + QColor highlightBackColor; + QColor highlightTextColor; + QColor highlightHiddenColor; + QString picPath; + QString picTitl; + QString picStr; + QWidget *snwgt; + +signals: + void pictureDeleted(); + void widgetSelected(); + void widgetDeselected(); + void allWidgetsSelected(); + void allWidgetsDeselected(); + void nextPictureRequested(QWidget *dialog); + void previousPictureRequested(QWidget *dialog); +}; + +#endif // SNAPMATICWIDGET_H diff --git a/SnapmaticWidget.ui b/SnapmaticWidget.ui old mode 100644 new mode 100755 index a3e7e89..1a6f42f --- a/SnapmaticWidget.ui +++ b/SnapmaticWidget.ui @@ -1,169 +1,166 @@ - - - SnapmaticWidget - - - - 0 - 0 - 490 - 45 - - - - Snapmatic Widget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - - - - Qt::NoFocus - - - - - - - - - - - 48 - 27 - - - - - 48 - 27 - - - - 0 - - - - - - true - - - - - - - - 0 - 0 - - - - PHOTO - 00/00/00 00:00:00 - - - true - - - - - - - - 0 - 0 - - - - View picture - - - View - - - true - - - - - - - - 0 - 0 - - - - Copy picture - - - Copy - - - - - - - - 0 - 0 - - - - Export picture - - - Export - - - - - - - - 0 - 0 - - - - Delete picture - - - Delete - - - true - - - - - - - - - - - + + + SnapmaticWidget + + + + 0 + 0 + 490 + 45 + + + + Snapmatic Widget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + + + + + + + + + + + + 48 + 27 + + + + + 48 + 27 + + + + 0 + + + + + + true + + + + + + + + 0 + 0 + + + + PHOTO - 00/00/00 00:00:00 + + + true + + + + + + + + 0 + 0 + + + + View picture + + + View + + + true + + + + + + + + 0 + 0 + + + + Copy picture + + + Copy + + + + + + + + 0 + 0 + + + + Export picture + + + Export + + + + + + + + 0 + 0 + + + + Delete picture + + + Delete + + + true + + + + + + + + + + + diff --git a/StandardPaths.cpp b/StandardPaths.cpp old mode 100644 new mode 100755 index c2f8111..3e9f38a --- a/StandardPaths.cpp +++ b/StandardPaths.cpp @@ -1,125 +1,128 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "StandardPaths.h" -#if QT_VERSION >= 0x050000 -#include -#else -#include -#endif - -QString StandardPaths::applicationsLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::ApplicationsLocation); -#endif -} - -QString StandardPaths::cacheLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::CacheLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::CacheLocation); -#endif -} - -QString StandardPaths::dataLocation() -{ -#if QT_VERSION >= 0x060000 - return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); -#elif QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::DataLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::DataLocation); -#endif -} - -QString StandardPaths::desktopLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); -#endif -} - -QString StandardPaths::documentsLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); -#endif -} - -QString StandardPaths::moviesLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::MoviesLocation); -#endif -} - -QString StandardPaths::picturesLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::PicturesLocation); -#endif -} - -QString StandardPaths::fontsLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::FontsLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::FontsLocation); -#endif -} - -QString StandardPaths::homeLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::HomeLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::HomeLocation); -#endif -} - -QString StandardPaths::musicLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::MusicLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::MusicLocation); -#endif -} - -QString StandardPaths::tempLocation() -{ -#if QT_VERSION >= 0x050000 - return QStandardPaths::writableLocation(QStandardPaths::TempLocation); -#else - return QDesktopServices::storageLocation(QDesktopServices::TempLocation); -#endif -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "StandardPaths.h" +#if QT_VERSION >= 0x050000 +#include +#else +#include +#endif + +StandardPaths::StandardPaths() +{ + +} + +QString StandardPaths::applicationsLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::ApplicationsLocation); +#endif +} + +QString StandardPaths::cacheLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::CacheLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::CacheLocation); +#endif +} + +QString StandardPaths::dataLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::DataLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::DataLocation); +#endif +} + +QString StandardPaths::desktopLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); +#endif +} + +QString StandardPaths::documentsLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); +#endif +} + +QString StandardPaths::moviesLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::MoviesLocation); +#endif +} + +QString StandardPaths::picturesLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::PicturesLocation); +#endif +} + +QString StandardPaths::fontsLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::FontsLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::FontsLocation); +#endif +} + +QString StandardPaths::homeLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::HomeLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::HomeLocation); +#endif +} + +QString StandardPaths::musicLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::MusicLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::MusicLocation); +#endif +} + +QString StandardPaths::tempLocation() +{ +#if QT_VERSION >= 0x050000 + return QStandardPaths::writableLocation(QStandardPaths::TempLocation); +#else + return QDesktopServices::storageLocation(QDesktopServices::TempLocation); +#endif +} diff --git a/StandardPaths.h b/StandardPaths.h old mode 100644 new mode 100755 index 590e0dc..d78f25c --- a/StandardPaths.h +++ b/StandardPaths.h @@ -1,40 +1,41 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef STANDARDPATHS_H -#define STANDARDPATHS_H - -#include - -class StandardPaths -{ -public: - static QString applicationsLocation(); - static QString cacheLocation(); - static QString dataLocation(); - static QString desktopLocation(); - static QString documentsLocation(); - static QString fontsLocation(); - static QString homeLocation(); - static QString moviesLocation(); - static QString picturesLocation(); - static QString musicLocation(); - static QString tempLocation(); -}; - -#endif // STANDARDPATHS_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef STANDARDPATHS_H +#define STANDARDPATHS_H + +#include + +class StandardPaths +{ +public: + StandardPaths(); + static QString applicationsLocation(); + static QString cacheLocation(); + static QString dataLocation(); + static QString desktopLocation(); + static QString documentsLocation(); + static QString fontsLocation(); + static QString homeLocation(); + static QString moviesLocation(); + static QString picturesLocation(); + static QString musicLocation(); + static QString tempLocation(); +}; + +#endif // STANDARDPATHS_H diff --git a/StringParser.cpp b/StringParser.cpp old mode 100644 new mode 100755 index 4ac3fba..aebe01a --- a/StringParser.cpp +++ b/StringParser.cpp @@ -1,54 +1,62 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "StringParser.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include - -QString StringParser::escapeString(const QString &toEscape) -{ -#if QT_VERSION >= 0x050000 - return toEscape.toHtmlEscaped(); -#else - return Qt::escape(toEscape); -#endif -} - -QString StringParser::convertBuildedString(const QString &buildedStr) -{ - QString outputStr = buildedStr; - outputStr.replace("APPNAME:", QString::fromUtf8(GTA5SYNC_APPSTR)); - outputStr.replace("SHAREDDIR:", QString::fromUtf8(GTA5SYNC_SHARE)); - outputStr.replace("RUNDIR:", QFileInfo(QApplication::applicationFilePath()).canonicalPath()); -#if QT_VERSION >= 0x060000 - outputStr.replace("QCONFLANG:", QLibraryInfo::path(QLibraryInfo::TranslationsPath)); - outputStr.replace("QCONFPLUG:", QLibraryInfo::path(QLibraryInfo::PluginsPath)); -#else - outputStr.replace("QCONFLANG:", QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - outputStr.replace("QCONFPLUG:", QLibraryInfo::location(QLibraryInfo::PluginsPath)); -#endif - outputStr.replace("SEPARATOR:", QDir::separator()); - return outputStr; -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "StringParser.h" +#include "config.h" +#include +#include +#include +#include +#include +#include +#include + +StringParser::StringParser() +{ + +} + +QString StringParser::parseTitleString(const QByteArray &commitBytes, int maxLength) +{ + Q_UNUSED(maxLength) + QString retStr = QTextCodec::codecForName("UTF-16LE")->toUnicode(commitBytes).trimmed(); + retStr.remove(QChar((char)0x00)); + return retStr; +} + +QString StringParser::convertDrawStringForLog(const QString &inputStr) +{ + QString outputStr = inputStr; + return outputStr.replace("&","&u;").replace(",","&c;"); +} + +QString StringParser::convertLogStringForDraw(const QString &inputStr) +{ + QString outputStr = inputStr; + return outputStr.replace("&c;",",").replace("&u;","&"); +} + +QString StringParser::convertBuildedString(const QString &buildedStr) +{ + QString outputStr = buildedStr; + QByteArray sharePath = GTA5SYNC_SHARE; + outputStr.replace("$SHAREDIR", QString::fromUtf8(sharePath)); + outputStr.replace("$RUNDIR", QFileInfo(qApp->applicationFilePath()).absoluteDir().absolutePath()); + outputStr.replace("$SEPARATOR", QDir::separator()); + return outputStr; +} diff --git a/StringParser.h b/StringParser.h old mode 100644 new mode 100755 index 7dac436..44346b6 --- a/StringParser.h +++ b/StringParser.h @@ -1,32 +1,35 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef STRINGPARSER_H -#define STRINGPARSER_H - -#include -#include - -class StringParser -{ -public: - static QString escapeString(const QString &toEscape); - static QString convertBuildedString(const QString &buildedStr); -}; - -#endif // STRINGPARSER_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef STRINGPARSER_H +#define STRINGPARSER_H + +#include +#include + +class StringParser +{ +public: + StringParser(); + static QString parseTitleString(const QByteArray &commitBytes, int maxLength); + static QString convertDrawStringForLog(const QString &inputStr); + static QString convertLogStringForDraw(const QString &inputStr); + static QString convertBuildedString(const QString &buildedStr); +}; + +#endif // STRINGPARSER_H diff --git a/TelemetryClass.cpp b/TelemetryClass.cpp deleted file mode 100644 index 724e0c3..0000000 --- a/TelemetryClass.cpp +++ /dev/null @@ -1,596 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2018 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "TelemetryClassAuthenticator.h" -#include "TelemetryClass.h" -#include "StandardPaths.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef GTA5SYNC_TELEMETRY_WEBURL -#define GTA5SYNC_TELEMETRY_WEBURL "" -#endif - -#ifdef Q_OS_WIN -#include "windows.h" -#include "intrin.h" -#include "d3d9.h" -#endif - -TelemetryClass TelemetryClass::telemetryClassInstance; - -void TelemetryClass::init() -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Telemetry"); - telemetryEnabled = true; - telemetryStateForced = true; - QString telemetryLegacyClientID = settings.value("ClientID", QString()).toString(); - if (telemetryLegacyClientID.isEmpty() || telemetryLegacyClientID == "v2+") - { - telemetryClientID = QString::fromUtf8(QByteArray::fromBase64(settings.value("Identification", QByteArray()).toByteArray())); - } - else - { - QDir dir; - dir.mkpath(StandardPaths::dataLocation()); - dir.setPath(StandardPaths::dataLocation()); - QString dirPath = dir.absolutePath(); - QString portLoc = dirPath % "/.ported"; - bool telemetryPortedKey = settings.value("IsPorted", false).toBool(); - bool telemetryPortedFile = QFile::exists(portLoc); - if (!telemetryPortedKey && !telemetryPortedFile) - { - QFile portFile(portLoc); - if (portFile.open(QFile::WriteOnly)) - { - portFile.write("\n"); - portFile.flush(); - } - portFile.close(); - telemetryClientID = telemetryLegacyClientID; - settings.setValue("Identification", telemetryLegacyClientID.toUtf8().toBase64()); - settings.setValue("IsPorted", true); - settings.setValue("ClientID", "v2+"); - } - else - { - telemetryClientID = QString(); - } - } - telemetryPushAppConf = settings.value("PushAppConf", false).toBool(); - settings.endGroup(); -} - -void TelemetryClass::refresh() -{ - init(); -} - -bool TelemetryClass::canPush() -{ - if (!isEnabled() || !isRegistered() || !TelemetryClassAuthenticator::havePushURL()) return false; - return true; -} - -bool TelemetryClass::canRegister() -{ - QDir dir; - dir.mkpath(StandardPaths::dataLocation()); - dir.setPath(StandardPaths::dataLocation()); - QString dirPath = dir.absolutePath(); - QString regLoc = dirPath % "/.reg"; - if (QFile::exists(regLoc)) return false; - if (!isEnabled() || isRegistered() || !TelemetryClassAuthenticator::haveRegURL()) return false; - return true; -} - -bool TelemetryClass::isEnabled() -{ - return telemetryEnabled; -} - -bool TelemetryClass::isStateForced() -{ - return telemetryStateForced; -} - -bool TelemetryClass::isRegistered() -{ - return !telemetryClientID.isEmpty(); -} - -QString TelemetryClass::getRegisteredID() -{ - return telemetryClientID; -} - -void TelemetryClass::setEnabled(bool enabled) -{ - telemetryEnabled = enabled; - telemetryStateForced = true; -} - -void TelemetryClass::setDisabled(bool disabled) -{ - telemetryEnabled = !disabled; - telemetryStateForced = true; -} - -void TelemetryClass::push(TelemetryCategory category) -{ - if (!canPush()) return; - switch (category) - { - case TelemetryCategory::OperatingSystemSpec: - push(category, getOperatingSystem()); - break; - case TelemetryCategory::HardwareSpec: - push(category, getSystemHardware()); - break; - case TelemetryCategory::UserLocaleData: - push(category, getSystemLocaleList()); - break; - case TelemetryCategory::ApplicationConf: - push(category, getApplicationConf()); - break; - case TelemetryCategory::ApplicationSpec: - push(category, getApplicationSpec()); - break; - case TelemetryCategory::UserFeedback: - break; - case TelemetryCategory::PersonalData: - break; - case TelemetryCategory::CustomEmitted: - break; - } -} - -void TelemetryClass::push(TelemetryCategory category, QJsonDocument json) -{ - if (!canPush()) return; - - QJsonDocument jsonDocument(json); - QJsonObject jsonObject = jsonDocument.object(); - jsonObject["ClientID"] = telemetryClientID; - jsonDocument.setObject(jsonObject); - - QHttpMultiPart *httpMultiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - - QHttpPart categoryPart; - categoryPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"json-category\"")); - categoryPart.setBody(categoryToString(category).toUtf8()); - - QHttpPart jsonPart; - jsonPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream")); - jsonPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"json-deflated\"")); - jsonPart.setBody(qCompress(jsonDocument.toJson(QJsonDocument::Compact))); - - httpMultiPart->append(categoryPart); - httpMultiPart->append(jsonPart); - - QNetworkAccessManager *netManager = new QNetworkAccessManager(); - QNetworkRequest netRequest(TelemetryClassAuthenticator::getTrackingPushURL()); - netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent()); - QNetworkReply *netReply = netManager->post(netRequest, httpMultiPart); - httpMultiPart->setParent(netReply); - - connect(netManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(pushFinished(QNetworkReply*))); -} - -QJsonDocument TelemetryClass::getOperatingSystem() -{ - QJsonDocument jsonDocument; - QJsonObject jsonObject; -#if QT_VERSION >= 0x050400 - jsonObject["KernelType"] = QSysInfo::kernelType(); - jsonObject["KernelVersion"] = QSysInfo::kernelVersion(); - jsonObject["ProductType"] = QSysInfo::productType(); - jsonObject["ProductVersion"] = QSysInfo::productVersion(); - jsonObject["OSName"] = QSysInfo::prettyProductName(); - jsonObject["OSArch"] = QSysInfo::currentCpuArchitecture(); -#endif - jsonDocument.setObject(jsonObject); - return jsonDocument; -} - -QJsonDocument TelemetryClass::getSystemHardware() -{ - QJsonDocument jsonDocument; - QJsonObject jsonObject; -#ifdef Q_OS_WIN - { - int CPUInfo[4] = {-1}; - unsigned nExIds, ic = 0; - char CPUBrandString[0x40]; - __cpuid(CPUInfo, 0x80000000); - nExIds = CPUInfo[0]; - for (ic = 0x80000000; ic <= nExIds; ic++) - { - __cpuid(CPUInfo, ic); - if (ic == 0x80000002) { memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo)); } - else if (ic == 0x80000003) { memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo)); } - else if (ic == 0x80000004) { memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo)); } - } - jsonObject["CPUName"] = QString::fromLatin1(CPUBrandString).simplified(); - SYSTEM_INFO sysInfo; - GetSystemInfo(&sysInfo); - jsonObject["CPUThreads"] = QString::number(sysInfo.dwNumberOfProcessors); - MEMORYSTATUSEX statex; - statex.dwLength = sizeof(statex); - GlobalMemoryStatusEx(&statex); - jsonObject["SystemRAM"] = QString(QString::number((statex.ullTotalPhys / 1024) / 1024) % "MB"); - QStringList gpusList; - IDirect3D9 *pD3D = Direct3DCreate9(D3D_SDK_VERSION); - int adapters = pD3D->GetAdapterCount(); - for (int ia = 0; ia < adapters; ia++) - { - D3DADAPTER_IDENTIFIER9 d3dIdent; - HRESULT result = pD3D->GetAdapterIdentifier(ia, 0, &d3dIdent); - if (result == D3D_OK) - { - QString gpuAdapter = QString::fromLatin1(d3dIdent.Description); - if (!gpusList.contains(gpuAdapter)) { gpusList << gpuAdapter; } - } - } - pD3D->Release(); - jsonObject["GPUs"] = QJsonValue::fromVariant(gpusList); - } -#else - QDir procDir("/proc"); - if (procDir.exists()) - { - QFile cpuInfo("/proc/cpuinfo"); - if (cpuInfo.open(QFile::ReadOnly)) - { - QByteArray cpuInfoArray = cpuInfo.readAll(); - QBuffer cpuInfoBuffer(&cpuInfoArray); - if (cpuInfoBuffer.open(QBuffer::ReadOnly)) - { - QByteArray toFind = "model name"; - while (cpuInfoBuffer.canReadLine()) - { - QByteArray cpuData = cpuInfoBuffer.readLine(); - if (cpuData.left(toFind.length()) == toFind) - { - jsonObject["CPUName"] = QString::fromUtf8(cpuData).split(':').at(1).simplified(); - break; - } - } - int cpuThreads = 0; - toFind = "processor"; - cpuInfoBuffer.seek(0); - while (cpuInfoBuffer.canReadLine()) - { - QByteArray cpuData = cpuInfoBuffer.readLine(); - if (cpuData.left(toFind.length()) == toFind) - { - cpuThreads++; - } - } - jsonObject["CPUThreads"] = QString::number(cpuThreads); - } - } - - QFile memInfo("/proc/meminfo"); - if (memInfo.open(QFile::ReadOnly)) - { - QByteArray memInfoArray = memInfo.readAll(); - QBuffer memInfoBuffer(&memInfoArray); - if (memInfoBuffer.open(QBuffer::ReadOnly)) - { - QByteArray toFind = "MemTotal:"; - while (memInfoBuffer.canReadLine()) - { - QByteArray memData = memInfoBuffer.readLine(); - if (memData.left(toFind.length()) == toFind) - { - QByteArray memDataVal = memData.mid(toFind.length()).trimmed(); - int totalMemoryInKB = memDataVal.left(memDataVal.length() - 3).toInt(); - jsonObject["SystemRAM"] = QString(QString::number(totalMemoryInKB / 1024) % "MB"); - break; - } - } - } - } - } -#endif - - jsonDocument.setObject(jsonObject); - return jsonDocument; -} - -QJsonDocument TelemetryClass::getApplicationSpec() -{ - QJsonDocument jsonDocument; - QJsonObject jsonObject; -#if QT_VERSION >= 0x050400 - jsonObject["Arch"] = QSysInfo::buildCpuArchitecture(); -#endif - jsonObject["Name"] = GTA5SYNC_APPSTR; -#ifdef GTA5SYNC_COMMIT - jsonObject["Commit"] = GTA5SYNC_COMMIT; -#endif - jsonObject["Version"] = GTA5SYNC_APPVER; - jsonObject["BuildDateTime"] = AppEnv::getBuildDateTime(); - jsonObject["BuildType"] = GTA5SYNC_BUILDTYPE; - jsonObject["BuildCode"] = AppEnv::getBuildCode(); - jsonObject["QtVersion"] = qVersion(); - jsonDocument.setObject(jsonObject); - return jsonDocument; -} - -QJsonDocument TelemetryClass::getApplicationConf() -{ - QJsonDocument jsonDocument; - QJsonObject jsonObject; - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - - settings.beginGroup("Interface"); - QJsonObject interfaceObject; - interfaceObject["AreaLanguage"] = settings.value("AreaLanguage", "Auto").toString(); - interfaceObject["Language"] = settings.value("Language", "System").toString(); - interfaceObject["NavigationBar"] = settings.value("NavigationBar", false).toBool(); - jsonObject["Interface"] = interfaceObject; - settings.endGroup(); - - settings.beginGroup("Pictures"); - QJsonObject picturesObject; - picturesObject["AspectRatio"] = ((Qt::AspectRatioMode)settings.value("AspectRatio").toInt() == Qt::IgnoreAspectRatio) ? "IgnoreAspectRatio" : "KeepAspectRatio"; - picturesObject["CustomQuality"] = settings.value("CustomQuality", 100).toInt(); - picturesObject["CustomQualityEnabled"] = settings.value("CustomQualityEnabled", false).toBool(); - picturesObject["ExportSizeMode"] = settings.value("ExportSizeMode", "Default").toString(); - jsonObject["Pictures"] = picturesObject; - settings.endGroup(); - - settings.beginGroup("Profile"); - QJsonObject profileObject; - int contentMode = settings.value("ContentMode", 0).toInt(); - switch (contentMode) - { - case 0: - profileObject["ContentMode"] = "OpenWithSingleClick"; - break; - case 1: - profileObject["ContentMode"] = "OpenWithDoubleClick"; - break; - case 2: - profileObject["ContentMode"] = "SelectWithSingleClick"; - break; - } - jsonObject["Profile"] = profileObject; - settings.endGroup(); - - settings.beginGroup("Startup"); - QJsonObject startupObject; - startupObject["AppStyle"] = settings.value("AppStyle", "System").toString(); - startupObject["CustomStyle"] = settings.value("CustomStyle", false).toBool(); - startupObject["StartCount"] = QString::number(settings.value("StartCount", 0).toUInt()); - jsonObject["Startup"] = startupObject; - settings.endGroup(); - - jsonDocument.setObject(jsonObject); - return jsonDocument; -} - -QJsonDocument TelemetryClass::getSystemLocaleList() -{ - QJsonDocument jsonDocument; - QJsonObject jsonObject; - QStringList languagesList = QLocale::system().uiLanguages(); - if (languagesList.length() >= 1) - { - jsonObject["PrimaryLanguage"] = languagesList.at(0); - } - if (languagesList.length() >= 2) - { - languagesList.removeAt(0); - jsonObject["SecondaryLanguages"] = QJsonValue::fromVariant(languagesList); - } - jsonDocument.setObject(jsonObject); - return jsonDocument; -} - -QString TelemetryClass::categoryToString(TelemetryCategory category) -{ - switch (category) - { - case TelemetryCategory::OperatingSystemSpec: - return QString("OperatingSystemSpec"); - break; - case TelemetryCategory::HardwareSpec: - return QString("HardwareSpec"); - break; - case TelemetryCategory::UserLocaleData: - return QString("UserLocaleData"); - break; - case TelemetryCategory::ApplicationConf: - return QString("ApplicationConf"); - break; - case TelemetryCategory::ApplicationSpec: - return QString("ApplicationSpec"); - break; - case TelemetryCategory::UserFeedback: - return QString("UserFeedback"); - break; - case TelemetryCategory::PersonalData: - return QString("PersonalData"); - break; - case TelemetryCategory::CustomEmitted: - return QString("CustomEmitted"); - break; - default: - return QString("UnknownCategory"); - break; - } -} - -QUrl TelemetryClass::getWebURL() -{ - return QUrl(GTA5SYNC_TELEMETRY_WEBURL); -} - -void TelemetryClass::registerClient() -{ - QNetworkAccessManager *netManager = new QNetworkAccessManager(); - QNetworkRequest netRequest(TelemetryClassAuthenticator::getTrackingRegURL()); - netRequest.setRawHeader("User-Agent", AppEnv::getUserAgent()); - netManager->get(netRequest); - - connect(netManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(registerFinished(QNetworkReply*))); -} - -void TelemetryClass::work() -{ - if (!canPush() && canRegister()) - { - connect(this, SIGNAL(registered(bool)), this, SLOT(work_pd(bool))); - registerClient(); - } - else if (canPush()) - { - work_p(true); - } -} - -void TelemetryClass::work_p(bool doWork) -{ - if (doWork) - { - push(TelemetryCategory::ApplicationSpec); - push(TelemetryCategory::UserLocaleData); - push(TelemetryCategory::OperatingSystemSpec); - push(TelemetryCategory::HardwareSpec); - if (telemetryPushAppConf) - { - push(TelemetryCategory::ApplicationConf); - } - else - { - push(TelemetryCategory::ApplicationConf, QJsonDocument()); - } - } -} - -void TelemetryClass::work_pd(bool doWork) -{ - disconnect(this, SIGNAL(registered(bool)), this, SLOT(work_pd(bool))); - work_p(doWork); -} - -void TelemetryClass::pushFinished(QNetworkReply *reply) -{ - bool isSuccessful = false; - if (reply->canReadLine()) - { - QByteArray readedData = reply->readLine(); - if (QString::fromUtf8(readedData).trimmed() == QString("Submit success!")) - { -#ifdef GTA5SYNC_DEBUG - qDebug() << "Telemetry" << QString("Submit success!"); -#endif - isSuccessful = true; -#ifdef GTA5SYNC_DEBUG - if (reply->isReadable()) - { - readedData = reply->readAll().trimmed(); - if (!readedData.isEmpty()) { qDebug() << "Telemetry Push" << readedData; } - } -#endif - } - else - { -#ifdef GTA5SYNC_DEBUG - qDebug() << "Telemetry" << QString("Submit failed!"); -#endif - } - } - else - { -#ifdef GTA5SYNC_DEBUG - qDebug() << "Telemetry" << QString("Submit failed!"); -#endif - } - reply->deleteLater(); - sender()->deleteLater(); - emit pushed(isSuccessful); -} - -void TelemetryClass::registerFinished(QNetworkReply *reply) -{ - bool isSuccessful = false; - if (reply->canReadLine()) - { - QByteArray readedData = reply->readLine(); - if (QString::fromUtf8(readedData).trimmed() == QString("Registration success!") && reply->canReadLine()) - { - QDir dir; - dir.mkpath(StandardPaths::dataLocation()); - dir.setPath(StandardPaths::dataLocation()); - QString dirPath = dir.absolutePath(); - QString regLoc = dirPath % "/.reg"; - readedData = reply->readLine(); - telemetryClientID = QString::fromUtf8(readedData).trimmed(); - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Telemetry"); - settings.setValue("Identification", telemetryClientID.toUtf8().toBase64()); - settings.endGroup(); - QFile regFile(regLoc); - if (regFile.open(QFile::WriteOnly)) - { - regFile.write("\n"); - regFile.flush(); - } - regFile.close(); -#ifdef GTA5SYNC_DEBUG - qDebug() << "Telemetry" << QString("Registration success!"); -#endif - isSuccessful = true; - } - else - { -#ifdef GTA5SYNC_DEBUG - qDebug() << "Telemetry" << QString("Registration failed!"); -#endif - } - } - else - { -#ifdef GTA5SYNC_DEBUG - qDebug() << "Telemetry" << QString("Registration failed!"); -#endif - } - reply->deleteLater(); - sender()->deleteLater(); - emit registered(isSuccessful); -} diff --git a/TelemetryClass.h b/TelemetryClass.h deleted file mode 100644 index 834c3ed..0000000 --- a/TelemetryClass.h +++ /dev/null @@ -1,80 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2018 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef TELEMETRYCLASS_H -#define TELEMETRYCLASS_H - -#include -#include -#include -#include -#include - -enum class TelemetryCategory : int { OperatingSystemSpec = 0, HardwareSpec = 1, UserLocaleData = 2, ApplicationConf = 3, UserFeedback = 4, ApplicationSpec = 5, PersonalData = 6, CustomEmitted = 99 }; - -class TelemetryClass : public QObject -{ - Q_OBJECT -public: - static TelemetryClass* getInstance() { return &telemetryClassInstance; } - static QString categoryToString(TelemetryCategory category); - static QUrl getWebURL(); - bool canPush(); - bool canRegister(); - bool isEnabled(); - bool isStateForced(); - bool isRegistered(); - void init(); - void work(); - void refresh(); - void setEnabled(bool enabled); - void setDisabled(bool disabled); - void push(TelemetryCategory category); - void push(TelemetryCategory category, const QJsonDocument json); - void registerClient(); - QString getRegisteredID(); - -private: - static TelemetryClass telemetryClassInstance; - QString telemetryClientID; - bool telemetryEnabled; - bool telemetryStateForced; - bool telemetryPushAppConf; - - void work_p(bool doWork); - QJsonDocument getOperatingSystem(); - QJsonDocument getSystemHardware(); - QJsonDocument getApplicationSpec(); - QJsonDocument getApplicationConf(); - QJsonDocument getSystemLocaleList(); - -private slots: - void pushFinished(QNetworkReply *reply); - void registerFinished(QNetworkReply *reply); - void work_pd(bool doWork); - -signals: - void pushed(bool isSucessful); - void registered(bool isSucessful); -}; - -extern TelemetryClass telemetryClass; - -#define Telemetry TelemetryClass::getInstance() - -#endif // TELEMETRYCLASS_H diff --git a/TranslationClass.cpp b/TranslationClass.cpp deleted file mode 100644 index 06450d1..0000000 --- a/TranslationClass.cpp +++ /dev/null @@ -1,605 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "TranslationClass.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if QT_VERSION >= 0x050000 -#define QtBaseTranslationFormat "qtbase_" -#else -#define QtBaseTranslationFormat "qt_" -#endif - -TranslationClass TranslationClass::translationClassInstance; - -void TranslationClass::initUserLanguage() -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Interface"); - userLanguage = settings.value("Language", "System").toString(); - userAreaLanguage = settings.value("AreaLanguage", "Auto").toString(); - settings.endGroup(); -} - -void TranslationClass::loadTranslation(QApplication *app) -{ - if (isLangLoaded) { - unloadTranslation(app); - } - else { - currentLangIndex = 0; - } - const QString exLangPath = AppEnv::getExLangFolder(); - const QString inLangPath = AppEnv::getInLangFolder(); - if (userLanguage == "en" || userLanguage == "en_GB") { - currentLanguage = "en_GB"; - if (loadQtTranslation_p(exLangPath, &exQtTranslator)) { - app->installTranslator(&exQtTranslator); - } - else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) { - app->installTranslator(&inQtTranslator); - } -#if QT_VERSION >= 0x060000 - QLocale::setDefault(QLocale(currentLanguage)); -#else - QLocale::setDefault(currentLanguage); -#endif - isLangLoaded = true; - return; - } -#ifndef GTA5SYNC_QCONF // Classic modable loading method - QString externalLanguageStr; - bool externalLanguageReady = false; - bool externalEnglishMode = false; - bool loadInternalLang = false; - bool trLoadSuccess = false; - if (isUserLanguageSystem_p()) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadExSystemLanguage"; -#endif - trLoadSuccess = loadSystemTranslation_p(exLangPath, &exAppTranslator); - } - else { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadExUserLanguage"; -#endif - trLoadSuccess = loadUserTranslation_p(exLangPath, &exAppTranslator); - if (!trLoadSuccess) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadInUserLanguage"; -#endif - trLoadSuccess = loadUserTranslation_p(inLangPath, &inAppTranslator); - if (!trLoadSuccess) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadUserLanguageFailed"; -#endif - } - else { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadUserLanguageSuccess"; -#endif - loadInternalLang = true; - isLangLoaded = true; - } - } - else { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadUserLanguageSuccess"; -#endif - isLangLoaded = true; - } - } - if (trLoadSuccess) { - // Don't install the language until we know we not have a better language for the user - if (currentLangIndex != 0 || isEnglishMode) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "externalLanguageReady" << currentLanguage; -#endif - externalEnglishMode = isEnglishMode; - externalLanguageStr = currentLanguage; - externalLanguageReady = true; - } - else { -#ifdef GTA5SYNC_DEBUG - qDebug() << "installTranslation"; -#endif - if (loadInternalLang) { - app->installTranslator(&inAppTranslator); - } - else { - app->installTranslator(&exAppTranslator); - } - if (loadQtTranslation_p(exLangPath, &exQtTranslator)) { - app->installTranslator(&exQtTranslator); - } - else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) { - app->installTranslator(&inQtTranslator); - } -#if QT_VERSION >= 0x060000 - QLocale::setDefault(QLocale(currentLanguage)); -#else - QLocale::setDefault(currentLanguage); -#endif - isLangLoaded = true; - } - } - if (externalLanguageReady) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadInSystemLanguage"; -#endif - int externalLangIndex = currentLangIndex; - trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator); -#ifdef GTA5SYNC_DEBUG - qDebug() << "externalLangIndex" << externalLangIndex << "internalLangIndex" << currentLangIndex; - qDebug() << "externalEnglishMode" << externalEnglishMode << "internalEnglishMode" << isEnglishMode; -#endif - if ((trLoadSuccess && externalLangIndex > currentLangIndex) || (trLoadSuccess && externalEnglishMode && !isEnglishMode)) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "installInternalTranslation"; -#endif - app->installTranslator(&inAppTranslator); - if (loadQtTranslation_p(exLangPath, &exQtTranslator)) { - app->installTranslator(&exQtTranslator); - } - else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) { - app->installTranslator(&inQtTranslator); - } -#if QT_VERSION >= 0x060000 - QLocale::setDefault(QLocale(currentLanguage)); -#else - QLocale::setDefault(currentLanguage); -#endif - isLangLoaded = true; - } - else { -#ifdef GTA5SYNC_DEBUG - qDebug() << "installExternalTranslation"; -#endif - isEnglishMode = externalEnglishMode; - currentLanguage = externalLanguageStr; - app->installTranslator(&exAppTranslator); - if (loadQtTranslation_p(exLangPath, &exQtTranslator)) { - app->installTranslator(&exQtTranslator); - } - else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) { - app->installTranslator(&inQtTranslator); - } -#if QT_VERSION >= 0x060000 - QLocale::setDefault(QLocale(currentLanguage)); -#else - QLocale::setDefault(currentLanguage); -#endif - isLangLoaded = true; - } - } - else if (!isLangLoaded) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadInSystemLanguage"; -#endif - trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator); - if (trLoadSuccess) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "installInternalTranslation"; -#endif - app->installTranslator(&inAppTranslator); - if (loadQtTranslation_p(exLangPath, &exQtTranslator)) { - app->installTranslator(&exQtTranslator); - } - else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) { - app->installTranslator(&inQtTranslator); - } -#if QT_VERSION >= 0x060000 - QLocale::setDefault(QLocale(currentLanguage)); -#else - QLocale::setDefault(currentLanguage); -#endif - isLangLoaded = true; - } - else if (!trLoadSuccess) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "fallbackToDefaultApplicationLanguage"; -#endif - currentLanguage = "en_GB"; - if (loadQtTranslation_p(exLangPath, &exQtTranslator)) { - app->installTranslator(&exQtTranslator); - } - else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) { - app->installTranslator(&inQtTranslator); - } -#if QT_VERSION >= 0x060000 - QLocale::setDefault(QLocale(currentLanguage)); -#else - QLocale::setDefault(currentLanguage); -#endif - isLangLoaded = true; - } - } -#else // New qconf loading method - bool trLoadSuccess; - if (isUserLanguageSystem_p()) { - trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator); - } - else { - trLoadSuccess = loadUserTranslation_p(inLangPath, &inAppTranslator); - } - if (!trLoadSuccess && !isUserLanguageSystem_p()) { - trLoadSuccess = loadSystemTranslation_p(inLangPath, &inAppTranslator); - } - if (trLoadSuccess) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "installTranslation" << currentLanguage; -#endif - app->installTranslator(&inAppTranslator); - if (loadQtTranslation_p(exLangPath, &exQtTranslator)) { - app->installTranslator(&exQtTranslator); - } - else if (loadQtTranslation_p(inLangPath, &inQtTranslator)) { - app->installTranslator(&inQtTranslator); - } -#if QT_VERSION >= 0x060000 - QLocale::setDefault(QLocale(currentLanguage)); -#else - QLocale::setDefault(currentLanguage); -#endif - isLangLoaded = true; - } -#endif -} - -QStringList TranslationClass::listTranslations(const QString &langPath) -{ - QDir langDir; - langDir.setNameFilters(QStringList("gta5sync_*.qm")); - langDir.setPath(langPath); - QStringList availableLanguages; - for (const QString &lang : langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort)) { - availableLanguages << QString(lang).remove("gta5sync_").remove(".qm"); - } - return availableLanguages; -} - -QStringList TranslationClass::listAreaTranslations() -{ - QDir langDir; - langDir.setNameFilters(QStringList("global.*.ini")); - langDir.setPath(":/global"); - QStringList availableLanguages; - for (const QString &lang : langDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort)) { - availableLanguages << QString(lang).remove("global.").remove(".ini"); - } - return availableLanguages; -} - -bool TranslationClass::loadSystemTranslation_p(const QString &langPath, QTranslator *appTranslator) -{ -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadSystemTranslation_p"; -#endif - int currentLangCounter = 0; - for (const QString &languageName : QLocale::system().uiLanguages()) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguage" << languageName; -#endif - const QStringList langList = QString(languageName).replace("-","_").split("_"); - if (langList.length() == 2) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm"); -#endif - if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm")) { - if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm")) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm"); -#endif - isEnglishMode = false; - currentLanguage = languageName; - currentLangIndex = currentLangCounter; - return true; - } - } -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm"); -#endif - if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm")) { - if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm")) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm"); -#endif - isEnglishMode = false; - currentLanguage = languageName; - currentLangIndex = currentLangCounter; - return true; - } - else if (langList.at(0) == "en") { -#ifdef GTA5SYNC_DEBUG - qDebug() << "languageEnglishMode index" << currentLangCounter; -#endif - isEnglishMode = true; - currentLanguage = languageName; - currentLangIndex = currentLangCounter; - return true; - } - } - else if (langList.at(0) == "en") { -#ifdef GTA5SYNC_DEBUG - qDebug() << "languageEnglishMode index" << currentLangCounter; -#endif - isEnglishMode = true; - currentLanguage = languageName; - currentLangIndex = currentLangCounter; - return true; - } - } - else if (langList.length() == 1) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm"); -#endif - if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm")) { - if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm")) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm"); -#endif - isEnglishMode = false; - currentLanguage = languageName; - currentLangIndex = currentLangCounter; - return true; - } - } - } -#ifdef GTA5SYNC_DEBUG - qDebug() << "currentLangCounter bump"; -#endif - currentLangCounter++; - } - return false; -} - -bool TranslationClass::loadUserTranslation_p(const QString &langPath, QTranslator *appTranslator) -{ -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadUserTranslation_p"; -#endif - const QString languageName = userLanguage; - const QStringList langList = QString(languageName).replace("-","_").split("_"); - if (langList.length() == 2) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm"); -#endif - if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm")) { - if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm")) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % "_" % langList.at(1) % ".qm"); -#endif - currentLanguage = languageName; - return true; - } - } -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm"); -#endif - if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm")) { - if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm")) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm"); -#endif - currentLanguage = languageName; - return true; - } - } - } - else if (langList.length() == 1) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFile" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm"); -#endif - if (QFile::exists(langPath % "/gta5sync_" % langList.at(0) % ".qm")) { - if (appTranslator->load(langPath % "/gta5sync_" % langList.at(0) % ".qm")) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFileSuccess" << QString(langPath % "/gta5sync_" % langList.at(0) % ".qm"); -#endif - currentLanguage = languageName; - return true; - } - } - } - return false; -} - -bool TranslationClass::loadQtTranslation_p(const QString &langPath, QTranslator *qtTranslator) -{ -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadQtTranslation_p" << currentLanguage; -#endif - const QString languageName = currentLanguage; - const QStringList langList = QString(languageName).replace("-","_").split("_"); - if (langList.length() == 2) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFile" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm"); -#endif - if (QFile::exists(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm")) { - if (qtTranslator->load(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm")) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFileSuccess" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % "_" % langList.at(1) % ".qm"); -#endif - return true; - } - } -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFile" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm"); -#endif - if (QFile::exists(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm")) { - if (qtTranslator->load(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm")) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFileSuccess" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm"); -#endif - return true; - } - } - } - else if (langList.length() == 1) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFile" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm"); -#endif - if (QFile::exists(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm")) { - if (qtTranslator->load(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm")) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "loadLanguageFileSuccess" << QString(langPath % QDir::separator() % QtBaseTranslationFormat % langList.at(0) % ".qm"); -#endif - return true; - } - } - } - return false; -} - -bool TranslationClass::isUserLanguageSystem_p() -{ - return (userLanguage == "System" || userLanguage.trimmed().isEmpty()); -} - -QString TranslationClass::getCurrentAreaLanguage() -{ - const QStringList areaTranslations = listAreaTranslations(); - if (userAreaLanguage == "Auto" || userAreaLanguage.trimmed().isEmpty()) { - const GameLanguage gameLanguage = AppEnv::getGameLanguage(AppEnv::getGameVersion()); - if (gameLanguage == GameLanguage::Undefined) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "autoAreaLanguageModeInterface"; -#endif - QString langCode = QString(currentLanguage).replace("-", "_"); - if (areaTranslations.contains(langCode)) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "autoAreaLanguageSelected" << langCode; -#endif - return langCode; - } - else if (langCode.contains("_")) { - langCode = langCode.split("_").at(0); - if (!areaTranslations.contains(langCode)) - goto outputDefaultLanguage; -#ifdef GTA5SYNC_DEBUG - qDebug() << "autoAreaLanguageSelected" << langCode; -#endif - return langCode; - } - } - else { -#ifdef GTA5SYNC_DEBUG - qDebug() << "autoAreaLanguageModeGame"; -#endif - QString langCode = AppEnv::gameLanguageToString(gameLanguage).replace("-", "_"); - if (areaTranslations.contains(langCode)) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "autoAreaLanguageSelected" << langCode; -#endif - return langCode; - } - else if (langCode.contains("_")) { - langCode = langCode.split("_").at(0); - if (!areaTranslations.contains(langCode)) - goto outputDefaultLanguage; -#ifdef GTA5SYNC_DEBUG - qDebug() << "autoAreaLanguageSelected" << langCode; -#endif - return langCode; - } - } - } - else if (areaTranslations.contains(userAreaLanguage)) { -#ifdef GTA5SYNC_DEBUG - qDebug() << "userAreaLanguageSelected" << userAreaLanguage; -#endif - return userAreaLanguage; - } - else if (userAreaLanguage.contains("_")) { - const QString langCode = QString(userAreaLanguage).replace("-", "_").split("_").at(0); - if (!areaTranslations.contains(langCode)) - goto outputDefaultLanguage; -#ifdef GTA5SYNC_DEBUG - qDebug() << "userAreaLanguageSelected" << langCode; -#endif - return langCode; - } -outputDefaultLanguage: -#ifdef GTA5SYNC_DEBUG - qDebug() << "defaultAreaLanguageSelected"; -#endif - return "en"; -} - -QString TranslationClass::getCurrentLanguage() -{ - return currentLanguage; -} - -bool TranslationClass::isLanguageLoaded() -{ - return isLangLoaded; -} - -void TranslationClass::unloadTranslation(QApplication *app) -{ - if (isLangLoaded) { -#ifndef GTA5SYNC_QCONF - app->removeTranslator(&exAppTranslator); - app->removeTranslator(&exQtTranslator); - app->removeTranslator(&inAppTranslator); - app->removeTranslator(&inQtTranslator); -#else - app->removeTranslator(&inAppTranslator); - app->removeTranslator(&exQtTranslator); -#endif - currentLangIndex = 0; - currentLanguage = QString(); - QLocale::setDefault(QLocale::c()); - isEnglishMode = false; - isLangLoaded = false; - } -#ifdef _MSC_VER // Fix dumb Microsoft compiler warning - Q_UNUSED(app) -#endif -} - -QString TranslationClass::getCountryCode(QLocale::Country country) -{ - const QList locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, country); - if (!locales.isEmpty()) { - const QStringList localeStrList = locales.at(0).name().split("_"); - if (localeStrList.length() >= 2) { - return localeStrList.at(1).toLower(); - } - } - return QString(); -} - -QString TranslationClass::getCountryCode(QLocale locale) -{ - QStringList localeStrList = locale.name().split("_"); - if (localeStrList.length() >= 2) { - return localeStrList.at(1).toLower(); - } - return QString(); -} diff --git a/TranslationClass.h b/TranslationClass.h deleted file mode 100644 index 963eaff..0000000 --- a/TranslationClass.h +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef TRANSLATIONCLASS_H -#define TRANSLATIONCLASS_H - -#include -#include -#include -#include -#include -#include - -class TranslationClass : public QObject -{ - Q_OBJECT -public: - static TranslationClass* getInstance() { return &translationClassInstance; } - static QString getCountryCode(QLocale::Country country); - static QString getCountryCode(QLocale locale); - void initUserLanguage(); - void loadTranslation(QApplication *app); - void unloadTranslation(QApplication *app); - static QStringList listTranslations(const QString &langPath); - static QStringList listAreaTranslations(); - QString getCurrentAreaLanguage(); - QString getCurrentLanguage(); - bool isLanguageLoaded(); - -private: - static TranslationClass translationClassInstance; - bool loadSystemTranslation_p(const QString &langPath, QTranslator *appTranslator); - bool loadUserTranslation_p(const QString &langPath, QTranslator *appTranslator); - bool loadQtTranslation_p(const QString &langPath, QTranslator *qtTranslator); - bool isUserLanguageSystem_p(); - QTranslator exAppTranslator; - QTranslator exQtTranslator; - QTranslator inAppTranslator; - QTranslator inQtTranslator; - QString userAreaLanguage; - QString currentLanguage; - QString userLanguage; - int currentLangIndex; - bool isEnglishMode; - bool isLangLoaded; -}; - -extern TranslationClass translationClass; - -#define Translator TranslationClass::getInstance() - -#endif // TRANSLATIONCLASS_H diff --git a/UserInterface.cpp b/UserInterface.cpp old mode 100644 new mode 100755 index a990b51..45f4a41 --- a/UserInterface.cpp +++ b/UserInterface.cpp @@ -1,920 +1,472 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "UserInterface.h" -#include "ui_UserInterface.h" -#include "ProfileInterface.h" -#include "SnapmaticPicture.h" -#include "SidebarGenerator.h" -#include "SavegameDialog.h" -#include "StandardPaths.h" -#include "OptionsDialog.h" -#include "PictureDialog.h" -#include "SavegameData.h" -#include "AboutDialog.h" -#include "IconLoader.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GTA5SYNC_DONATE -#ifdef GTA5SYNC_DONATE_ADDRESSES -#include -#include -#include -#include "QrCode.h" -using namespace qrcodegen; -#endif -#endif - -#ifdef GTA5SYNC_MOTD -UserInterface::UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, MessageThread *threadMessage, QWidget *parent) : - QMainWindow(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), threadMessage(threadMessage), - ui(new Ui::UserInterface) - #else -UserInterface::UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent) : - QMainWindow(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), - ui(new Ui::UserInterface) - #endif -{ - ui->setupUi(this); - contentMode = 0; - profileOpen = 0; - profileUI = 0; - ui->menuProfile->setEnabled(false); - ui->actionSelect_profile->setEnabled(false); - ui->actionAbout_gta5sync->setIcon(IconLoader::loadingAppIcon()); -#ifdef Q_OS_MAC - ui->actionAbout_gta5sync->setText(QApplication::translate("MAC_APPLICATION_MENU", "About %1").arg(GTA5SYNC_APPSTR)); - ui->actionOptions->setText(QApplication::translate("MAC_APPLICATION_MENU", "Preferences...")); -#else - ui->actionAbout_gta5sync->setText(tr("&About %1").arg(GTA5SYNC_APPSTR)); -#endif - ui->cmdClose->setToolTip(ui->cmdClose->toolTip().arg(GTA5SYNC_APPSTR)); - defaultWindowTitle = tr("%2 - %1").arg("%1", GTA5SYNC_APPSTR); - - setWindowTitle(defaultWindowTitle.arg(tr("Select Profile"))); - QString appVersion = QApplication::applicationVersion(); - const char* literalBuildType = GTA5SYNC_BUILDTYPE; -#ifdef GTA5SYNC_COMMIT - if ((strcmp(literalBuildType, REL_BUILDTYPE) != 0) && !appVersion.contains("-")) - appVersion = appVersion % "-" % GTA5SYNC_COMMIT; -#endif - ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion)); - - // Set Icon for Close Button - if (QIcon::hasThemeIcon("dialog-close")) { - ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) { - ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close")); - } - - // Set Icon for Reload Button - if (QIcon::hasThemeIcon("view-refresh")) { - ui->cmdReload->setIcon(QIcon::fromTheme("view-refresh")); - } - else if (QIcon::hasThemeIcon("reload")) { - ui->cmdReload->setIcon(QIcon::fromTheme("reload")); - } - - // Set Icon for Choose GTA V Folder Menu Item - if (QIcon::hasThemeIcon("document-open-folder")) { - ui->actionSelect_GTA_Folder->setIcon(QIcon::fromTheme("document-open-folder")); - } - else if (QIcon::hasThemeIcon("gtk-directory")) { - ui->actionSelect_GTA_Folder->setIcon(QIcon::fromTheme("gtk-directory")); - } - - // Set Icon for Open File Menu Item - if (QIcon::hasThemeIcon("document-open")) { - ui->actionOpen_File->setIcon(QIcon::fromTheme("document-open")); - } - - // Set Icon for Close Profile Menu Item - if (QIcon::hasThemeIcon("dialog-close")) { - ui->actionSelect_profile->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) { - ui->actionSelect_profile->setIcon(QIcon::fromTheme("gtk-close")); - } - - // Set Icon for Exit Menu Item - if (QIcon::hasThemeIcon("application-exit")) { -#ifndef Q_OS_MACOS // Setting icon for exit/quit lead to a crash in Mac OS X - ui->actionExit->setIcon(QIcon::fromTheme("application-exit")); -#endif - } - - // Set Icon for Preferences Menu Item - if (QIcon::hasThemeIcon("preferences-system")) { -#ifndef Q_OS_MACOS // Setting icon for preferences/settings/options lead to a crash in Mac OS X - ui->actionOptions->setIcon(QIcon::fromTheme("preferences-system")); -#endif - } - else if (QIcon::hasThemeIcon("configure")) { -#ifndef Q_OS_MACOS // Setting icon for preferences/settings/options lead to a crash in Mac OS X - ui->actionOptions->setIcon(QIcon::fromTheme("configure")); -#endif - } - - // Set Icon for Profile Import Menu Item - if (QIcon::hasThemeIcon("document-import")) { - ui->action_Import->setIcon(QIcon::fromTheme("document-import")); - } - else if (QIcon::hasThemeIcon("document-open")) { - ui->action_Import->setIcon(QIcon::fromTheme("document-open")); - } - - // Set Icon for Profile Export Menu Item - if (QIcon::hasThemeIcon("document-export")) { - ui->actionExport_selected->setIcon(QIcon::fromTheme("document-export")); - } - else if (QIcon::hasThemeIcon("document-save")) { - ui->actionExport_selected->setIcon(QIcon::fromTheme("document-save")); - } - - // Set Icon for Profile Remove Menu Item - if (QIcon::hasThemeIcon("remove")) { - ui->actionDelete_selected->setIcon(QIcon::fromTheme("remove")); - } - -#ifdef GTA5SYNC_DONATE -#ifdef GTA5SYNC_DONATE_ADDRESSES - donateAction = new QAction(tr("&Donate"), this); - if (QIcon::hasThemeIcon("help-donate")) { - donateAction->setIcon(QIcon::fromTheme("help-donate")); - } - else if (QIcon::hasThemeIcon("taxes-finances")) { - donateAction->setIcon(QIcon::fromTheme("taxes-finances")); - } - else { - donateAction->setIcon(QIcon(":/img/donate.svgz")); - } - ui->menuHelp->insertAction(ui->actionAbout_gta5sync, donateAction); - QObject::connect(donateAction, &QAction::triggered, this, [=](){ - QDialog *donateDialog = new QDialog(this); - donateDialog->setWindowTitle(QString("%1 - %2").arg(GTA5SYNC_APPSTR, tr("Donate"))); -#if QT_VERSION >= 0x050900 - donateDialog->setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - donateDialog->setWindowFlags(donateDialog->windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - QVBoxLayout *donateLayout = new QVBoxLayout; - donateDialog->setLayout(donateLayout); - QLabel *methodsLabel = new QLabel(QString("%1").arg(tr("Donation methods").toHtmlEscaped()), donateDialog); - methodsLabel->setWordWrap(true); - donateLayout->addWidget(methodsLabel); - QHBoxLayout *currencyLayout = new QHBoxLayout; - donateLayout->addLayout(currencyLayout); - const QStringList addressList = QString::fromUtf8(GTA5SYNC_DONATE_ADDRESSES).split(','); - for (const QString &address : addressList) { - const QStringList addressList = address.split(':'); - if (addressList.length() == 2) { - const QString currency = addressList.at(0); - const QString address = addressList.at(1); - QString currencyStr = currency; - const QString strPath = QString(":/donate/%1.str").arg(currency); - if (QFile::exists(strPath)) { - QFile strFile(strPath); - if (strFile.open(QIODevice::ReadOnly)) { - currencyStr = QString::fromUtf8(strFile.readAll()); - strFile.close(); - } - } - const QString iconPath = QString(":/donate/%1.svgz").arg(currency); - QPushButton *currencyButton = new QPushButton(currencyStr, donateDialog); - currencyButton->setToolTip(currencyStr); - if (QFile::exists(iconPath)) { - currencyButton->setIconSize(QSize(32, 32)); - currencyButton->setIcon(QIcon(iconPath)); - } - currencyLayout->addWidget(currencyButton); - QObject::connect(currencyButton, &QPushButton::pressed, donateDialog, [=](){ - QDialog *addressDialog = new QDialog(donateDialog); - addressDialog->setWindowTitle(currencyStr); -#if QT_VERSION >= 0x050900 - addressDialog->setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - addressDialog->setWindowFlags(donateDialog->windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - QVBoxLayout *addressLayout = new QVBoxLayout; - addressDialog->setLayout(addressLayout); - QLabel *addressLabel = new QLabel(address, addressDialog); - addressLabel->setAlignment(Qt::AlignCenter); - addressLabel->setTextFormat(Qt::PlainText); - addressLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - addressLayout->addWidget(addressLabel); - QHBoxLayout *qrLayout = new QHBoxLayout; - qrLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); - QrCode qr = QrCode::encodeText(address.toUtf8().constData(), QrCode::Ecc::MEDIUM); - const std::string svgString = qr.toSvgString(0); - QSvgRenderer svgRenderer(QByteArray::fromRawData(svgString.c_str(), svgString.size())); - qreal screenRatioPR = AppEnv::screenRatioPR(); - const QSize widgetSize = QSize(200, 200); - const QSize pixmapSize = widgetSize * screenRatioPR; - QPixmap qrPixmap(pixmapSize); - qrPixmap.fill(Qt::white); - QPainter qrPainter(&qrPixmap); - svgRenderer.render(&qrPainter, QRectF(QPointF(0, 0), pixmapSize)); - qrPainter.end(); -#if QT_VERSION >= 0x050600 - qrPixmap.setDevicePixelRatio(screenRatioPR); -#endif - QLabel *qrLabel = new QLabel(addressDialog); - qrLabel->setFixedSize(widgetSize); - qrLabel->setPixmap(qrPixmap); - qrLayout->addWidget(qrLabel); - qrLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); - addressLayout->addLayout(qrLayout); - QHBoxLayout *buttonLayout = new QHBoxLayout; - buttonLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); - QPushButton *copyAddressButton = new QPushButton(tr("&Copy"), addressDialog); - if (QIcon::hasThemeIcon("edit-copy")) { - copyAddressButton->setIcon(QIcon::fromTheme("edit-copy")); - } - QObject::connect(copyAddressButton, &QPushButton::pressed, addressDialog, [=](){ - QApplication::clipboard()->setText(address); - }); - buttonLayout->addWidget(copyAddressButton); - QPushButton *closeButton = new QPushButton(tr("&Close"), addressDialog); - if (QIcon::hasThemeIcon("dialog-close")) { - closeButton->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) { - closeButton->setIcon(QIcon::fromTheme("gtk-close")); - } - closeButton->setDefault(true); - buttonLayout->addWidget(closeButton); - buttonLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); - addressLayout->addLayout(buttonLayout); - QObject::connect(closeButton, &QPushButton::clicked, addressDialog, &QDialog::accept); - QObject::connect(addressDialog, &QDialog::finished, addressDialog, &QDialog::deleteLater); - QTimer::singleShot(0, addressDialog, [=](){ - addressDialog->setFocus(); - }); - addressDialog->open(); - addressDialog->setFixedSize(addressDialog->size()); - }); - } - } - QHBoxLayout *buttonLayout = new QHBoxLayout; - buttonLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); - QPushButton *closeButton = new QPushButton(donateDialog); - closeButton->setText(tr("&Close")); - if (QIcon::hasThemeIcon("dialog-close")) { - closeButton->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) { - closeButton->setIcon(QIcon::fromTheme("gtk-close")); - } - closeButton->setDefault(true); - buttonLayout->addWidget(closeButton); - donateLayout->addLayout(buttonLayout); - QObject::connect(closeButton, &QPushButton::clicked, donateDialog, &QDialog::accept); - QObject::connect(donateDialog, &QDialog::finished, donateDialog, &QDialog::deleteLater); - QTimer::singleShot(0, donateDialog, [=](){ - donateDialog->setFocus(); - }); - donateDialog->open(); - donateDialog->setFixedSize(donateDialog->size()); - }); -#endif -#endif - - // DPI calculation - qreal screenRatio = AppEnv::screenRatio(); -#ifndef Q_QS_ANDROID - resize(625 * screenRatio, 500 * screenRatio); -#endif - ui->vlUserInterface->setSpacing(6 * screenRatio); - ui->vlUserInterface->setContentsMargins(9 * screenRatio, 9 * screenRatio, 9 * screenRatio, 9 * screenRatio); -} - -void UserInterface::setupDirEnv(bool showFolderDialog) -{ - // settings init - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - - bool folderExists; - GTAV_Folder = AppEnv::getGameFolder(&folderExists); - if (folderExists) { - QDir::setCurrent(GTAV_Folder); - } - else if (showFolderDialog) { - GTAV_Folder = QFileDialog::getExistingDirectory(this, tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly); - if (QDir(GTAV_Folder).exists()) { - folderExists = true; - QDir::setCurrent(GTAV_Folder); - AppEnv::setGameFolder(GTAV_Folder); - - // First time folder selection save - settings.beginGroup("dir"); - if (settings.value("dir", "").toString().isEmpty()) { - settings.setValue("dir", GTAV_Folder); - } - settings.endGroup(); - } - } - - // profiles init - settings.beginGroup("Profile"); - QString defaultProfile = settings.value("Default", "").toString(); - - contentMode = settings.value("ContentMode", 0).toInt(); - if (contentMode == 1) { - contentMode = 21; - } - else if (contentMode != 10 && contentMode != 11 && contentMode != 20 && contentMode != 21) { - contentMode = 20; - } - - if (folderExists) { - QDir GTAV_ProfilesDir; - GTAV_ProfilesFolder = GTAV_Folder % "/Profiles"; - GTAV_ProfilesDir.setPath(GTAV_ProfilesFolder); - - GTAV_Profiles = GTAV_ProfilesDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::NoSort); - setupProfileUi(); - - if (GTAV_Profiles.length() == 1) { - openProfile(GTAV_Profiles.at(0)); - } - else if(GTAV_Profiles.contains(defaultProfile)) { - openProfile(defaultProfile); - } - } - else { - GTAV_Profiles = QStringList(); - setupProfileUi(); - } - settings.endGroup(); -} - -void UserInterface::setupProfileUi() -{ - qreal screenRatio = AppEnv::screenRatio(); - if (GTAV_Profiles.isEmpty()) { - QPushButton *changeDirBtn = new QPushButton(tr("Select >A V Folder..."), ui->swSelection); - changeDirBtn->setObjectName("cmdChangeDir"); - changeDirBtn->setMinimumSize(0, 40 * screenRatio); - changeDirBtn->setAutoDefault(true); - ui->vlButtons->addWidget(changeDirBtn); - profileBtns += changeDirBtn; - - QObject::connect(changeDirBtn, SIGNAL(clicked(bool)), this, SLOT(changeFolder_clicked())); - } - else for (const QString >AV_Profile : GTAV_Profiles) { - QPushButton *profileBtn = new QPushButton(GTAV_Profile, ui->swSelection); - profileBtn->setObjectName(GTAV_Profile); - profileBtn->setMinimumSize(0, 40 * screenRatio); - profileBtn->setAutoDefault(true); - ui->vlButtons->addWidget(profileBtn); - profileBtns += profileBtn; - - QObject::connect(profileBtn, SIGNAL(clicked(bool)), this, SLOT(profileButton_clicked())); - } - profileBtns.at(0)->setFocus(); -} - -void UserInterface::changeFolder_clicked() -{ - on_actionSelect_GTA_Folder_triggered(); -} - -void UserInterface::on_cmdReload_clicked() -{ - for (QPushButton *profileBtn : profileBtns) { - ui->vlButtons->removeWidget(profileBtn); - delete profileBtn; - } - profileBtns.clear(); - setupDirEnv(); -} - -void UserInterface::profileButton_clicked() -{ - QPushButton *profileBtn = (QPushButton*)sender(); - openProfile(profileBtn->objectName()); -} - -void UserInterface::openProfile(const QString &profileName_) -{ - profileOpen = true; - profileName = profileName_; - profileUI = new ProfileInterface(profileDB, crewDB, threadDB); - ui->swProfile->addWidget(profileUI); - ui->swProfile->setCurrentWidget(profileUI); - profileUI->setProfileFolder(GTAV_ProfilesFolder % QDir::separator() % profileName, profileName); - profileUI->settingsApplied(contentMode, false); - profileUI->setupProfileInterface(); - QObject::connect(profileUI, SIGNAL(profileClosed()), this, SLOT(closeProfile())); - QObject::connect(profileUI, SIGNAL(profileLoaded()), this, SLOT(profileLoaded())); - setWindowTitle(defaultWindowTitle.arg(profileName)); -} - -void UserInterface::closeProfile() -{ - if (profileOpen) { - closeProfile_p(); - } - setWindowTitle(defaultWindowTitle.arg(tr("Select Profile"))); -} - -void UserInterface::closeProfile_p() -{ - profileOpen = false; - profileName.clear(); - profileName.squeeze(); - ui->menuProfile->setEnabled(false); - ui->actionSelect_profile->setEnabled(false); - ui->swProfile->removeWidget(profileUI); - profileUI->disconnect(); - delete profileUI; -} - -void UserInterface::closeEvent(QCloseEvent *ev) -{ - Q_UNUSED(ev) -#ifdef GTA5SYNC_MOTD - threadMessage->terminateThread(); -#else - threadDB->terminateThread(); -#endif -} - -UserInterface::~UserInterface() -{ - if (profileOpen) - closeProfile_p(); - for (QPushButton *profileBtn : profileBtns) { - delete profileBtn; - } - profileBtns.clear(); - delete ui; -} - -void UserInterface::on_actionExit_triggered() -{ - close(); -} - -void UserInterface::on_actionSelect_profile_triggered() -{ - closeProfile(); - openSelectProfile(); -} - -void UserInterface::openSelectProfile() -{ - // not needed right now -} - -void UserInterface::on_actionAbout_gta5sync_triggered() -{ - AboutDialog *aboutDialog = new AboutDialog(this); - aboutDialog->setWindowIcon(windowIcon()); - aboutDialog->setModal(true); -#ifdef Q_OS_ANDROID - // Android ... - aboutDialog->showMaximized(); -#else - aboutDialog->show(); -#endif - aboutDialog->exec(); - delete aboutDialog; -} - -void UserInterface::profileLoaded() -{ - ui->menuProfile->setEnabled(true); - ui->actionSelect_profile->setEnabled(true); -} - -void UserInterface::on_actionSelect_all_triggered() -{ - if (profileOpen) - profileUI->selectAllWidgets(); -} - -void UserInterface::on_actionDeselect_all_triggered() -{ - if (profileOpen) - profileUI->deselectAllWidgets(); -} - -void UserInterface::on_actionExport_selected_triggered() -{ - if (profileOpen) - profileUI->exportSelected(); -} - -void UserInterface::on_actionDelete_selected_triggered() -{ - if (profileOpen) - profileUI->deleteSelected(); -} - -void UserInterface::on_actionOptions_triggered() -{ - OptionsDialog *optionsDialog = new OptionsDialog(profileDB, this); - optionsDialog->setWindowIcon(windowIcon()); - optionsDialog->commitProfiles(GTAV_Profiles); - QObject::connect(optionsDialog, SIGNAL(settingsApplied(int, bool)), this, SLOT(settingsApplied(int, bool))); - - optionsDialog->setModal(true); -#ifdef Q_OS_ANDROID - // Android ... - optionsDialog->showMaximized(); -#else - optionsDialog->show(); -#endif - optionsDialog->exec(); - - delete optionsDialog; -} - -void UserInterface::on_action_Import_triggered() -{ - if (profileOpen) - profileUI->importFiles(); -} - -void UserInterface::on_actionOpen_File_triggered() -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("FileDialogs"); - -fileDialogPreOpen: - QFileDialog fileDialog(this); - fileDialog.setFileMode(QFileDialog::ExistingFiles); - fileDialog.setViewMode(QFileDialog::Detail); - fileDialog.setAcceptMode(QFileDialog::AcceptOpen); - fileDialog.setOption(QFileDialog::DontUseNativeDialog, false); -#if QT_VERSION >= 0x050900 - fileDialog.setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - fileDialog.setWindowTitle(tr("Open File...")); - - QStringList filters; - filters << ProfileInterface::tr("All profile files (*.g5e SGTA* PGTA*)"); - filters << ProfileInterface::tr("GTA V Export (*.g5e)"); - filters << ProfileInterface::tr("Savegames files (SGTA*)"); - filters << ProfileInterface::tr("Snapmatic pictures (PGTA*)"); - filters << ProfileInterface::tr("All files (**)"); - fileDialog.setNameFilters(filters); - - QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); - - fileDialog.setSidebarUrls(sidebarUrls); - fileDialog.setDirectory(settings.value("OpenDialogDirectory", StandardPaths::documentsLocation()).toString()); - fileDialog.restoreGeometry(settings.value("OpenDialogGeometry","").toByteArray()); - - if (fileDialog.exec()) { - QStringList selectedFiles = fileDialog.selectedFiles(); - if (selectedFiles.length() == 1) { - QString selectedFile = selectedFiles.at(0); - if (!openFile(selectedFile, true)) goto fileDialogPreOpen; - } - } - - settings.setValue("OpenDialogGeometry", fileDialog.saveGeometry()); - settings.setValue("OpenDialogDirectory", fileDialog.directory().absolutePath()); - settings.endGroup(); -} - -bool UserInterface::openFile(QString selectedFile, bool warn) -{ - QString selectedFileName = QFileInfo(selectedFile).fileName(); - if (QFile::exists(selectedFile)) { - if (selectedFileName.left(4) == "PGTA" || selectedFileName.right(4) == ".g5e") { - SnapmaticPicture *picture = new SnapmaticPicture(selectedFile); - if (picture->readingPicture()) { - openSnapmaticFile(picture); - delete picture; - return true; - } - else { - if (warn) - QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Snapmatic picture")); - delete picture; - return false; - } - } - else if (selectedFileName.left(4) == "SGTA") { - SavegameData *savegame = new SavegameData(selectedFile); - if (savegame->readingSavegame()) { - openSavegameFile(savegame); - delete savegame; - return true; - } - else { - if (warn) - QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Savegame file")); - delete savegame; - return false; - } - } - else { - SnapmaticPicture *picture = new SnapmaticPicture(selectedFile); - SavegameData *savegame = new SavegameData(selectedFile); - if (picture->readingPicture()) { - delete savegame; - openSnapmaticFile(picture); - delete picture; - return true; - } - else if (savegame->readingSavegame()) { - delete picture; - openSavegameFile(savegame); - delete savegame; - return true; - } - else { - delete savegame; - delete picture; - if (warn) - QMessageBox::warning(this, tr("Open File"), tr("Can't open %1 because of not valid file format").arg("\""+selectedFileName+"\"")); - return false; - } - } - } - if (warn) - QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("No valid file is selected")); - return false; -} - -void UserInterface::openSnapmaticFile(SnapmaticPicture *picture) -{ - PictureDialog picDialog(profileDB, crewDB, this); - picDialog.setSnapmaticPicture(picture, true); - picDialog.setModal(true); - - int crewID = picture->getSnapmaticProperties().crewID; - if (crewID != 0) - crewDB->addCrew(crewID); - - QObject::connect(threadDB, SIGNAL(crewNameUpdated()), &picDialog, SLOT(crewNameUpdated())); - QObject::connect(threadDB, SIGNAL(playerNameUpdated()), &picDialog, SLOT(playerNameUpdated())); - -#ifdef Q_OS_ANDROID - // Android optimization should be put here - picDialog.showMaximized(); -#else - picDialog.show(); - picDialog.setMinimumSize(picDialog.size()); - picDialog.setMaximumSize(picDialog.size()); -#endif - - picDialog.exec(); -} - -void UserInterface::openSavegameFile(SavegameData *savegame) -{ - SavegameDialog sgdDialog(this); - sgdDialog.setSavegameData(savegame, savegame->getSavegameFileName(), true); - sgdDialog.setModal(true); -#ifdef Q_OS_ANDROID - // Android optimization should be put here - sgdDialog.showMaximized(); -#else - sgdDialog.show(); -#endif - sgdDialog.exec(); -} - -void UserInterface::settingsApplied(int _contentMode, bool languageChanged) -{ - if (languageChanged) { - retranslateUi(); - } - contentMode = _contentMode; - if (profileOpen) { - profileUI->settingsApplied(contentMode, languageChanged); - } -} - -#ifdef GTA5SYNC_MOTD -void UserInterface::messagesArrived(const QJsonObject &object) -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Messages"); - QJsonObject::const_iterator it = object.constBegin(); - QJsonObject::const_iterator end = object.constEnd(); - QStringList messages; - while (it != end) { - const QString key = it.key(); - const QJsonValue value = it.value(); - bool uintOk; - uint messageId = key.toUInt(&uintOk); - if (uintOk && value.isString()) { - const QString valueStr = value.toString(); - settings.setValue(QString::number(messageId), valueStr); - messages << valueStr; - } - it++; - } - settings.endGroup(); - if (!messages.isEmpty()) - showMessages(messages); -} - -void UserInterface::showMessages(const QStringList messages) -{ - QDialog *messageDialog = new QDialog(this); - messageDialog->setWindowTitle(tr("%1 - Messages").arg(GTA5SYNC_APPSTR)); -#if QT_VERSION >= 0x050900 - messageDialog->setWindowFlag(Qt::WindowContextHelpButtonHint, false); -#else - messageDialog->setWindowFlags(messageDialog->windowFlags()^Qt::WindowContextHelpButtonHint); -#endif - QVBoxLayout *messageLayout = new QVBoxLayout; - messageDialog->setLayout(messageLayout); - QStackedWidget *stackWidget = new QStackedWidget(messageDialog); - for (const QString message : messages) { - QLabel *messageLabel = new QLabel(messageDialog); - messageLabel->setText(message); - messageLabel->setWordWrap(true); - stackWidget->addWidget(messageLabel); - } - messageLayout->addWidget(stackWidget); - QHBoxLayout *buttonLayout = new QHBoxLayout; - QPushButton *backButton = new QPushButton(messageDialog); - QPushButton *nextButton = new QPushButton(messageDialog); - if (QIcon::hasThemeIcon("go-previous") && QIcon::hasThemeIcon("go-next") && QIcon::hasThemeIcon("list-add")) { - backButton->setIcon(QIcon::fromTheme("go-previous")); - nextButton->setIcon(QIcon::fromTheme("go-next")); - } - else { - backButton->setIcon(QIcon(AppEnv::getImagesFolder() % "/back.svgz")); - nextButton->setIcon(QIcon(AppEnv::getImagesFolder() % "/next.svgz")); - } - backButton->setEnabled(false); - if (stackWidget->count() <= 1) { - nextButton->setEnabled(false); - } - buttonLayout->addWidget(backButton); - buttonLayout->addWidget(nextButton); - buttonLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); - QPushButton *closeButton = new QPushButton(messageDialog); - closeButton->setText(tr("&Close")); - if (QIcon::hasThemeIcon("dialog-close")) { - closeButton->setIcon(QIcon::fromTheme("dialog-close")); - } - else if (QIcon::hasThemeIcon("gtk-close")) { - closeButton->setIcon(QIcon::fromTheme("gtk-close")); - } - buttonLayout->addWidget(closeButton); - messageLayout->addLayout(buttonLayout); - QObject::connect(backButton, &QPushButton::clicked, [stackWidget,backButton,nextButton,closeButton]() { - int index = stackWidget->currentIndex(); - if (index > 0) { - index--; - stackWidget->setCurrentIndex(index); - nextButton->setEnabled(true); - if (index > 0) { - backButton->setEnabled(true); - } - else { - backButton->setEnabled(false); - closeButton->setFocus(); - } - } - }); - QObject::connect(nextButton, &QPushButton::clicked, [stackWidget,backButton,nextButton,closeButton]() { - int index = stackWidget->currentIndex(); - if (index < stackWidget->count()-1) { - index++; - stackWidget->setCurrentIndex(index); - backButton->setEnabled(true); - if (index < stackWidget->count()-1) { - nextButton->setEnabled(true); - } - else { - nextButton->setEnabled(false); - closeButton->setFocus(); - } - } - }); - QObject::connect(closeButton, &QPushButton::clicked, messageDialog, &QDialog::accept); - QObject::connect(messageDialog, &QDialog::finished, messageDialog, &QDialog::deleteLater); - QTimer::singleShot(0, closeButton, [=](){ - closeButton->setFocus(); - }); - messageDialog->show(); -} - -void UserInterface::updateCacheId(uint cacheId) -{ - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Messages"); - settings.setValue("CacheId", cacheId); - settings.endGroup(); -} -#endif - -void UserInterface::on_actionSelect_GTA_Folder_triggered() -{ - QString GTAV_Folder_Temp = QFileDialog::getExistingDirectory(this, tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly); - if (QDir(GTAV_Folder_Temp).exists()) { - if (profileOpen) { - closeProfile_p(); - } - GTAV_Folder = GTAV_Folder_Temp; - QDir::setCurrent(GTAV_Folder); - AppEnv::setGameFolder(GTAV_Folder); - on_cmdReload_clicked(); - } -} - -void UserInterface::on_action_Enable_In_game_triggered() -{ - if (profileOpen) - profileUI->enableSelected(); -} - -void UserInterface::on_action_Disable_In_game_triggered() -{ - if (profileOpen) - profileUI->disableSelected(); -} - -void UserInterface::retranslateUi() -{ - ui->retranslateUi(this); -#ifdef GTA5SYNC_DONATE -#ifdef GTA5SYNC_DONATE_ADDRESSES - donateAction->setText(tr("&Donate")); -#endif -#endif -#ifdef Q_OS_MAC - ui->actionAbout_gta5sync->setText(QApplication::translate("MAC_APPLICATION_MENU", "About %1").arg(GTA5SYNC_APPSTR)); - ui->actionOptions->setText(QApplication::translate("MAC_APPLICATION_MENU", "Preferences...")); -#else - ui->actionAbout_gta5sync->setText(tr("&About %1").arg(GTA5SYNC_APPSTR)); -#endif - QString appVersion = QApplication::applicationVersion(); - const char* literalBuildType = GTA5SYNC_BUILDTYPE; -#ifdef GTA5SYNC_COMMIT - if ((strcmp(literalBuildType, REL_BUILDTYPE) != 0) && !appVersion.contains("-")) - appVersion = appVersion % "-" % GTA5SYNC_COMMIT; -#endif - ui->labVersion->setText(QString("%1 %2").arg(GTA5SYNC_APPSTR, appVersion)); - if (profileOpen) { - setWindowTitle(defaultWindowTitle.arg(profileName)); - } - else { - setWindowTitle(defaultWindowTitle.arg(tr("Select Profile"))); - } -} - -void UserInterface::on_actionQualify_as_Avatar_triggered() -{ - profileUI->massTool(MassTool::Qualify); -} - -void UserInterface::on_actionChange_Players_triggered() -{ - profileUI->massTool(MassTool::Players); -} - -void UserInterface::on_actionSet_Crew_triggered() -{ - profileUI->massTool(MassTool::Crew); -} - -void UserInterface::on_actionSet_Title_triggered() -{ - profileUI->massTool(MassTool::Title); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "UserInterface.h" +#include "ui_UserInterface.h" +#include "ProfileInterface.h" +#include "SnapmaticPicture.h" +#include "SidebarGenerator.h" +#include "SavegameDialog.h" +#include "StandardPaths.h" +#include "OptionsDialog.h" +#include "PictureDialog.h" +#include "SavegameData.h" +#include "AboutDialog.h" +#include "IconLoader.h" +#include "AppEnv.h" +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +UserInterface::UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent) : + QMainWindow(parent), profileDB(profileDB), crewDB(crewDB), threadDB(threadDB), + ui(new Ui::UserInterface) +{ + ui->setupUi(this); + contentMode = 0; + profileOpen = 0; + profileUI = 0; + ui->menuProfile->setEnabled(false); + ui->actionSelect_profile->setEnabled(false); + ui->actionAbout_gta5sync->setIcon(IconLoader::loadingAppIcon()); + defaultWindowTitle = tr("%2 - %1").arg("%1", GTA5SYNC_APPSTR); + + this->setWindowTitle(defaultWindowTitle.arg(tr("Select Profile"))); + ui->labVersion->setText(ui->labVersion->text().arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER)); +} + +void UserInterface::setupDirEnv() +{ + bool folderExists; + GTAV_Folder = AppEnv::getGameFolder(&folderExists); + if (folderExists) + { + QDir::setCurrent(GTAV_Folder); + } + else + { + GTAV_Folder = QFileDialog::getExistingDirectory(this, tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly); + if (QFileInfo(GTAV_Folder).exists()) + { + folderExists = true; + QDir::setCurrent(GTAV_Folder); + AppEnv::setGameFolder(GTAV_Folder); + } + } + + // profiles init + QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + settings.beginGroup("Profile"); + QString defaultProfile = settings.value("Default", "").toString(); + + bool contentModeOk; + contentMode = settings.value("ContentMode", 0).toInt(&contentModeOk); + if (contentMode != 0 && contentMode != 1 && contentMode != 2) + { + contentMode = 0; + } + + if (folderExists) + { + QDir GTAV_ProfilesDir; + GTAV_ProfilesFolder = GTAV_Folder + QDir::separator() + "Profiles"; + GTAV_ProfilesDir.setPath(GTAV_ProfilesFolder); + + GTAV_Profiles = GTAV_ProfilesDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::NoSort); + setupProfileUi(); + + if (GTAV_Profiles.length() == 1) + { + openProfile(GTAV_Profiles.at(0)); + } + else if(GTAV_Profiles.contains(defaultProfile)) + { + openProfile(defaultProfile); + } + } + else + { + GTAV_Profiles = QStringList(); + setupProfileUi(); + } + settings.endGroup(); +} + +void UserInterface::setupProfileUi() +{ + if (GTAV_Profiles.length() == 0) + { + QPushButton *changeDirBtn = new QPushButton(tr("Select >A V Folder..."), ui->swSelection); + changeDirBtn->setObjectName("cmdChangeDir"); + changeDirBtn->setMinimumSize(0, 40); + changeDirBtn->setAutoDefault(true); + ui->vlButtons->addWidget(changeDirBtn); + profileBtns.append(changeDirBtn); + + QObject::connect(changeDirBtn, SIGNAL(clicked(bool)), this, SLOT(changeFolder_clicked())); + } + else foreach(const QString >AV_Profile, GTAV_Profiles) + { + QPushButton *profileBtn = new QPushButton(GTAV_Profile, ui->swSelection); + profileBtn->setObjectName(GTAV_Profile); + profileBtn->setMinimumSize(0, 40); + profileBtn->setAutoDefault(true); + ui->vlButtons->addWidget(profileBtn); + profileBtns.append(profileBtn); + + QObject::connect(profileBtn, SIGNAL(clicked(bool)), this, SLOT(profileButton_clicked())); + } + profileBtns.at(0)->setFocus(); +} + +void UserInterface::changeFolder_clicked() +{ + on_actionSelect_GTA_Folder_triggered(); +} + +void UserInterface::on_cmdReload_clicked() +{ + foreach(QPushButton *profileBtn, profileBtns) + { + ui->vlButtons->removeWidget(profileBtn); + profileBtns.removeAll(profileBtn); + delete profileBtn; + } + setupDirEnv(); +} + +void UserInterface::profileButton_clicked() +{ + QPushButton *profileBtn = (QPushButton*)sender(); + openProfile(profileBtn->objectName()); +} + +void UserInterface::openProfile(QString profileName) +{ + profileOpen = true; + profileUI = new ProfileInterface(profileDB, crewDB, threadDB); + ui->swProfile->addWidget(profileUI); + ui->swProfile->setCurrentWidget(profileUI); + profileUI->setProfileFolder(GTAV_ProfilesFolder + QDir::separator() + profileName, profileName); + profileUI->settingsApplied(contentMode, language); + profileUI->setupProfileInterface(); + QObject::connect(profileUI, SIGNAL(profileClosed()), this, SLOT(closeProfile())); + QObject::connect(profileUI, SIGNAL(profileLoaded()), this, SLOT(profileLoaded())); + this->setWindowTitle(defaultWindowTitle.arg(profileName)); +} + +void UserInterface::closeProfile() +{ + if (profileOpen) + { + profileOpen = false; + ui->menuProfile->setEnabled(false); + ui->actionSelect_profile->setEnabled(false); + ui->swProfile->removeWidget(profileUI); + profileUI->deleteLater(); + delete profileUI; + } + this->setWindowTitle(defaultWindowTitle.arg(tr("Select Profile"))); +} + +UserInterface::~UserInterface() +{ + foreach (QPushButton *profileBtn, profileBtns) + { + delete profileBtn; + } + delete ui; +} + +void UserInterface::on_actionExit_triggered() +{ + this->close(); +} + +void UserInterface::on_actionSelect_profile_triggered() +{ + closeProfile(); + openSelectProfile(); +} + +void UserInterface::openSelectProfile() +{ + // not needed right now +} + +void UserInterface::on_actionAbout_gta5sync_triggered() +{ + AboutDialog *aboutDialog = new AboutDialog(this); + aboutDialog->setWindowFlags(aboutDialog->windowFlags()^Qt::WindowContextHelpButtonHint); + aboutDialog->setModal(true); + aboutDialog->show(); + aboutDialog->exec(); + aboutDialog->deleteLater(); + delete aboutDialog; +} + +void UserInterface::profileLoaded() +{ + ui->menuProfile->setEnabled(true); + ui->actionSelect_profile->setEnabled(true); +} + +void UserInterface::on_actionSelect_all_triggered() +{ + if (profileOpen) + { + profileUI->selectAllWidgets(); + } +} + +void UserInterface::on_actionDeselect_all_triggered() +{ + if (profileOpen) + { + profileUI->deselectAllWidgets(); + } +} + +void UserInterface::on_actionExport_selected_triggered() +{ + if (profileOpen) + { + profileUI->exportSelected(); + } +} + +void UserInterface::on_actionDelete_selected_triggered() +{ + if (profileOpen) + { + profileUI->deleteSelected(); + } +} + +void UserInterface::on_actionOptions_triggered() +{ + OptionsDialog *optionsDialog = new OptionsDialog(profileDB, this); + optionsDialog->setWindowFlags(optionsDialog->windowFlags()^Qt::WindowContextHelpButtonHint); + optionsDialog->commitProfiles(GTAV_Profiles); + QObject::connect(optionsDialog, SIGNAL(settingsApplied(int,QString)), this, SLOT(settingsApplied(int,QString))); + + optionsDialog->setModal(true); + optionsDialog->show(); + optionsDialog->exec(); + delete optionsDialog; +} + +void UserInterface::on_action_Import_triggered() +{ + if (profileOpen) + { + profileUI->importFiles(); + } +} + +void UserInterface::on_actionOpen_File_triggered() +{ + QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + settings.beginGroup("FileDialogs"); + +fileDialogPreOpen: + QFileDialog fileDialog(this); + fileDialog.setFileMode(QFileDialog::ExistingFiles); + fileDialog.setViewMode(QFileDialog::Detail); + fileDialog.setAcceptMode(QFileDialog::AcceptOpen); + fileDialog.setOption(QFileDialog::DontUseNativeDialog, false); + fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint); + fileDialog.setWindowTitle(tr("Open File...")); + + QStringList filters; + filters << ProfileInterface::tr("All profile files (SGTA* PGTA*)"); + filters << ProfileInterface::tr("Savegames files (SGTA*)"); + filters << ProfileInterface::tr("Snapmatic pictures (PGTA*)"); + filters << ProfileInterface::tr("All files (**)"); + fileDialog.setNameFilters(filters); + + QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); + + fileDialog.setSidebarUrls(sidebarUrls); + fileDialog.setDirectory(settings.value("OpenDialogDirectory", StandardPaths::documentsLocation()).toString()); + fileDialog.restoreGeometry(settings.value("OpenDialogGeometry","").toByteArray()); + + if (fileDialog.exec()) + { + QStringList selectedFiles = fileDialog.selectedFiles(); + if (selectedFiles.length() == 1) + { + QString selectedFile = selectedFiles.at(0); + if (!openFile(selectedFile, true)) goto fileDialogPreOpen; + } + } + + settings.setValue("OpenDialogGeometry", fileDialog.saveGeometry()); + settings.setValue("OpenDialogDirectory", fileDialog.directory().absolutePath()); + settings.endGroup(); +} + +bool UserInterface::openFile(QString selectedFile, bool warn) +{ + QString selectedFileName = QFileInfo(selectedFile).fileName(); + if (QFile::exists(selectedFile)) + { + if (selectedFileName.left(4) == "PGTA") + { + SnapmaticPicture *picture = new SnapmaticPicture(selectedFile); + if (picture->readingPicture()) + { + openSnapmaticFile(picture); + delete picture; + return true; + } + else + { + if (warn) QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Snapmatic picture")); + delete picture; + return false; + } + } + else if (selectedFileName.left(4) == "SGTA") + { + SavegameData *savegame = new SavegameData(selectedFile); + if (savegame->readingSavegame()) + { + openSavegameFile(savegame); + delete savegame; + return true; + } + else + { + if (warn) QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Savegame file")); + delete savegame; + return false; + } + } + else + { + SnapmaticPicture *picture = new SnapmaticPicture(selectedFile); + SavegameData *savegame = new SavegameData(selectedFile); + if (picture->readingPicture()) + { + delete savegame; + openSnapmaticFile(picture); + delete picture; + return true; + } + else if (savegame->readingSavegame()) + { + delete picture; + openSavegameFile(savegame); + delete savegame; + return true; + } + else + { + delete savegame; + delete picture; + if (warn) QMessageBox::warning(this, tr("Open File"), tr("Can't open %1 because of not valid file format").arg("\""+selectedFileName+"\"")); + return false; + } + } + } + if (warn) QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("No valid file is selected")); + return false; +} + +void UserInterface::openSnapmaticFile(SnapmaticPicture *picture) +{ + PictureDialog *picDialog = new PictureDialog(profileDB, crewDB, this); + picDialog->setWindowFlags(picDialog->windowFlags()^Qt::WindowContextHelpButtonHint); + picDialog->setSnapmaticPicture(picture, true); + picDialog->setModal(true); + + int crewID = picture->getSnapmaticProperties().crewID; + if (crewID != 0) { crewDB->addCrew(crewID); } + + QObject::connect(threadDB, SIGNAL(playerNameFound(int, QString)), profileDB, SLOT(setPlayerName(int, QString))); + QObject::connect(threadDB, SIGNAL(playerNameUpdated()), picDialog, SLOT(playerNameUpdated())); + + picDialog->show(); + picDialog->setMinimumSize(picDialog->size()); + picDialog->setMaximumSize(picDialog->size()); + + picDialog->exec(); + delete picDialog; +} + +void UserInterface::openSavegameFile(SavegameData *savegame) +{ + SavegameDialog *sgdDialog = new SavegameDialog(this); + sgdDialog->setWindowFlags(sgdDialog->windowFlags()^Qt::WindowContextHelpButtonHint); + sgdDialog->setSavegameData(savegame, savegame->getSavegameFileName(), true); + sgdDialog->setModal(true); + + sgdDialog->show(); + sgdDialog->exec(); + delete sgdDialog; +} + +void UserInterface::settingsApplied(int _contentMode, QString _language) +{ + language = _language; + contentMode = _contentMode; + if (profileOpen) + { + profileUI->settingsApplied(contentMode, language); + } +} + +void UserInterface::on_actionSelect_GTA_Folder_triggered() +{ + QString GTAV_Folder_Temp = QFileDialog::getExistingDirectory(this, tr("Select GTA V Folder..."), StandardPaths::documentsLocation(), QFileDialog::ShowDirsOnly); + if (QFileInfo(GTAV_Folder_Temp).exists()) + { + GTAV_Folder = GTAV_Folder_Temp; + QDir::setCurrent(GTAV_Folder); + AppEnv::setGameFolder(GTAV_Folder); + on_cmdReload_clicked(); + } +} + +void UserInterface::on_action_Enable_In_game_triggered() +{ + if (profileOpen) + { + profileUI->enableSelected(); + } +} + +void UserInterface::on_action_Disable_In_game_triggered() +{ + if (profileOpen) + { + profileUI->disableSelected(); + } +} diff --git a/UserInterface.h b/UserInterface.h old mode 100644 new mode 100755 index 12abc90..9f9a74a --- a/UserInterface.h +++ b/UserInterface.h @@ -1,122 +1,89 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef USERINTERFACE_H -#define USERINTERFACE_H - -#include "SnapmaticPicture.h" -#include "ProfileInterface.h" -#include "ProfileDatabase.h" -#include "DatabaseThread.h" -#include "CrewDatabase.h" -#include "SavegameData.h" -#include -#include -#include -#include -#include - -#ifdef GTA5SYNC_MOTD -#include "MessageThread.h" -#endif - -namespace Ui { -class UserInterface; -} - -class UserInterface : public QMainWindow -{ - Q_OBJECT -public: -#ifdef GTA5SYNC_MOTD - explicit UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, MessageThread *messageThread, QWidget *parent = 0); -#else - explicit UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent = 0); -#endif - void setupDirEnv(bool showFolderDialog = true); - ~UserInterface(); - -private slots: - void closeProfile(); - void profileLoaded(); - void changeFolder_clicked(); - void profileButton_clicked(); - void on_cmdReload_clicked(); - void on_actionExit_triggered(); - void on_actionSelect_profile_triggered(); - void on_actionAbout_gta5sync_triggered(); - void on_actionSelect_all_triggered(); - void on_actionDeselect_all_triggered(); - void on_actionExport_selected_triggered(); - void on_actionDelete_selected_triggered(); - void on_actionOptions_triggered(); - void on_action_Import_triggered(); - void on_actionOpen_File_triggered(); - void on_actionSelect_GTA_Folder_triggered(); - void on_action_Enable_In_game_triggered(); - void on_action_Disable_In_game_triggered(); - void on_actionQualify_as_Avatar_triggered(); - void on_actionChange_Players_triggered(); - void on_actionSet_Crew_triggered(); - void on_actionSet_Title_triggered(); - void settingsApplied(int contentMode, bool languageChanged); -#ifdef GTA5SYNC_MOTD - void messagesArrived(const QJsonObject &object); - void showMessages(const QStringList messages); - void updateCacheId(uint cacheId); -#endif - -protected: - void closeEvent(QCloseEvent *ev); - -private: - ProfileDatabase *profileDB; - CrewDatabase *crewDB; - DatabaseThread *threadDB; -#ifdef GTA5SYNC_MOTD - MessageThread *threadMessage; -#endif -#ifdef GTA5SYNC_DONATE -#ifdef GTA5SYNC_DONATE_ADDRESSES - QAction *donateAction; -#endif -#endif - Ui::UserInterface *ui; - ProfileInterface *profileUI; - QList profileBtns; - QString profileName; - bool profileOpen; - int contentMode; - QString language; - QString defaultWindowTitle; - QString GTAV_Folder; - QString GTAV_ProfilesFolder; - QStringList GTAV_Profiles; - void setupProfileUi(); - void openProfile(const QString &profileName); - void closeProfile_p(); - void openSelectProfile(); - void retranslateUi(); - - // Open File - bool openFile(QString selectedFile, bool warn = true); - void openSavegameFile(SavegameData *savegame); - void openSnapmaticFile(SnapmaticPicture *picture); -}; - -#endif // USERINTERFACE_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef USERINTERFACE_H +#define USERINTERFACE_H + +#include "SnapmaticPicture.h" +#include "ProfileInterface.h" +#include "ProfileDatabase.h" +#include "DatabaseThread.h" +#include "CrewDatabase.h" +#include "SavegameData.h" +#include +#include +#include + +namespace Ui { +class UserInterface; +} + +class UserInterface : public QMainWindow +{ + Q_OBJECT +public: + explicit UserInterface(ProfileDatabase *profileDB, CrewDatabase *crewDB, DatabaseThread *threadDB, QWidget *parent = 0); + void setupDirEnv(); + ~UserInterface(); + +private slots: + void closeProfile(); + void profileLoaded(); + void changeFolder_clicked(); + void profileButton_clicked(); + void on_cmdReload_clicked(); + void on_actionExit_triggered(); + void on_actionSelect_profile_triggered(); + void on_actionAbout_gta5sync_triggered(); + void on_actionSelect_all_triggered(); + void on_actionDeselect_all_triggered(); + void on_actionExport_selected_triggered(); + void on_actionDelete_selected_triggered(); + void on_actionOptions_triggered(); + void on_action_Import_triggered(); + void on_actionOpen_File_triggered(); + void on_actionSelect_GTA_Folder_triggered(); + void on_action_Enable_In_game_triggered(); + void on_action_Disable_In_game_triggered(); + void settingsApplied(int contentMode, QString language); + +private: + ProfileDatabase *profileDB; + CrewDatabase *crewDB; + DatabaseThread *threadDB; + Ui::UserInterface *ui; + ProfileInterface *profileUI; + QList profileBtns; + bool profileOpen; + int contentMode; + QString language; + QString defaultWindowTitle; + QString GTAV_Folder; + QString GTAV_ProfilesFolder; + QStringList GTAV_Profiles; + void setupProfileUi(); + void openProfile(QString profileName); + void openSelectProfile(); + + // Open File + bool openFile(QString selectedFile, bool warn = true); + void openSavegameFile(SavegameData *savegame); + void openSnapmaticFile(SnapmaticPicture *picture); +}; + +#endif // USERINTERFACE_H diff --git a/UserInterface.ui b/UserInterface.ui old mode 100644 new mode 100755 index 7927dcc..b2f835f --- a/UserInterface.ui +++ b/UserInterface.ui @@ -1,396 +1,359 @@ - - - UserInterface - - - - 0 - 0 - 625 - 500 - - - - - 625 - 500 - - - - %2 - %1 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - 6 - - - 9 - - - 9 - - - 9 - - - 9 - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - Select profile - - - Qt::AlignCenter - - - true - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - %1 %2 - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Reload profile overview - - - &Reload - - - true - - - - - - - - 0 - 0 - - - - Close %1 - - - &Close - - - true - - - - - - - - - - - - - - - 0 - 0 - 625 - 23 - - - - - &File - - - - - - - - - - &Help - - - - - - &Edit - - - - - - &Profile - - - - &Selection visibility - - - - - - - Selection &mass tools - - - - - - - - - - - - - - - - - - - - - - - - &About %1 - - - Ctrl+P - - - - - &Exit - - - Exit - - - Ctrl+Q - - - - - Close &Profile - - - Ctrl+End - - - - - &Settings - - - Ctrl+S - - - - - Select &All - - - Ctrl+A - - - - - &Deselect All - - - Ctrl+D - - - - - &Export selected... - - - Ctrl+E - - - - - &Remove selected - - - Ctrl+Del - - - - - &Import files... - - - Ctrl+I - - - - - &Open File... - - - Ctrl+O - - - - - Select &GTA V Folder... - - - Select GTA V Folder... - - - Ctrl+G - - - - - Show In-gam&e - - - Shift+E - - - - - Hi&de In-game - - - Shift+D - - - - - Change &Title... - - - Shift+T - - - - - Change &Crew... - - - Shift+C - - - - - &Qualify as Avatar - - - Shift+Q - - - - - Change &Players... - - - Shift+P - - - - - - - cmdClose - clicked() - UserInterface - close() - - - 572 - 476 - - - 312 - 249 - - - - - + + + UserInterface + + + + 0 + 0 + 625 + 500 + + + + + 625 + 500 + + + + gta5view - %1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + Select profile + + + Qt::AlignCenter + + + true + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + %1 %2 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + &Reload + + + true + + + + + + + + 0 + 0 + + + + &Close + + + + + + true + + + + + + + + + + + + + + + 0 + 0 + 625 + 21 + + + + + &File + + + + + + + + + + &Help + + + + + + &Edit + + + + + + &Profile + + + + &Selection visibility + + + + + + + + + + + + + + + + + + + + + &About gta5view + + + Ctrl+P + + + + + + .. + + + &Exit + + + Exit + + + Ctrl+Q + + + + + Close &Profile + + + Ctrl+End + + + + + + .. + + + &Settings + + + Ctrl+S + + + + + Select &All + + + Ctrl+A + + + + + &Deselect All + + + Ctrl+D + + + + + &Export selected... + + + Ctrl+E + + + + + &Remove selected + + + Ctrl+Del + + + + + &Import files... + + + Ctrl+I + + + + + &Open File... + + + Ctrl+O + + + + + Select &GTA V Folder... + + + Select GTA V Folder... + + + Ctrl+G + + + + + Show In-gam&e + + + Shift+E + + + + + Hi&de In-game + + + Shift+D + + + + + + + cmdClose + clicked() + UserInterface + close() + + + 572 + 476 + + + 312 + 249 + + + + + diff --git a/anpro/QrCode.cpp b/anpro/QrCode.cpp deleted file mode 100644 index 6d67ee9..0000000 --- a/anpro/QrCode.cpp +++ /dev/null @@ -1,862 +0,0 @@ -/* - * QR Code generator library (C++) - * - * Copyright (c) Project Nayuki. (MIT License) - * https://www.nayuki.io/page/qr-code-generator-library - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "QrCode.h" - -using std::int8_t; -using std::uint8_t; -using std::size_t; -using std::vector; - - -namespace qrcodegen { - -QrSegment::Mode::Mode(int mode, int cc0, int cc1, int cc2) : - modeBits(mode) { - numBitsCharCount[0] = cc0; - numBitsCharCount[1] = cc1; - numBitsCharCount[2] = cc2; -} - - -int QrSegment::Mode::getModeBits() const { - return modeBits; -} - - -int QrSegment::Mode::numCharCountBits(int ver) const { - return numBitsCharCount[(ver + 7) / 17]; -} - - -const QrSegment::Mode QrSegment::Mode::NUMERIC (0x1, 10, 12, 14); -const QrSegment::Mode QrSegment::Mode::ALPHANUMERIC(0x2, 9, 11, 13); -const QrSegment::Mode QrSegment::Mode::BYTE (0x4, 8, 16, 16); -const QrSegment::Mode QrSegment::Mode::KANJI (0x8, 8, 10, 12); -const QrSegment::Mode QrSegment::Mode::ECI (0x7, 0, 0, 0); - - -QrSegment QrSegment::makeBytes(const vector &data) { - if (data.size() > static_cast(INT_MAX)) - throw std::length_error("Data too long"); - BitBuffer bb; - for (uint8_t b : data) - bb.appendBits(b, 8); - return QrSegment(Mode::BYTE, static_cast(data.size()), std::move(bb)); -} - - -QrSegment QrSegment::makeNumeric(const char *digits) { - BitBuffer bb; - int accumData = 0; - int accumCount = 0; - int charCount = 0; - for (; *digits != '\0'; digits++, charCount++) { - char c = *digits; - if (c < '0' || c > '9') - throw std::domain_error("String contains non-numeric characters"); - accumData = accumData * 10 + (c - '0'); - accumCount++; - if (accumCount == 3) { - bb.appendBits(static_cast(accumData), 10); - accumData = 0; - accumCount = 0; - } - } - if (accumCount > 0) // 1 or 2 digits remaining - bb.appendBits(static_cast(accumData), accumCount * 3 + 1); - return QrSegment(Mode::NUMERIC, charCount, std::move(bb)); -} - - -QrSegment QrSegment::makeAlphanumeric(const char *text) { - BitBuffer bb; - int accumData = 0; - int accumCount = 0; - int charCount = 0; - for (; *text != '\0'; text++, charCount++) { - const char *temp = std::strchr(ALPHANUMERIC_CHARSET, *text); - if (temp == nullptr) - throw std::domain_error("String contains unencodable characters in alphanumeric mode"); - accumData = accumData * 45 + static_cast(temp - ALPHANUMERIC_CHARSET); - accumCount++; - if (accumCount == 2) { - bb.appendBits(static_cast(accumData), 11); - accumData = 0; - accumCount = 0; - } - } - if (accumCount > 0) // 1 character remaining - bb.appendBits(static_cast(accumData), 6); - return QrSegment(Mode::ALPHANUMERIC, charCount, std::move(bb)); -} - - -vector QrSegment::makeSegments(const char *text) { - // Select the most efficient segment encoding automatically - vector result; - if (*text == '\0'); // Leave result empty - else if (isNumeric(text)) - result.push_back(makeNumeric(text)); - else if (isAlphanumeric(text)) - result.push_back(makeAlphanumeric(text)); - else { - vector bytes; - for (; *text != '\0'; text++) - bytes.push_back(static_cast(*text)); - result.push_back(makeBytes(bytes)); - } - return result; -} - - -QrSegment QrSegment::makeEci(long assignVal) { - BitBuffer bb; - if (assignVal < 0) - throw std::domain_error("ECI assignment value out of range"); - else if (assignVal < (1 << 7)) - bb.appendBits(static_cast(assignVal), 8); - else if (assignVal < (1 << 14)) { - bb.appendBits(2, 2); - bb.appendBits(static_cast(assignVal), 14); - } else if (assignVal < 1000000L) { - bb.appendBits(6, 3); - bb.appendBits(static_cast(assignVal), 21); - } else - throw std::domain_error("ECI assignment value out of range"); - return QrSegment(Mode::ECI, 0, std::move(bb)); -} - - -QrSegment::QrSegment(Mode md, int numCh, const std::vector &dt) : - mode(md), - numChars(numCh), - data(dt) { - if (numCh < 0) - throw std::domain_error("Invalid value"); -} - - -QrSegment::QrSegment(Mode md, int numCh, std::vector &&dt) : - mode(md), - numChars(numCh), - data(std::move(dt)) { - if (numCh < 0) - throw std::domain_error("Invalid value"); -} - - -int QrSegment::getTotalBits(const vector &segs, int version) { - int result = 0; - for (const QrSegment &seg : segs) { - int ccbits = seg.mode.numCharCountBits(version); - if (seg.numChars >= (1L << ccbits)) - return -1; // The segment's length doesn't fit the field's bit width - if (4 + ccbits > INT_MAX - result) - return -1; // The sum will overflow an int type - result += 4 + ccbits; - if (seg.data.size() > static_cast(INT_MAX - result)) - return -1; // The sum will overflow an int type - result += static_cast(seg.data.size()); - } - return result; -} - - -bool QrSegment::isAlphanumeric(const char *text) { - for (; *text != '\0'; text++) { - if (std::strchr(ALPHANUMERIC_CHARSET, *text) == nullptr) - return false; - } - return true; -} - - -bool QrSegment::isNumeric(const char *text) { - for (; *text != '\0'; text++) { - char c = *text; - if (c < '0' || c > '9') - return false; - } - return true; -} - - -QrSegment::Mode QrSegment::getMode() const { - return mode; -} - - -int QrSegment::getNumChars() const { - return numChars; -} - - -const std::vector &QrSegment::getData() const { - return data; -} - - -const char *QrSegment::ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; - - - -int QrCode::getFormatBits(Ecc ecl) { - switch (ecl) { - case Ecc::LOW : return 1; - case Ecc::MEDIUM : return 0; - case Ecc::QUARTILE: return 3; - case Ecc::HIGH : return 2; - default: throw std::logic_error("Assertion error"); - } -} - - -QrCode QrCode::encodeText(const char *text, Ecc ecl) { - vector segs = QrSegment::makeSegments(text); - return encodeSegments(segs, ecl); -} - - -QrCode QrCode::encodeBinary(const vector &data, Ecc ecl) { - vector segs{QrSegment::makeBytes(data)}; - return encodeSegments(segs, ecl); -} - - -QrCode QrCode::encodeSegments(const vector &segs, Ecc ecl, - int minVersion, int maxVersion, int mask, bool boostEcl) { - if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7) - throw std::invalid_argument("Invalid value"); - - // Find the minimal version number to use - int version, dataUsedBits; - for (version = minVersion; ; version++) { - int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available - dataUsedBits = QrSegment::getTotalBits(segs, version); - if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) - break; // This version number is found to be suitable - if (version >= maxVersion) { // All versions in the range could not fit the given data - std::ostringstream sb; - if (dataUsedBits == -1) - sb << "Segment too long"; - else { - sb << "Data length = " << dataUsedBits << " bits, "; - sb << "Max capacity = " << dataCapacityBits << " bits"; - } - throw data_too_long(sb.str()); - } - } - if (dataUsedBits == -1) - throw std::logic_error("Assertion error"); - - // Increase the error correction level while the data still fits in the current version number - for (Ecc newEcl : vector{Ecc::MEDIUM, Ecc::QUARTILE, Ecc::HIGH}) { // From low to high - if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8) - ecl = newEcl; - } - - // Concatenate all segments to create the data bit string - BitBuffer bb; - for (const QrSegment &seg : segs) { - bb.appendBits(static_cast(seg.getMode().getModeBits()), 4); - bb.appendBits(static_cast(seg.getNumChars()), seg.getMode().numCharCountBits(version)); - bb.insert(bb.end(), seg.getData().begin(), seg.getData().end()); - } - if (bb.size() != static_cast(dataUsedBits)) - throw std::logic_error("Assertion error"); - - // Add terminator and pad up to a byte if applicable - size_t dataCapacityBits = static_cast(getNumDataCodewords(version, ecl)) * 8; - if (bb.size() > dataCapacityBits) - throw std::logic_error("Assertion error"); - bb.appendBits(0, std::min(4, static_cast(dataCapacityBits - bb.size()))); - bb.appendBits(0, (8 - static_cast(bb.size() % 8)) % 8); - if (bb.size() % 8 != 0) - throw std::logic_error("Assertion error"); - - // Pad with alternating bytes until data capacity is reached - for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11) - bb.appendBits(padByte, 8); - - // Pack bits into bytes in big endian - vector dataCodewords(bb.size() / 8); - for (size_t i = 0; i < bb.size(); i++) - dataCodewords[i >> 3] |= (bb.at(i) ? 1 : 0) << (7 - (i & 7)); - - // Create the QR Code object - return QrCode(version, ecl, dataCodewords, mask); -} - - -QrCode::QrCode(int ver, Ecc ecl, const vector &dataCodewords, int msk) : - // Initialize fields and check arguments - version(ver), - errorCorrectionLevel(ecl) { - if (ver < MIN_VERSION || ver > MAX_VERSION) - throw std::domain_error("Version value out of range"); - if (msk < -1 || msk > 7) - throw std::domain_error("Mask value out of range"); - size = ver * 4 + 17; - size_t sz = static_cast(size); - modules = vector >(sz, vector(sz)); // Initially all white - isFunction = vector >(sz, vector(sz)); - - // Compute ECC, draw modules - drawFunctionPatterns(); - const vector allCodewords = addEccAndInterleave(dataCodewords); - drawCodewords(allCodewords); - - // Do masking - if (msk == -1) { // Automatically choose best mask - long minPenalty = LONG_MAX; - for (int i = 0; i < 8; i++) { - applyMask(i); - drawFormatBits(i); - long penalty = getPenaltyScore(); - if (penalty < minPenalty) { - msk = i; - minPenalty = penalty; - } - applyMask(i); // Undoes the mask due to XOR - } - } - if (msk < 0 || msk > 7) - throw std::logic_error("Assertion error"); - this->mask = msk; - applyMask(msk); // Apply the final choice of mask - drawFormatBits(msk); // Overwrite old format bits - - isFunction.clear(); - isFunction.shrink_to_fit(); -} - - -int QrCode::getVersion() const { - return version; -} - - -int QrCode::getSize() const { - return size; -} - - -QrCode::Ecc QrCode::getErrorCorrectionLevel() const { - return errorCorrectionLevel; -} - - -int QrCode::getMask() const { - return mask; -} - - -bool QrCode::getModule(int x, int y) const { - return 0 <= x && x < size && 0 <= y && y < size && module(x, y); -} - - -std::string QrCode::toSvgString(int border) const { - if (border < 0) - throw std::domain_error("Border must be non-negative"); - if (border > INT_MAX / 2 || border * 2 > INT_MAX - size) - throw std::overflow_error("Border too large"); - - std::ostringstream sb; - sb << "\n"; - sb << "\n"; - sb << "\n"; - sb << "\t\n"; - sb << "\t\n"; - sb << "\n"; - return sb.str(); -} - - -void QrCode::drawFunctionPatterns() { - // Draw horizontal and vertical timing patterns - for (int i = 0; i < size; i++) { - setFunctionModule(6, i, i % 2 == 0); - setFunctionModule(i, 6, i % 2 == 0); - } - - // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) - drawFinderPattern(3, 3); - drawFinderPattern(size - 4, 3); - drawFinderPattern(3, size - 4); - - // Draw numerous alignment patterns - const vector alignPatPos = getAlignmentPatternPositions(); - size_t numAlign = alignPatPos.size(); - for (size_t i = 0; i < numAlign; i++) { - for (size_t j = 0; j < numAlign; j++) { - // Don't draw on the three finder corners - if (!((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0))) - drawAlignmentPattern(alignPatPos.at(i), alignPatPos.at(j)); - } - } - - // Draw configuration data - drawFormatBits(0); // Dummy mask value; overwritten later in the constructor - drawVersion(); -} - - -void QrCode::drawFormatBits(int msk) { - // Calculate error correction code and pack bits - int data = getFormatBits(errorCorrectionLevel) << 3 | msk; // errCorrLvl is uint2, msk is uint3 - int rem = data; - for (int i = 0; i < 10; i++) - rem = (rem << 1) ^ ((rem >> 9) * 0x537); - int bits = (data << 10 | rem) ^ 0x5412; // uint15 - if (bits >> 15 != 0) - throw std::logic_error("Assertion error"); - - // Draw first copy - for (int i = 0; i <= 5; i++) - setFunctionModule(8, i, getBit(bits, i)); - setFunctionModule(8, 7, getBit(bits, 6)); - setFunctionModule(8, 8, getBit(bits, 7)); - setFunctionModule(7, 8, getBit(bits, 8)); - for (int i = 9; i < 15; i++) - setFunctionModule(14 - i, 8, getBit(bits, i)); - - // Draw second copy - for (int i = 0; i < 8; i++) - setFunctionModule(size - 1 - i, 8, getBit(bits, i)); - for (int i = 8; i < 15; i++) - setFunctionModule(8, size - 15 + i, getBit(bits, i)); - setFunctionModule(8, size - 8, true); // Always black -} - - -void QrCode::drawVersion() { - if (version < 7) - return; - - // Calculate error correction code and pack bits - int rem = version; // version is uint6, in the range [7, 40] - for (int i = 0; i < 12; i++) - rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); - long bits = static_cast(version) << 12 | rem; // uint18 - if (bits >> 18 != 0) - throw std::logic_error("Assertion error"); - - // Draw two copies - for (int i = 0; i < 18; i++) { - bool bit = getBit(bits, i); - int a = size - 11 + i % 3; - int b = i / 3; - setFunctionModule(a, b, bit); - setFunctionModule(b, a, bit); - } -} - - -void QrCode::drawFinderPattern(int x, int y) { - for (int dy = -4; dy <= 4; dy++) { - for (int dx = -4; dx <= 4; dx++) { - int dist = std::max(std::abs(dx), std::abs(dy)); // Chebyshev/infinity norm - int xx = x + dx, yy = y + dy; - if (0 <= xx && xx < size && 0 <= yy && yy < size) - setFunctionModule(xx, yy, dist != 2 && dist != 4); - } - } -} - - -void QrCode::drawAlignmentPattern(int x, int y) { - for (int dy = -2; dy <= 2; dy++) { - for (int dx = -2; dx <= 2; dx++) - setFunctionModule(x + dx, y + dy, std::max(std::abs(dx), std::abs(dy)) != 1); - } -} - - -void QrCode::setFunctionModule(int x, int y, bool isBlack) { - size_t ux = static_cast(x); - size_t uy = static_cast(y); - modules .at(uy).at(ux) = isBlack; - isFunction.at(uy).at(ux) = true; -} - - -bool QrCode::module(int x, int y) const { - return modules.at(static_cast(y)).at(static_cast(x)); -} - - -vector QrCode::addEccAndInterleave(const vector &data) const { - if (data.size() != static_cast(getNumDataCodewords(version, errorCorrectionLevel))) - throw std::invalid_argument("Invalid argument"); - - // Calculate parameter numbers - int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[static_cast(errorCorrectionLevel)][version]; - int blockEccLen = ECC_CODEWORDS_PER_BLOCK [static_cast(errorCorrectionLevel)][version]; - int rawCodewords = getNumRawDataModules(version) / 8; - int numShortBlocks = numBlocks - rawCodewords % numBlocks; - int shortBlockLen = rawCodewords / numBlocks; - - // Split data into blocks and append ECC to each block - vector > blocks; - const vector rsDiv = reedSolomonComputeDivisor(blockEccLen); - for (int i = 0, k = 0; i < numBlocks; i++) { - vector dat(data.cbegin() + k, data.cbegin() + (k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1))); - k += static_cast(dat.size()); - const vector ecc = reedSolomonComputeRemainder(dat, rsDiv); - if (i < numShortBlocks) - dat.push_back(0); - dat.insert(dat.end(), ecc.cbegin(), ecc.cend()); - blocks.push_back(std::move(dat)); - } - - // Interleave (not concatenate) the bytes from every block into a single sequence - vector result; - for (size_t i = 0; i < blocks.at(0).size(); i++) { - for (size_t j = 0; j < blocks.size(); j++) { - // Skip the padding byte in short blocks - if (i != static_cast(shortBlockLen - blockEccLen) || j >= static_cast(numShortBlocks)) - result.push_back(blocks.at(j).at(i)); - } - } - if (result.size() != static_cast(rawCodewords)) - throw std::logic_error("Assertion error"); - return result; -} - - -void QrCode::drawCodewords(const vector &data) { - if (data.size() != static_cast(getNumRawDataModules(version) / 8)) - throw std::invalid_argument("Invalid argument"); - - size_t i = 0; // Bit index into the data - // Do the funny zigzag scan - for (int right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair - if (right == 6) - right = 5; - for (int vert = 0; vert < size; vert++) { // Vertical counter - for (int j = 0; j < 2; j++) { - size_t x = static_cast(right - j); // Actual x coordinate - bool upward = ((right + 1) & 2) == 0; - size_t y = static_cast(upward ? size - 1 - vert : vert); // Actual y coordinate - if (!isFunction.at(y).at(x) && i < data.size() * 8) { - modules.at(y).at(x) = getBit(data.at(i >> 3), 7 - static_cast(i & 7)); - i++; - } - // If this QR Code has any remainder bits (0 to 7), they were assigned as - // 0/false/white by the constructor and are left unchanged by this method - } - } - } - if (i != data.size() * 8) - throw std::logic_error("Assertion error"); -} - - -void QrCode::applyMask(int msk) { - if (msk < 0 || msk > 7) - throw std::domain_error("Mask value out of range"); - size_t sz = static_cast(size); - for (size_t y = 0; y < sz; y++) { - for (size_t x = 0; x < sz; x++) { - bool invert; - switch (msk) { - case 0: invert = (x + y) % 2 == 0; break; - case 1: invert = y % 2 == 0; break; - case 2: invert = x % 3 == 0; break; - case 3: invert = (x + y) % 3 == 0; break; - case 4: invert = (x / 3 + y / 2) % 2 == 0; break; - case 5: invert = x * y % 2 + x * y % 3 == 0; break; - case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break; - case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; - default: throw std::logic_error("Assertion error"); - } - modules.at(y).at(x) = modules.at(y).at(x) ^ (invert & !isFunction.at(y).at(x)); - } - } -} - - -long QrCode::getPenaltyScore() const { - long result = 0; - - // Adjacent modules in row having same color, and finder-like patterns - for (int y = 0; y < size; y++) { - bool runColor = false; - int runX = 0; - std::array runHistory = {}; - for (int x = 0; x < size; x++) { - if (module(x, y) == runColor) { - runX++; - if (runX == 5) - result += PENALTY_N1; - else if (runX > 5) - result++; - } else { - finderPenaltyAddHistory(runX, runHistory); - if (!runColor) - result += finderPenaltyCountPatterns(runHistory) * PENALTY_N3; - runColor = module(x, y); - runX = 1; - } - } - result += finderPenaltyTerminateAndCount(runColor, runX, runHistory) * PENALTY_N3; - } - // Adjacent modules in column having same color, and finder-like patterns - for (int x = 0; x < size; x++) { - bool runColor = false; - int runY = 0; - std::array runHistory = {}; - for (int y = 0; y < size; y++) { - if (module(x, y) == runColor) { - runY++; - if (runY == 5) - result += PENALTY_N1; - else if (runY > 5) - result++; - } else { - finderPenaltyAddHistory(runY, runHistory); - if (!runColor) - result += finderPenaltyCountPatterns(runHistory) * PENALTY_N3; - runColor = module(x, y); - runY = 1; - } - } - result += finderPenaltyTerminateAndCount(runColor, runY, runHistory) * PENALTY_N3; - } - - // 2*2 blocks of modules having same color - for (int y = 0; y < size - 1; y++) { - for (int x = 0; x < size - 1; x++) { - bool color = module(x, y); - if ( color == module(x + 1, y) && - color == module(x, y + 1) && - color == module(x + 1, y + 1)) - result += PENALTY_N2; - } - } - - // Balance of black and white modules - int black = 0; - for (const vector &row : modules) { - for (bool color : row) { - if (color) - black++; - } - } - int total = size * size; // Note that size is odd, so black/total != 1/2 - // Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)% - int k = static_cast((std::abs(black * 20L - total * 10L) + total - 1) / total) - 1; - result += k * PENALTY_N4; - return result; -} - - -vector QrCode::getAlignmentPatternPositions() const { - if (version == 1) - return vector(); - else { - int numAlign = version / 7 + 2; - int step = (version == 32) ? 26 : - (version*4 + numAlign*2 + 1) / (numAlign*2 - 2) * 2; - vector result; - for (int i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step) - result.insert(result.begin(), pos); - result.insert(result.begin(), 6); - return result; - } -} - - -int QrCode::getNumRawDataModules(int ver) { - if (ver < MIN_VERSION || ver > MAX_VERSION) - throw std::domain_error("Version number out of range"); - int result = (16 * ver + 128) * ver + 64; - if (ver >= 2) { - int numAlign = ver / 7 + 2; - result -= (25 * numAlign - 10) * numAlign - 55; - if (ver >= 7) - result -= 36; - } - if (!(208 <= result && result <= 29648)) - throw std::logic_error("Assertion error"); - return result; -} - - -int QrCode::getNumDataCodewords(int ver, Ecc ecl) { - return getNumRawDataModules(ver) / 8 - - ECC_CODEWORDS_PER_BLOCK [static_cast(ecl)][ver] - * NUM_ERROR_CORRECTION_BLOCKS[static_cast(ecl)][ver]; -} - - -vector QrCode::reedSolomonComputeDivisor(int degree) { - if (degree < 1 || degree > 255) - throw std::domain_error("Degree out of range"); - // Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1. - // For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}. - vector result(static_cast(degree)); - result.at(result.size() - 1) = 1; // Start off with the monomial x^0 - - // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}), - // and drop the highest monomial term which is always 1x^degree. - // Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D). - uint8_t root = 1; - for (int i = 0; i < degree; i++) { - // Multiply the current product by (x - r^i) - for (size_t j = 0; j < result.size(); j++) { - result.at(j) = reedSolomonMultiply(result.at(j), root); - if (j + 1 < result.size()) - result.at(j) ^= result.at(j + 1); - } - root = reedSolomonMultiply(root, 0x02); - } - return result; -} - - -vector QrCode::reedSolomonComputeRemainder(const vector &data, const vector &divisor) { - vector result(divisor.size()); - for (uint8_t b : data) { // Polynomial division - uint8_t factor = b ^ result.at(0); - result.erase(result.begin()); - result.push_back(0); - for (size_t i = 0; i < result.size(); i++) - result.at(i) ^= reedSolomonMultiply(divisor.at(i), factor); - } - return result; -} - - -uint8_t QrCode::reedSolomonMultiply(uint8_t x, uint8_t y) { - // Russian peasant multiplication - int z = 0; - for (int i = 7; i >= 0; i--) { - z = (z << 1) ^ ((z >> 7) * 0x11D); - z ^= ((y >> i) & 1) * x; - } - if (z >> 8 != 0) - throw std::logic_error("Assertion error"); - return static_cast(z); -} - - -int QrCode::finderPenaltyCountPatterns(const std::array &runHistory) const { - int n = runHistory.at(1); - if (n > size * 3) - throw std::logic_error("Assertion error"); - bool core = n > 0 && runHistory.at(2) == n && runHistory.at(3) == n * 3 && runHistory.at(4) == n && runHistory.at(5) == n; - return (core && runHistory.at(0) >= n * 4 && runHistory.at(6) >= n ? 1 : 0) - + (core && runHistory.at(6) >= n * 4 && runHistory.at(0) >= n ? 1 : 0); -} - - -int QrCode::finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, std::array &runHistory) const { - if (currentRunColor) { // Terminate black run - finderPenaltyAddHistory(currentRunLength, runHistory); - currentRunLength = 0; - } - currentRunLength += size; // Add white border to final run - finderPenaltyAddHistory(currentRunLength, runHistory); - return finderPenaltyCountPatterns(runHistory); -} - - -void QrCode::finderPenaltyAddHistory(int currentRunLength, std::array &runHistory) const { - if (runHistory.at(0) == 0) - currentRunLength += size; // Add white border to initial run - std::copy_backward(runHistory.cbegin(), runHistory.cend() - 1, runHistory.end()); - runHistory.at(0) = currentRunLength; -} - - -bool QrCode::getBit(long x, int i) { - return ((x >> i) & 1) != 0; -} - - -/*---- Tables of constants ----*/ - -const int QrCode::PENALTY_N1 = 3; -const int QrCode::PENALTY_N2 = 3; -const int QrCode::PENALTY_N3 = 40; -const int QrCode::PENALTY_N4 = 10; - - -const int8_t QrCode::ECC_CODEWORDS_PER_BLOCK[4][41] = { - // Version: (note that index 0 is for padding, and is set to an illegal value) - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level - {-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Low - {-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, // Medium - {-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Quartile - {-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // High -}; - -const int8_t QrCode::NUM_ERROR_CORRECTION_BLOCKS[4][41] = { - // Version: (note that index 0 is for padding, and is set to an illegal value) - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level - {-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low - {-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium - {-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile - {-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High -}; - - -data_too_long::data_too_long(const std::string &msg) : - std::length_error(msg) {} - - - -BitBuffer::BitBuffer() - : std::vector() {} - - -void BitBuffer::appendBits(std::uint32_t val, int len) { - if (len < 0 || len > 31 || val >> len != 0) - throw std::domain_error("Value out of range"); - for (int i = len - 1; i >= 0; i--) // Append bit by bit - this->push_back(((val >> i) & 1) != 0); -} - -} diff --git a/anpro/QrCode.h b/anpro/QrCode.h deleted file mode 100644 index 7341e41..0000000 --- a/anpro/QrCode.h +++ /dev/null @@ -1,556 +0,0 @@ -/* - * QR Code generator library (C++) - * - * Copyright (c) Project Nayuki. (MIT License) - * https://www.nayuki.io/page/qr-code-generator-library - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#pragma once - -#include -#include -#include -#include -#include - - -namespace qrcodegen { - -/* - * A segment of character/binary/control data in a QR Code symbol. - * Instances of this class are immutable. - * The mid-level way to create a segment is to take the payload data - * and call a static factory function such as QrSegment::makeNumeric(). - * The low-level way to create a segment is to custom-make the bit buffer - * and call the QrSegment() constructor with appropriate values. - * This segment class imposes no length restrictions, but QR Codes have restrictions. - * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data. - * Any segment longer than this is meaningless for the purpose of generating QR Codes. - */ -class QrSegment final { - - /*---- Public helper enumeration ----*/ - - /* - * Describes how a segment's data bits are interpreted. Immutable. - */ - public: class Mode final { - - /*-- Constants --*/ - - public: static const Mode NUMERIC; - public: static const Mode ALPHANUMERIC; - public: static const Mode BYTE; - public: static const Mode KANJI; - public: static const Mode ECI; - - - /*-- Fields --*/ - - // The mode indicator bits, which is a uint4 value (range 0 to 15). - private: int modeBits; - - // Number of character count bits for three different version ranges. - private: int numBitsCharCount[3]; - - - /*-- Constructor --*/ - - private: Mode(int mode, int cc0, int cc1, int cc2); - - - /*-- Methods --*/ - - /* - * (Package-private) Returns the mode indicator bits, which is an unsigned 4-bit value (range 0 to 15). - */ - public: int getModeBits() const; - - /* - * (Package-private) Returns the bit width of the character count field for a segment in - * this mode in a QR Code at the given version number. The result is in the range [0, 16]. - */ - public: int numCharCountBits(int ver) const; - - }; - - - - /*---- Static factory functions (mid level) ----*/ - - /* - * Returns a segment representing the given binary data encoded in - * byte mode. All input byte vectors are acceptable. Any text string - * can be converted to UTF-8 bytes and encoded as a byte mode segment. - */ - public: static QrSegment makeBytes(const std::vector &data); - - - /* - * Returns a segment representing the given string of decimal digits encoded in numeric mode. - */ - public: static QrSegment makeNumeric(const char *digits); - - - /* - * Returns a segment representing the given text string encoded in alphanumeric mode. - * The characters allowed are: 0 to 9, A to Z (uppercase only), space, - * dollar, percent, asterisk, plus, hyphen, period, slash, colon. - */ - public: static QrSegment makeAlphanumeric(const char *text); - - - /* - * Returns a list of zero or more segments to represent the given text string. The result - * may use various segment modes and switch modes to optimize the length of the bit stream. - */ - public: static std::vector makeSegments(const char *text); - - - /* - * Returns a segment representing an Extended Channel Interpretation - * (ECI) designator with the given assignment value. - */ - public: static QrSegment makeEci(long assignVal); - - - /*---- Public static helper functions ----*/ - - /* - * Tests whether the given string can be encoded as a segment in alphanumeric mode. - * A string is encodable iff each character is in the following set: 0 to 9, A to Z - * (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon. - */ - public: static bool isAlphanumeric(const char *text); - - - /* - * Tests whether the given string can be encoded as a segment in numeric mode. - * A string is encodable iff each character is in the range 0 to 9. - */ - public: static bool isNumeric(const char *text); - - - - /*---- Instance fields ----*/ - - /* The mode indicator of this segment. Accessed through getMode(). */ - private: Mode mode; - - /* The length of this segment's unencoded data. Measured in characters for - * numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode. - * Always zero or positive. Not the same as the data's bit length. - * Accessed through getNumChars(). */ - private: int numChars; - - /* The data bits of this segment. Accessed through getData(). */ - private: std::vector data; - - - /*---- Constructors (low level) ----*/ - - /* - * Creates a new QR Code segment with the given attributes and data. - * The character count (numCh) must agree with the mode and the bit buffer length, - * but the constraint isn't checked. The given bit buffer is copied and stored. - */ - public: QrSegment(Mode md, int numCh, const std::vector &dt); - - - /* - * Creates a new QR Code segment with the given parameters and data. - * The character count (numCh) must agree with the mode and the bit buffer length, - * but the constraint isn't checked. The given bit buffer is moved and stored. - */ - public: QrSegment(Mode md, int numCh, std::vector &&dt); - - - /*---- Methods ----*/ - - /* - * Returns the mode field of this segment. - */ - public: Mode getMode() const; - - - /* - * Returns the character count field of this segment. - */ - public: int getNumChars() const; - - - /* - * Returns the data bits of this segment. - */ - public: const std::vector &getData() const; - - - // (Package-private) Calculates the number of bits needed to encode the given segments at - // the given version. Returns a non-negative number if successful. Otherwise returns -1 if a - // segment has too many characters to fit its length field, or the total bits exceeds INT_MAX. - public: static int getTotalBits(const std::vector &segs, int version); - - - /*---- Private constant ----*/ - - /* The set of all legal characters in alphanumeric mode, where - * each character value maps to the index in the string. */ - private: static const char *ALPHANUMERIC_CHARSET; - -}; - - - -/* - * A QR Code symbol, which is a type of two-dimension barcode. - * Invented by Denso Wave and described in the ISO/IEC 18004 standard. - * Instances of this class represent an immutable square grid of black and white cells. - * The class provides static factory functions to create a QR Code from text or binary data. - * The class covers the QR Code Model 2 specification, supporting all versions (sizes) - * from 1 to 40, all 4 error correction levels, and 4 character encoding modes. - * - * Ways to create a QR Code object: - * - High level: Take the payload data and call QrCode::encodeText() or QrCode::encodeBinary(). - * - Mid level: Custom-make the list of segments and call QrCode::encodeSegments(). - * - Low level: Custom-make the array of data codeword bytes (including - * segment headers and final padding, excluding error correction codewords), - * supply the appropriate version number, and call the QrCode() constructor. - * (Note that all ways require supplying the desired error correction level.) - */ -class QrCode final { - - /*---- Public helper enumeration ----*/ - - /* - * The error correction level in a QR Code symbol. - */ - public: enum class Ecc { - LOW = 0 , // The QR Code can tolerate about 7% erroneous codewords - MEDIUM , // The QR Code can tolerate about 15% erroneous codewords - QUARTILE, // The QR Code can tolerate about 25% erroneous codewords - HIGH , // The QR Code can tolerate about 30% erroneous codewords - }; - - - // Returns a value in the range 0 to 3 (unsigned 2-bit integer). - private: static int getFormatBits(Ecc ecl); - - - - /*---- Static factory functions (high level) ----*/ - - /* - * Returns a QR Code representing the given Unicode text string at the given error correction level. - * As a conservative upper bound, this function is guaranteed to succeed for strings that have 2953 or fewer - * UTF-8 code units (not Unicode code points) if the low error correction level is used. The smallest possible - * QR Code version is automatically chosen for the output. The ECC level of the result may be higher than - * the ecl argument if it can be done without increasing the version. - */ - public: static QrCode encodeText(const char *text, Ecc ecl); - - - /* - * Returns a QR Code representing the given binary data at the given error correction level. - * This function always encodes using the binary segment mode, not any text mode. The maximum number of - * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output. - * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version. - */ - public: static QrCode encodeBinary(const std::vector &data, Ecc ecl); - - - /*---- Static factory functions (mid level) ----*/ - - /* - * Returns a QR Code representing the given segments with the given encoding parameters. - * The smallest possible QR Code version within the given range is automatically - * chosen for the output. Iff boostEcl is true, then the ECC level of the result - * may be higher than the ecl argument if it can be done without increasing the - * version. The mask number is either between 0 to 7 (inclusive) to force that - * mask, or -1 to automatically choose an appropriate mask (which may be slow). - * This function allows the user to create a custom sequence of segments that switches - * between modes (such as alphanumeric and byte) to encode text in less space. - * This is a mid-level API; the high-level API is encodeText() and encodeBinary(). - */ - public: static QrCode encodeSegments(const std::vector &segs, Ecc ecl, - int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true); // All optional parameters - - - - /*---- Instance fields ----*/ - - // Immutable scalar parameters: - - /* The version number of this QR Code, which is between 1 and 40 (inclusive). - * This determines the size of this barcode. */ - private: int version; - - /* The width and height of this QR Code, measured in modules, between - * 21 and 177 (inclusive). This is equal to version * 4 + 17. */ - private: int size; - - /* The error correction level used in this QR Code. */ - private: Ecc errorCorrectionLevel; - - /* The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive). - * Even if a QR Code is created with automatic masking requested (mask = -1), - * the resulting object still has a mask value between 0 and 7. */ - private: int mask; - - // Private grids of modules/pixels, with dimensions of size*size: - - // The modules of this QR Code (false = white, true = black). - // Immutable after constructor finishes. Accessed through getModule(). - private: std::vector > modules; - - // Indicates function modules that are not subjected to masking. Discarded when constructor finishes. - private: std::vector > isFunction; - - - - /*---- Constructor (low level) ----*/ - - /* - * Creates a new QR Code with the given version number, - * error correction level, data codeword bytes, and mask number. - * This is a low-level API that most users should not use directly. - * A mid-level API is the encodeSegments() function. - */ - public: QrCode(int ver, Ecc ecl, const std::vector &dataCodewords, int msk); - - - - /*---- Public instance methods ----*/ - - /* - * Returns this QR Code's version, in the range [1, 40]. - */ - public: int getVersion() const; - - - /* - * Returns this QR Code's size, in the range [21, 177]. - */ - public: int getSize() const; - - - /* - * Returns this QR Code's error correction level. - */ - public: Ecc getErrorCorrectionLevel() const; - - - /* - * Returns this QR Code's mask, in the range [0, 7]. - */ - public: int getMask() const; - - - /* - * Returns the color of the module (pixel) at the given coordinates, which is false - * for white or true for black. The top left corner has the coordinates (x=0, y=0). - * If the given coordinates are out of bounds, then false (white) is returned. - */ - public: bool getModule(int x, int y) const; - - - /* - * Returns a string of SVG code for an image depicting this QR Code, with the given number - * of border modules. The string always uses Unix newlines (\n), regardless of the platform. - */ - public: std::string toSvgString(int border) const; - - - - /*---- Private helper methods for constructor: Drawing function modules ----*/ - - // Reads this object's version field, and draws and marks all function modules. - private: void drawFunctionPatterns(); - - - // Draws two copies of the format bits (with its own error correction code) - // based on the given mask and this object's error correction level field. - private: void drawFormatBits(int msk); - - - // Draws two copies of the version bits (with its own error correction code), - // based on this object's version field, iff 7 <= version <= 40. - private: void drawVersion(); - - - // Draws a 9*9 finder pattern including the border separator, - // with the center module at (x, y). Modules can be out of bounds. - private: void drawFinderPattern(int x, int y); - - - // Draws a 5*5 alignment pattern, with the center module - // at (x, y). All modules must be in bounds. - private: void drawAlignmentPattern(int x, int y); - - - // Sets the color of a module and marks it as a function module. - // Only used by the constructor. Coordinates must be in bounds. - private: void setFunctionModule(int x, int y, bool isBlack); - - - // Returns the color of the module at the given coordinates, which must be in range. - private: bool module(int x, int y) const; - - - /*---- Private helper methods for constructor: Codewords and masking ----*/ - - // Returns a new byte string representing the given data with the appropriate error correction - // codewords appended to it, based on this object's version and error correction level. - private: std::vector addEccAndInterleave(const std::vector &data) const; - - - // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire - // data area of this QR Code. Function modules need to be marked off before this is called. - private: void drawCodewords(const std::vector &data); - - - // XORs the codeword modules in this QR Code with the given mask pattern. - // The function modules must be marked and the codeword bits must be drawn - // before masking. Due to the arithmetic of XOR, calling applyMask() with - // the same mask value a second time will undo the mask. A final well-formed - // QR Code needs exactly one (not zero, two, etc.) mask applied. - private: void applyMask(int msk); - - - // Calculates and returns the penalty score based on state of this QR Code's current modules. - // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. - private: long getPenaltyScore() const; - - - - /*---- Private helper functions ----*/ - - // Returns an ascending list of positions of alignment patterns for this version number. - // Each position is in the range [0,177), and are used on both the x and y axes. - // This could be implemented as lookup table of 40 variable-length lists of unsigned bytes. - private: std::vector getAlignmentPatternPositions() const; - - - // Returns the number of data bits that can be stored in a QR Code of the given version number, after - // all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8. - // The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table. - private: static int getNumRawDataModules(int ver); - - - // Returns the number of 8-bit data (i.e. not error correction) codewords contained in any - // QR Code of the given version number and error correction level, with remainder bits discarded. - // This stateless pure function could be implemented as a (40*4)-cell lookup table. - private: static int getNumDataCodewords(int ver, Ecc ecl); - - - // Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be - // implemented as a lookup table over all possible parameter values, instead of as an algorithm. - private: static std::vector reedSolomonComputeDivisor(int degree); - - - // Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials. - private: static std::vector reedSolomonComputeRemainder(const std::vector &data, const std::vector &divisor); - - - // Returns the product of the two given field elements modulo GF(2^8/0x11D). - // All inputs are valid. This could be implemented as a 256*256 lookup table. - private: static std::uint8_t reedSolomonMultiply(std::uint8_t x, std::uint8_t y); - - - // Can only be called immediately after a white run is added, and - // returns either 0, 1, or 2. A helper function for getPenaltyScore(). - private: int finderPenaltyCountPatterns(const std::array &runHistory) const; - - - // Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore(). - private: int finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, std::array &runHistory) const; - - - // Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore(). - private: void finderPenaltyAddHistory(int currentRunLength, std::array &runHistory) const; - - - // Returns true iff the i'th bit of x is set to 1. - private: static bool getBit(long x, int i); - - - /*---- Constants and tables ----*/ - - // The minimum version number supported in the QR Code Model 2 standard. - public: static constexpr int MIN_VERSION = 1; - - // The maximum version number supported in the QR Code Model 2 standard. - public: static constexpr int MAX_VERSION = 40; - - - // For use in getPenaltyScore(), when evaluating which mask is best. - private: static const int PENALTY_N1; - private: static const int PENALTY_N2; - private: static const int PENALTY_N3; - private: static const int PENALTY_N4; - - - private: static const std::int8_t ECC_CODEWORDS_PER_BLOCK[4][41]; - private: static const std::int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41]; - -}; - - - -/*---- Public exception class ----*/ - -/* - * Thrown when the supplied data does not fit any QR Code version. Ways to handle this exception include: - * - Decrease the error correction level if it was greater than Ecc::LOW. - * - If the encodeSegments() function was called with a maxVersion argument, then increase - * it if it was less than QrCode::MAX_VERSION. (This advice does not apply to the other - * factory functions because they search all versions up to QrCode::MAX_VERSION.) - * - Split the text data into better or optimal segments in order to reduce the number of bits required. - * - Change the text or binary data to be shorter. - * - Change the text to fit the character set of a particular segment mode (e.g. alphanumeric). - * - Propagate the error upward to the caller/user. - */ -class data_too_long : public std::length_error { - - public: explicit data_too_long(const std::string &msg); - -}; - - - -/* - * An appendable sequence of bits (0s and 1s). Mainly used by QrSegment. - */ -class BitBuffer final : public std::vector { - - /*---- Constructor ----*/ - - // Creates an empty bit buffer (length 0). - public: BitBuffer(); - - - - /*---- Method ----*/ - - // Appends the given number of low-order bits of the given value - // to this buffer. Requires 0 <= len <= 31 and val < 2^len. - public: void appendBits(std::uint32_t val, int len); - -}; - -} diff --git a/anpro/imagecropper.cpp b/anpro/imagecropper.cpp deleted file mode 100644 index 3d80f71..0000000 --- a/anpro/imagecropper.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/***************************************************************************** -* ImageCropper Qt Widget for cropping images -* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro -* Copyright (C) 2020 Syping -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "imagecropper.h" -#include "AppEnv.h" - -#include -#include -#include - -namespace { - static const QSize WIDGET_MINIMUM_SIZE(470, 470); -} - -ImageCropper::ImageCropper(QWidget* parent) : - QWidget(parent), - pimpl(new ImageCropperPrivate) -{ - setMinimumSize(WIDGET_MINIMUM_SIZE); - setMouseTracking(true); -} - -ImageCropper::~ImageCropper() -{ - delete pimpl; -} - -void ImageCropper::setImage(const QPixmap& _image) -{ - pimpl->imageForCropping = _image; - update(); -} - -void ImageCropper::setBackgroundColor(const QColor& _backgroundColor) -{ - pimpl->backgroundColor = _backgroundColor; - update(); -} - -void ImageCropper::setCroppingRectBorderColor(const QColor& _borderColor) -{ - pimpl->croppingRectBorderColor = _borderColor; - update(); -} - -void ImageCropper::setProportion(const QSizeF& _proportion) -{ - // Пропорции хранятся в коэффициентах приращения сторон - // Таким образом, при изменении размера области выделения, - // размеры сторон изменяются на размер зависящий от - // коэффициентов приращения. - - // Сохраним пропорциональную зависимость области выделения в коэффициентах приращения сторон - if (pimpl->proportion != _proportion) { - pimpl->proportion = _proportion; - // ... расчитаем коэффициенты - float heightDelta = (float)_proportion.height() / _proportion.width(); - float widthDelta = (float)_proportion.width() / _proportion.height(); - // ... сохраним коэффициенты - pimpl->deltas.setHeight(heightDelta); - pimpl->deltas.setWidth(widthDelta); - } - - // Обновим пропорции области выделения - if ( pimpl->isProportionFixed ) { - float croppintRectSideRelation = - (float)pimpl->croppingRect.width() / pimpl->croppingRect.height(); - float proportionSideRelation = - (float)pimpl->proportion.width() / pimpl->proportion.height(); - // Если область выделения не соответствует необходимым пропорциям обновим её - if (croppintRectSideRelation != proportionSideRelation) { - bool widthShotrerThenHeight = - pimpl->croppingRect.width() < pimpl->croppingRect.height(); - // ... установим размер той стороны, что длиннее - if (widthShotrerThenHeight) { - pimpl->croppingRect.setHeight( - pimpl->croppingRect.width() * pimpl->deltas.height()); - } else { - pimpl->croppingRect.setWidth( - pimpl->croppingRect.height() * pimpl->deltas.width()); - } - // ... перерисуем виджет - update(); - } - } - -} - -void ImageCropper::setProportionFixed(const bool _isFixed) -{ - if (pimpl->isProportionFixed != _isFixed) { - pimpl->isProportionFixed = _isFixed; - setProportion(pimpl->proportion); - } -} - -const QPixmap ImageCropper::cropImage() -{ - // Получим размер отображаемого изображения - QSize scaledImageSize = - pimpl->imageForCropping.scaled( - size(), Qt::KeepAspectRatio, Qt::SmoothTransformation - ).size(); - // Определим расстояние от левого и верхнего краёв - float leftDelta = 0; - float topDelta = 0; - const float HALF_COUNT = 2; - if (size().height() == scaledImageSize.height()) { - leftDelta = (width() - scaledImageSize.width()) / HALF_COUNT; - } else { - topDelta = (height() - scaledImageSize.height()) / HALF_COUNT; - } - // Определим пропорцию области обрезки по отношению к исходному изображению - float xScale = (float)pimpl->imageForCropping.width() / scaledImageSize.width(); - float yScale = (float)pimpl->imageForCropping.height() / scaledImageSize.height(); - // Расчитаем область обрезки с учётом коррекции размеров исходного изображения - QRectF realSizeRect( - QPointF(pimpl->croppingRect.left() - leftDelta, pimpl->croppingRect.top() - topDelta), - pimpl->croppingRect.size()); - // ... корректируем левый и верхний края - realSizeRect.setLeft((pimpl->croppingRect.left() - leftDelta) * xScale); - realSizeRect.setTop ((pimpl->croppingRect.top() - topDelta) * yScale); - // ... корректируем размер - realSizeRect.setWidth(pimpl->croppingRect.width() * xScale); - realSizeRect.setHeight(pimpl->croppingRect.height() * yScale); - // Получаем обрезанное изображение - return pimpl->imageForCropping.copy(realSizeRect.toRect()); -} - -// ******** -// Protected section - -void ImageCropper::paintEvent(QPaintEvent* _event) -{ - QWidget::paintEvent(_event); - // - QPainter widgetPainter(this); - // Рисуем изображение по центру виджета - { -#if QT_VERSION >= 0x050600 - qreal screenRatioPR = AppEnv::screenRatioPR(); - // ... подгоним изображение для отображения по размеру виджета - QPixmap scaledImage = - pimpl->imageForCropping.scaled(qRound((double)width() * screenRatioPR), qRound((double)height() * screenRatioPR), Qt::KeepAspectRatio, Qt::SmoothTransformation); - scaledImage.setDevicePixelRatio(screenRatioPR); -#else - QPixmap scaledImage = - pimpl->imageForCropping.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); -#endif - // ... заливаем фон - widgetPainter.fillRect(rect(), pimpl->backgroundColor); - // ... рисуем изображение по центру виджета -#if QT_VERSION >= 0x050600 - if (qRound((double)height() * screenRatioPR) == scaledImage.height()) { - widgetPainter.drawPixmap( ( qRound((double)width() * screenRatioPR) - scaledImage.width() ) / 2, 0, scaledImage ); - } else { - widgetPainter.drawPixmap( 0, ( qRound((double)height() * screenRatioPR) - scaledImage.height() ) / 2, scaledImage ); - } -#else - if (height() == scaledImage.height()) { - widgetPainter.drawPixmap( ( width()- scaledImage.width() ) / 2, 0, scaledImage ); - } else { - widgetPainter.drawPixmap( 0, ( height() - scaledImage.height() ) / 2, scaledImage ); - } -#endif - } - // Рисуем область обрезки - { - // ... если это первое отображение после инициилизации, то центруем областо обрезки - if (pimpl->croppingRect.isNull()) { - const int cwidth = WIDGET_MINIMUM_SIZE.width()/2; - const int cheight = WIDGET_MINIMUM_SIZE.height()/2; - pimpl->croppingRect.setSize(QSize(cwidth, cheight)); - float x = (width() - pimpl->croppingRect.width())/2; - float y = (height() - pimpl->croppingRect.height())/2; - pimpl->croppingRect.moveTo(x, y); - } - - // ... рисуем затемненную область - QPainterPath p; - p.addRect(pimpl->croppingRect); - p.addRect(rect()); - widgetPainter.setBrush(QBrush(QColor(0,0,0,120))); - widgetPainter.setPen(Qt::transparent); - widgetPainter.drawPath(p); - // Рамка и контрольные точки - widgetPainter.setPen(pimpl->croppingRectBorderColor); - // ... рисуем прямоугольник области обрезки - { - widgetPainter.setBrush(QBrush(Qt::transparent)); - widgetPainter.drawRect(pimpl->croppingRect); - } - // ... рисуем контрольные точки - { - widgetPainter.setBrush(QBrush(pimpl->croppingRectBorderColor)); - // Вспомогательные X координаты - int leftXCoord = pimpl->croppingRect.left() - 2; - int centerXCoord = pimpl->croppingRect.center().x() - 3; - int rightXCoord = pimpl->croppingRect.right() - 2; - // Вспомогательные Y координаты - int topYCoord = pimpl->croppingRect.top() - 2; - int middleYCoord = pimpl->croppingRect.center().y() - 3; - int bottomYCoord = pimpl->croppingRect.bottom() - 2; - // - const QSize pointSize(6, 6); - // - QVector points; - points - // левая сторона - << QRect( QPoint(leftXCoord, topYCoord), pointSize ) - << QRect( QPoint(leftXCoord, middleYCoord), pointSize ) - << QRect( QPoint(leftXCoord, bottomYCoord), pointSize ) - // центр - << QRect( QPoint(centerXCoord, topYCoord), pointSize ) - << QRect( QPoint(centerXCoord, middleYCoord), pointSize ) - << QRect( QPoint(centerXCoord, bottomYCoord), pointSize ) - // правая сторона - << QRect( QPoint(rightXCoord, topYCoord), pointSize ) - << QRect( QPoint(rightXCoord, middleYCoord), pointSize ) - << QRect( QPoint(rightXCoord, bottomYCoord), pointSize ); - // - widgetPainter.drawRects( points ); - } - // ... рисуем пунктирные линии - { - QPen dashPen(pimpl->croppingRectBorderColor); - dashPen.setStyle(Qt::DashLine); - widgetPainter.setPen(dashPen); - // ... вертикальная - widgetPainter.drawLine( - QPoint(pimpl->croppingRect.center().x(), pimpl->croppingRect.top()), - QPoint(pimpl->croppingRect.center().x(), pimpl->croppingRect.bottom()) ); - // ... горизонтальная - widgetPainter.drawLine( - QPoint(pimpl->croppingRect.left(), pimpl->croppingRect.center().y()), - QPoint(pimpl->croppingRect.right(), pimpl->croppingRect.center().y()) ); - } - } - // - widgetPainter.end(); -} - -void ImageCropper::mousePressEvent(QMouseEvent* _event) -{ - if (_event->button() == Qt::LeftButton) { - pimpl->isMousePressed = true; - pimpl->startMousePos = _event->pos(); - pimpl->lastStaticCroppingRect = pimpl->croppingRect; - } - // - updateCursorIcon(_event->pos()); -} - -void ImageCropper::mouseMoveEvent(QMouseEvent* _event) -{ - QPointF mousePos = _event->pos(); // относительно себя (виджета) - // - if (!pimpl->isMousePressed) { - // Обработка обычного состояния, т.е. не изменяется размер - // области обрезки, и она не перемещается по виджету - pimpl->cursorPosition = cursorPosition(pimpl->croppingRect, mousePos); - updateCursorIcon(mousePos); - } else if (pimpl->cursorPosition != CursorPositionUndefined) { - // Обработка действий над областью обрезки - // ... определим смещение курсора мышки - QPointF mouseDelta; - mouseDelta.setX( mousePos.x() - pimpl->startMousePos.x() ); - mouseDelta.setY( mousePos.y() - pimpl->startMousePos.y() ); - // - if (pimpl->cursorPosition != CursorPositionMiddle) { - // ... изменяем размер области обрезки - QRectF newGeometry = - calculateGeometry( - pimpl->lastStaticCroppingRect, - pimpl->cursorPosition, - mouseDelta); - // ... пользователь пытается вывернуть область обрезки наизнанку - if (!newGeometry.isNull()) { - pimpl->croppingRect = newGeometry; - } - } else { - // ... перемещаем область обрезки - pimpl->croppingRect.moveTo( pimpl->lastStaticCroppingRect.topLeft() + mouseDelta ); - } - // Перерисуем виджет - update(); - } -} - -void ImageCropper::mouseReleaseEvent(QMouseEvent* _event) -{ - pimpl->isMousePressed = false; - updateCursorIcon(_event->pos()); -} - -// ******** -// Private section - -namespace { - // Находится ли точка рядом с координатой стороны - static bool isPointNearSide (const int _sideCoordinate, const int _pointCoordinate) - { - static const int indent = 10; - return (_sideCoordinate - indent) < _pointCoordinate && _pointCoordinate < (_sideCoordinate + indent); - } -} - -CursorPosition ImageCropper::cursorPosition(const QRectF& _cropRect, const QPointF& _mousePosition) -{ - CursorPosition cursorPosition = CursorPositionUndefined; - // - if ( _cropRect.contains( _mousePosition ) ) { - // Двухстороннее направление - if (isPointNearSide(_cropRect.top(), _mousePosition.y()) && - isPointNearSide(_cropRect.left(), _mousePosition.x())) { - cursorPosition = CursorPositionTopLeft; - } else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y()) && - isPointNearSide(_cropRect.left(), _mousePosition.x())) { - cursorPosition = CursorPositionBottomLeft; - } else if (isPointNearSide(_cropRect.top(), _mousePosition.y()) && - isPointNearSide(_cropRect.right(), _mousePosition.x())) { - cursorPosition = CursorPositionTopRight; - } else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y()) && - isPointNearSide(_cropRect.right(), _mousePosition.x())) { - cursorPosition = CursorPositionBottomRight; - // Одностороннее направление - } else if (isPointNearSide(_cropRect.left(), _mousePosition.x())) { - cursorPosition = CursorPositionLeft; - } else if (isPointNearSide(_cropRect.right(), _mousePosition.x())) { - cursorPosition = CursorPositionRight; - } else if (isPointNearSide(_cropRect.top(), _mousePosition.y())) { - cursorPosition = CursorPositionTop; - } else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y())) { - cursorPosition = CursorPositionBottom; - // Без направления - } else { - cursorPosition = CursorPositionMiddle; - } - } - // - return cursorPosition; -} - -void ImageCropper::updateCursorIcon(const QPointF& _mousePosition) -{ - QCursor cursorIcon; - // - switch (cursorPosition(pimpl->croppingRect, _mousePosition)) - { - case CursorPositionTopRight: - case CursorPositionBottomLeft: - cursorIcon = QCursor(Qt::SizeBDiagCursor); - break; - case CursorPositionTopLeft: - case CursorPositionBottomRight: - cursorIcon = QCursor(Qt::SizeFDiagCursor); - break; - case CursorPositionTop: - case CursorPositionBottom: - cursorIcon = QCursor(Qt::SizeVerCursor); - break; - case CursorPositionLeft: - case CursorPositionRight: - cursorIcon = QCursor(Qt::SizeHorCursor); - break; - case CursorPositionMiddle: - cursorIcon = pimpl->isMousePressed ? - QCursor(Qt::ClosedHandCursor) : - QCursor(Qt::OpenHandCursor); - break; - case CursorPositionUndefined: - default: - cursorIcon = QCursor(Qt::ArrowCursor); - break; - } - // - this->setCursor(cursorIcon); -} - -const QRectF ImageCropper::calculateGeometry( - const QRectF& _sourceGeometry, - const CursorPosition _cursorPosition, - const QPointF& _mouseDelta - ) -{ - QRectF resultGeometry; - // - if ( pimpl->isProportionFixed ) { - resultGeometry = - calculateGeometryWithFixedProportions( - _sourceGeometry, _cursorPosition, _mouseDelta, pimpl->deltas); - } else { - resultGeometry = - calculateGeometryWithCustomProportions( - _sourceGeometry, _cursorPosition, _mouseDelta); - } - // Если пользователь пытается вывернуть область обрезки наизнанку, - // возвращаем null-прямоугольник - if ((resultGeometry.left() >= resultGeometry.right()) || - (resultGeometry.top() >= resultGeometry.bottom())) { - resultGeometry = QRect(); - } - // - return resultGeometry; -} - -const QRectF ImageCropper::calculateGeometryWithCustomProportions( - const QRectF& _sourceGeometry, - const CursorPosition _cursorPosition, - const QPointF& _mouseDelta - ) -{ - QRectF resultGeometry = _sourceGeometry; - // - switch ( _cursorPosition ) - { - case CursorPositionTopLeft: - resultGeometry.setLeft( _sourceGeometry.left() + _mouseDelta.x() ); - resultGeometry.setTop ( _sourceGeometry.top() + _mouseDelta.y() ); - break; - case CursorPositionTopRight: - resultGeometry.setTop ( _sourceGeometry.top() + _mouseDelta.y() ); - resultGeometry.setRight( _sourceGeometry.right() + _mouseDelta.x() ); - break; - case CursorPositionBottomLeft: - resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() ); - resultGeometry.setLeft ( _sourceGeometry.left() + _mouseDelta.x() ); - break; - case CursorPositionBottomRight: - resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() ); - resultGeometry.setRight ( _sourceGeometry.right() + _mouseDelta.x() ); - break; - case CursorPositionTop: - resultGeometry.setTop( _sourceGeometry.top() + _mouseDelta.y() ); - break; - case CursorPositionBottom: - resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() ); - break; - case CursorPositionLeft: - resultGeometry.setLeft( _sourceGeometry.left() + _mouseDelta.x() ); - break; - case CursorPositionRight: - resultGeometry.setRight( _sourceGeometry.right() + _mouseDelta.x() ); - break; - default: - break; - } - // - return resultGeometry; -} - -const QRectF ImageCropper::calculateGeometryWithFixedProportions( - const QRectF& _sourceGeometry, - const CursorPosition _cursorPosition, - const QPointF& _mouseDelta, - const QSizeF& _deltas - ) -{ - QRectF resultGeometry = _sourceGeometry; - // - switch (_cursorPosition) - { - case CursorPositionLeft: - resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.x() * _deltas.height()); - resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x()); - break; - case CursorPositionRight: - resultGeometry.setTop(_sourceGeometry.top() - _mouseDelta.x() * _deltas.height()); - resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x()); - break; - case CursorPositionTop: - resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y()); - resultGeometry.setRight(_sourceGeometry.right() - _mouseDelta.y() * _deltas.width()); - break; - case CursorPositionBottom: - resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y()); - resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.y() * _deltas.width()); - break; - case CursorPositionTopLeft: - if ((_mouseDelta.x() * _deltas.height()) < (_mouseDelta.y())) { - resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.x() * _deltas.height()); - resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x()); - } else { - resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y()); - resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.y() * _deltas.width()); - } - break; - case CursorPositionTopRight: - if ((_mouseDelta.x() * _deltas.height() * -1) < (_mouseDelta.y())) { - resultGeometry.setTop(_sourceGeometry.top() - _mouseDelta.x() * _deltas.height()); - resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x() ); - } else { - resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y()); - resultGeometry.setRight(_sourceGeometry.right() - _mouseDelta.y() * _deltas.width()); - } - break; - case CursorPositionBottomLeft: - if ((_mouseDelta.x() * _deltas.height()) < (_mouseDelta.y() * -1)) { - resultGeometry.setBottom(_sourceGeometry.bottom() - _mouseDelta.x() * _deltas.height()); - resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x()); - } else { - resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y()); - resultGeometry.setLeft(_sourceGeometry.left() - _mouseDelta.y() * _deltas.width()); - } - break; - case CursorPositionBottomRight: - if ((_mouseDelta.x() * _deltas.height()) > (_mouseDelta.y())) { - resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.x() * _deltas.height()); - resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x()); - } else { - resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y()); - resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.y() * _deltas.width()); - } - break; - default: - break; - } - // - return resultGeometry; -} - diff --git a/anpro/imagecropper.h b/anpro/imagecropper.h deleted file mode 100644 index a5a19a0..0000000 --- a/anpro/imagecropper.h +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************** -* ImageCropper Qt Widget for cropping images -* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef IMAGECROPPER_H -#define IMAGECROPPER_H - -#include "imagecropper_p.h" -#include "imagecropper_e.h" - -#include - -class ImageCropper : public QWidget -{ - Q_OBJECT - -public: - ImageCropper(QWidget *parent = 0); - ~ImageCropper(); - -public slots: - // Установить изображение для обрезки - void setImage(const QPixmap& _image); - // Установить цвет фона виджета обрезки - void setBackgroundColor(const QColor& _backgroundColor); - // Установить цвет рамки области обрезки - void setCroppingRectBorderColor(const QColor& _borderColor); - // Установить пропорции области выделения - void setProportion(const QSizeF& _proportion); - // Использовать фиксированные пропорции области виделения - void setProportionFixed(const bool _isFixed); - -public: - // Обрезать изображение - const QPixmap cropImage(); - -protected: - virtual void paintEvent(QPaintEvent* _event); - virtual void mousePressEvent(QMouseEvent* _event); - virtual void mouseMoveEvent(QMouseEvent* _event); - virtual void mouseReleaseEvent(QMouseEvent* _event); - -private: - // Определение местоположения курсора над виджетом - CursorPosition cursorPosition(const QRectF& _cropRect, const QPointF& _mousePosition); - // Обновить иконку курсора соответствующую местоположению мыши - void updateCursorIcon(const QPointF& _mousePosition); - - // Получить размер виджета после его изменения мышью - // -------- - // Контракты: - // 1. Метод должен вызываться, только при зажатой кнопке мыши - // (т.е. при перемещении или изменении размера виджета) - // -------- - // В случае неудачи возвращает null-прямоугольник - const QRectF calculateGeometry( - const QRectF& _sourceGeometry, - const CursorPosition _cursorPosition, - const QPointF& _mouseDelta - ); - // Получить размер виджета после его изменения мышью - // Метод изменяет виджет не сохраняя начальных пропорций сторон - // ------ - // Контракты: - // 1. Метод должен вызываться, только при зажатой кнопке мыши - // (т.е. при перемещении или изменении размера виджета) - const QRectF calculateGeometryWithCustomProportions( - const QRectF& _sourceGeometry, - const CursorPosition _cursorPosition, - const QPointF& _mouseDelta - ); - // Получить размер виджета после его изменения мышью - // Метод изменяет виджет сохраняя начальные пропорции сторон - // ------ - // Контракты: - // 1. Метод должен вызываться, только при зажатой кнопке мыши - // (т.е. при перемещении или изменении размера виджета) - const QRectF calculateGeometryWithFixedProportions(const QRectF &_sourceGeometry, - const CursorPosition _cursorPosition, - const QPointF &_mouseDelta, - const QSizeF &_deltas - ); - -private: - // Private data implementation - ImageCropperPrivate* pimpl; -}; - -#endif // IMAGECROPPER_H diff --git a/anpro/imagecropper_e.h b/anpro/imagecropper_e.h deleted file mode 100644 index a9ced6a..0000000 --- a/anpro/imagecropper_e.h +++ /dev/null @@ -1,36 +0,0 @@ -/***************************************************************************** -* ImageCropper Qt Widget for cropping images -* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef IMAGECROPPER_E_H -#define IMAGECROPPER_E_H - -enum CursorPosition -{ - CursorPositionUndefined, - CursorPositionMiddle, - CursorPositionTop, - CursorPositionBottom, - CursorPositionLeft, - CursorPositionRight, - CursorPositionTopLeft, - CursorPositionTopRight, - CursorPositionBottomLeft, - CursorPositionBottomRight -}; - -#endif // IMAGECROPPER_E_H diff --git a/anpro/imagecropper_p.h b/anpro/imagecropper_p.h deleted file mode 100644 index bd09dbb..0000000 --- a/anpro/imagecropper_p.h +++ /dev/null @@ -1,76 +0,0 @@ -/***************************************************************************** -* ImageCropper Qt Widget for cropping images -* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef IMAGECROPPER_P_H -#define IMAGECROPPER_P_H - -#include "imagecropper_e.h" - -#include -#include -#include - -namespace { - const QRect INIT_CROPPING_RECT = QRect(); - const QSizeF INIT_PROPORTION = QSizeF(1.0, 1.0); -} - -class ImageCropperPrivate { -public: - ImageCropperPrivate() : - imageForCropping(QPixmap()), - croppingRect(INIT_CROPPING_RECT), - lastStaticCroppingRect(QRect()), - cursorPosition(CursorPositionUndefined), - isMousePressed(false), - isProportionFixed(false), - startMousePos(QPoint()), - proportion(INIT_PROPORTION), - deltas(INIT_PROPORTION), - backgroundColor(Qt::black), - croppingRectBorderColor(Qt::white) - {} - -public: - // Изображение для обрезки - QPixmap imageForCropping; - // Область обрезки - QRectF croppingRect; - // Последняя фиксированная область обрезки - QRectF lastStaticCroppingRect; - // Позиция курсора относительно области обрезки - CursorPosition cursorPosition; - // Зажата ли левая кнопка мыши - bool isMousePressed; - // Фиксировать пропорции области обрезки - bool isProportionFixed; - // Начальная позиция курсора при изменении размера области обрезки - QPointF startMousePos; - // Пропорции - QSizeF proportion; - // Приращения - // width - приращение по x - // height - приращение по y - QSizeF deltas; - // Цвет заливки фона под изображением - QColor backgroundColor; - // Цвет рамки области обрезки - QColor croppingRectBorderColor; -}; - -#endif // IMAGECROPPER_P_H diff --git a/config.h b/config.h old mode 100644 new mode 100755 index 6f96056..a9f638f --- a/config.h +++ b/config.h @@ -1,124 +1,73 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef CONFIG_H -#define CONFIG_H - -#if __cplusplus -#include -#define REL_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Release") -#define RC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Release Candidate") -#define BETA_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Beta") -#define ALPHA_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Alpha") -#define DEV_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Developer") -#define DAILY_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Daily Build") -#define CUSTOM_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Custom") -#endif - -#ifndef GTA5SYNC_APPVENDOR -#define GTA5SYNC_APPVENDOR "Syping" -#endif - -#ifndef GTA5SYNC_APPVENDORLINK -#define GTA5SYNC_APPVENDORLINK "g5e://about?U3lwaW5n:R2l0TGFiOiA8YSBocmVmPSJodHRwczovL2dpdGxhYi5jb20vU3lwaW5nIj5TeXBpbmc8L2E+PGJyLz5HaXRIdWI6IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9TeXBpbmciPlN5cGluZzwvYT48YnIvPlNvY2lhbCBDbHViOiA8YSBocmVmPSJodHRwczovL3NvY2lhbGNsdWIucm9ja3N0YXJnYW1lcy5jb20vbWVtYmVyL1N5cGluZy80NjMwMzA1NiI+U3lwaW5nPC9hPg" -#endif - -#ifndef GTA5SYNC_APPSTR -#define GTA5SYNC_APPSTR "gta5view" -#endif - -#ifndef GTA5SYNC_APPDES -#define GTA5SYNC_APPDES "INSERT YOUR APPLICATION DESCRIPTION HERE" -#endif - -#ifndef GTA5SYNC_COPYRIGHT -#define GTA5SYNC_COPYRIGHT "2016-2023" -#endif - -#ifndef GTA5SYNC_APPVER -#define GTA5SYNC_APPVER "1.10.2" -#endif - -#if __cplusplus -#ifndef GTA5SYNC_BUILDTYPE -#define GTA5SYNC_BUILDTYPE QT_TRANSLATE_NOOP("AboutDialog", "Custom") -#endif - -#ifndef GTA5SYNC_BUILDCODE -#define GTA5SYNC_BUILDCODE "Source" -#endif - -#ifdef GTA5SYNC_QCONF -#ifndef GTA5SYNC_SHARE -#ifdef Q_OS_WIN -#define GTA5SYNC_SHARE "RUNDIR:" -#else -#define GTA5SYNC_SHARE "RUNDIR:/../share" -#endif -#endif -#ifndef GTA5SYNC_LANG -#define GTA5SYNC_LANG "QCONFLANG:" -#endif -#ifndef GTA5SYNC_PLUG -#define GTA5SYNC_PLUG "QCONFPLUG:" -#endif -#ifdef GTA5SYNC_QCONF_IN -#ifndef GTA5SYNC_INLANG -#define GTA5SYNC_INLANG ":/tr" -#endif -#endif -#else -#ifndef GTA5SYNC_SHARE -#define GTA5SYNC_SHARE "RUNDIR:" -#endif -#ifndef GTA5SYNC_LANG -#define GTA5SYNC_LANG "SHAREDDIR:/lang" -#endif -#ifndef GTA5SYNC_PLUG -#define GTA5SYNC_PLUG "RUNDIR:/plugins" -#endif -#endif - -#ifndef GTA5SYNC_COMPILER -#ifdef __clang__ -#ifndef Q_OS_MAC -#define GTA5SYNC_COMPILER QString("Clang %1.%2.%3").arg(QString::number(__clang_major__), QString::number(__clang_minor__), QString::number(__clang_patchlevel__)) -#else -#define GTA5SYNC_COMPILER QString("Apple LLVM %1.%2.%3").arg(QString::number(__clang_major__), QString::number(__clang_minor__), QString::number(__clang_patchlevel__)) -#endif -#elif defined(__GNUC__) -#define GTA5SYNC_COMPILER QString("GCC %1.%2.%3").arg(QString::number(__GNUC__), QString::number(__GNUC_MINOR__), QString::number(__GNUC_PATCHLEVEL__)) -#elif defined(__GNUG__) -#define GTA5SYNC_COMPILER QString("GCC %1.%2.%3").arg(QString::number(__GNUG__), QString::number(__GNUC_MINOR__), QString::number(__GNUC_PATCHLEVEL__)) -#elif defined(_MSC_VER) -#define GTA5SYNC_COMPILER QString("MSVC %1").arg(QString::number(_MSC_VER).insert(2, ".")) -#else -#define GTA5SYNC_COMPILER QString("Unknown Compiler") -#endif -#endif - -#ifndef GTA5SYNC_BUILDDATETIME -#define GTA5SYNC_BUILDDATETIME QString("%1, %2").arg(__DATE__, __TIME__) -#endif - -#ifndef GTA5SYNC_BUILDSTRING -#define GTA5SYNC_BUILDSTRING QString("%1, %2").arg(QT_VERSION_STR, GTA5SYNC_COMPILER) -#endif -#endif - -#endif // CONFIG_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef CONFIG_H +#define CONFIG_H +#include + +#ifndef GTA5SYNC_APPVENDOR +#define GTA5SYNC_APPVENDOR "Syping" +#endif + +#ifndef GTA5SYNC_APPSTR +#define GTA5SYNC_APPSTR "gta5view" +#endif + +#ifndef GTA5SYNC_APPVER +#ifndef GTA5SYNC_DAILYB +#define GTA5SYNC_APPVER "1.1.1" +#else +#define GTA5SYNC_APPVER QString("%1").arg(GTA5SYNC_DAILYB) +#endif +#endif + +#ifndef GTA5SYNC_BUILDTYPE +#define GTA5SYNC_BUILDTYPE "Custom" +#endif + +#ifndef GTA5SYNC_SHARE +#define GTA5SYNC_SHARE "$RUNDIR" +#endif + +#ifndef GTA5SYNC_LANG +#define GTA5SYNC_LANG "$SHAREDIR$SEPARATORlang" +#endif + +#ifndef GTA5SYNC_PLUG +#define GTA5SYNC_PLUG "$RUNDIR$SEPARATORplugins" +#endif + +#ifdef GTA5SYNC_WINRT +#undef GTA5SYNC_WIN +#endif + +#ifndef GTA5SYNC_COMPILER +#ifdef __clang__ +#define GTA5SYNC_COMPILER QString("Clang %1.%2.%3").arg(QString::number(__clang_major__), QString::number(__clang_minor__), QString::number(__clang_patchlevel__)) +#elif defined(__GNUC__) +#define GTA5SYNC_COMPILER QString("GCC %1.%2.%3").arg(QString::number(__GNUC__), QString::number(__GNUC_MINOR__), QString::number(__GNUC_PATCHLEVEL__)) +#elif defined(__GNUG__) +#define GTA5SYNC_COMPILER QString("GCC %1.%2.%3").arg(QString::number(__GNUG__), QString::number(__GNUC_MINOR__), QString::number(__GNUC_PATCHLEVEL__)) +#elif defined(_MSC_VER) +#define GTA5SYNC_COMPILER QString("MSVC %1").arg(QString::number(_MSC_VER).insert(2, ".")) +#else +#define GTA5SYNC_COMPILER QString("Unknown Compiler") +#endif +#endif + +#endif // CONFIG_H diff --git a/gta5view.pro b/gta5view.pro old mode 100644 new mode 100755 index 9326210..f5a0fb7 --- a/gta5view.pro +++ b/gta5view.pro @@ -1,285 +1,155 @@ -#/***************************************************************************** -#* gta5view Grand Theft Auto V Profile Viewer -#* Copyright (C) 2015-2021 Syping -#* -#* This program is free software: you can redistribute it and/or modify -#* it under the terms of the GNU General Public License as published by -#* the Free Software Foundation, either version 3 of the License, or -#* (at your option) any later version. -#* -#* This program is distributed in the hope that it will be useful, -#* but WITHOUT ANY WARRANTY; without even the implied warranty of -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#* GNU General Public License for more details. -#* -#* You should have received a copy of the GNU General Public License -#* along with this program. If not, see . -#*****************************************************************************/ - -QT += core gui network svg - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -greaterThan(QT_MAJOR_VERSION, 4): win32: LIBS += -ldwmapi - -DEPLOYMENT.display_name = gta5view -TARGET = gta5view -TEMPLATE = app - -HEADERS += config.h \ - wrapper.h -PRECOMPILED_HEADER += config.h - -SOURCES += main.cpp \ - AboutDialog.cpp \ - AppEnv.cpp \ - CrewDatabase.cpp \ - DatabaseThread.cpp \ - ExportDialog.cpp \ - ExportThread.cpp \ - GlobalString.cpp \ - IconLoader.cpp \ - ImportDialog.cpp \ - JsonEditorDialog.cpp \ - MapLocationDialog.cpp \ - MessageThread.cpp \ - OptionsDialog.cpp \ - PictureDialog.cpp \ - PictureExport.cpp \ - PictureWidget.cpp \ - PlayerListDialog.cpp \ - ProfileDatabase.cpp \ - ProfileInterface.cpp \ - ProfileLoader.cpp \ - ProfileWidget.cpp \ - RagePhoto.cpp \ - SavegameCopy.cpp \ - SavegameData.cpp \ - SavegameDialog.cpp \ - SavegameWidget.cpp \ - SidebarGenerator.cpp \ - SnapmaticEditor.cpp \ - SnapmaticPicture.cpp \ - SnapmaticWidget.cpp \ - StandardPaths.cpp \ - StringParser.cpp \ - TelemetryClass.cpp \ - TranslationClass.cpp \ - UserInterface.cpp \ - anpro/imagecropper.cpp \ - pcg/pcg_basic.c \ - tmext/TelemetryClassAuthenticator.cpp \ - uimod/JSHighlighter.cpp \ - uimod/UiModLabel.cpp \ - uimod/UiModWidget.cpp - -HEADERS += \ - AboutDialog.h \ - AppEnv.h \ - CrewDatabase.h \ - DatabaseThread.h \ - ExportDialog.h \ - ExportThread.h \ - GlobalString.h \ - IconLoader.h \ - ImportDialog.h \ - JsonEditorDialog.h \ - MapLocationDialog.h \ - MessageThread.h \ - OptionsDialog.h \ - PictureDialog.h \ - PictureExport.h \ - PictureWidget.h \ - PlayerListDialog.h \ - ProfileDatabase.h \ - ProfileInterface.h \ - ProfileLoader.h \ - ProfileWidget.h \ - RagePhoto.h \ - SavegameCopy.h \ - SavegameData.h \ - SavegameDialog.h \ - SavegameWidget.h \ - SidebarGenerator.h \ - SnapmaticEditor.h \ - SnapmaticPicture.h \ - SnapmaticWidget.h \ - StandardPaths.h \ - StringParser.h \ - TelemetryClass.h \ - TranslationClass.h \ - UserInterface.h \ - anpro/imagecropper.h \ - anpro/imagecropper_e.h \ - anpro/imagecropper_p.h \ - pcg/pcg_basic.h \ - tmext/TelemetryClassAuthenticator.h \ - uimod/JSHighlighter.h \ - uimod/UiModLabel.h \ - uimod/UiModWidget.h - -FORMS += \ - AboutDialog.ui \ - ExportDialog.ui \ - ImportDialog.ui \ - JsonEditorDialog.ui \ - MapLocationDialog.ui \ - OptionsDialog.ui \ - PictureDialog.ui \ - PlayerListDialog.ui \ - ProfileInterface.ui \ - SavegameDialog.ui \ - SavegameWidget.ui \ - SnapmaticEditor.ui \ - SnapmaticWidget.ui \ - UserInterface.ui - -TRANSLATIONS += \ - res/gta5sync.ts \ - res/gta5sync_de.ts \ - res/gta5sync_en_US.ts \ - res/gta5sync_fr.ts \ - res/gta5sync_ko.ts \ - res/gta5sync_ru.ts \ - res/gta5sync_uk.ts \ - res/gta5sync_zh_TW.ts - -RESOURCES += \ - res/img.qrc \ - res/template.qrc \ - res/tr_g5p.qrc - -DISTFILES += \ - res/gta5view-16.png \ - res/gta5view-24.png \ - res/gta5view-32.png \ - res/gta5view-40.png \ - res/gta5view-48.png \ - res/gta5view-64.png \ - res/gta5view-96.png \ - res/gta5view-128.png \ - res/gta5view-256.png \ - res/gta5view-512.png \ - res/app.rc \ - res/de.syping.gta5view.desktop \ - res/de.syping.gta5view.png \ - res/gta5sync_de.ts \ - res/gta5sync_en_US.ts \ - res/gta5sync_fr.ts \ - res/gta5sync_ko.ts \ - res/gta5sync_ru.ts \ - res/gta5sync_uk.ts \ - res/gta5sync_zh_TW.ts \ - res/gta5view.exe.manifest \ - res/gta5view.png \ - lang/README.txt - -INCLUDEPATH += ./anpro ./pcg ./tmext ./uimod - -# GTA5SYNC/GTA5VIEW ONLY - -DEFINES += GTA5SYNC_QMAKE # We using qmake do we? -DEFINES += GTA5SYNC_PROJECT # Enable exclusive gta5sync/gta5view functions - -# WINDOWS ONLY - -win32: RC_FILE += res/app.rc -win32: CONFIG -= embed_manifest_exe -contains(DEFINES, GTA5SYNC_TELEMETRY): win32: LIBS += -ld3d9 # Required for getting information about GPU - -# MAC OS X ONLY -macx: ICON = res/gta5view.icns - -# QT4 ONLY STUFF - -isEqual(QT_MAJOR_VERSION, 4): INCLUDEPATH += ./qjson4 -isEqual(QT_MAJOR_VERSION, 4): HEADERS += qjson4/QJsonArray.h \ - qjson4/QJsonDocument.h \ - qjson4/QJsonObject.h \ - qjson4/QJsonParseError.h \ - qjson4/QJsonValue.h \ - qjson4/QJsonValueRef.h \ - qjson4/QJsonParser.h \ - qjson4/QJsonRoot.h - -isEqual(QT_MAJOR_VERSION, 4): SOURCES += qjson4/QJsonArray.cpp \ - qjson4/QJsonDocument.cpp \ - qjson4/QJsonObject.cpp \ - qjson4/QJsonParseError.cpp \ - qjson4/QJsonValue.cpp \ - qjson4/QJsonValueRef.cpp \ - qjson4/QJsonParser.cpp - -isEqual(QT_MAJOR_VERSION, 4): RESOURCES += res/qt4/tr_qt.qrc -isEqual(QT_MAJOR_VERSION, 4): GTA5SYNC_RCC = $$[QT_INSTALL_BINS]/rcc - -# QT5 ONLY STUFF - -isEqual(QT_MAJOR_VERSION, 5): RESOURCES += res/qt5/tr_qt.qrc - -# QT5+ ONLY STUFF - -greaterThan(QT_MAJOR_VERSION, 4): GTA5SYNC_RCC = $$[QT_HOST_BINS]/rcc - -# QT6 ONLY STUFF - -isEqual(QT_MAJOR_VERSION, 6): RESOURCES += res/qt6/tr_qt.qrc - -# RESOURCE COMPILATION - -system($$GTA5SYNC_RCC -threshold 0 -compress 9 $$PWD/res/global.qrc -o $$OUT_PWD/qrc_global.cpp) { - SOURCES += $$OUT_PWD/qrc_global.cpp -} else { - message("Failed to generate qrc_global.cpp") -} - -# PROJECT INSTALLATION - -isEmpty(GTA5SYNC_PREFIX): GTA5SYNC_PREFIX = /usr/local - -appfiles.path = $$GTA5SYNC_PREFIX/share/applications -appfiles.files = $$PWD/res/de.syping.gta5view.desktop -pixmaps.path = $$GTA5SYNC_PREFIX/share/pixmaps -pixmaps.files = $$PWD/res/de.syping.gta5view.png -target.path = $$GTA5SYNC_PREFIX/bin -INSTALLS += target pixmaps appfiles - -# QCONF BASED BUILD STUFF - -contains(DEFINES, GTA5SYNC_QCONF) { - isEqual(QT_MAJOR_VERSION, 4): RESOURCES -= res/qt4/tr_qt.qrc - isEqual(QT_MAJOR_VERSION, 5): RESOURCES -= res/qt5/tr_qt.qrc - isEqual(QT_MAJOR_VERSION, 6): RESOURCES -= res/qt6/tr_qt.qrc - !contains(DEFINES, GTA5SYNC_QCONF_IN) { - RESOURCES -= res/tr_g5p.qrc - langfiles.path = $$GTA5SYNC_PREFIX/share/gta5view/translations - langfiles.files = $$PWD/res/gta5sync_en_US.qm $$PWD/res/gta5sync_de.qm $$PWD/res/gta5sync_fr.qm $$PWD/res/gta5sync_ko.qm $$PWD/res/gta5sync_ru.qm $$PWD/res/gta5sync_uk.qm $$PWD/res/gta5sync_zh_TW.qm $$PWD/res/qtbase_en_GB.qm - INSTALLS += langfiles - } -} - -# TELEMETRY BASED STUFF - -!contains(DEFINES, GTA5SYNC_TELEMETRY) { - SOURCES -= TelemetryClass.cpp \ - tmext/TelemetryClassAuthenticator.cpp - HEADERS -= TelemetryClass.h \ - tmext/TelemetryClassAuthenticator.h -} - -!contains(DEFINES, GTA5SYNC_MOTD) { - SOURCES -= MessageThread.cpp - HEADERS -= MessageThread.h -} else { - lessThan(QT_MAJOR_VERSION, 5) { - SOURCES -= MessageThread.cpp - HEADERS -= MessageThread.h - DEFINES -= GTA5SYNC_MOTD - message("Messages require Qt5 or newer!") - } -} - -# CMAKE BASED STUFF - -greaterThan(QT_MAJOR_VERSION, 4) { - message("Building gta5view with QMake is deprecated, please use CMake instead!") -} +#/***************************************************************************** +#* gta5view Grand Theft Auto V Profile Viewer +#* Copyright (C) 2015-2016 Syping +#* +#* This program is free software: you can redistribute it and/or modify +#* it under the terms of the GNU General Public License as published by +#* the Free Software Foundation, either version 3 of the License, or +#* (at your option) any later version. +#* +#* This program is distributed in the hope that it will be useful, +#* but WITHOUT ANY WARRANTY; without even the implied warranty of +#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#* GNU General Public License for more details. +#* +#* You should have received a copy of the GNU General Public License +#* along with this program. If not, see . +#*****************************************************************************/ + +QT += core gui network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +greaterThan(QT_MAJOR_VERSION, 4): greaterThan(QT_MINOR_VERSION, 1): win32: QT += winextras + +DEPLOYMENT.display_name = gta5view +TARGET = gta5view +TEMPLATE = app + +SOURCES += main.cpp \ + AboutDialog.cpp \ + AppEnv.cpp \ + CrewDatabase.cpp \ + DatabaseThread.cpp \ + ExportDialog.cpp \ + ExportThread.cpp \ + GlobalString.cpp \ + IconLoader.cpp \ + OptionsDialog.cpp \ + PictureCopy.cpp \ + PictureDialog.cpp \ + PictureExport.cpp \ + PictureWidget.cpp \ + ProfileDatabase.cpp \ + ProfileInterface.cpp \ + ProfileLoader.cpp \ + ProfileWidget.cpp \ + SavegameCopy.cpp \ + SavegameData.cpp \ + SavegameDialog.cpp \ + SavegameWidget.cpp \ + SidebarGenerator.cpp \ + SnapmaticEditor.cpp \ + SnapmaticPicture.cpp \ + SnapmaticWidget.cpp \ + StandardPaths.cpp \ + StringParser.cpp \ + UserInterface.cpp \ + uimod/UiModLabel.cpp + +HEADERS += \ + AboutDialog.h \ + AppEnv.h \ + config.h \ + CrewDatabase.h \ + DatabaseThread.h \ + ExportDialog.h \ + ExportThread.h \ + GlobalString.h \ + IconLoader.h \ + OptionsDialog.h \ + PictureCopy.h \ + PictureDialog.h \ + PictureExport.h \ + PictureWidget.h \ + ProfileDatabase.h \ + ProfileInterface.h \ + ProfileLoader.h \ + ProfileWidget.h \ + SavegameCopy.h \ + SavegameData.h \ + SavegameDialog.h \ + SavegameWidget.h \ + SidebarGenerator.h \ + SnapmaticEditor.h \ + SnapmaticPicture.h \ + SnapmaticWidget.h \ + StandardPaths.h \ + StringParser.h \ + UserInterface.h \ + uimod/UiModLabel.h + +FORMS += \ + AboutDialog.ui \ + ExportDialog.ui \ + OptionsDialog.ui \ + PictureDialog.ui \ + ProfileInterface.ui \ + SavegameDialog.ui \ + SavegameWidget.ui \ + SnapmaticEditor.ui \ + SnapmaticWidget.ui \ + UserInterface.ui + +TRANSLATIONS += \ + res/gta5sync_de.ts \ + res/gta5sync_fr.ts \ + lang/gta5sync_ru.ts + +RESOURCES += \ + res/app.qrc + +DISTFILES += res/app.rc \ + res/gta5sync.desktop \ + res/gta5sync_de.ts \ + res/gta5sync_fr.ts \ + lang/qtbase_ru.qm \ + lang/gta5sync_ru.ts \ + lang/qt_ru.qm \ + lang/README.txt + +INCLUDEPATH += ./uimod + +# WINDOWS ONLY + +win32: DEFINES += GTA5SYNC_WIN +win32: RC_FILE += res/app.rc +win32: LIBS += -luser32 + +# QT4 ONLY STUFF + +isEqual(QT_MAJOR_VERSION, 4): INCLUDEPATH += ./qjson4 +isEqual(QT_MAJOR_VERSION, 4): HEADERS += qjson4/QJsonArray.h \ + qjson4/QJsonDocument.h \ + qjson4/QJsonObject.h \ + qjson4/QJsonParseError.h \ + qjson4/QJsonValue.h \ + qjson4/QJsonValueRef.h \ + qjson4/QJsonParser.h \ + qjson4/QJsonRoot.h + +isEqual(QT_MAJOR_VERSION, 4): SOURCES += qjson4/QJsonArray.cpp \ + qjson4/QJsonDocument.cpp \ + qjson4/QJsonObject.cpp \ + qjson4/QJsonParseError.cpp \ + qjson4/QJsonValue.cpp \ + qjson4/QJsonValueRef.cpp \ + qjson4/QJsonParser.cpp + +# UNIX SYSTEM STUFF + +unix: !macx: appfiles.path = $$(INSTALL_PATH)/share/applications +unix: !macx: appfiles.files = $$PWD/res/gta5view.desktop +unix: !macx: pixmaps.path = $$(INSTALL_PATH)/share/pixmaps +unix: !macx: pixmaps.files = $$PWD/res/gta5view.xpm +unix: !macx: target.path = $$(INSTALL_PATH)/bin +unix: !macx: INSTALLS += target pixmaps appfiles diff --git a/lang/README.txt b/lang/README.txt old mode 100644 new mode 100755 index fd72055..c21786f --- a/lang/README.txt +++ b/lang/README.txt @@ -2,4 +2,4 @@ Community translation files They get loaded in ApplicationPathExecFileFolder/lang -You can help translate with using Qt Linguist, after you've translated you'll need to send me a pull request on https://github.com/SyDevTeam/gta5view +You can help translate with using Qt Linguist, after you've translated you'll need to send me a pull request on https://github.com/Syping/gta5sync diff --git a/lang/gta5sync_ru.qm b/lang/gta5sync_ru.qm new file mode 100755 index 0000000..ef6b45b Binary files /dev/null and b/lang/gta5sync_ru.qm differ diff --git a/lang/gta5sync_ru.ts b/lang/gta5sync_ru.ts new file mode 100755 index 0000000..3c855fb --- /dev/null +++ b/lang/gta5sync_ru.ts @@ -0,0 +1,1418 @@ + + + + + AboutDialog + + About gta5sync + О программе gta5sync + + + + About gta5view + + + + + <span style=" font-weight:600;">gta5view</span><br/> +<br/> +A project for viewing Grand Theft Auto V Snapmatic<br/> +Pictures and Savegames<br/> +<br/> +Project version: %1<br/> +Project build: %4, %5<br/> +Compiled with Qt %2<br/> +Running with Qt %3<br/> +<br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5view is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + + + + + &Close + + + + <span style=" font-weight:600;">gta5sync</span><br/><br/>A project for viewing and sync Grand Theft Auto 5 Snapmatic Pictures and Savegames<br/><br/>Project version: %1<br/>Compiled with Qt %2<br/>Running with Qt %3<br/><br/>Copyright © <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + <span style=" font-weight:600;">gta5sync</span><br/><br/>Проект для просмотра и синхронизации фотографий Snapmatic и сохранений от Grand Theft Auto 5<br/><br/>Версия проекта: %1<br/>Скомпилировано с Qt %2<br/>Работает на Qt %3<br/><br/>Copyright © <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync лицензирован по <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + + + Close + Закрыть + + + + ExportDialog + + + Dialog + + + + + &JPEG/PNG format + + + + + GTA &Snapmatic format + + + + + Export Format + + + + + Export Size + + + + + Default &Size + + + + + &Desktop Size + + + + + &Custom Size + + + + + Custom Size: + + + + + x + + + + + &Export + + + + + &Close + + + + + OptionsDialog + + + Content Open/Select Mode + + + + + Open with Singleclick + + + + + Open with Doubleclick + + + + + Select with Singleclick + + + + + Default Profile + + + + + Pictures + + + + + Export Size + + + + + Screen Resolution: %1x%2 + + + + + Default: %1x%2 + + + + + %1 - Settings + + + + + Profiles + + + + + Custom GTA V Folder + + + + + Force using Custom Folder + + + + + ... + + + + + + Custom Size: + + + + + x + + + + + Ignore Aspect Ratio + + + + + Export Quality + + + + + Enable Custom Quality + + + + + Quality: + + + + + %1% + + + + + Picture Viewer + + + + + Enable Navigation Bar + + + + + Players + + + + + ID + + + + + Name + + + + + + Language + + + + + &OK + OK, Cancel, Apply + + + + + &Cancel + OK, Cancel, Apply + + + + + System + System like PC System + + + + + %1 (%2 if available) + System like PC System = %1, System Language like Deutsch = %2 + + + + + + %1 + %1 + + + + + The new Custom Folder will initialize after you restart %1. + + + + + The language change will take effect after you restart %1. + + + + + No Profile + No Profile, as default + + + + + + + Profile: %1 + + + + + PictureDialog + + + %1 - Snapmatic Picture Viewer + %1 - Просмотрщик фотографий Snapmatic + + + <span style=" font-weight:600;">Title: </span>%6<br> +<span style=" font-weight:600;">Location: </span>%1, %2, %3 <br> +<span style=" font-weight:600;">Players: </span>%4<br> +<span style=" font-weight:600;">Crew ID: </span>%5 + <span style=" font-weight:600;">Заголовок: </span>%6<br> +<span style=" font-weight:600;">Позиция: </span>%1, %2, %3 <br> +<span style=" font-weight:600;">Игроки: </span>%4<br> +<span style=" font-weight:600;">ID группы: </span>%5 + + + + <span style=" font-weight:600;">Title: </span>%6<br/> +<span style=" font-weight:600;">Location: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Players: </span>%4 (Crew %5)<br/> +<span style=" font-weight:600;">Created: </span>%8 + + + + + Export picture + Экспорт картинки + + + + + &Export + + + + + &Close + + + + + Export + Экспорт + + + Copy + Копировать + + + + Close + Закрыть + + + + Export as &JPG picture... + + + + + Export as &GTA Snapmatic... + + + + + + Snapmatic Picture Viewer + Просмотрщик фотографий Snapmatic + + + + + Failed at %1 + Ошибка при %1 + + + + + No player + Игроков нет + + + + + No crew + Без группы + + + + Unknown Location + + + + + Export as JPG picture... + + + + + JPEG picture (*.jpg) + Картинка JPEG (*.jpg) + + + + Portable Network Graphics (*.png) + Картинка Portable Network Graphics (*.png) + + + + + + + Export as JPG picture + + + + + + Overwrite %1 with current Snapmatic picture? + Перезаписать %1 текущей картинкой Snapmatic? + + + + + + + Export as GTA Snapmatic + + + + + + Failed to overwrite %1 with current Snapmatic picture + Не удалось перезаписать %1 картинкой Snapmatic + + + + Failed to export current Snapmatic picture + Не удалось экспортировать текущую картинку Snapmatic + + + + + No valid file is selected + Выбранный файл неверен + + + Copy picture + Скопировать картинку + + + + Export as GTA Snapmatic... + + + + + Snapmatic pictures (PGTA*) + Картинки Snapmatic (PGTA*) + + + + All files (**) + Все файлы (**) + + + + Failed to copy current Snapmatic picture + Не удалось скопировать текущую картинку Snapmatic + + + + ProfileInterface + + + Profile Interface + Интерфейс профиля + + + + Loading file %1 of %2 files + Загружается файл %1 из %2 + + + + %1 %2 + + + + + Import exported file + + + + + &Import... + + + + + Close profile + + + + + &Close + + + + Import copy + Импортировать копию + + + Close Profile + Закрыть профиль + + + + Loading... + Загрузка... + + + + Import... + + + + + + + + + + + + + + + + Import + + + + + + All profile files (SGTA* PGTA*) + Все файлы профиля (SGTA* PGTA*) + + + + + Savegames files (SGTA*) + Файлы сохранения (SGTA*) + + + + + Snapmatic pictures (PGTA*) + Картинка Snapmatic (PGTA*) + + + + + All files (**) + Все файлы (**) + + + + Import failed with... + +%1 + + + + + + Failed to read Snapmatic picture + Не удалось загрузить картинку Snapmatic + + + + + Failed to read Savegame file + Не удалось загрузить файл сохранения + + + + Can't import %1 because of not valid file format + Не получилось импортировать %1 из-за неправильного формата файла + + + + + + No valid file is selected + Выбранный файл неверен + + + + Enabled pictures: %1 of %2 + + + + + Failed to import the Snapmatic picture, file not begin with PGTA + + + + + Failed to import the Snapmatic picture, the picture is already in the game + + + + + Failed to import the Snapmatic picture, can't copy the file into profile + + + + + Failed to import the Savegame, can't copy the file into profile + + + + + Failed to import the Savegame, no Savegame slot is left + + + + + + JPG pictures and GTA Snapmatic + + + + + + JPG pictures only + + + + + + GTA Snapmatic only + + + + + + No Snapmatic pictures or Savegames files are selected + + + + + + + Remove selected + + + + + You really want remove the selected Snapmatic picutres and Savegame files? + + + + + Failed at remove the complete selected Snapmatic pictures and/or Savegame files + + + + Failed to import copy of Snapmatic picture because the file not begin with PGTA + Не удалось имортировать копию картинки Snapmatic, т.к. файл не начинается с PGTA + + + Failed to import copy of Snapmatic picture because the copy failed + Не получилось имортировать копию картинки Snapmatic, потому что не удалось его скопировать + + + Failed to import copy of Savegame file because the copy failed + Не получилось имортировать копию сохранения, потому что не удалось его скопировать + + + Failed to import copy of Savegame file because no free Savegame slot left + Не получилось имортировать копию сохранения, потому что не осталось свободных под них слотов + + + + + + + Export selected + + + + + %1Export Snapmatic pictures%2<br><br>JPG pictures make it possible to open the picture with a Image Viewer<br>GTA Snapmatic make it possible to import the picture into the game<br><br>Export as: + + + + + Export selected... + + + + + Initializing export... + + + + + Export failed with... + +%1 + + + + + + + Export file %1 of %2 files + + + + + QApplication + + + Font + + + + + Selected Font: %1 + + + + + SavegameDialog + + + + Savegame Viewer + Просмотрщик сохранений + + + + <span style=" font-weight:600;">Savegame</span><br><br>%1 + <span style=" font-weight:600;">Сохранение</span><br><br>%1 + + + + &Export + + + + + &Close + + + + Copy + Копировать + + + Close + Закрыть + + + + Failed at %1 + Ошибка при %1 + + + + SavegameWidget + + + Savegame Widget + Виджет сохранений + + + The Third Way (100%) - 00/00/00 00:00:00 + Третий путь (100%) - 00/00/00 00:00:00 + + + + View savegame + + + + + View + Просмотр + + + + Export + Экспорт + + + Copy + Копировать + + + + Delete + Удалить + + + + + + Delete savegame + Удалить сохранение + + + + Export Savegame... + + + + + SAVE %3 - %1<br>%2 + + + + + + WRONG FORMAT + + + + + AUTOSAVE - %1 +%2 + + + + + SAVE %3 - %1 +%2 + + + + + UNKNOWN + + + + + Are you sure to delete %1 from your savegames? + Вы уверены, что хотите удалить сохранение %1? + + + + Failed at deleting %1 from your savegames + Не удалось удалить сохранение %1 + + + + &View + + + + + &Remove + + + + + + &Select + + + + + &Deselect + + + + + + Select &All + + + + + &Deselect All + + + + + Copy savegame + Копировать сохранение + + + + + &Export + + + + + Savegame files (SGTA*) + Файлы сохранений (SGTA*) + + + + All files (**) + Все файлы (**) + + + + + + + Export Savegame + + + + + Overwrite %1 with current Savegame? + + + + + Failed to overwrite %1 with current Savegame + + + + + Failed to export current Savegame + + + + Overwrite %1 with current savegame? + Перезаписать %1 текущим сохранением? + + + Failed to overwrite %1 with current savegame + Не удалось перезаписать %1 текущим сохранением + + + Failed to copy current savegame + Не удалось скопировать текущее сохранение + + + + No valid file is selected + Выбранный файл неверен + + + + SnapmaticEditor + + + + + Snapmatic Properties + + + + + Snapmatic Type + + + + + + Editor + + + + + + Selfie + + + + + Regular + + + + + + Mugshot + + + + + Director + + + + + Meme + + + + + Extras + + + + + Qualify as Avatar automatically at apply + + + + + Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture + + + + + &Apply + + + + + &Cancel + + + + + Patching of Snapmatic Properties failed because of I/O Error + + + + + SnapmaticWidget + + + Snapmatic Widget + Виджет Snapmatic + + + + PHOTO - 00/00/00 00:00:00 + ФОТО - 00/00/00 00:00:00 + + + + View picture + + + + + View + Просмотр + + + + Copy + Копировать + + + + Export + Экспорт + + + + Delete + Удалить + + + + + + Delete picture + Удалить картинку + + + + Are you sure to delete %1 from your Snapmatic pictures? + Уверены, что хотите удалить %1 из коллекции картинок Snapmatic? + + + + Failed at deleting %1 from your Snapmatic pictures + Не удалось удалить %1 из колелкции картинок Snapmatic + + + + Edi&t + + + + + Show &In-game + + + + + Hide &In-game + + + + + &Edit Properties... + + + + + &Export + + + + + Export as &JPG picture... + + + + + Export as &GTA Snapmatic... + + + + + &View + + + + + &Remove + + + + + + &Select + + + + + &Deselect + + + + + + Select &All + + + + + &Deselect All + + + + + Copy picture + Скопировать картинку + + + + Export picture + Экспорт картинки + + + + UserInterface + + gta5sync - %1 + gta5sync - %1 + + + + Select profile + Выбор профиля + + + + %1 %2 + + + + + &File + + + + + &Help + + + + + &Edit + + + + + &Profile + + + + + &Exit + + + + + Exit + + + + + Close &Profile + + + + + Ctrl+End + + + + + &Settings + + + + + Ctrl+Del + + + + + &Import files... + + + + + Ctrl+I + + + + + + Select &GTA V Folder... + + + + + Ctrl+G + + + + + Show In-gam&e + + + + + Shift+E + + + + + Hi&de In-game + + + + + Shift+D + + + + + &Close + + + + + gta5view - %1 + + + + + &Selection visibility + + + + + &About gta5view + + + + + Select &All + + + + + &Deselect All + + + + + &Export selected... + + + + + &Remove selected + + + + File + Файл + + + Help + Помощь + + + About gta5sync + О программе gta5sync + + + + Ctrl+A + Ctrl+A + + + Close + Закрыть + + + + Ctrl+Q + Ctrl+Q + + + + Ctrl+P + Ctrl+P + + + + &Open File... + + + + + Ctrl+O + + + + + Ctrl+S + + + + + Ctrl+E + + + + + Ctrl+D + + + + + + Select Profile + + + + + + + + Select GTA V Folder... + + + + + %2 - %1 + + + + + Open File... + + + + + + + + Open File + + + + + Can't open %1 because of not valid file format + + + + gta5sync + gta5sync + + + + &Reload + + + + GTA V Folder not found! + Папка GTA V не была найдена! + + + diff --git a/res/qt4/qt_ru.qm b/lang/qt_ru.qm old mode 100644 new mode 100755 similarity index 100% rename from res/qt4/qt_ru.qm rename to lang/qt_ru.qm diff --git a/lang/qtbase_ru.qm b/lang/qtbase_ru.qm new file mode 100755 index 0000000..8dba5ce Binary files /dev/null and b/lang/qtbase_ru.qm differ diff --git a/main.cpp b/main.cpp old mode 100644 new mode 100755 index 350d430..e58c35b --- a/main.cpp +++ b/main.cpp @@ -1,310 +1,483 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2021 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "TranslationClass.h" -#include "SnapmaticPicture.h" -#include "ProfileDatabase.h" -#include "DatabaseThread.h" -#include "SavegameDialog.h" -#include "OptionsDialog.h" -#include "PictureDialog.h" -#include "UserInterface.h" -#include "CrewDatabase.h" -#include "SavegameData.h" -#include "UiModWidget.h" -#include "UiModLabel.h" -#include "IconLoader.h" -#include "AppEnv.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if QT_VERSION < 0x060000 -#include -#endif - -#ifdef Q_OS_WIN -#include "windows.h" -#include -#endif - -#ifdef GTA5SYNC_MOTD -#include "MessageThread.h" -#endif - -#ifdef GTA5SYNC_TELEMETRY -#include "TelemetryClass.h" -#endif - -int main(int argc, char *argv[]) -{ -#if QT_VERSION >= 0x050600 -#if QT_VERSION < 0x060000 - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); - QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); -#endif -#endif - QApplication a(argc, argv); - a.setApplicationName(GTA5SYNC_APPSTR); - a.setApplicationVersion(GTA5SYNC_APPVER); - a.setQuitOnLastWindowClosed(false); - - QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - settings.beginGroup("Startup"); - -#ifdef GTA5SYNC_TELEMETRY - // Increase Start count at every startup - uint startCount = settings.value("StartCount", 0).toUInt(); - startCount++; - settings.setValue("StartCount", startCount); - settings.sync(); -#endif - - bool customStyle = settings.value("CustomStyle", false).toBool(); - if (customStyle) { - const QString appStyle = settings.value("AppStyle", "Default").toString(); - if (QStyleFactory::keys().contains(appStyle, Qt::CaseInsensitive)) { - a.setStyle(QStyleFactory::create(appStyle)); - } - } - -#ifdef Q_OS_WIN -#if QT_VERSION >= 0x060000 - a.setFont(QApplication::font("QMenu")); -#elif QT_VERSION >= 0x050400 - if (QSysInfo::windowsVersion() >= 0x0080) { - a.setFont(QApplication::font("QMenu")); - } -#endif -#endif - - bool customFont = settings.value("CustomFont", false).toBool(); - if (customFont) { - const QFont appFont = qvariant_cast(settings.value("AppFont", a.font())); - a.setFont(appFont); - } - - QStringList applicationArgs = a.arguments(); - QString selectedAction; - QString arg1; - applicationArgs.removeAt(0); - - Translator->initUserLanguage(); - Translator->loadTranslation(&a); - -#ifdef GTA5SYNC_TELEMETRY - Telemetry->init(); - Telemetry->work(); -#endif - -#ifdef GTA5SYNC_TELEMETRY - bool telemetryWindowLaunched = settings.value("PersonalUsageDataWindowLaunched", false).toBool(); - bool pushUsageData = settings.value("PushUsageData", false).toBool(); - if (!telemetryWindowLaunched && !pushUsageData) { - QDialog *telemetryDialog = new QDialog(); - telemetryDialog->setObjectName(QStringLiteral("TelemetryDialog")); - telemetryDialog->setWindowTitle(QString("%1 %2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER)); - telemetryDialog->setWindowFlags(telemetryDialog->windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowCloseButtonHint); - telemetryDialog->setWindowIcon(IconLoader::loadingAppIcon()); - QVBoxLayout *telemetryLayout = new QVBoxLayout(telemetryDialog); - telemetryLayout->setObjectName(QStringLiteral("TelemetryLayout")); - telemetryDialog->setLayout(telemetryLayout); - UiModLabel *telemetryLabel = new UiModLabel(telemetryDialog); - telemetryLabel->setObjectName(QStringLiteral("TelemetryLabel")); - telemetryLabel->setText(QString("

%2

%1").arg( - QApplication::translate("TelemetryDialog", "You want help %1 to improve in the future by including personal usage data in your submission?").arg(GTA5SYNC_APPSTR), - QApplication::translate("TelemetryDialog", "%1 User Statistics").arg(GTA5SYNC_APPSTR))); - telemetryLayout->addWidget(telemetryLabel); - QCheckBox *telemetryCheckBox = new QCheckBox(telemetryDialog); - telemetryCheckBox->setObjectName(QStringLiteral("TelemetryCheckBox")); - telemetryCheckBox->setText(QApplication::translate("TelemetryDialog", "Yes, I want include personal usage data.")); - telemetryLayout->addWidget(telemetryCheckBox); - QHBoxLayout *telemetryButtonLayout = new QHBoxLayout(); - telemetryButtonLayout->setObjectName(QStringLiteral("TelemetryButtonLayout")); - telemetryLayout->addLayout(telemetryButtonLayout); - QSpacerItem *telemetryButtonSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); - telemetryButtonLayout->addSpacerItem(telemetryButtonSpacer); - QPushButton *telemetryButton = new QPushButton(telemetryDialog); - telemetryButton->setObjectName(QStringLiteral("TelemetryButton")); - telemetryButton->setText(QApplication::translate("TelemetryDialog", "&OK")); - telemetryButtonLayout->addWidget(telemetryButton); - QObject::connect(telemetryButton, SIGNAL(clicked(bool)), telemetryDialog, SLOT(close())); - telemetryDialog->setFixedSize(telemetryDialog->sizeHint()); - telemetryDialog->exec(); - QObject::disconnect(telemetryButton, SIGNAL(clicked(bool)), telemetryDialog, SLOT(close())); - if (telemetryCheckBox->isChecked()) { - QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - telemetrySettings.beginGroup("Telemetry"); - telemetrySettings.setValue("PushUsageData", true); - telemetrySettings.setValue("PushAppConf", true); - telemetrySettings.endGroup(); - telemetrySettings.sync(); - Telemetry->init(); - Telemetry->work(); - } - settings.setValue("PersonalUsageDataWindowLaunched", true); - delete telemetryDialog; - } -#endif - settings.endGroup(); - - for (const QString ¤tArg : applicationArgs) { - QString reworkedArg; - if (currentArg.left(9) == "-showpic=" && selectedAction == "") { - reworkedArg = QString(currentArg).remove(0,9); - arg1 = reworkedArg; - selectedAction = "showpic"; - } - else if (currentArg.left(9) == "-showsgd=" && selectedAction == "") { - reworkedArg = QString(currentArg).remove(0,9); - arg1 = reworkedArg; - selectedAction = "showsgd"; - } - else if (selectedAction == "") { - QFile argumentFile(currentArg); - QFileInfo argumentFileInfo(argumentFile); - if (argumentFile.exists()) { - QString argumentFileName = argumentFileInfo.fileName(); - QString argumentFileType = argumentFileName.left(4); - QString argumentFileExt = argumentFileName.right(4); - - if (argumentFileType == "PGTA" || argumentFileExt == ".g5e") { - arg1 = currentArg; - selectedAction = "showpic"; - } - else if (argumentFileType == "SGTA") { - arg1 = currentArg; - selectedAction = "showsgd"; - } - else if (argumentFileType == "MISR") { - arg1 = currentArg; - selectedAction = "showsgd"; - } - } - } - } - - if (selectedAction == "showpic") { - CrewDatabase crewDB; - ProfileDatabase profileDB; - DatabaseThread threadDB(&crewDB); - PictureDialog picDialog(true, &profileDB, &crewDB); - SnapmaticPicture picture; - - bool readOk = picture.readingPictureFromFile(arg1); - picDialog.setWindowIcon(IconLoader::loadingAppIcon()); - picDialog.setSnapmaticPicture(&picture, readOk); - picDialog.setWindowFlags(picDialog.windowFlags()^Qt::Dialog^Qt::Window); - - int crewID = picture.getSnapmaticProperties().crewID; - if (crewID != 0) - crewDB.addCrew(crewID); - if (!readOk) - return 1; - - QObject::connect(&threadDB, SIGNAL(crewNameFound(int, QString)), &crewDB, SLOT(setCrewName(int, QString))); - QObject::connect(&threadDB, SIGNAL(crewNameUpdated()), &picDialog, SLOT(crewNameUpdated())); - QObject::connect(&threadDB, SIGNAL(playerNameFound(int, QString)), &profileDB, SLOT(setPlayerName(int, QString))); - QObject::connect(&threadDB, SIGNAL(playerNameUpdated()), &picDialog, SLOT(playerNameUpdated())); - QObject::connect(&threadDB, SIGNAL(finished()), &a, SLOT(quit())); - QObject::connect(&picDialog, SIGNAL(endDatabaseThread()), &threadDB, SLOT(terminateThread())); - threadDB.start(); - - picDialog.show(); - - return a.exec(); - } - else if (selectedAction == "showsgd") { - SavegameDialog savegameDialog; - SavegameData savegame; - - bool readOk = savegame.readingSavegameFromFile(arg1); - savegameDialog.setWindowIcon(IconLoader::loadingAppIcon()); - savegameDialog.setSavegameData(&savegame, arg1, readOk); - savegameDialog.setWindowFlags(savegameDialog.windowFlags()^Qt::Dialog^Qt::Window); - - if (!readOk) - return 1; - - a.setQuitOnLastWindowClosed(true); - savegameDialog.show(); - - return a.exec(); - } - - CrewDatabase crewDB; - ProfileDatabase profileDB; - DatabaseThread threadDB(&crewDB); - - QObject::connect(&threadDB, SIGNAL(crewNameFound(int,QString)), &crewDB, SLOT(setCrewName(int, QString))); - QObject::connect(&threadDB, SIGNAL(playerNameFound(int, QString)), &profileDB, SLOT(setPlayerName(int, QString))); - QObject::connect(&threadDB, SIGNAL(finished()), &a, SLOT(quit())); - threadDB.start(); - -#ifdef GTA5SYNC_MOTD - uint cacheId; - { - QSettings messageSettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); - messageSettings.beginGroup("Messages"); - cacheId = messageSettings.value("CacheId", 0).toUInt(); - messageSettings.endGroup(); - } - MessageThread threadMessage(cacheId); - QObject::connect(&threadMessage, SIGNAL(finished()), &threadDB, SLOT(terminateThread())); - threadMessage.start(); -#endif - -#ifdef GTA5SYNC_MOTD - UserInterface uiWindow(&profileDB, &crewDB, &threadDB, &threadMessage); - QObject::connect(&threadMessage, SIGNAL(messagesArrived(QJsonObject)), &uiWindow, SLOT(messagesArrived(QJsonObject))); - QObject::connect(&threadMessage, SIGNAL(updateCacheId(uint)), &uiWindow, SLOT(updateCacheId(uint))); -#else - UserInterface uiWindow(&profileDB, &crewDB, &threadDB); -#endif - uiWindow.setWindowIcon(IconLoader::loadingAppIcon()); -#ifdef GTA5SYNC_FLATPAK - uiWindow.setupDirEnv(false); -#else - uiWindow.setupDirEnv(); -#endif -#ifdef Q_OS_ANDROID - uiWindow.showMaximized(); -#else - uiWindow.show(); -#endif - - return a.exec(); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "SnapmaticPicture.h" +#include "ProfileDatabase.h" +#include "DatabaseThread.h" +#include "SavegameDialog.h" +#include "PictureDialog.h" +#include "UserInterface.h" +#include "CrewDatabase.h" +#include "SavegameData.h" +#include "IconLoader.h" +#include "AppEnv.h" +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef GTA5SYNC_WIN +#include "windows.h" +#include +#endif + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + a.setApplicationName(GTA5SYNC_APPSTR); + a.setApplicationVersion(GTA5SYNC_APPVER); + +#ifdef GTA5SYNC_WIN +#if QT_VERSION >= 0x050400 + if (QSysInfo::windowsVersion() >= 0x0080) + { + // Get Windows Font + NONCLIENTMETRICS ncm; + ncm.cbSize = sizeof(ncm); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0); + LOGFONTW uiFont = ncm.lfMessageFont; + QString uiFontStr(QString::fromStdWString(std::wstring(uiFont.lfFaceName))); + +#ifdef GTA5SYNC_DEBUG + QMessageBox::information(a.desktop(), QApplication::tr("Font"), QApplication::tr("Selected Font: %1").arg(uiFontStr)); +#endif + + // Set Application Font + QFont appFont(uiFontStr, 9); + a.setFont(appFont); + } +#endif +#endif + + QString pluginsDir = AppEnv::getPluginsFolder(); + if (QFileInfo(pluginsDir).exists()) + { + a.addLibraryPath(pluginsDir); + } + + // Loading translation settings + QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR); + settings.beginGroup("Interface"); + QString language = settings.value("Language","System").toString(); + settings.endGroup(); + + // Start external translate loading + QString langpath = AppEnv::getLangFolder(); + bool trsf = false; + bool svlp = false; + QTranslator EappTranslator; + if (language == "System" || language.trimmed() == "") + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(langpath + QDir::separator() + "gta5sync_" + langList.at(0) + ".qm")) + { + EappTranslator.load(langpath + QDir::separator() + "/gta5sync_" + langList.at(0) + ".qm"); + QLocale::setDefault(QLocale::system()); + } + } + } + else + { + QString languageName = language; + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(langpath + QDir::separator() + "gta5sync_" + langList.at(0) + ".qm")) + { + if (!EappTranslator.load(langpath + QDir::separator() + "gta5sync_" + langList.at(0) + ".qm")) + { + if (langList.at(0) != "en") + { + trsf = true; + } + } + else + { + QLocale::setDefault(QLocale(langList.at(0))); + svlp = true; + } + } + else + { + if (langList.at(0) != "en") + { + trsf = true; + } + } + } + } + if (trsf) + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(langpath + QDir::separator() + "gta5sync_" + langList.at(0) + ".qm")) + { + EappTranslator.load(langpath + QDir::separator() + "gta5sync_" + langList.at(0) + ".qm"); + QLocale::setDefault(QLocale(langList.at(0))); + } + } + } + a.installTranslator(&EappTranslator); +#if QT_VERSION >= 0x050000 + QTranslator EqtTranslator1; + if (language == "System" || language.trimmed() == "") + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(langpath + QDir::separator() + "qtbase_" + langList.at(0) + ".qm")) + { + EqtTranslator1.load(langpath + QDir::separator() + "qtbase_" + langList.at(0) + ".qm"); + } + } + } + else + { + QString languageName = language; + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(langpath + QDir::separator() + "qtbase_" + langList.at(0) + ".qm")) + { + EqtTranslator1.load(langpath + QDir::separator() + "qtbase_" + langList.at(0) + ".qm"); + } + } + } + if (trsf) + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(langpath + QDir::separator() + "qtbase_" + langList.at(0) + ".qm")) + { + EqtTranslator1.load(langpath + QDir::separator() + "qtbase_" + langList.at(0) + ".qm"); + } + } + } + a.installTranslator(&EqtTranslator1); +#else + QTranslator EqtTranslator; + if (language == "System" || language.trimmed() == "") + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(langpath + QDir::separator() + "qt_" + langList.at(0) + ".qm")) + { + EqtTranslator.load(langpath + QDir::separator() + "qt_" + langList.at(0) + ".qm"); + } + } + } + else + { + QString languageName = language; + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(langpath + QDir::separator() + "qt_" + langList.at(0) + ".qm")) + { + EqtTranslator.load(langpath + QDir::separator() + "qt_" + langList.at(0) + ".qm"); + } + } + } + if (trsf) + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(langpath + QDir::separator() + "qt_" + langList.at(0) + ".qm")) + { + EqtTranslator.load(langpath + QDir::separator() + "qt_" + langList.at(0) + ".qm"); + } + } + } + a.installTranslator(&EqtTranslator); +#endif + // End external translate loading + // Start internal translate loading + QTranslator appTranslator; + trsf = false; + if (language == "System" || language.trimmed() == "") + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(":/tr/gta5sync_" + langList.at(0) + ".qm")) + { + if (!appTranslator.load(":/tr/gta5sync_" + langList.at(0) + ".qm")) + { + if (langList.at(0) != "en") + { + if (svlp) { trsf = true; } + } + } + else + { + QLocale::setDefault(QLocale(langList.at(0))); + } + } + else + { + if (langList.at(0) != "en") + { + if (svlp) { trsf = true; } + } + } + } + } + else if (language == "en" || language == "English") + { + QLocale::setDefault(QLocale(QLocale::English, QLocale::AnyCountry)); + } + else + { + QString languageName = language; + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(":/tr/gta5sync_" + langList.at(0) + ".qm")) + { + appTranslator.load(":/tr/gta5sync_" + langList.at(0) + ".qm"); + QLocale::setDefault(QLocale(langList.at(0))); + + } + } + } + if (trsf) + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(":/tr/gta5sync_" + langList.at(0) + ".qm")) + { + appTranslator.load(":/tr/gta5sync_" + langList.at(0) + ".qm"); + QLocale::setDefault(QLocale(langList.at(0))); + } + } + } + a.installTranslator(&appTranslator); +#if QT_VERSION >= 0x050000 + QTranslator qtTranslator1; + if (language == "System" || language.trimmed() == "") + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(":/tr/qtbase_" + langList.at(0) + ".qm")) + { + qtTranslator1.load(":/tr/qtbase_" + langList.at(0) + ".qm"); + } + } + } + else + { + QString languageName = language; + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(":/tr/qtbase_" + langList.at(0) + ".qm")) + { + qtTranslator1.load(":/tr/qtbase_" + langList.at(0) + ".qm"); + } + } + } + if (trsf) + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(":/tr/qtbase_" + langList.at(0) + ".qm")) + { + qtTranslator1.load(":/tr/qtbase_" + langList.at(0) + ".qm"); + } + } + } + a.installTranslator(&qtTranslator1); +#else + QTranslator qtTranslator1; + if (language == "System" || language.trimmed() == "") + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(":/tr/qt_" + langList.at(0) + ".qm")) + { + qtTranslator1.load(":/tr/qt_" + langList.at(0) + ".qm"); + } + } + } + else + { + QString languageName = language; + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(":/tr/qt_" + langList.at(0) + ".qm")) + { + qtTranslator1.load(":/tr/qt_" + langList.at(0) + ".qm"); + } + } + } + if (trsf) + { + QString languageName = QLocale::system().name(); + QStringList langList = languageName.split("_"); + if (langList.length() >= 1) + { + if (QFile::exists(":/tr/qt_" + langList.at(0) + ".qm")) + { + qtTranslator1.load(":/tr/qt_" + langList.at(0) + ".qm"); + } + } + } + a.installTranslator(&qtTranslator1); +#endif + // End internal translate loading + + QStringList applicationArgs = a.arguments(); + QString selectedAction; + QString arg1; + applicationArgs.removeAt(0); + + foreach(QString currentArg, applicationArgs) + { + QString reworkedArg; + if (currentArg.left(9) == "-showpic=" && selectedAction == "") + { + reworkedArg = currentArg.remove(0,9); + arg1 = reworkedArg; + selectedAction = "showpic"; + } + else if (currentArg.left(9) == "-showsgd=" && selectedAction == "") + { + reworkedArg = currentArg.remove(0,9); + arg1 = reworkedArg; + selectedAction = "showsgd"; + } + else if (selectedAction == "") + { + QFile argumentFile(currentArg); + QFileInfo argumentFileInfo(argumentFile); + if (argumentFile.exists()) + { + QString argumentFileName = argumentFileInfo.fileName(); + QString argumentFileType = argumentFileName.left(4); + + if (argumentFileType == "PGTA") + { + arg1 = currentArg; + selectedAction = "showpic"; + } + else if (argumentFileType == "SGTA") + { + arg1 = currentArg; + selectedAction = "showsgd"; + } + else if (argumentFileType == "MISR") + { + arg1 = currentArg; + selectedAction = "showsgd"; + } + } + } + } + + if (selectedAction == "showpic") + { + CrewDatabase *crewDB = new CrewDatabase(); + ProfileDatabase *profileDB = new ProfileDatabase(); + DatabaseThread *threadDB = new DatabaseThread(crewDB); + PictureDialog *picDialog = new PictureDialog(profileDB, crewDB); + SnapmaticPicture picture; + + bool readOk = picture.readingPictureFromFile(arg1); + picDialog->setWindowFlags(picDialog->windowFlags()^Qt::WindowContextHelpButtonHint); + picDialog->setWindowIcon(IconLoader::loadingAppIcon()); + picDialog->setSnapmaticPicture(&picture, readOk); + + int crewID = picture.getSnapmaticProperties().crewID; + if (crewID != 0) { crewDB->addCrew(crewID); } + if (!readOk) { return 1; } + + QObject::connect(threadDB, SIGNAL(playerNameFound(int, QString)), profileDB, SLOT(setPlayerName(int, QString))); + QObject::connect(threadDB, SIGNAL(playerNameUpdated()), picDialog, SLOT(playerNameUpdated())); + threadDB->start(); + + picDialog->show(); + picDialog->setMinimumSize(picDialog->size()); + picDialog->setMaximumSize(picDialog->size()); + + return a.exec(); + } + else if (selectedAction == "showsgd") + { + SavegameDialog *savegameDialog = new SavegameDialog(); + SavegameData savegame; + + bool readOk = savegame.readingSavegameFromFile(arg1); + savegameDialog->setWindowFlags(savegameDialog->windowFlags()^Qt::WindowContextHelpButtonHint); + savegameDialog->setWindowIcon(IconLoader::loadingAppIcon()); + savegameDialog->setSavegameData(&savegame, arg1, readOk); + + if (!readOk) { return 1; } + + savegameDialog->show(); + + return a.exec(); + } + + CrewDatabase *crewDB = new CrewDatabase(); + ProfileDatabase *profileDB = new ProfileDatabase(); + DatabaseThread *threadDB = new DatabaseThread(crewDB); + + QObject::connect(threadDB, SIGNAL(playerNameFound(int, QString)), profileDB, SLOT(setPlayerName(int, QString))); + threadDB->start(); + + UserInterface *uiWindow = new UserInterface(profileDB, crewDB, threadDB); + uiWindow->setWindowIcon(IconLoader::loadingAppIcon()); + uiWindow->setupDirEnv(); + uiWindow->show(); + + return a.exec(); +} + diff --git a/pcg/LICENSE.txt b/pcg/LICENSE.txt deleted file mode 100644 index 8dada3e..0000000 --- a/pcg/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/pcg/pcg_basic.c b/pcg/pcg_basic.c deleted file mode 100644 index 8c2fd0d..0000000 --- a/pcg/pcg_basic.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * PCG Random Number Generation for C. - * - * Copyright 2014 Melissa O'Neill - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For additional information about the PCG random number generation scheme, - * including its license and other licensing options, visit - * - * http://www.pcg-random.org - */ - -/* - * This code is derived from the full C implementation, which is in turn - * derived from the canonical C++ PCG implementation. The C++ version - * has many additional features and is preferable if you can use C++ in - * your project. - */ - -#include "pcg_basic.h" - -// state for global RNGs - -static pcg32_random_t pcg32_global = PCG32_INITIALIZER; - -// pcg32_srandom(initstate, initseq) -// pcg32_srandom_r(rng, initstate, initseq): -// Seed the rng. Specified in two parts, state initializer and a -// sequence selection constant (a.k.a. stream id) - -void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq) -{ - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg32_random_r(rng); - rng->state += initstate; - pcg32_random_r(rng); -} - -void pcg32_srandom(uint64_t seed, uint64_t seq) -{ - pcg32_srandom_r(&pcg32_global, seed, seq); -} - -// pcg32_random() -// pcg32_random_r(rng) -// Generate a uniformly distributed 32-bit random number - -uint32_t pcg32_random_r(pcg32_random_t* rng) -{ - uint64_t oldstate = rng->state; - rng->state = oldstate * 6364136223846793005ULL + rng->inc; - uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; - uint32_t rot = oldstate >> 59u; - return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); -} - -uint32_t pcg32_random() -{ - return pcg32_random_r(&pcg32_global); -} - - -// pcg32_boundedrand(bound): -// pcg32_boundedrand_r(rng, bound): -// Generate a uniformly distributed number, r, where 0 <= r < bound - -uint32_t pcg32_boundedrand_r(pcg32_random_t* rng, uint32_t bound) -{ - // To avoid bias, we need to make the range of the RNG a multiple of - // bound, which we do by dropping output less than a threshold. - // A naive scheme to calculate the threshold would be to do - // - // uint32_t threshold = 0x100000000ull % bound; - // - // but 64-bit div/mod is slower than 32-bit div/mod (especially on - // 32-bit platforms). In essence, we do - // - // uint32_t threshold = (0x100000000ull-bound) % bound; - // - // because this version will calculate the same modulus, but the LHS - // value is less than 2^32. - - uint32_t threshold = -bound % bound; - - // Uniformity guarantees that this loop will terminate. In practice, it - // should usually terminate quickly; on average (assuming all bounds are - // equally likely), 82.25% of the time, we can expect it to require just - // one iteration. In the worst case, someone passes a bound of 2^31 + 1 - // (i.e., 2147483649), which invalidates almost 50% of the range. In - // practice, bounds are typically small and only a tiny amount of the range - // is eliminated. - for (;;) { - uint32_t r = pcg32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - - -uint32_t pcg32_boundedrand(uint32_t bound) -{ - return pcg32_boundedrand_r(&pcg32_global, bound); -} - diff --git a/pcg/pcg_basic.h b/pcg/pcg_basic.h deleted file mode 100644 index e2b526a..0000000 --- a/pcg/pcg_basic.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * PCG Random Number Generation for C. - * - * Copyright 2014 Melissa O'Neill - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For additional information about the PCG random number generation scheme, - * including its license and other licensing options, visit - * - * http://www.pcg-random.org - */ - -/* - * This code is derived from the full C implementation, which is in turn - * derived from the canonical C++ PCG implementation. The C++ version - * has many additional features and is preferable if you can use C++ in - * your project. - */ - -#ifndef PCG_BASIC_H_INCLUDED -#define PCG_BASIC_H_INCLUDED 1 - -#include - -#if __cplusplus -extern "C" { -#endif - -struct pcg_state_setseq_64 { // Internals are *Private*. - uint64_t state; // RNG state. All values are possible. - uint64_t inc; // Controls which RNG sequence (stream) is - // selected. Must *always* be odd. -}; -typedef struct pcg_state_setseq_64 pcg32_random_t; - -// If you *must* statically initialize it, here's one. - -#define PCG32_INITIALIZER { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL } - -// pcg32_srandom(initstate, initseq) -// pcg32_srandom_r(rng, initstate, initseq): -// Seed the rng. Specified in two parts, state initializer and a -// sequence selection constant (a.k.a. stream id) - -void pcg32_srandom(uint64_t initstate, uint64_t initseq); -void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, - uint64_t initseq); - -// pcg32_random() -// pcg32_random_r(rng) -// Generate a uniformly distributed 32-bit random number - -uint32_t pcg32_random(void); -uint32_t pcg32_random_r(pcg32_random_t* rng); - -// pcg32_boundedrand(bound): -// pcg32_boundedrand_r(rng, bound): -// Generate a uniformly distributed number, r, where 0 <= r < bound - -uint32_t pcg32_boundedrand(uint32_t bound); -uint32_t pcg32_boundedrand_r(pcg32_random_t* rng, uint32_t bound); - -#if __cplusplus -} -#endif - -#endif // PCG_BASIC_H_INCLUDED diff --git a/qjson4/QJsonArray b/qjson4/QJsonArray old mode 100644 new mode 100755 diff --git a/qjson4/QJsonArray.cpp b/qjson4/QJsonArray.cpp old mode 100644 new mode 100755 index ad8a82b..531941f --- a/qjson4/QJsonArray.cpp +++ b/qjson4/QJsonArray.cpp @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonArray.h b/qjson4/QJsonArray.h old mode 100644 new mode 100755 index dc4fc69..94aab1b --- a/qjson4/QJsonArray.h +++ b/qjson4/QJsonArray.h @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonDocument b/qjson4/QJsonDocument old mode 100644 new mode 100755 diff --git a/qjson4/QJsonDocument.cpp b/qjson4/QJsonDocument.cpp old mode 100644 new mode 100755 index 7f8ad18..59adf32 --- a/qjson4/QJsonDocument.cpp +++ b/qjson4/QJsonDocument.cpp @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify @@ -39,45 +39,45 @@ QJsonDocument::QJsonDocument() : root_(0) { // Name: QJsonDocument //------------------------------------------------------------------------------ QJsonDocument::QJsonDocument(const QJsonObject &object) : root_(0) { - setObject(object); + setObject(object); } //------------------------------------------------------------------------------ // Name: QJsonDocument //------------------------------------------------------------------------------ QJsonDocument::QJsonDocument(const QJsonArray &array) : root_(0) { - setArray(array); + setArray(array); } //------------------------------------------------------------------------------ // Name: QJsonDocument //------------------------------------------------------------------------------ QJsonDocument::QJsonDocument(const QJsonDocument &other) : root_(0) { - if(other.root_) { - root_ = other.root_->clone(); - } + if(other.root_) { + root_ = other.root_->clone(); + } } //------------------------------------------------------------------------------ // Name: ~QJsonDocument //------------------------------------------------------------------------------ QJsonDocument::~QJsonDocument() { - delete root_; + delete root_; } //------------------------------------------------------------------------------ // Name: operator= //------------------------------------------------------------------------------ QJsonDocument &QJsonDocument::operator=(const QJsonDocument &other) { - QJsonDocument(other).swap(*this); - return *this; + QJsonDocument(other).swap(*this); + return *this; } //------------------------------------------------------------------------------ // Name: operator!= //------------------------------------------------------------------------------ bool QJsonDocument::operator!=(const QJsonDocument &other) const { - return !(*this == other); + return !(*this == other); } //------------------------------------------------------------------------------ @@ -85,30 +85,30 @@ bool QJsonDocument::operator!=(const QJsonDocument &other) const { //------------------------------------------------------------------------------ bool QJsonDocument::operator==(const QJsonDocument &other) const { - if(isArray() && other.isArray()) { - return array() == other.array(); - } + if(isArray() && other.isArray()) { + return array() == other.array(); + } - if(isObject() && other.isObject()) { - return object() == other.object(); - } + if(isObject() && other.isObject()) { + return object() == other.object(); + } - if(isEmpty() && other.isEmpty()) { - return true; - } + if(isEmpty() && other.isEmpty()) { + return true; + } - if(isNull() && other.isNull()) { - return true; - } + if(isNull() && other.isNull()) { + return true; + } - return false; + return false; } //------------------------------------------------------------------------------ // Name: isArray //------------------------------------------------------------------------------ bool QJsonDocument::isArray() const { - return root_ && root_->toArray(); + return root_ && root_->toArray(); } //------------------------------------------------------------------------------ @@ -116,56 +116,56 @@ bool QJsonDocument::isArray() const { //------------------------------------------------------------------------------ bool QJsonDocument::isEmpty() const { - // TODO(eteran): figure out the rules here that Qt5 uses - // it *looks* like they define empty as being NULL - // which is obviously different than this + // TODO(eteran): figure out the rules here that Qt5 uses + // it *looks* like they define empty as being NULL + // which is obviously different than this - return !root_; + return !root_; } //------------------------------------------------------------------------------ // Name: isNull //------------------------------------------------------------------------------ bool QJsonDocument::isNull() const { - return !root_; + return !root_; } //------------------------------------------------------------------------------ // Name: isObject //------------------------------------------------------------------------------ bool QJsonDocument::isObject() const { - return root_ && root_->toObject(); + return root_ && root_->toObject(); } //------------------------------------------------------------------------------ // Name: setArray //------------------------------------------------------------------------------ void QJsonDocument::setArray(const QJsonArray &array) { - setRoot(array); + setRoot(array); } //------------------------------------------------------------------------------ // Name: setObject //------------------------------------------------------------------------------ void QJsonDocument::setObject(const QJsonObject &object) { - setRoot(object); + setRoot(object); } //------------------------------------------------------------------------------ // Name: setRoot //------------------------------------------------------------------------------ void QJsonDocument::setRoot(const QJsonRoot &root) { - delete root_; - root_ = root.clone(); + delete root_; + root_ = root.clone(); } //------------------------------------------------------------------------------ // Name: toBinaryData //------------------------------------------------------------------------------ QByteArray QJsonDocument::toBinaryData() const { - QByteArray r; - // TODO(eteran): implement this - return r; + QByteArray r; + // TODO(eteran): implement this + return r; } //------------------------------------------------------------------------------ @@ -173,107 +173,100 @@ QByteArray QJsonDocument::toBinaryData() const { //------------------------------------------------------------------------------ QString QJsonDocument::escapeString(const QString &s) const { - QString r; + QString r; - Q_FOREACH(QChar ch, s) { - switch(ch.toLatin1()) { - case '\"': r.append("\\\""); break; - case '\\': r.append("\\\\"); break; -#if 0 - case '/': r.append("\\/"); break; -#endif - case '\b': r.append("\\b"); break; - case '\f': r.append("\\f"); break; - case '\n': r.append("\\n"); break; - case '\r': r.append("\\r"); break; - case '\t': r.append("\\t"); break; - default: - r += ch; - break; - } - } + Q_FOREACH(QChar ch, s) { + switch(ch.toLatin1()) { + case '\"': r.append("\\\""); break; + case '\\': r.append("\\\\"); break; + #if 0 + case '/': r.append("\\/"); break; + #endif + case '\b': r.append("\\b"); break; + case '\f': r.append("\\f"); break; + case '\n': r.append("\\n"); break; + case '\r': r.append("\\r"); break; + case '\t': r.append("\\t"); break; + default: + r += ch; + break; + } + } - return r; + return r; } //------------------------------------------------------------------------------ // Name: toJson //------------------------------------------------------------------------------ -QString QJsonDocument::toJson(const QJsonValue &v, JsonFormat format, int indent) const { +QString QJsonDocument::toJson(const QJsonValue &v, JsonFormat format) const { - QString b; - QTextStream ss(&b, QIODevice::WriteOnly | QIODevice::Text); - bool compact = (format == JsonFormat::Compact); + QString b; + QTextStream ss(&b, QIODevice::WriteOnly | QIODevice::Text); - switch(v.type()) { - case QJsonValue::Null: - ss << "null"; - break; - case QJsonValue::Bool: - ss << (v.toBool() ? "true" : "false"); - break; - case QJsonValue::Double: - { - double d = v.toDouble (); - if (qIsFinite(d)) { - // +2 to format to ensure the expected precision - ss << QByteArray::number(d, 'g', 15 + 2); // ::digits10 is 15 - } else { - ss << "null"; // +INF || -INF || NaN (see RFC4627#section2.4) - } - } - break; - case QJsonValue::String: - ss << '"' << escapeString(v.toString()) << '"'; - break; - case QJsonValue::Array: - { - const QJsonArray a = v.toArray(); - ss << (compact ? "[" : "[\n"); - if(!a.empty()) { - QJsonArray::const_iterator it = a.begin(); - QJsonArray::const_iterator e = a.end(); + switch(v.type()) { + case QJsonValue::Null: + ss << "null"; + break; + case QJsonValue::Bool: + ss << (v.toBool() ? "true" : "false"); + break; + case QJsonValue::Double: + { + double d = v.toDouble (); + if (qIsFinite(d)) { + // +2 to format to ensure the expected precision + ss << QByteArray::number(d, 'g', 15 + 2); // ::digits10 is 15 + } else { + ss << "null"; // +INF || -INF || NaN (see RFC4627#section2.4) + } + } + break; + case QJsonValue::String: + ss << '"' << escapeString(v.toString()) << '"'; + break; + case QJsonValue::Array: + { + const QJsonArray a = v.toArray(); + ss << "["; + if(!a.empty()) { + QJsonArray::const_iterator it = a.begin(); + QJsonArray::const_iterator e = a.end(); - if (!compact) ss << QByteArray(4*indent, ' '); - ss << toJson(*it++, format, indent+1); + ss << toJson(*it++, format); - for(;it != e; ++it) { - ss << (compact ? "," : ",\n"); - if (!compact) ss << QByteArray(4*indent, ' '); - ss << toJson(*it, format, indent+1); - } - } - indent--; - ss << (compact ? "]" : QString("\n%1]").arg(QString(4*indent, ' '))); - } - break; - case QJsonValue::Object: - { - const QJsonObject o = v.toObject(); - ss << (compact ? "{" : "{\n"); - if(!o.empty()) { - QJsonObject::const_iterator it = o.begin(); - QJsonObject::const_iterator e = o.end(); + for(;it != e; ++it) { + ss << ','; + ss << toJson(*it, format); + } + } + ss << "]"; + } + break; + case QJsonValue::Object: + { + const QJsonObject o = v.toObject(); + ss << "{"; + if(!o.empty()) { + QJsonObject::const_iterator it = o.begin(); + QJsonObject::const_iterator e = o.end(); - if (!compact) ss << QByteArray(4*indent, ' '); - ss << '"' << escapeString(it.key()) << (compact ? "\":" : "\": ") << toJson(it.value(), format, indent+1); - ++it; - for(;it != e; ++it) { - ss << (compact ? "," : ",\n"); - if (!compact) ss << QByteArray(4*indent, ' '); - ss << '"' << escapeString(it.key()) << (compact ? "\":" : "\": ") << toJson(it.value(), format, indent+1); - } - } - indent--; - ss << (compact ? "}" : QString("\n%1}").arg(QString(4*indent, ' '))); - } - break; - case QJsonValue::Undefined: - Q_ASSERT(0); - break; - } + ss << '"' << escapeString(it.key()) << "\": " << toJson(it.value(), format); + ++it; + for(;it != e; ++it) { + ss << ','; + ss << '"' << escapeString(it.key()) << "\": " << toJson(it.value(), format); + } + } + ss << "}"; + } + break; + case QJsonValue::Undefined: + Q_ASSERT(0); + break; + } - return b; + return b; } //------------------------------------------------------------------------------ @@ -281,19 +274,19 @@ QString QJsonDocument::toJson(const QJsonValue &v, JsonFormat format, int indent //------------------------------------------------------------------------------ QByteArray QJsonDocument::toJson(JsonFormat format) const { - Q_UNUSED(format); + Q_UNUSED(format); - if(isArray()) { - QString s = toJson(array(), format); - return s.toUtf8(); - } + if(isArray()) { + QString s = toJson(array(), format); + return s.toUtf8(); + } - if(isObject()) { - QString s = toJson(object(), format); - return s.toUtf8(); - } + if(isObject()) { + QString s = toJson(object(), format); + return s.toUtf8(); + } - return QByteArray(); + return QByteArray(); } //------------------------------------------------------------------------------ @@ -301,17 +294,17 @@ QByteArray QJsonDocument::toJson(JsonFormat format) const { //------------------------------------------------------------------------------ QVariant QJsonDocument::toVariant() const { - if(!isEmpty()) { - if(QJsonObject *const object = root_->toObject()) { - return object->toVariantMap(); - } + if(!isEmpty()) { + if(QJsonObject *const object = root_->toObject()) { + return object->toVariantMap(); + } - if(QJsonArray *const array = root_->toArray()) { - return array->toVariantList(); - } - } + if(QJsonArray *const array = root_->toArray()) { + return array->toVariantList(); + } + } - return QVariant(); + return QVariant(); } //------------------------------------------------------------------------------ @@ -319,13 +312,13 @@ QVariant QJsonDocument::toVariant() const { //------------------------------------------------------------------------------ QJsonArray QJsonDocument::array() const { - if(!isEmpty()) { - if(QJsonArray *const array = root_->toArray()) { - return *array; - } - } + if(!isEmpty()) { + if(QJsonArray *const array = root_->toArray()) { + return *array; + } + } - return QJsonArray(); + return QJsonArray(); } //------------------------------------------------------------------------------ @@ -333,54 +326,54 @@ QJsonArray QJsonDocument::array() const { //------------------------------------------------------------------------------ QJsonObject QJsonDocument::object() const { - if(!isEmpty()) { - if(QJsonObject *const object = root_->toObject()) { - return *object; - } - } + if(!isEmpty()) { + if(QJsonObject *const object = root_->toObject()) { + return *object; + } + } - return QJsonObject(); + return QJsonObject(); } //------------------------------------------------------------------------------ // Name: rawData //------------------------------------------------------------------------------ const char *QJsonDocument::rawData(int *size) const { - Q_UNUSED(size); - // TODO(eteran): implement this - return 0; + Q_UNUSED(size); + // TODO(eteran): implement this + return 0; } //------------------------------------------------------------------------------ // Name: fromBinaryData //------------------------------------------------------------------------------ QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation) { - Q_UNUSED(data); - Q_UNUSED(validation); + Q_UNUSED(data); + Q_UNUSED(validation); - QJsonDocument doc; - // TODO(eteran): implement this - return doc; + QJsonDocument doc; + // TODO(eteran): implement this + return doc; } //------------------------------------------------------------------------------ // Name: fromJson //------------------------------------------------------------------------------ QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error) { - QJsonDocument doc; + QJsonDocument doc; - const char *const begin = json.constData(); - const char *const end = begin + json.size(); + const char *const begin = json.constData(); + const char *const end = begin + json.size(); - QJsonParser parser(begin, end); + QJsonParser parser(begin, end); - doc.root_ = parser.parse(); + doc.root_ = parser.parse(); - if(error) { - *error = parser.state(); - } + if(error) { + *error = parser.state(); + } - return doc; + return doc; } //------------------------------------------------------------------------------ @@ -388,10 +381,10 @@ QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *e //------------------------------------------------------------------------------ QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidation validation) { - // data has to be aligned to a 4 byte boundary. - Q_ASSERT(!(reinterpret_cast(data) % 3)); + // data has to be aligned to a 4 byte boundary. + Q_ASSERT(!(reinterpret_cast(data) % 3)); - return fromBinaryData(QByteArray::fromRawData(data, size), validation); + return fromBinaryData(QByteArray::fromRawData(data, size), validation); } //------------------------------------------------------------------------------ @@ -399,26 +392,26 @@ QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidat //------------------------------------------------------------------------------ QJsonDocument QJsonDocument::fromVariant(const QVariant &variant) { - QJsonDocument doc; + QJsonDocument doc; - if (variant.type() == QVariant::Map) { - doc.setObject(QJsonObject::fromVariantMap(variant.toMap())); - } else if (variant.type() == QVariant::Hash) { - doc.setObject(QJsonObject::fromVariantHash(variant.toHash())); - } else if (variant.type() == QVariant::List) { - doc.setArray(QJsonArray::fromVariantList(variant.toList())); - } else if (variant.type() == QVariant::StringList) { - doc.setArray(QJsonArray::fromStringList(variant.toStringList())); - } + if (variant.type() == QVariant::Map) { + doc.setObject(QJsonObject::fromVariantMap(variant.toMap())); + } else if (variant.type() == QVariant::Hash) { + doc.setObject(QJsonObject::fromVariantHash(variant.toHash())); + } else if (variant.type() == QVariant::List) { + doc.setArray(QJsonArray::fromVariantList(variant.toList())); + } else if (variant.type() == QVariant::StringList) { + doc.setArray(QJsonArray::fromStringList(variant.toStringList())); + } - return doc; + return doc; } //------------------------------------------------------------------------------ // Name: swap //------------------------------------------------------------------------------ void QJsonDocument::swap(QJsonDocument &other) { - qSwap(root_, other.root_); + qSwap(root_, other.root_); } #endif diff --git a/qjson4/QJsonDocument.h b/qjson4/QJsonDocument.h old mode 100644 new mode 100755 index 3731f62..12e8fc7 --- a/qjson4/QJsonDocument.h +++ b/qjson4/QJsonDocument.h @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify @@ -36,66 +36,66 @@ class QJsonRoot; class QJsonDocument { public: - enum DataValidation { - Validate = 0, - BypassValidation = 1 - }; + enum DataValidation { + Validate = 0, + BypassValidation = 1 + }; - enum JsonFormat { - Indented, - Compact - }; + enum JsonFormat { + Indented, + Compact + }; public: - QJsonDocument(); - QJsonDocument(const QJsonObject &object); - QJsonDocument(const QJsonArray &array); - QJsonDocument(const QJsonDocument &other); - ~QJsonDocument(); + QJsonDocument(); + QJsonDocument(const QJsonObject &object); + QJsonDocument(const QJsonArray &array); + QJsonDocument(const QJsonDocument &other); + ~QJsonDocument(); public: - QJsonDocument &operator=(const QJsonDocument &other); + QJsonDocument &operator=(const QJsonDocument &other); public: - bool operator!=(const QJsonDocument &other) const; - bool operator==(const QJsonDocument &other) const; + bool operator!=(const QJsonDocument &other) const; + bool operator==(const QJsonDocument &other) const; public: - bool isArray() const; - bool isEmpty() const; - bool isNull() const; - bool isObject() const; + bool isArray() const; + bool isEmpty() const; + bool isNull() const; + bool isObject() const; public: - QByteArray toBinaryData() const; - QByteArray toJson(JsonFormat format = Indented) const; - QVariant toVariant() const; + QByteArray toBinaryData() const; + QByteArray toJson(JsonFormat format = Indented) const; + QVariant toVariant() const; public: - QJsonArray array() const; - QJsonObject object() const; - const char *rawData(int *size) const; + QJsonArray array() const; + QJsonObject object() const; + const char *rawData(int *size) const; public: - void setArray(const QJsonArray &array); - void setObject(const QJsonObject &object); + void setArray(const QJsonArray &array); + void setObject(const QJsonObject &object); public: - static QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate); - static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = 0); - static QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate); - static QJsonDocument fromVariant(const QVariant &variant); + static QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate); + static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = 0); + static QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate); + static QJsonDocument fromVariant(const QVariant &variant); private: - void setRoot(const QJsonRoot &root); - QString toJson(const QJsonValue &v, JsonFormat format, int indent = 1) const; - QString escapeString(const QString &s) const; + void setRoot(const QJsonRoot &root); + QString toJson(const QJsonValue &v, JsonFormat format) const; + QString escapeString(const QString &s) const; private: - void swap(QJsonDocument &other); + void swap(QJsonDocument &other); private: - QJsonRoot *root_; + QJsonRoot *root_; }; #endif diff --git a/qjson4/QJsonObject b/qjson4/QJsonObject old mode 100644 new mode 100755 diff --git a/qjson4/QJsonObject.cpp b/qjson4/QJsonObject.cpp old mode 100644 new mode 100755 index ac36bb0..55f8cf1 --- a/qjson4/QJsonObject.cpp +++ b/qjson4/QJsonObject.cpp @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonObject.h b/qjson4/QJsonObject.h old mode 100644 new mode 100755 index 6ee3a97..ad657bc --- a/qjson4/QJsonObject.h +++ b/qjson4/QJsonObject.h @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonParseError b/qjson4/QJsonParseError old mode 100644 new mode 100755 diff --git a/qjson4/QJsonParseError.cpp b/qjson4/QJsonParseError.cpp old mode 100644 new mode 100755 index 598c67c..6bcfd98 --- a/qjson4/QJsonParseError.cpp +++ b/qjson4/QJsonParseError.cpp @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonParseError.h b/qjson4/QJsonParseError.h old mode 100644 new mode 100755 index eddf04d..b87d7aa --- a/qjson4/QJsonParseError.h +++ b/qjson4/QJsonParseError.h @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonParser.cpp b/qjson4/QJsonParser.cpp old mode 100644 new mode 100755 index 052c9a8..9b084f7 --- a/qjson4/QJsonParser.cpp +++ b/qjson4/QJsonParser.cpp @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonParser.h b/qjson4/QJsonParser.h old mode 100644 new mode 100755 index f11f5a0..d54a0d9 --- a/qjson4/QJsonParser.h +++ b/qjson4/QJsonParser.h @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonRoot b/qjson4/QJsonRoot old mode 100644 new mode 100755 diff --git a/qjson4/QJsonRoot.h b/qjson4/QJsonRoot.h old mode 100644 new mode 100755 index d249465..77b9751 --- a/qjson4/QJsonRoot.h +++ b/qjson4/QJsonRoot.h @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonValue b/qjson4/QJsonValue old mode 100644 new mode 100755 diff --git a/qjson4/QJsonValue.cpp b/qjson4/QJsonValue.cpp old mode 100644 new mode 100755 index 8ac4770..68bf87f --- a/qjson4/QJsonValue.cpp +++ b/qjson4/QJsonValue.cpp @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonValue.h b/qjson4/QJsonValue.h old mode 100644 new mode 100755 index d902352..bf32898 --- a/qjson4/QJsonValue.h +++ b/qjson4/QJsonValue.h @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonValueRef b/qjson4/QJsonValueRef old mode 100644 new mode 100755 diff --git a/qjson4/QJsonValueRef.cpp b/qjson4/QJsonValueRef.cpp old mode 100644 new mode 100755 index dade257..7d67ef4 --- a/qjson4/QJsonValueRef.cpp +++ b/qjson4/QJsonValueRef.cpp @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/qjson4/QJsonValueRef.h b/qjson4/QJsonValueRef.h old mode 100644 new mode 100755 index 478b657..567c68a --- a/qjson4/QJsonValueRef.h +++ b/qjson4/QJsonValueRef.h @@ -1,5 +1,5 @@ /***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer +* gta5sync GRAND THEFT AUTO V SYNC * Copyright (C) 2016 Syping * * This program is free software: you can redistribute it and/or modify diff --git a/res/5sync-128.png b/res/5sync-128.png new file mode 100644 index 0000000..4b4bf5a Binary files /dev/null and b/res/5sync-128.png differ diff --git a/res/5sync-16.png b/res/5sync-16.png new file mode 100644 index 0000000..9db49fd Binary files /dev/null and b/res/5sync-16.png differ diff --git a/res/5sync-24.png b/res/5sync-24.png new file mode 100644 index 0000000..01c2fcf Binary files /dev/null and b/res/5sync-24.png differ diff --git a/res/5sync-256.png b/res/5sync-256.png new file mode 100644 index 0000000..bf41d47 Binary files /dev/null and b/res/5sync-256.png differ diff --git a/res/5sync-32.png b/res/5sync-32.png new file mode 100644 index 0000000..6a768fd Binary files /dev/null and b/res/5sync-32.png differ diff --git a/res/5sync-40.png b/res/5sync-40.png new file mode 100644 index 0000000..0852394 Binary files /dev/null and b/res/5sync-40.png differ diff --git a/res/5sync-48.png b/res/5sync-48.png new file mode 100755 index 0000000..ff8390c Binary files /dev/null and b/res/5sync-48.png differ diff --git a/res/5sync-64.png b/res/5sync-64.png new file mode 100644 index 0000000..123db7e Binary files /dev/null and b/res/5sync-64.png differ diff --git a/res/5sync-96.png b/res/5sync-96.png new file mode 100644 index 0000000..49f1db7 Binary files /dev/null and b/res/5sync-96.png differ diff --git a/res/5sync.ico b/res/5sync.ico old mode 100644 new mode 100755 index af3d0fc..2abd805 Binary files a/res/5sync.ico and b/res/5sync.ico differ diff --git a/res/960x536.png b/res/960x536.png new file mode 100644 index 0000000..0feac2d Binary files /dev/null and b/res/960x536.png differ diff --git a/res/add.svgz b/res/add.svgz deleted file mode 100644 index ca716e5..0000000 Binary files a/res/add.svgz and /dev/null differ diff --git a/res/app.qrc b/res/app.qrc new file mode 100755 index 0000000..b380c75 --- /dev/null +++ b/res/app.qrc @@ -0,0 +1,34 @@ + + + gta5sync_de.qm + qt_de.qm + qtbase_de.qm + gta5sync_fr.qm + qt_fr.qm + qtbase_fr.qm + + + savegame.png + 5sync-48.png + 5sync-16.png + 5sync-24.png + 5sync-32.png + 5sync-40.png + 5sync-64.png + 5sync-96.png + 5sync-128.png + 5sync-256.png + back.png + next.png + 960x536.png + empty1x16.png + + + global.de.ini + global.en.ini + global.ja.ini + global.fr.ini + global.zh.ini + global.es.ini + + diff --git a/res/app.rc b/res/app.rc old mode 100644 new mode 100755 index 56b1561..2d8ac5b --- a/res/app.rc +++ b/res/app.rc @@ -1,33 +1,32 @@ -IDI_ICON1 ICON DISCARDABLE "5sync.ico" -#define RT_MANIFEST 24 -#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "gta5view.exe.manifest" -#include -VS_VERSION_INFO VERSIONINFO -FILEVERSION 1, 10, 2, 0 -PRODUCTVERSION 1, 10, 2, 0 -FILEFLAGSMASK 0x3fL -FILEFLAGS 0 -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_APP -FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0809, 1200 - END - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Syping" - VALUE "FileDescription", "gta5view" - VALUE "FileVersion", "1.10.2" - VALUE "InternalName", "gta5view" - VALUE "LegalCopyright", "Copyright 2016-2023 Syping" - VALUE "OriginalFilename", "gta5view.exe" - VALUE "ProductName", "gta5view" - VALUE "ProductVersion", "1.10.2" - END - END -END +IDI_ICON1 ICON DISCARDABLE "5sync.ico" + +#include + +VS_VERSION_INFO VERSIONINFO +FILEVERSION 1, 1, 1, 0 +PRODUCTVERSION 1, 1, 1, 0 +FILEFLAGSMASK 0x3fL +FILEFLAGS 0 +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1200 + END + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Syping" + VALUE "FileDescription", "gta5view\0" + VALUE "FileVersion", "1.1.1\0" + VALUE "InternalName", "gta5view\0" + VALUE "LegalCopyright", "Copyright 2016 Syping\0" + VALUE "OriginalFilename", "gta5view.exe\0" + VALUE "ProductName", "gta5view\0" + VALUE "ProductVersion", "1.1.1\0" + END + END +END diff --git a/res/avatararea.png b/res/avatararea.png deleted file mode 100644 index 463d846..0000000 Binary files a/res/avatararea.png and /dev/null differ diff --git a/res/avatarareaimport.png b/res/avatarareaimport.png deleted file mode 100644 index cddc1d8..0000000 Binary files a/res/avatarareaimport.png and /dev/null differ diff --git a/res/back.png b/res/back.png new file mode 100644 index 0000000..49beb0a Binary files /dev/null and b/res/back.png differ diff --git a/res/back.svgz b/res/back.svgz deleted file mode 100644 index f2f90a5..0000000 Binary files a/res/back.svgz and /dev/null differ diff --git a/res/btc.str b/res/btc.str deleted file mode 100644 index 33e40a5..0000000 --- a/res/btc.str +++ /dev/null @@ -1 +0,0 @@ -Bitcoin \ No newline at end of file diff --git a/res/btc.svgz b/res/btc.svgz deleted file mode 100644 index e10b3a5..0000000 Binary files a/res/btc.svgz and /dev/null differ diff --git a/res/de.syping.gta5view.desktop b/res/de.syping.gta5view.desktop deleted file mode 100644 index ed9c7d1..0000000 --- a/res/de.syping.gta5view.desktop +++ /dev/null @@ -1,13 +0,0 @@ -[Desktop Entry] -Type=Application -Name=gta5view -Comment=Open and edit GTA V profiles -Comment[de]=GTA V Profile öffnen und bearbeiten -Comment[ko]=GTA V 프로필을 열고 편집 -Comment[ru]=Просмотрщик и редактор профилей GTA V -Comment[zh_TW]=打開與編輯 GTA V 個人檔案 -Categories=Qt;Utility;FileTools; -TryExec=gta5view -Exec=gta5view %f -Icon=de.syping.gta5view -MimeType=application/x-gta5view-export; diff --git a/res/de.syping.gta5view.metainfo.xml b/res/de.syping.gta5view.metainfo.xml deleted file mode 100644 index c5ab767..0000000 --- a/res/de.syping.gta5view.metainfo.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - de.syping.gta5view - de.syping.gta5view.desktop - CC0-1.0 - GPL-3.0+ - - gta5view - - Open and edit GTA V profiles - GTA V Profile öffnen und bearbeiten - GTA V 프로필을 열고 편집 - Просмотрщик и редактор профилей GTA V - 打開與編輯 GTA V 個人檔案 - - https://img.syping.de/gta5view/gta5view.png - - -

Open Source Snapmatic and Savegame viewer/editor for GTA V

-

Features

-
    -
  • View Snapmatics with the ability to disable them in-game
  • -
  • Edit Snapmatic pictures and properties in multiple ways
  • -
  • Import/Export Snapmatics, Savegames and pictures
  • -
  • Choose between multiple Social Club accounts as GTA V profiles IDs
  • -
-
- - - Utility - - - Syping - - - - - - - - - - - - - - User Interface - https://img.syping.de/gta5view/mainui_kde.png - - - Snapmatic Viewer - https://img.syping.de/gta5view/picture_kde.png - - - Picture Importer - https://img.syping.de/gta5view/import_kde.png - - - Snapmatic Player Editor - https://img.syping.de/gta5view/players_kde.png - - - Snapmatic Property Editor - https://img.syping.de/gta5view/prop_kde.png - - - - - - https://gta5view.syping.de/ -
diff --git a/res/de.syping.gta5view.png b/res/de.syping.gta5view.png deleted file mode 100644 index 3e955a6..0000000 Binary files a/res/de.syping.gta5view.png and /dev/null differ diff --git a/res/de.syping.gta5view.xml b/res/de.syping.gta5view.xml deleted file mode 100644 index 820ed88..0000000 --- a/res/de.syping.gta5view.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - gta5view Export - - - - diff --git a/res/donate.qrc b/res/donate.qrc deleted file mode 100644 index e4a0005..0000000 --- a/res/donate.qrc +++ /dev/null @@ -1,15 +0,0 @@ - - - btc.str - btc.svgz - eth.str - eth.svgz - ltc.str - ltc.svgz - xmr.str - xmr.svgz - - - donate.svgz - - diff --git a/res/donate.svgz b/res/donate.svgz deleted file mode 100644 index c9b7f63..0000000 Binary files a/res/donate.svgz and /dev/null differ diff --git a/res/empty1x16.png b/res/empty1x16.png new file mode 100644 index 0000000..6ab4481 Binary files /dev/null and b/res/empty1x16.png differ diff --git a/res/eth.str b/res/eth.str deleted file mode 100644 index 24b4676..0000000 --- a/res/eth.str +++ /dev/null @@ -1 +0,0 @@ -Ethereum \ No newline at end of file diff --git a/res/eth.svgz b/res/eth.svgz deleted file mode 100644 index a2fbcc5..0000000 Binary files a/res/eth.svgz and /dev/null differ diff --git a/res/flag-de.png b/res/flag-de.png deleted file mode 100644 index 2aeaf35..0000000 Binary files a/res/flag-de.png and /dev/null differ diff --git a/res/flag-fr.png b/res/flag-fr.png deleted file mode 100644 index d54b858..0000000 Binary files a/res/flag-fr.png and /dev/null differ diff --git a/res/flag-gb.png b/res/flag-gb.png deleted file mode 100644 index a425dcc..0000000 Binary files a/res/flag-gb.png and /dev/null differ diff --git a/res/flag-kr.png b/res/flag-kr.png deleted file mode 100644 index c0058ea..0000000 Binary files a/res/flag-kr.png and /dev/null differ diff --git a/res/flag-ru.png b/res/flag-ru.png deleted file mode 100644 index c0111e2..0000000 Binary files a/res/flag-ru.png and /dev/null differ diff --git a/res/flag-tw.png b/res/flag-tw.png deleted file mode 100644 index 4a8faac..0000000 Binary files a/res/flag-tw.png and /dev/null differ diff --git a/res/flag-ua.png b/res/flag-ua.png deleted file mode 100644 index 0ee802d..0000000 Binary files a/res/flag-ua.png and /dev/null differ diff --git a/res/flag-us.png b/res/flag-us.png deleted file mode 100644 index 293337e..0000000 Binary files a/res/flag-us.png and /dev/null differ diff --git a/res/global.de.ini b/res/global.de.ini old mode 100644 new mode 100755 index 0916785..fea6010 --- a/res/global.de.ini +++ b/res/global.de.ini @@ -41,8 +41,9 @@ HARMO="Harmony" HAWICK="Hawick" HEART="Heart Attacks Beach" HORS="Vinewood-Rennbahn" +HUD_MG_TRI_ALA="Alamosee" +HUD_MG_TRI_VES="Vespucci" HUMLAB="Humane Labs and Research" -ISHEIST="Cayo Perico" JAIL="Bolingbroke-Strafanstalt" KOREAT="Little Seoul" LACT="Land-Act-Stausee" @@ -51,6 +52,8 @@ LDAM="Land-Act-Staudamm" LMESA="La Mesa" LOSPUER="La Puerta" LOSSF="Los Santos Freeway" +MGCR_1="South Los Santos" +MGSR_3="Raton Canyon" MIRR="Mirror Park" MORN="Morningwood" MOVIE="Richards Majestic" diff --git a/res/global.en.ini b/res/global.en.ini old mode 100644 new mode 100755 index 97c84dd..4c31ad3 --- a/res/global.en.ini +++ b/res/global.en.ini @@ -41,8 +41,9 @@ HARMO="Harmony" HAWICK="Hawick" HEART="Heart Attacks Beach" HORS="Vinewood Racetrack" +HUD_MG_TRI_ALA="Alamo Sea" +HUD_MG_TRI_VES="Vespucci" HUMLAB="Humane Labs and Research" -ISHEIST="Cayo Perico" JAIL="Bolingbroke Penitentiary" KOREAT="Little Seoul" LACT="Land Act Reservoir" @@ -51,6 +52,9 @@ LDAM="Land Act Dam" LMESA="La Mesa" LOSPUER="La Puerta" LOSSF="Los Santos Freeway" +MGCR_1="South Los Santos" +MGCR_6="Vespucci Canals" +MGSR_3="Raton Canyon" MIRR="Mirror Park" MORN="Morningwood" MOVIE="Richards Majestic" diff --git a/res/global.es.ini b/res/global.es.ini index b364c50..dda46a7 100644 --- a/res/global.es.ini +++ b/res/global.es.ini @@ -41,8 +41,9 @@ HARMO="Harmony" HAWICK="Hawick" HEART="Heart Attacks Beach" HORS="Circuito de Vinewood" +HUD_MG_TRI_ALA="Alamo Sea" +HUD_MG_TRI_VES="Vespucci" HUMLAB="Laboratorios Humane" -ISHEIST="Cayo Perico" JAIL="Penitenciaría de Bolingbroke" KOREAT="Little Seoul" LACT="Embalse de Land Act" @@ -52,9 +53,14 @@ LMESA="La Mesa" LOSPFY="Autopista de La Puerta" LOSPUER="La Puerta" LOSSF="Autopista de Los Santos" +MGCR_1="Los Santos Sur" +MGCR_6="Canales de Vespucci" +MGSR_3="Raton Canyon" MIRR="Mirror Park" MORN="Morningwood" MOVIE="Richards Majestic" +MO_CS_HIGH="Alta" +MO_HIGH="Alta" MTCHIL="Monte Chiliad" MTGORDO="Monte Gordo" MTJOSE="Monte Josiah" diff --git a/res/global.es_MX.ini b/res/global.es_MX.ini deleted file mode 100644 index 620ef14..0000000 --- a/res/global.es_MX.ini +++ /dev/null @@ -1,101 +0,0 @@ -[Global] -AIRP="Aeropuerto Internacional de Los Santos" -ALAMO="Alamo Sea" -ALTA="Alta" -ARMYB="Fort Zancudo" -BANNING="Banning" -BAYTRE="Baytree Canyon" -BEACH="Vespucci Beach" -BHAMCA="Banham Canyon" -BRADP="Braddock Pass" -BRADT="Braddock Tunnel" -BURTON="Burton" -CALAFB="Calafia Bridge" -CANNY="Raton Canyon" -CCREAK="Cassidy Creek" -CHAMH="Chamberlain Hills" -CHIL="Vinewood Hills" -CHU="Chumash" -CMSW="Reserva Natural Mount Chiliad" -COSI="Zona Rural" -CYPRE="Cypress Flats" -DAVIS="Davis" -DELBE="Del Perro Beach" -DELPE="Del Perro" -DELSOL="La Puerta" -DESRT="Grand Senora Desert" -DOWNT="Centro" -DTVINE="Centro de Vinewood" -EAST_V="Vinewood Este" -EBURO="El Burro Heights" -ECLIPS="Eclipse" -ELGORL="Faro de El Gordo" -ELSANT="Los Santos Este" -ELYSIAN="Elysian Island" -GALFISH="Galilee" -GALLI="Galileo Park" -GOLF="Club de golf GW" -GRAPES="Grapeseed" -GREATC="Great Chaparral" -HARMO="Harmony" -HAWICK="Hawick" -HEART="Heart Attacks Beach" -HORS="Circuito de Vinewood" -HUMLAB="Humane Labs and Research" -ISHEIST="Cayo Perico" -JAIL="Penitenciaría de Bolingbroke" -KOREAT="Little Seoul" -LACT="Presa de Land Act" -LAGO="Lago Zancudo" -LDAM="Presa de Land Act" -LMESA="La Mesa" -LOSPFY="La Puerta Freeway" -LOSPUER="La Puerta" -LOSSF="Los Santos Freeway" -MIRR="Mirror Park" -MORN="Morningwood" -MOVIE="Richards Majestic" -MTCHIL="Mount Chiliad" -MTGORDO="Mount Gordo" -MTJOSE="Mount Josiah" -MURRI="Murrieta Heights" -NCHU="Chumash Norte" -OBSERV="Observatorio Galileo" -OCEANA="Océano Pacífico" -PALCOV="Paleto Cove" -PALETO="Paleto Bay" -PALFOR="Paleto Forest" -PALHIGH="Palomino Highlands" -PALMPOW="Central Palmer-Taylor" -PBLUFF="Pacific Bluffs" -PBOX="Pillbox Hill" -PROCOB="Procopio Beach" -PROL="North Yankton" -RANCHO="Rancho" -RGLEN="Richman Glen" -RICHM="Richman" -ROCKF="Rockford Hills" -RTRAK="Circuito Redwood Lights" -SANAND="San Andreas" -SANCHIA="San Chianski Mountain Range" -SANDY="Sandy Shores" -SENORA="Senora Freeway" -SKID="Mission Row" -SLAB="Stab City" -SLSANT="Los Santos Sur" -STAD="Maze Bank Arena" -STRAW="Strawberry" -TATAMO="Tataviam Mountains" -TERMINA="Terminal" -TEXTI="Textile City" -TONGVAH="Tongva Hills" -TONGVAV="Tongva Valley" -UTOPIAG="Utopia Gardens" -VCANA="Vespucci Canals" -VESP="Vespucci" -VINE="Vinewood" -WINDF="Granja eólica Ron Alternates" -WMIRROR="West Mirror Drive" -WVINE="Vinewood Oeste" -ZANCUDO="Río Zancudo" -ZENORA="Senora Freeway" diff --git a/res/global.fr.ini b/res/global.fr.ini index 807c5ec..130709f 100644 --- a/res/global.fr.ini +++ b/res/global.fr.ini @@ -40,8 +40,9 @@ HARMO="Harmony" HAWICK="Hawick" HEART="Heart Attacks Beach" HORS="Hippodrome de Vinewood" +HUD_MG_TRI_ALA="Alamo Sea" +HUD_MG_TRI_VES="Vespucci" HUMLAB="Laboratoires Humane" -ISHEIST="Cayo Perico" JAIL="Pénitencier de Bolingbroke" KOREAT="Little Seoul" LACT="Land Act Reservoir" @@ -51,6 +52,9 @@ LMESA="La Mesa" LOSPFY="La Puerta Freeway" LOSPUER="La Puerta" LOSSF="Los Santos Freeway" +MGCR_1="South Los Santos" +MGCR_6="Canaux de Vespucci" +MGSR_3="Raton Canyon" MIRR="Mirror Park" MORN="Morningwood" MOVIE="Richards Majestic" diff --git a/res/global.it.ini b/res/global.it.ini deleted file mode 100644 index 4c89a36..0000000 --- a/res/global.it.ini +++ /dev/null @@ -1,100 +0,0 @@ -[Global] -AIRP="Los Santos International Airport" -ALAMO="Alamo Sea" -ALTA="Alta" -ARMYB="Fort Zancudo" -BANNING="Banning" -BAYTRE="Baytree Canyon" -BEACH="Vespucci Beach" -BHAMCA="Banham Canyon" -BRADP="Braddock Pass" -BRADT="Braddock Tunnel" -BURTON="Burton" -CALAFB="Calafia Bridge" -CANNY="Raton Canyon" -CCREAK="Cassidy Creek" -CHAMH="Chamberlain Hills" -CHIL="Vinewood Hills" -CHU="Chumash" -CMSW="Chiliad Mountain State Wilderness" -COSI="Campagna" -CYPRE="Cypress Flats" -DAVIS="Davis" -DELBE="Del Perro Beach" -DELPE="Del Perro" -DELSOL="La Puerta" -DESRT="Grand Senora Desert" -DOWNT="Centro" -DTVINE="Downtown Vinewood" -EAST_V="East Vinewood" -EBURO="El Burro Heights" -ECLIPS="Eclipse" -ELGORL="Faro di El Gordo" -ELSANT="East Los Santos" -ELYSIAN="Elysian Island" -GALFISH="Galilee" -GALLI="Galileo Park" -GOLF="GWC and Golfing Society" -GRAPES="Grapeseed" -GREATC="Grande boscaglia" -HARMO="Harmony" -HAWICK="Hawick" -HEART="Heart Attacks Beach" -HORS="Vinewood Racetrack" -HUMLAB="Laboratori di ricerca Humane" -ISHEIST="Cayo Perico" -JAIL="Bolingbroke Penitentiary" -KOREAT="Little Seoul" -LACT="Land Act Reservoir" -LAGO="Lago Zancudo" -LDAM="Land Act Dam" -LMESA="La Mesa" -LOSPFY="La Puerta Freeway" -LOSPUER="La Puerta" -LOSSF="Los Santos Freeway" -MIRR="Mirror Park" -MORN="Morningwood" -MOVIE="Richards Majestic" -MTCHIL="Mount Chiliad" -MTGORDO="Mount Gordo" -MTJOSE="Mount Josiah" -NCHU="North Chumash" -OBSERV="Galileo Observatory" -OCEANA="Oceano Pacifico" -PALCOV="Paleto Cove" -PALETO="Paleto Bay" -PALFOR="Paleto Forest" -PALHIGH="Palomino Highlands" -PALMPOW="Centrale elettrica Palmer-Taylor" -PBLUFF="Pacific Bluffs" -PBOX="Pillbox Hill" -PROCOB="Procopio Beach" -PROL="North Yankton" -RANCHO="Rancho" -RGLEN="Richman Glen" -RICHM="Richman" -ROCKF="Rockford Hills" -RTRAK="Redwood Lights Track" -SANAND="San Andreas" -SANCHIA="San Chianski Mountain Range" -SANDY="Sandy Shores" -SENORA="Senora Freeway" -SKID="Mission Row" -SLAB="Stab City" -SLSANT="South Los Santos" -STAD="Maze Bank Arena" -STRAW="Strawberry" -TATAMO="Tataviam Mountains" -TERMINA="Terminal" -TEXTI="Textile City" -TONGVAH="Tongva Hills" -TONGVAV="Tongva Valley" -UTOPIAG="Utopia Gardens" -VCANA="Vespucci Canals" -VESP="Vespucci" -VINE="Vinewood" -WINDF="Parco eolico Ron Alternates" -WMIRROR="West Mirror Drive" -WVINE="West Vinewood" -ZANCUDO="Zancudo River" -ZENORA="Senora Freeway" diff --git a/res/global.ja.ini b/res/global.ja.ini old mode 100644 new mode 100755 index f38223d..366e294 --- a/res/global.ja.ini +++ b/res/global.ja.ini @@ -9,6 +9,7 @@ BEACH="ベスプッチ・ビーチ" BHAMCA="バンナムキャニオン" BRADP="ブラドック・パス" BRADT="ブラドック・トンネル" +BSS_BSTR_131="リチャーズ・マジェスティック" BURTON="バートン" CALAFB="カラフィア橋" CANNY="ラトン・キャニオン" @@ -41,8 +42,9 @@ HARMO="ハーモニー" HAWICK="ハウィック" HEART="ハートアタック・ビーチ" HORS="バインウッド・レーストラック" +HUD_MG_TRI_ALA="アラモ海" +HUD_MG_TRI_VES="ベスプッチ" HUMLAB="ヒューメイン研究所" -ISHEIST="カヨ・ペリコ" JAIL="ボーリングブローク刑務所" KOREAT="リトル・ソウル" LACT="ランド・アクト貯水池" @@ -52,6 +54,9 @@ LMESA="ラ・メサ" LOSPFY="ラ・プエルタ高速道路" LOSPUER="ラ・プエルタ" LOSSF="ロスサントス高速道路" +MGCR_1="サウス・ロスサントス" +MGCR_6="ベスプッチ運河" +MGSR_3="ラトン・キャニオン" MIRR="ミラー・パーク" MORN="モーニングウッド" MOVIE="リチャーズ・マジェスティック" diff --git a/res/global.ko.ini b/res/global.ko.ini deleted file mode 100644 index 7296638..0000000 --- a/res/global.ko.ini +++ /dev/null @@ -1,101 +0,0 @@ -[Global] -AIRP="로스 산토스 국제공항" -ALAMO="알라모 해" -ALTA="알타" -ARMYB="포트 잔쿠도" -BANNING="배닝" -BAYTRE="베이트리 협곡" -BEACH="베스푸치 해변" -BHAMCA="밴험 협곡" -BRADP="브래독 패스" -BRADT="브래독 터널" -BURTON="버튼" -CALAFB="칼라피아 브릿지" -CANNY="레이튼 협곡" -CCREAK="캐시디 크리크" -CHAMH="쳄벌레인 힐즈" -CHIL="바인우드 힐즈" -CHU="추마쉬" -CMSW="칠리아드 마운틴 주 황무지" -COSI="시골 지역" -CYPRE="사이프레스 플랫" -DAVIS="데이비스" -DELBE="델 페로 해변" -DELPE="델 페로" -DELSOL="라 푸에르타" -DESRT="그랜드 세뇨라 사막" -DOWNT="다운타운" -DTVINE="다운타운 바인우드" -EAST_V="동부 바인우드" -EBURO="엘 부로 하이츠" -ECLIPS="이클립스" -ELGORL="엘 고르도 라이트하우스" -ELSANT="동부 로스 산토스" -ELYSIAN="엘리시안 섬" -GALFISH="갈릴리" -GALLI="갈릴레오 파크" -GOLF="GWC & 골프 클럽" -GRAPES="그레이프시드" -GREATC="그레이트 섀퍼럴" -HARMO="하모니" -HAWICK="호익" -HEART="하트 어택 해변" -HORS="바인우드 레이스트랙" -HUMLAB="휴메인 실험 연구소" -ISHEIST="카요 페리코" -JAIL="볼링브로크 교도소" -KOREAT="리틀 서울" -LACT="랜드 액트 저수지" -LAGO="라고 잔쿠도" -LDAM="랜드 액트 댐" -LMESA="라 메사" -LOSPFY="라 푸에르타 고속도로" -LOSPUER="라 푸에르타" -LOSSF="로스 산토스 고속도로" -MIRR="미러 파크" -MORN="모닝우드" -MOVIE="리차드 마제스틱" -MTCHIL="마운트 칠리아드" -MTGORDO="고르도 산" -MTJOSE="마운트 조시아" -MURRI="무리에타 하이츠" -NCHU="북부 추마쉬" -OBSERV="갈릴레오 관측소" -OCEANA="퍼시픽 오션" -PALCOV="팔레토 코브" -PALETO="팔레토 항구" -PALFOR="팔레토 숲" -PALHIGH="팔로미노 고원" -PALMPOW="파머 테일러 발전소" -PBLUFF="퍼시픽 블러프" -PBOX="필박스 힐" -PROCOB="프로코피오 해변" -PROL="북부 양크턴" -RANCHO="란초" -RGLEN="리치맨 글렌" -RICHM="리치맨" -ROCKF="락포드 힐즈" -RTRAK="레드우드 라이트 트랙" -SANAND="산 안드레아스" -SANCHIA="샌 치안스키 산맥" -SANDY="샌디 해안" -SENORA="세뇨라 고속도로" -SKID="미션 로우" -SLAB="스탭 시티" -SLSANT="남부 로스 산토스" -STAD="메이즈 은행 경기장" -STRAW="스트로베리" -TATAMO="타타비암 산" -TERMINA="터미널" -TEXTI="텍스타일 시티" -TONGVAH="통바 힐즈" -TONGVAV="통바 계곡" -UTOPIAG="유토피아 가든" -VCANA="베스푸치 운하" -VESP="베스푸치" -VINE="바인우드" -WINDF="론 얼터네이트 윈드 팜" -WMIRROR="서 미러 드라이브" -WVINE="서부 바인우드" -ZANCUDO="잔쿠도 강" -ZENORA="세뇨라 고속도로" diff --git a/res/global.pl.ini b/res/global.pl.ini deleted file mode 100644 index e318284..0000000 --- a/res/global.pl.ini +++ /dev/null @@ -1,96 +0,0 @@ -[Global] -AIRP="Lotnisko międzynarodowe Los Santos" -ALAMO="Alamo Sea" -ALTA="Alta" -ARMYB="Fort Zancudo" -BANNING="Banning" -BAYTRE="Kanion Baytree" -BEACH="Vespucci Beach" -BHAMCA="Kanion Banham" -BRADP="Przełęcz Braddock" -BRADT="Tunel Braddock" -BURTON="Burton" -CALAFB="Most Calafia" -CANNY="Kanion Raton" -CCREAK="Cassidy Creek" -CHAMH="Chamberlain Hills" -CHIL="Vinewood Hills" -CHU="Chumash" -CMSW="Park krajobrazowy Góry Chiliad" -COSI="Tereny pozamiejskie" -CYPRE="Cypress Flats" -DAVIS="Davis" -DELBE="Plaża Del Perro" -DELPE="Del Perro" -DELSOL="La Puerta" -DESRT="Pustynia Grand Senora" -DOWNT="Centrum" -DTVINE="Centrum Vinewood" -EAST_V="Wschodnie Vinewood" -EBURO="El Burro Heights" -ECLIPS="Eclipse" -ELGORL="Latarnia El Gordo" -ELSANT="Wschodnie Los Santos" -ELYSIAN="Wyspa Elizejska" -GALFISH="Galilee" -GALLI="Park Galileusza" -GOLF="Stowarzyszenie GWC & Golfing" -GRAPES="Grapeseed" -GREATC="Great Chaparral" -HARMO="Harmony" -HAWICK="Hawick" -HEART="Plaża Zawałowców" -HORS="Tor wyścigowy Vinewood" -HUMLAB="Humane Labs and Research" -ISHEIST="Cayo Perico" -JAIL="Zakład karny Bolingbroke" -KOREAT="Mały Seul" -LACT="Jezioro zaporowe" -LAGO="Lago Zancudo" -LMESA="La Mesa" -LOSPFY="La Puerta Freeway" -LOSPUER="La Puerta" -LOSSF="Los Santos Freeway" -MIRR="Park Mirror" -MORN="Morningwood" -MOVIE="Richards Majestic" -MTCHIL="Góra Chiliad" -MTGORDO="Góra Gordo" -MURRI="Murrieta Heights" -NCHU="Północne Chumash" -OBSERV="Obserwatorium Galileusza" -PALCOV="Zatoka Paleto" -PALETO="Paleto Bay" -PALFOR="Las Paleto" -PALHIGH="Wyżyna Palomino" -PALMPOW="Elektrownia Palmer-Taylor" -PBLUFF="Pacific Bluffs" -PBOX="Pillbox Hill" -PROCOB="Plaża Procopio" -PROL="North Yankton" -RANCHO="Ranczo" -RGLEN="Richman Glen" -RICHM="Richman" -ROCKF="Rockford Hills" -RTRAK="Tor Redwood Lights" -SANAND="San Andreas" -SANCHIA="Masyw górski San Chianski" -SANDY="Sandy Shores" -SKID="Mission Row" -SLAB="Stab City" -SLSANT="Południowe Los Santos" -STAD="Stadion Maze Bank" -STRAW="Strawberry" -TATAMO="Góry Tataviam" -TERMINA="Terminal" -TEXTI="Textile City" -TONGVAH="Tongva Hills" -TONGVAV="Dolina Tongva" -UTOPIAG="Utopia Gardens" -VCANA="Vespucci Canals" -VESP="Vespucci" -VINE="Vinewood" -WINDF="Farma wiatrowa Ron Alternates" -WVINE="Zachodnie Vinewood" -ZANCUDO="Rzeka Zancudo" -ZENORA="Senora Freeway" diff --git a/res/global.pt.ini b/res/global.pt.ini deleted file mode 100644 index 79d46ab..0000000 --- a/res/global.pt.ini +++ /dev/null @@ -1,100 +0,0 @@ -[Global] -AIRP="Aeroporto Internacional de Los Santos" -ALAMO="Mar Alamo" -ALTA="Alta" -ARMYB="Fort Zancudo" -BANNING="Banning" -BAYTRE="Baytree Canyon" -BEACH="Vespucci Beach" -BHAMCA="Banham Canyon" -BRADP="Braddock Pass" -BRADT="Braddock Tunnel" -BURTON="Burton" -CALAFB="Calafia Bridge" -CANNY="Raton Canyon" -CCREAK="Cassidy Creek" -CHAMH="Chamberlain Hills" -CHIL="Vinewood Hills" -CHU="Chumash" -CMSW="Reserva Natural Monte Chiliad" -COSI="Zona Rural" -CYPRE="Cypress Flats" -DAVIS="Davis" -DELBE="Del Perro Beach" -DELPE="Del Perro" -DELSOL="La Puerta" -DESRT="Deserto Grand Senora" -DOWNT="Centro" -EAST_V="East Vinewood" -EBURO="El Burro Heights" -ECLIPS="Eclipse" -ELGORL="Farol El Gordo" -ELSANT="East Los Santos" -ELYSIAN="Elysian Island" -GALFISH="Galilee" -GALLI="Galileo Park" -GOLF="Clube de campo e golfe GW" -GRAPES="Grapeseed" -GREATC="Great Chaparral" -HARMO="Harmony" -HAWICK="Hawick" -HEART="Heart Attacks Beach" -HORS="Hipódromo de Vinewood" -HUMLAB="Laboratórios e Pesquisas Humane" -ISHEIST="Cayo Perico" -JAIL="Penitenciária Bolingbroke" -KOREAT="Little Seoul" -LACT="Reservatório Land Act" -LAGO="Lago Zancudo" -LDAM="Represa Land Act" -LMESA="La Mesa" -LOSPFY="La Puerta Freeway" -LOSPUER="La Puerta" -LOSSF="Los Santos Freeway" -MIRR="Mirror Park" -MORN="Morningwood" -MOVIE="Richards Majestic" -MTCHIL="Monte Chiliad" -MTGORDO="Monte Gordo" -MTJOSE="Monte Josiah" -MURRI="Murrieta Heights" -NCHU="North Chumash" -OBSERV="Observatório Galileo" -OCEANA="Oceano Pacífico" -PALCOV="Paleto Cove" -PALETO="Paleto Bay" -PALFOR="Paleto Forest" -PALHIGH="Palomino Highlands" -PALMPOW="Usina Elétrica Palmer-Taylor" -PBLUFF="Pacific Bluffs" -PBOX="Pillbox Hill" -PROCOB="Procopio Beach" -PROL="North Yankton" -RANCHO="Rancho" -RGLEN="Richman Glen" -RICHM="Richman" -ROCKF="Rockford Hills" -RTRAK="Pista Redwood Lights" -SANAND="San Andreas" -SANCHIA="Cordilheira San Chianski" -SANDY="Sandy Shores" -SENORA="Senora Freeway" -SKID="Mission Row" -SLAB="Stab City" -SLSANT="South Los Santos" -STAD="Arena Maze Bank" -STRAW="Strawberry" -TATAMO="Montanhas Tataviam" -TERMINA="Terminal" -TEXTI="Textile City" -TONGVAH="Tongva Hills" -TONGVAV="Tongva Valley" -UTOPIAG="Utopia Gardens" -VCANA="Vespucci Canals" -VESP="Vespucci" -VINE="Vinewood" -WINDF="Parque Eólico Ron Alternates" -WMIRROR="West Mirror Drive" -WVINE="West Vinewood" -ZANCUDO="Rio Zancudo" -ZENORA="Senora Freeway" diff --git a/res/global.qrc b/res/global.qrc deleted file mode 100644 index 424d0ab..0000000 --- a/res/global.qrc +++ /dev/null @@ -1,17 +0,0 @@ - - - global.de.ini - global.en.ini - global.es.ini - global.es_MX.ini - global.fr.ini - global.it.ini - global.ja.ini - global.ko.ini - global.pl.ini - global.pt.ini - global.ru.ini - global.zh.ini - global.zh.loc - - diff --git a/res/global.rcc b/res/global.rcc deleted file mode 100644 index 60cc688..0000000 Binary files a/res/global.rcc and /dev/null differ diff --git a/res/global.ru.ini b/res/global.ru.ini deleted file mode 100644 index 996f807..0000000 --- a/res/global.ru.ini +++ /dev/null @@ -1,101 +0,0 @@ -[Global] -AIRP="Международный аэропорт Лос-Сантос" -ALAMO="Аламо-Си" -ALTA="Альта" -ARMYB="Форт-Занкудо" -BANNING="Бэннинг" -BAYTRE="Каньон Бэйтри" -BEACH="Веспуччи-Бич" -BHAMCA="Каньон Бэнхэм" -BRADP="Перевал Брэддока" -BRADT="Тоннель Брэддока" -BURTON="Бертон" -CALAFB="Калафиа-Бридж" -CANNY="Каньон Ратон" -CCREAK="Кэссиди-Крик" -CHAMH="Чемберлен-Хиллз" -CHIL="Вайнвуд-Хиллз" -CHU="Чумаш" -CMSW="Заповедник горы Чилиад" -COSI="Загород" -CYPRE="Сайпрес-Флэтс" -DAVIS="Дэвис" -DELBE="Дель-Перро-Бич" -DELPE="Дель-Перро" -DELSOL="Ла-Пуэрта" -DESRT="Пустыня Гранд-Сенора" -DOWNT="Центр" -DTVINE="Центр Вайнвуда" -EAST_V="Восточный Вайнвуд" -EBURO="Эль-Бурро-Хайтс" -ECLIPS="Эклипс" -ELGORL="Маяк Эль-Гордо" -ELSANT="Восточный Лос-Сантос" -ELYSIAN="Элизиан-Айленд" -GALFISH="Галили" -GALLI="Галилео-Парк" -GOLF="Гольф-клуб" -GRAPES="Грейпсид" -GREATC="Грейт-Чапаррал" -HARMO="Хармони" -HAWICK="Хавик" -HEART="Харт-Аттакс-Бич" -HORS="Гоночная трасса Вайнвуда" -HUMLAB="Лаборатория Humane Labs and Research" -ISHEIST="Кайо-Перико" -JAIL="Тюрьма Болингброук" -KOREAT="Маленький Сеул" -LACT="Лэнд-экт-резервуар" -LAGO="Лаго-Занкудо" -LDAM="Лэнд-экт-дэм" -LMESA="Ла-Меса" -LOSPFY="Шоссе Ла-Пуэрта" -LOSPUER="Ла-Пуэрта" -LOSSF="Шоссе Лос-Сантоса" -MIRR="Миррор-Парк" -MORN="Морнингвуд" -MOVIE="Richards Majestic" -MTCHIL="Гора Чилиад" -MTGORDO="Гора Гордо" -MTJOSE="Гора Джосайя" -MURRI="Мурьета-Хайтс" -NCHU="Северный Чумаш" -OBSERV="Обсерватория Галилео" -OCEANA="Тихий океан" -PALCOV="Бухта Палето" -PALETO="Палето-Бэй" -PALFOR="Лес Палето" -PALHIGH="Нагорья Паломино" -PALMPOW="Электростанция Палмер-Тэйлор" -PBLUFF="Пасифик-Блаффс" -PBOX="Пиллбокс-Хилл" -PROCOB="Прокопио-Бич" -PROL="Северный Янктон" -RANCHO="Ранчо" -RGLEN="Ричман-Глен" -RICHM="Ричман" -ROCKF="Рокфорд-Хиллз" -RTRAK="Трасса Redwood Lights" -SANAND="Сан-Андреас" -SANCHIA="Сан-Шаньский горный хребет" -SANDY="Сэнди-Шорс" -SENORA="Шоссе Сенора" -SKID="Мишн-Роу" -SLAB="Стэб-Сити" -SLSANT="Южный Лос-Сантос" -STAD="Арена Maze Bank" -STRAW="Строберри" -TATAMO="Татавиамские горы" -TERMINA="Терминал" -TEXTI="Текстайл-Сити" -TONGVAH="Тонгва-Хиллз" -TONGVAV="Долина Тонгва" -UTOPIAG="Утопия-Гарденс" -VCANA="Каналы Веспуччи" -VESP="Веспуччи" -VINE="Вайнвуд" -WINDF="Ветряная ферма Ron Alternates" -WMIRROR="Вест-Миррор-драйв" -WVINE="Западный Вайнвуд" -ZANCUDO="Река Занкудо" -ZENORA="Шоссе Сенора" diff --git a/res/global.zh.ini b/res/global.zh.ini index 49650cc..35564bd 100644 --- a/res/global.zh.ini +++ b/res/global.zh.ini @@ -40,8 +40,9 @@ HARMO="和美尼" HAWICK="霍伊克" HEART="驚心海灘" HORS="好麥塢賽馬場" +HUD_MG_TRI_ALA="阿拉莫海" +HUD_MG_TRI_VES="威斯普奇" HUMLAB="人道研究實驗室" -ISHEIST="佩里克島" JAIL="博林布魯克監獄" KOREAT="小首爾" LACT="蘭艾水庫" @@ -51,6 +52,9 @@ LMESA="梅薩" LOSPFY="洛波塔高速公路" LOSPUER="洛波塔" LOSSF="洛聖都高速公路" +MGCR_1="南洛聖都" +MGCR_6="威斯普奇運河" +MGSR_3="雷通峽谷" MIRR="米羅公園" MORN="摩寧塢" MOVIE="李察尊爵" diff --git a/res/global.zh.loc b/res/global.zh.loc deleted file mode 100644 index dad8857..0000000 --- a/res/global.zh.loc +++ /dev/null @@ -1 +0,0 @@ -zh_TW diff --git a/res/gta5sync.ts b/res/gta5sync.ts deleted file mode 100644 index 88ab419..0000000 --- a/res/gta5sync.ts +++ /dev/null @@ -1,2505 +0,0 @@ - - - - - AboutDialog - - - About %1 - - - - - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -Version %3<br/> -Created on %4<br/> -Built with Qt %5<br/> -Running with Qt %6<br/> -<br/> -%7 - - - - - &Close - - - - - Translated by %1 - Translated by translator, example Translated by Syping - - - - - TRANSLATOR - Insert your name here and profile here in following scheme, First Translator,First Profile\nSecond Translator\nThird Translator,Second Profile - - - - - A project for viewing Grand Theft Auto V Snapmatic<br/> -Pictures and Savegames - - - - - Copyright &copy; <a href="%1">%2</a> %3 - - - - - %1 is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - - - - - Release - - - - - Release Candidate - - - - - Daily Build - - - - - Developer - - - - - Beta - - - - - Alpha - - - - - - Custom - - - - - CrewDatabase - - - - No Crew - - - - - ExportDialog - - - Dialog - - - - - Export Format - - - - - &JPEG/PNG format - - - - - GTA &Snapmatic format - - - - - Export Size - - - - - Default &Size - - - - - &Desktop Size - - - - - &Custom Size - - - - - Custom Size: - - - - - x - - - - - &Export - - - - - &Close - - - - - ImageEditorDialog - - - Overwrite Image... - - - - - Apply changes - - - - - &Overwrite - - - - - Discard changes - - - - - &Close - - - - - - - - Snapmatic Image Editor - - - - - - Patching of Snapmatic Image failed because of I/O Error - - - - - - Patching of Snapmatic Image failed because of Image Error - - - - - ImportDialog - - - Import... - - - - - Picture - - - - - Avatar - - - - - - Ignore Aspect Ratio - - - - - Watermark - - - - - Crop to Aspect Ratio - - - - - Background - - - - - - - - Background Colour: <span style="color: %1">%1</span> - - - - - Select background colour - - - - - - - - Background Image: - - - - - Select background image - - - - - Remove background image - - - - - Force Colour in Avatar Zone - - - - - Advanced - - - - - Resolution: - - - - - Snapmatic resolution - - - - - Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic - - - - - Unlimited Buffer - - - - - Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing - - - - - Import as-is - - - - - Import options - - - - - &Options - - - - - Import picture - - - - - &OK - - - - - Discard picture - - - - - &Cancel - - - - - &Import new Picture... - - - - - &Crop Picture... - - - - - &Load Settings... - - - - - &Save Settings... - - - - - - Custom Avatar - Custom Avatar Description in SC, don't use Special Character! - - - - - - - Custom Picture - Custom Picture Description in SC, don't use Special Character! - - - - - Storage - Background Image: Storage - - - - - Crop Picture... - - - - - &Crop - - - - - Crop Picture - - - - - - Please import a new picture first - - - - - - Default - Default as Default Profile - - - - - - - - - - - - - - - - - - - - - - - - Profile %1 - Profile %1 as Profile 1 - - - - - - Load Settings... - - - - - - Save Settings... - - - - - - Snapmatic Avatar Zone - - - - - - Are you sure to use a square image outside of the Avatar Zone? -When you want to use it as Avatar the image will be detached! - - - - - Select Colour... - - - - - - Background Image: %1 - - - - - - Please select your settings profile - - - - - File - Background Image: File - - - - - JsonEditorDialog - - - Snapmatic JSON Editor - - - - - Apply changes - - - - - &Save - - - - - Discard changes - - - - - &Close - - - - - JSON Error - - - - - MapLocationDialog - - - Snapmatic Map Viewer - - - - - Close viewer - - - - - &Close - - - - - Apply new position - - - - - &Apply - - - - - Revert old position - - - - - &Revert - - - - - Select new position - - - - - &Select - - - - - Quit select position - - - - - &Done - - - - - X: %1 -Y: %2 - X and Y position - - - - - OptionsDialog - - - %1 - Settings - - - - - Profiles - - - - - Content Open/Select Mode - - - - - Open with Doubleclick - - - - - Default Profile - - - - - Custom GTA V Folder - - - - - Force using Custom Folder - - - - - ... - - - - - Pictures - - - - - Export Size - - - - - Default: %1x%2 - - - - - Screen Resolution: %1x%2 - - - - - - Custom Size: - - - - - x - - - - - Ignore Aspect Ratio - - - - - Export Quality - - - - - Enable Custom Quality - - - - - Quality: - - - - - %1% - - - - - Picture Viewer - - - - - Enable Navigation Bar - - - - - Players - - - - - ID - - - - - Name - - - - - Game - - - - - Social Club Version - - - - - - - - - - - - Found: %1 - - - - - - - - - - - - - - Language: %1 - - - - - Steam Version - - - - - Feedback - - - - - Participation - - - - - - Participate in %1 User Statistics - - - - - Categories - - - - - Hardware, Application and OS Specification - - - - - System Language Configuration - - - - - Application Configuration - - - - - Personal Usage Data - - - - - Other - - - - - - - Participation ID: %1 - - - - - &Copy - - - - - Interface - - - - - Language for Interface - - - - - - - - Current: %1 - - - - - Language for Areas - - - - - Style - - - - - Use Default Style (Restart) - - - - - Style: - - - - - Font - - - - - Use Default Font (Restart) - - - - - Font: - - - - - Apply changes - - - - - &OK - OK, Cancel, Apply - - - - - Discard changes - - - - - &Cancel - OK, Cancel, Apply - - - - - System - System in context of System default - - - - - %1 (Game language) - Next closest language compared to the Game settings - - - - - - %1 (Closest to Interface) - Next closest language compared to the Interface - - - - - - - Auto - Automatic language choice. - - - - - %1 (Language priority) - First language a person can talk with a different person/application. "Native" or "Not Native". - - - - - %1 - %1 - - - - - The new Custom Folder will initialise after you restart %1. - - - - - No Profile - No Profile, as default - - - - - - - Profile: %1 - - - - - View %1 User Statistics Online - - - - - Not registered - - - - - - - - Yes - - - - - - No - - - - - - OS defined - - - - - - Steam defined - - - - - PictureDialog - - - Snapmatic Picture Viewer - %1 - - - - - <span style="font-weight:600">Title: </span>%6<br/> -<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Created: </span>%8 - - - - - Manage picture - - - - - &Manage - - - - - Close viewer - - - - - &Close - - - - - - Export as &Picture... - - - - - - Export as &Snapmatic... - - - - - - &Edit Properties... - - - - - - &Overwrite Image... - - - - - - Open &Map Viewer... - - - - - - Open &JSON Editor... - - - - - Key 1 - Avatar Preview Mode -Key 2 - Toggle Overlay -Arrow Keys - Navigate - - - - - Snapmatic Picture Viewer - - - - - Failed at %1 - - - - - - - No Players - - - - - - No Crew - - - - - Unknown Location - - - - - Avatar Preview Mode -Press 1 for Default View - - - - - Export as Picture... - - - - - - Export - - - - - JPEG Graphics (*.jpg *.jpeg) - - - - - Portable Network Graphics (*.png) - - - - - - - - - - Export as Picture - - - - - - Overwrite %1 with current Snapmatic picture? - - - - - Failed to export the picture because the system occurred a write failure - - - - - Failed to export the picture because the format detection failures - - - - - Failed to export the picture because the file can't be written - - - - - Failed to export the picture because of an unknown reason - - - - - - No valid file is selected - - - - - Export as Snapmatic... - - - - - GTA V Export (*.g5e) - - - - - GTA V Raw Export (*.auto) - - - - - Snapmatic pictures (PGTA*) - - - - - - - - - Export as Snapmatic - - - - - - Failed to export current Snapmatic picture - - - - - Exported Snapmatic to "%1" because of using the .auto extension. - - - - - PlayerListDialog - - - Edit Players... - - - - - Available Players: - - - - - Selected Players: - - - - - &Apply - - - - - &Cancel - - - - - Add Players... - - - - - Failed to add more Players because the limit of Players are %1! - - - - - - Add Player... - - - - - Enter Social Club Player ID - - - - - Failed to add Player %1 because Player %1 is already added! - - - - - ProfileInterface - - - Profile Interface - - - - - Loading file %1 of %2 files - - - - - %1 %2 - - - - - Import file - - - - - &Import... - - - - - Close profile - - - - - &Close - - - - - - - Export file %1 of %2 files - - - - - - - - - - - - - - - - - - - - - - - Import... - - - - - - - - - - Import - - - - - - - All image files (%1) - - - - - - - - All files (**) - - - - - - - Can't import %1 because file can't be open - - - - - - - Can't import %1 because file can't be parsed properly - - - - - Enabled pictures: %1 of %2 - - - - - Loading... - - - - - Snapmatic Loader - - - - - <h4>Following Snapmatic Pictures got repaired</h4>%1 - - - - - Importable files (%1) - - - - - - GTA V Export (*.g5e) - - - - - - Savegames files (SGTA*) - - - - - - Snapmatic pictures (PGTA*) - - - - - - - No valid file is selected - - - - - - Import file %1 of %2 files - - - - - Import failed with... - -%1 - - - - - - Failed to read Snapmatic picture - - - - - - Failed to read Savegame file - - - - - Can't import %1 because file format can't be detected - - - - - Prepare Content for Import... - - - - - Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e - - - - - A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp? - - - - - Failed to import the Snapmatic picture, can't copy the file into profile - - - - - Failed to import the Savegame, can't copy the file into profile - - - - - Failed to import the Savegame, no Savegame slot is left - - - - - - - - - Export selected... - - - - - - JPG pictures and GTA Snapmatic - - - - - - JPG pictures only - - - - - - GTA Snapmatic only - - - - - %1Export Snapmatic pictures%2<br><br>JPG pictures make it possible to open the picture with a Image Viewer<br>GTA Snapmatic make it possible to import the picture into the game<br><br>Export as: - - - - - Initialising export... - - - - - Export failed with... - -%1 - - - - - - No Snapmatic pictures or Savegames files are selected - - - - - - - Remove selected - - - - - You really want remove the selected Snapmatic picutres and Savegame files? - - - - - Failed to remove all selected Snapmatic pictures and/or Savegame files - - - - - - - - - - No Snapmatic pictures are selected - - - - - - - - - - %1 failed with... - -%2 - Action failed with... - - - - - - Qualify as Avatar - - - - - - - - Patch selected... - - - - - - - - - - - - Patch file %1 of %2 files - - - - - Qualify - %1 failed with... - - - - - - Change Players... - - - - - Change Players - %1 failed with... - - - - - - - Change Crew... - - - - - Failed to enter a valid Snapmatic Crew ID - - - - - Change Crew - %1 failed with... - - - - - - - Change Title... - - - - - Failed to enter a valid Snapmatic title - - - - - Change Title - %1 failed with... - - - - - All profile files (*.g5e SGTA* PGTA*) - - - - - SavegameDialog - - - - Savegame Viewer - - - - - <span style="font-weight:600">Savegame</span><br><br>%1 - - - - - &Export - - - - - &Close - - - - - Failed at %1 - - - - - SavegameWidget - - - Savegame Widget - - - - - SAVE %3 - %1<br>%2 - - - - - View savegame - - - - - View - - - - - Copy savegame - - - - - - Export - - - - - Delete savegame - - - - - Delete - - - - - &View - - - - - - - &Export - - - - - - - &Remove - - - - - - &Select - - - - - - &Deselect - - - - - - Select &All - - - - - - &Deselect All - - - - - Savegame files (SGTA*) - - - - - All files (**) - - - - - - - - Export Savegame - - - - - Overwrite %1 with current Savegame? - - - - - Failed to overwrite %1 with current Savegame - - - - - Failed to export current Savegame - - - - - No valid file is selected - - - - - Export Savegame... - - - - - - AUTOSAVE - %1 -%2 - - - - - - SAVE %3 - %1 -%2 - - - - - - WRONG FORMAT - - - - - UNKNOWN - - - - - - Delete Savegame - - - - - Are you sure to delete %1 from your savegames? - - - - - Failed at deleting %1 from your savegames - - - - - SnapmaticEditor - - - - - - - - - - - Snapmatic Properties - - - - - Snapmatic Type - - - - - Editor - - - - - Selfie - - - - - Regular - - - - - Mugshot - - - - - Meme - - - - - Director - - - - - Snapmatic Values - - - - - Extras - - - - - Qualify as Avatar automatically at apply - - - - - Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture - - - - - Apply changes - - - - - &Apply - - - - - Discard changes - - - - - &Cancel - - - - - <h4>Unsaved changes detected</h4>You want to save the JSON content before you quit? - - - - - Patching of Snapmatic Properties failed because of %1 - - - - - - - - Patching of Snapmatic Properties failed because of I/O Error - - - - - Patching of Snapmatic Properties failed because of JSON Error - - - - - - Snapmatic Crew - - - - - - New Snapmatic crew: - - - - - - Snapmatic Title - - - - - - New Snapmatic title: - - - - - - - Edit - - - - - Players: %1 (%2) - Multiple Player are inserted here - - - - - Player: %1 (%2) - One Player is inserted here - - - - - Title: %1 (%2) - - - - - - Appropriate: %1 - - - - - Yes - Yes, should work fine - - - - - No - No, could lead to issues - - - - - Crew: %1 (%2) - - - - - SnapmaticPicture - - - - JSON is incomplete and malformed - - - - - - JSON is incomplete - - - - - - JSON is malformed - - - - - PHOTO - %1 - - - - - open file %1 - - - - - header not exists - - - - - header is malformed - - - - - picture not exists (%1) - - - - - JSON not exists (%1) - - - - - title not exists (%1) - - - - - description not exists (%1) - - - - - reading file %1 because of %2 - Example for %2: JSON is malformed error - - - - - SnapmaticWidget - - - Snapmatic Widget - - - - - PHOTO - 00/00/00 00:00:00 - - - - - View picture - - - - - View - - - - - Copy picture - - - - - Copy - - - - - Export picture - - - - - Export - - - - - - - Delete picture - - - - - Delete - - - - - - - Edi&t - - - - - - - Show &In-game - - - - - - - Hide &In-game - - - - - &Export - - - - - &View - - - - - &Remove - - - - - - &Select - - - - - - &Deselect - - - - - - Select &All - - - - - - &Deselect All - - - - - Are you sure to delete %1 from your Snapmatic pictures? - - - - - Failed at deleting %1 from your Snapmatic pictures - - - - - Failed to hide %1 In-game from your Snapmatic pictures - - - - - Failed to show %1 In-game from your Snapmatic pictures - - - - - TelemetryDialog - - - You want help %1 to improve in the future by including personal usage data in your submission? - - - - - %1 User Statistics - - - - - Yes, I want include personal usage data. - - - - - &OK - - - - - UserInterface - - - - %2 - %1 - - - - - Select profile - - - - - %1 %2 - - - - - Reload profile overview - - - - - &Reload - - - - - Close %1 - Close %1 <- (gta5view/gta5sync) - %1 will be replaced automatically - - - - - - - - &Close - - - - - &File - - - - - &Help - - - - - &Edit - - - - - &Profile - - - - - &Selection visibility - - - - - Selection &mass tools - - - - - - - &About %1 - - - - - &Exit - - - - - Exit - - - - - Close &Profile - - - - - &Settings - - - - - Select &All - - - - - &Deselect All - - - - - &Export selected... - - - - - &Remove selected - - - - - &Import files... - - - - - &Open File... - - - - - - Select &GTA V Folder... - - - - - - - - Select GTA V Folder... - - - - - Show In-gam&e - - - - - Hi&de In-game - - - - - - - Change &Title... - - - - - - - Change &Crew... - - - - - - - &Qualify as Avatar - - - - - - - Change &Players... - - - - - - - Show In-game - - - - - - - Hide In-game - - - - - - - Select Profile - - - - - - &Donate - - - - - Donate - - - - - Donation methods - - - - - &Copy - - - - - Open File... - - - - - - - - Open File - - - - - Can't open %1 because of not valid file format - - - - - %1 - Messages - - - - diff --git a/res/gta5sync_de.qm b/res/gta5sync_de.qm old mode 100644 new mode 100755 index f25770f..ada88af Binary files a/res/gta5sync_de.qm and b/res/gta5sync_de.qm differ diff --git a/res/gta5sync_de.ts b/res/gta5sync_de.ts old mode 100644 new mode 100755 index 054fac6..bf75dad --- a/res/gta5sync_de.ts +++ b/res/gta5sync_de.ts @@ -1,114 +1,108 @@ - + AboutDialog + + About gta5sync + Über gta5sync + + + <span style=" font-weight:600;">gta5sync</span><br/> +<br/> +A project for viewing and sync Grand Theft Auto V Snapmatic<br/> +Pictures and Savegames<br/> +<br/> +Project version: %1<br/> +Project build: %4, %5<br/> +Compiled with Qt %2<br/> +Running with Qt %3<br/> +<br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + <span style=" font-weight:600;">gta5sync</span><br/> +<br/> +Ein Projekt zum ansehen und synchronisieren von<br/> +Grand Theft Auto V Snapmatic Bilder und Spielständen<br/> +<br/> +Projektversion: %1<br/> +Projektbau: %4, %5<br/> +Gebaut mit Qt %2<br/> +Läuft auf Qt %3<br/> +<br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is lizenziert unter <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + + + <span style=" font-weight:600;">gta5sync</span><br/> +<br/> +A project for viewing and sync Grand Theft Auto 5 Snapmatic Pictures and Savegames<br/> +<br/> +Project version: %1<br/> +Project build: %4, %5<br/> +Compiled with Qt %2<br/> +Running with Qt %3<br/> +<br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + <span style=" font-weight:600;">gta5sync</span><br/> +<br/> +Ein Projekt zum ansehen und synchronisieren von Grand Theft Auto 5 Snapmatic Bilder und Spielständen<br/> +<br/> +Projektversion: %1<br/> +Projektbau: %4, %5<br/> +Gebaut mit Qt %2<br/> +Läuft auf Qt %3<br/> +<br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is lizenziert unter <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + - About %1 - Über %1 + About gta5view + Über gta5view - <span style="font-weight:600">%1</span><br/> + <span style=" font-weight:600;">gta5view</span><br/> <br/> -%2<br/> +A project for viewing Grand Theft Auto V Snapmatic<br/> +Pictures and Savegames<br/> <br/> -Version %3<br/> -Created on %4<br/> -Built with Qt %5<br/> -Running with Qt %6<br/> +Project version: %1<br/> +Project build: %4, %5<br/> +Compiled with Qt %2<br/> +Running with Qt %3<br/> <br/> -%7 - <span style="font-weight:600">%1</span><br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5view is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + <span style=" font-weight:600;">gta5view</span><br/> <br/> -%2<br/> +Ein Projekt zum ansehen von Grand Theft Auto V<br/> +Snapmatic Bilder und Spielständen<br/> <br/> -Version %3<br/> -Erstellt am %4<br/> -Gebaut mit Qt %5<br/> -Läuft auf Qt %6<br/> +Projektversion: %1<br/> +Projektbau: %4, %5<br/> +Gebaut mit Qt %2<br/> +Läuft auf Qt %3<br/> <br/> -%7 +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5view ist lizenziert unter <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - + &Close S&chließen - - Translated by %1 - Translated by translator, example Translated by Syping - Übersetzt von %1 + generated by class + Generiert von der Klasse - - TRANSLATOR - Insert your name here and profile here in following scheme, First Translator,First Profile\nSecond Translator\nThird Translator,Second Profile - Syping,g5e://about?U3lwaW5n:R2l0TGFiOiA8YSBocmVmPSJodHRwczovL2dpdGxhYi5jb20vU3lwaW5nIj5TeXBpbmc8L2E+PGJyLz5HaXRIdWI6IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9TeXBpbmciPlN5cGluZzwvYT48YnIvPlNvY2lhbCBDbHViOiA8YSBocmVmPSJodHRwczovL3NvY2lhbGNsdWIucm9ja3N0YXJnYW1lcy5jb20vbWVtYmVyL1N5cGluZy80NjMwMzA1NiI+U3lwaW5nPC9hPg + <span style=" font-weight:600;">gta5sync</span><br/><br/>A project for viewing and sync Grand Theft Auto 5 Snapmatic Pictures and Savegames<br/><br/>Project version: %1<br/>Compiled with Qt %2<br/>Running with Qt %3<br/><br/>Copyright © <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + <span style=" font-weight:600;">gta5sync</span><br/><br/>Ein Projekt zum ansehen und synchronisieren von Grand Theft Auto 5 Snapmatic Bilder und Spielständen<br/><br/>Projektversion: %1<br/>Gebaut mit Qt %2<br/>Läuft auf Qt %3<br/><br/>Copyright © <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is lizenziert unter <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - - A project for viewing Grand Theft Auto V Snapmatic<br/> -Pictures and Savegames - Ein Projekt zum ansehen von Grand Theft Auto V<br/> -Snapmatic Bilder und Spielständen + Close + Schließen - - Copyright &copy; <a href="%1">%2</a> %3 - Copyright &copy; <a href="%1">%2</a> %3 - - - - %1 is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - %1 ist lizenziert unter <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - - - - Release - Release - - - - Release Candidate - Release Candidate - - - - Daily Build - Daily Build - - - - Developer - Entwickler - - - - Beta - Beta - - - - Alpha - Alpha - - - - - Custom - Eigener - - - - CrewDatabase - - - - No Crew - Keine Crew + <span style=" font-weight:600;">gta5sync</span><br/><br/>A project for viewing and sync Grand Theft Auto 5 Snapmatic Pictures and Savegames<br/><br/>Project version: %1<br/>Compiled with Qt %2<br/>Running with Qt %3<br/><br/>Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + <span style=" font-weight:600;">gta5sync</span><br/><br/>Ein Projekt zum ansehen und synchronisieren von Grand Theft Auto 5 Snapmatic Bilder und Spielständen<br/><br/>Projektversion: %1<br/>Gebaut mit Qt %2<br/>Läuft auf Qt %3<br/><br/>Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is lizenziert unter <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> @@ -116,525 +110,109 @@ Snapmatic Bilder und Spielständen Dialog - Dialog + - + Format + Format + + + &JPEG/PNG format &JPEG/PNG Format - + GTA &Snapmatic format GTA &Snapmatic Format - + Resolution + Auflösung + + + Export Format Export Format - + Export Size Export Größe - + Default &Size &Standard Größe - + &Desktop Size &Desktop Größe - + &Custom Size &Eigene Größe - + Custom Size: Eigene Größe: - + x x - + &Export &Exportieren - + &Close S&chließen - - ImageEditorDialog - - - - - - Snapmatic Image Editor - Snapmatic Bild Editor - - - - Overwrite Image... - Bild überschreiben... - - - - Apply changes - Änderungen übernehmen - - - - &Overwrite - &Überschreiben - - - - Discard changes - Änderungen verwerfen - - - - &Close - S&chließen - - - - - Patching of Snapmatic Image failed because of I/O Error - Patchen von Snapmatic Bild fehlgeschlagen wegen I/O Fehler - - - - - Patching of Snapmatic Image failed because of Image Error - Patchen von Snapmatic Bild fehlgeschlagen wegen Bild Fehler - - - - ImportDialog - - - Import... - Importieren... - - - - - Ignore Aspect Ratio - Seitenverhältnis ignorieren - - - - Avatar - Avatar - - - - Picture - Bild - - - - Watermark - Wasserzeichen - - - Force Borderless - Erzwinge keine Ränder - - - - Background - Hintergrund - - - - - - - Background Colour: <span style="color: %1">%1</span> - Hintergrundfarbe: <span style="color: %1">%1</span> - - - - Select background colour - Hintergrundfarbe auswählen - - - ... - ... - - - - Select background image - Hintergrundbild auswählen - - - - Remove background image - Hintergrundbild entfernen - - - - Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing - Importiere das Bild ohne Veränderungen, Snapmatic wird garantiert beschädigt wenn du nicht weißt was du tust - - - - - Background Image: %1 - Hintergrundbild: %1 - - - X - X - - - - Crop to Aspect Ratio - Seitenverhältnis zuschneiden - - - - Force Colour in Avatar Zone - Erzwinge Farbe in Avatar Zone - - - - Advanced - Erweitert - - - - Resolution: - Auflösung: - - - - Snapmatic resolution - Snapmatic Auflösung - - - - Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic - Vermeide Kom­pri­mie­rung und vergrößere Buffer stattdessen, verbessert Bild Qualität, aber könnte Snapmatic beschädigen - - - - Unlimited Buffer - Un­li­mi­tierter Buffer - - - - Import as-is - Importiere unverändert - - - - Import options - Import Optionen - - - - &Options - &Optionen - - - - Import picture - Bild importieren - - - - &OK - &OK - - - - Discard picture - Bild verwerfen - - - - &Cancel - Abbre&chen - - - - - - - Background Image: - Hintergrundbild: - - - - &Import new Picture... - Neues Bild &importieren... - - - - &Crop Picture... - Bild zu&schneiden... - - - - &Load Settings... - Einstellungen &laden... - - - - &Save Settings... - Einstellungen &speichern... - - - - - Custom Avatar - Custom Avatar Description in SC, don't use Special Character! - Eigener Avatar - - - - - - Custom Picture - Custom Picture Description in SC, don't use Special Character! - Eigenes Bild - - - - Storage - Background Image: Storage - Speicher - - - - Crop Picture... - Bild zuschneiden... - - - - &Crop - Zu&schneiden - - - - Crop Picture - Bild zuschneiden - - - - - Please import a new picture first - Bitte importiere ein neues Bild zuerst - - - - - Default - Default as Default Profile - Standard - - - - - - - - - - - - - - - - - - - - - - - Profile %1 - Profile %1 as Profile 1 - Profil %1 - - - - - Load Settings... - Einstellungen laden... - - - - - Please select your settings profile - Bitte wähle dein Einstellungsprofil aus - - - - - Save Settings... - Einstellungen speichern... - - - - - Are you sure to use a square image outside of the Avatar Zone? -When you want to use it as Avatar the image will be detached! - Bist du sicher ein Quadrat Bild außerhalb der Avatar Zone zu verwenden? -Wenn du es als Avatar verwenden möchtest wird es abgetrennt! - - - - - Snapmatic Avatar Zone - Snapmatic Avatar Zone - - - - Select Colour... - Farbe auswählen... - - - - File - Background Image: File - Datei - - - - JsonEditorDialog - - - Snapmatic JSON Editor - Snapmatic JSON Editor - - - - Apply changes - Änderungen übernehmen - - - - &Save - &Speichern - - - - Discard changes - Änderungen verwerfen - - - - &Close - S&chließen - - - - JSON Error - JSON Fehler - - - - MapLocationDialog - - - Snapmatic Map Viewer - Snapmatic Kartenansicht - - - - Close viewer - Ansicht schließen - - - - &Close - S&chließen - - - - Apply new position - Neue Position festlegen - - - - &Apply - &Übernehmen - - - - Revert old position - Alte Position wiederherstellen - - - - &Revert - &Zurücksetzen - - - - Select new position - Neue Position auswählen - - - - &Select - Au&swählen - - - - Quit select position - Position auswählen verlassen - - - - &Done - &Fertig - - - - X: %1 -Y: %2 - X and Y position - X: %1 -Y: %2 - - OptionsDialog + + Options + Optionen + + + gta5sync - Options + gta5sync - Optionen + + + gta5sync - Settings + gta5sync - Einstellungen + + + Profile + Profil + Content Open/Select Mode Inhalte Öffnen/Auswählen Modus + Open with Singleclick - Ein Klick zum öffnen + Ein Klick zum öffnen - + Open with Doubleclick Doppelklick zum öffnen + Select with Singleclick - Ein Klick zum auswählen + Ein Klick zum auswählen @@ -651,11 +229,23 @@ Y: %2 Export Size Export Größe + + Default Size: %1x%2 + Standard Größe: %1x%2 + + + Desktop Size: %1x%2 + Desktop Größe: %1x%2 + Screen Resolution: %1x%2 Bildschirmauflösung: %1x%2 + + Custom Size + Eigene Größe + %1 - Settings @@ -749,272 +339,78 @@ Y: %2 - Game - Spiel - - - Social Club Version - Social Club Version + Language + Sprache - - - - - - - - - Found: %1 - Gefunden: %1 + Sync + Sync - - - - - - - - - - - Language: %1 - Sprache: %1 + Sync is not implemented at current time + Sync wurde bisher nicht implementiert - - Steam Version - Steam Version - - - - Feedback - Feedback - - - - Participation - Teilnahme - - - - - Participate in %1 User Statistics - An %1 Benutzerstatistik teilnehmen - - - - Categories - Kategorien - - - - Hardware, Application and OS Specification - Hardware, Anwendung und OS Spezifikation - - - - System Language Configuration - Spracheinstellungen des System - - - - Application Configuration - Anwendungseinstellungen - - - - Other - Sonstiges - - - - - - Participation ID: %1 - Teilnahme ID: %1 - - - - &Copy - &Kopieren - - - - Language for Areas - Sprache für Standorte - - - - Style - Stil - - - - Use Default Style (Restart) - Benutze Standard Stil (Neustart) - - - - Style: - Stil: - - - - Font - Schriftart - - - Always use Message Font (Windows 2003 and earlier) - Immer Nachrichtenschrift nutzen (Windows 2003 und früher) - - - - Interface - Oberfläche - - - - Personal Usage Data - Persönliche Nutzungsdaten - - - - Language for Interface - Sprache für Oberfläche - - - - - - - Current: %1 - Aktuell: %1 - - - - Use Default Font (Restart) - Benutze Standard Schriftart (Neustart) - - - - Font: - Schriftart: - - - - Apply changes - Änderungen übernehmen - - - + &OK OK, Cancel, Apply &OK - - Discard changes - Änderungen verwerfen - - - + &Cancel OK, Cancel, Apply Abbre&chen - + %1 (%2 if available) [sys] + System like PC System = %1, System Language like Deutsch = %2 + %1 (%2 wenn verfügbar) [sys] + + + + System + System like PC System + System + + + + %1 (%2 if available) + System like PC System = %1, System Language like Deutsch = %2 + %1 (%2 wenn verfügbar) + + + + %1 %1 %1 - - System - System in context of System default - System - - - - %1 (Game language) - Next closest language compared to the Game settings - %1 (Spielsprache) - - - - - %1 (Closest to Interface) - Next closest language compared to the Interface - %1 (Näheste zur Oberfläche) - - - - - - Auto - Automatic language choice. - Automatisch - - - - %1 (Language priority) - First language a person can talk with a different person/application. "Native" or "Not Native". - %1 (Sprachenpriorität) - - - - The new Custom Folder will initialise after you restart %1. + + The new Custom Folder will initialize after you restart %1. Der eigene Ordner wird initialisiert sobald du %1 neugestartet hast. - - View %1 User Statistics Online - %1 Benutzerstatistik Online ansehen + The new Custom Folder initialize after you restart %1. + Der eigene Ordner initialisiert sobald du %1 neugestartet hast. - - Not registered - Nicht registriert + + The language change will take effect after you restart %1. + Die Änderung der Sprache nimmt Effekt sobald du %1 neugestartet hast. - - - - - Yes - Ja - - - - - No - Nein - - - - - OS defined - OS-defined - - - - - Steam defined - Steam-definiert - - - + No Profile No Profile, as default Kein Profil - - - + + + Profile: %1 Profil: %1 @@ -1023,277 +419,239 @@ Y: %2 PictureDialog - Snapmatic Picture Viewer - %1 - Snapmatic Bildansicht - %1 + %1 - Snapmatic Picture Viewer + %1 - Snapmatic Bildansicht - - <span style="font-weight:600">Title: </span>%6<br/> -<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Created: </span>%8 - <span style="font-weight:600">Titel: </span>%6<br/> -<span style="font-weight:600">Standort: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Spieler: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Erstellt: </span>%8 + <html><head/><body><p><span style=" font-weight:600;">Title: </span>%6<br/><span style=" font-weight:600;">Location: </span>%7 (%1, %2, %3)<br/><span style=" font-weight:600;">Players: </span>%4<br/><span style=" font-weight:600;">Crew ID: </span>%5</p></body></html> + <html><head/><body><p><span style=" font-weight:600;">Titel: </span>%6<br/><span style=" font-weight:600;">Standort: </span>%7 (%1, %2, %3)<br/><span style=" font-weight:600;">Spieler: </span>%4<br/><span style=" font-weight:600;">Crew ID: </span>%5</p></body></html> - - Manage picture - Bild verwalten + <span style=" font-weight:600;">Title: </span>%6<br/> +<span style=" font-weight:600;">Location: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Players: </span>%4<br/> +<span style=" font-weight:600;">Crew ID: </span>%5 + <span style=" font-weight:600;">Titel: </span>%6<br/> +<span style=" font-weight:600;">Standort: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Spieler: </span>%4<br/> +<span style=" font-weight:600;">Crew ID: </span>%5 - - &Manage - &Verwalten + <span style=" font-weight:600;">Title: </span>%6<br/> +<span style=" font-weight:600;">Location: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Players: </span>%4 (Crew %5)<br/> +<span style=" font-weight:600;">Created: </span>%8<br/> + <span style=" font-weight:600;">Titel: </span>%6<br/> +<span style=" font-weight:600;">Standort: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Spieler: </span>%4 (Crew %5)<br/> +<span style=" font-weight:600;">Erstellt: </span>%8 - - Close viewer - Ansicht schließen + + <span style=" font-weight:600;">Title: </span>%6<br/> +<span style=" font-weight:600;">Location: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Players: </span>%4 (Crew %5)<br/> +<span style=" font-weight:600;">Created: </span>%8 + <span style=" font-weight:600;">Titel: </span>%6<br/> +<span style=" font-weight:600;">Standort: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Spieler: </span>%4 (Crew %5)<br/> +<span style=" font-weight:600;">Erstellt: </span>%8 - + + + &Export + &Exportieren + + + &Close - S&chließen + &Schließen - - + <span style=" font-weight:600;">Location: </span>%1, %2, %3 <br><span style=" font-weight:600;">Players: </span>%4<br><span style=" font-weight:600;">Crew ID: </span>%5 + <span style=" font-weight:600;">Standort: </span>%1, %2, %3 <br><span style=" font-weight:600;">Spieler: </span>%4<br><span style=" font-weight:600;">Crew ID: </span>%5 + + + <span style=" font-weight:600;">Picture Title: </span>%6<br> +<span style=" font-weight:600;">Location: </span>%1, %2, %3 <br> +<span style=" font-weight:600;">Players: </span>%4<br> +<span style=" font-weight:600;">Crew ID: </span>%5 + <span style=" font-weight:600;">Bildtitel: </span>%6<br> +<span style=" font-weight:600;">Standort: </span>%1, %2, %3 <br> +<span style=" font-weight:600;">Spieler: </span>%4<br> +<span style=" font-weight:600;">Crew ID: </span>%5 + + + <span style=" font-weight:600;">Title: </span>%6<br> +<span style=" font-weight:600;">Location: </span>%1, %2, %3 <br> +<span style=" font-weight:600;">Players: </span>%4<br> +<span style=" font-weight:600;">Crew ID: </span>%5 + <span style=" font-weight:600;">Titel: </span>%6<br> +<span style=" font-weight:600;">Standort: </span>%1, %2, %3 <br> +<span style=" font-weight:600;">Spieler: </span>%4<br> +<span style=" font-weight:600;">Crew ID: </span>%5 + + + Export Exportieren - - - Export as &Picture... - Als &Bild exportieren... + Copy + Kopieren - - - Export as &Snapmatic... - Als &Snapmatic exportieren... + + Close + Schließen - - - &Edit Properties... - Eigenschaften bearb&eiten... + + Export as &JPG picture... + Exportiere als &JPG Bild... - - - &Overwrite Image... - Bild &überschreiben... + + Export as &GTA Snapmatic... + Exportiere als &GTA Snapmatic... - - - Open &Map Viewer... - &Kartenansicht öffnen... - - - - Key 1 - Avatar Preview Mode -Key 2 - Toggle Overlay -Arrow Keys - Navigate - Taste 1 - Avatar Vorschaumodus -Taste 2 - Overlay umschalten -Pfeiltasten - Navigieren - - - + + Snapmatic Picture Viewer Snapmatic Bildansicht - + + Failed at %1 - Fehlgeschlagen beim %1 + Fehlgeschlagen bei %1 - - - No Crew - Keine Crew - - - - - - No Players + + + No player Keine Spieler - - Avatar Preview Mode -Press 1 for Default View - Avatar Vorschaumodus -Drücke 1 für Standardmodus + + + No crew + Keine Crew - + Unknown Location Unbekannter Standort - + Export picture... + Exportiere Bild... + + + + Export as JPG picture... + Exportiere als JPG Bild... + + + + JPEG picture (*.jpg) + JPEG Bild (*.jpg) + + + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - - + + + + + Export as JPG picture + Exportiere als JPG Bild + + + + Overwrite %1 with current Snapmatic picture? Überschreibe %1 mit aktuellen Snapmatic Bild? - - Export as Picture... - Als Bild exportieren... + + + + + Export as GTA Snapmatic + Exportiere als GTA Snapmatic - - JPEG Graphics (*.jpg *.jpeg) - JPEG Graphics (*.jpg *.jpeg) + + + Failed to overwrite %1 with current Snapmatic picture + Fehlgeschlagen beim Überschreiben von %1 mit aktuellen Snapmatic Bild - - - - - - - Export as Picture - Als Bild exportieren - - - - Failed to export the picture because the system occurred a write failure - Fehlgeschlagen beim Exportieren weil das System ein Schreibfehler ausgelöst hat - - - - Failed to export the picture because the format detection failures - Fehlgeschlagen beim Exportieren weil die Formaterkennung fehlschlägt - - - - Failed to export the picture because the file can't be written - Fehlgeschlagen beim Exportieren weil die Datei nicht beschrieben werden kann - - - - Failed to export the picture because of an unknown reason - Fehlgeschlagen beim Exportieren wegen einen unbekannten Grund - - - - + Failed to export current Snapmatic picture Fehlgeschlagen beim Exportieren vom aktuellen Snapmatic Bild - - Export as Snapmatic... - Als Snapmatic exportieren... + Copy picture + Bild kopieren - - - - - - Export as Snapmatic - Als Snapmatic exportieren + Export picture for Import... + Exporti - - Exported Snapmatic to "%1" because of using the .auto extension. - Snapmatic wurde wegen Benutzung der .auto Erweiterung zu "%1" exportiert. + + Export as GTA Snapmatic... + Exportiere als GTA Snapmatic... - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - - - - GTA V Raw Export (*.auto) - GTA V Roher Export (*.auto) - - - + Snapmatic pictures (PGTA*) Snapmatic Bilder (PGTA*) - - + + All files (**) + Alle Dateien (**) + + + + Failed to copy current Snapmatic picture + Fehlgeschlagen beim Kopieren vom Snapmatic Bild + + + Failed to save current picture + Fehlgeschlagen beim Speichern vom aktuellen Bild + + + JPEG picture (*.jpg);;Portable Network Graphics (*.png) + JPEG Bild (*.jpg);;Portable Network Graphics (*.png) + + + + Export picture + Bild exportieren + + + Snapmatic Picture Exporter + Snapmatic Bild Exporter + + + Failed to save the picture + Beim Speichern des Bildes ist ein Fehler aufgetreten + + + + No valid file is selected Keine gültige Datei wurde ausgewählt - - - - Open &JSON Editor... - &JSON Editor öffnen... - - - - PlayerListDialog - - - Edit Players... - Spieler bearbeiten... - - - - Available Players: - Verfügbare Spieler: - - - - Selected Players: - Ausgewählte Spieler: - - - - &Apply - &Übernehmen - - - - &Cancel - Abbre&chen - - - - Add Players... - Spieler hinzufügen... - - - - Failed to add more Players because the limit of Players are %1! - Fehlgeschlagen beim Hinzufügen von mehr Spielern weil der Limit von Spielern %1 ist! - - - - - Add Player... - Spieler hinzufügen... - - - - Enter Social Club Player ID - Social Club Spieler ID eingeben - - - - Failed to add Player %1 because Player %1 is already added! - Fehlgeschlagen beim Hinzufügen vom Spieler %1 weil Spieler %1 bereits hinzugefügt wurde! - ProfileInterface @@ -1309,118 +667,98 @@ Drücke 1 für Standardmodus Lade Datei %1 von %2 Dateien - + %1 %2 %1 %2 - - Import file - Importiere Datei + + Import exported file + Importiere exportierte Datei - + &Import... &Importieren... - + Close profile Profil schließen - + &Close S&chließen - + Import copy + Kopie importieren + + + Content of Profile %1 + Inhalt vom Profil %1 + + + View + Ansehen + + + Close Profile + Profil schließen + + + Loading... Lade... - - Snapmatic Loader - Snapmatic Lader - - - - <h4>Following Snapmatic Pictures got repaired</h4>%1 - <h4>Folgende Snapmatic Bilder wurden repariert</h4>%1 - - - - - - - - - - - - - - - - - - - - - + Import... Importieren... - - - - - - + + + + + + + + + + + + Import Importieren - - + + + All profile files (SGTA* PGTA*) + Alle Profildateien (SGTA* PGTA*) + + + + Savegames files (SGTA*) Spielstanddateien (SGTA*) - - + + Snapmatic pictures (PGTA*) Snapmatic Bilder (PGTA*) - - Importable files (%1) - Importfähige Dateien (%1) - - - - - - All image files (%1) - Alle Bilddateien (%1) - - - - - - + + All files (**) Alle Dateien (**) - - - Import file %1 of %2 files - Importiere Datei %1 von %2 Dateien - - - + Import failed with... %1 @@ -1429,301 +767,254 @@ Drücke 1 für Standardmodus %1 - - + + Failed to read Snapmatic picture Fehler beim Lesen vom Snapmatic Bild - - + + Failed to read Savegame file Fehler beim Lesen von Spielstanddatei - - - - Can't import %1 because file can't be open - Kann %1 nicht importieren weil die Datei nicht geöffnet werden kann + + Can't import %1 because of not valid file format + Kann %1 nicht importieren weil das Dateiformat nicht gültig ist - - - - Can't import %1 because file can't be parsed properly - Kann %1 nicht importieren weil die Datei nicht richtig gelesen werden kann + + Failed to import the Snapmatic picture, the picture is already in the game + Fehlgeschlagen beim Importieren vom Snapmatic Bild, dieses Bild ist bereits im Spiel - - Can't import %1 because file format can't be detected - Kann %1 nicht importieren weil das Dateiformat nicht erkannt werden kann - - - - Initialising export... - Initialisiere Export... - - - - Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e - Fehlgeschlagen beim Importieren vom Snapmatic Bild, Datei beginnt nicht mit PGTA oder endet mit .g5e - - - + %1Export Snapmatic pictures%2<br><br>JPG pictures make it possible to open the picture with a Image Viewer<br>GTA Snapmatic make it possible to import the picture into the game<br><br>Export as: %1Exportiere Snapmatic Bilder%2<br><br>JPG Bilder machen es möglich sie mit ein Bildansicht Programm zu öffnen<br>Das GTA Snapmatic Format macht es möglich sie wieder ins Game zu importieren<br><br>Exportieren als: - - - + + + No valid file is selected Keine gültige Datei wurde ausgewählt - + Enabled pictures: %1 of %2 Aktivierte Bilder: %1 von %2 - - A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp? - Ein Snapmatic Bild mit der Uid %1 existiert bereits, möchtest du dein Import eine neue Uid und Zeitstempel zuweisen? + + Failed to import the Snapmatic picture, file not begin with PGTA + Fehlgeschlagen beim Importieren vom Snapmatic Bild, Datei beginnt nicht mit PGTA - + Failed to import the Snapmatic picture, can't copy the file into profile - Fehlgeschlagen beim Importieren vom Snapmatic Bild, kann Snapmatic Bild nicht ins Profil kopieren + Fehlgeschlagen beim Importieren vom Snapmatic Bild, kann Snapmatic Bild nicht ins Profil kopieren - + Failed to import the Savegame, can't copy the file into profile Fehlgeschlagen beim Importieren vom Spielstand, kann Spielstanddatei nicht ins Profil kopieren - + Failed to import the Savegame, no Savegame slot is left Fehlgeschlagen beim Importieren vom Spielstand, kein Spielstandslot mehr frei - - + + JPG pictures and GTA Snapmatic JPG Bilder und GTA Snapmatic - - + + JPG pictures only Nur JPG Bilder - - + + GTA Snapmatic only Nur GTA Snapmatic - - - - - Patch selected... - Auswahl patchen... - - - - - - - - - - - Patch file %1 of %2 files - Patche Datei %1 von %2 Dateien - - - - - Qualify as Avatar - Als Avatar qualifizieren - - - - - - - - - No Snapmatic pictures are selected - Keine Snapmatic Bilder sind ausgewählt - - - - Failed to remove all selected Snapmatic pictures and/or Savegame files - Fehlgeschlagen beim Entfernen von allen augewählten Snapmatic Bildern und/oder Spielstanddateien - - - - - - - - - %1 failed with... + Export Snapmatic pictures -%2 - Action failed with... - %1 fehlgeschlagen mit... +JPG pictures make it possible to open the picture with a Image Viewer +GTA Snapmatic make it possible to import the picture into the game -%2 +Export as: + Exportiere Snapmatic Bilder + +JPG Bilder machen es möglich sie mit ein Bildansicht Programm zu öffnen +Das GTA Snapmatic Format macht es möglich sie wieder ins Game zu importieren + +Exportieren als: - - Prepare Content for Import... - Bereite Inhalt für Import vor... - - - - Qualify - %1 failed with... - Qualifizieren - - - - - Change Players... - Spieler ändern... - - - - Change Players - %1 failed with... - Spieler ändern - - - - - - Change Crew... - Crew ändern... - - - - Failed to enter a valid Snapmatic Crew ID - Fehlgeschlagen beim Eingeben von einer gültigen Crew ID - - - - Change Crew - %1 failed with... - Crew ändern - - - - - - Change Title... - Titel ändern... - - - - Failed to enter a valid Snapmatic title - Fehlgeschlagen beim Eingeben eines gültigen Snapmatic Titel - - - - Change Title - %1 failed with... - Titel ändern - - - - + + No Snapmatic pictures or Savegames files are selected - Keine Snapmatic Bilder oder Spielstände sind ausgewählt + Keine Snapmatic Bilder oder Spielstände ausgewählt - - - + + + Remove selected Auswahl löschen - + You really want remove the selected Snapmatic picutres and Savegame files? Möchtest du wirklich die ausgewählten Snapmatic Bilder und Spielstanddateien löschen? - - - - - + + Failed at remove the complete selected Snapmatic pictures and/or Savegame files + Fehlgeschlagen beim kompletten entfernen der ausgewählten Snapmatic Bilder und/oder der Spielstanddateien + + + Failed to import copy of Snapmatic picture because the file not begin with PGTA + Fehlgeschlagenen beim Import vom Snapmatic Bild weil die Datei nicht mit PGTA begint + + + Failed to import copy of Snapmatic picture because the copy failed + Fehlgeschlagenen beim Import vom Snapmatic Bild weil kopieren fehlgeschlagen ist + + + Failed to import copy of Savegame file because the copy failed + Fehlgeschlagenen beim Import vom Spielstand weil kopieren fehlgeschlagen ist + + + Failed to import copy of Savegame file because no free Savegame slot left + Fehlgeschlagenen beim Import vom Spielstand weil kein Spielstandslot mehr übrig ist + + + + + + + Export selected + Auswahl exportieren + + + Export and Copy pictures + Bilder exportieren und kopieren + + + Export pictures + Bilder exportieren + + + Copy pictures + Bilder kopieren + + + How should we deal with the Snapmatic pictures? + Wie sollen wir mit den Snapmatic Bilder umgehen? + + + Export selected... Auswahl exportieren... - + + Initializing export... + Initialisiere Export... + + + Initializing... + Initialisierung... + + + Export failed with... %1 Exportieren fehlgeschlagen bei...\n%1 - - - + Delete selected + Auswahl löschen + + + You really want delete the selected content? + Möchtest du wirklich den ausgewählten Inhalt löschen? + + + Failed at delete all selected content + Fehlgeschlagen beim Löschen von alle ausgewählte Inhalte + + + Current export job: %1 + Aktueller Exportiervorgang: %1 + + + + + Export file %1 of %2 files Exportiere Datei %1 von %2 Dateien - - - All profile files (*.g5e SGTA* PGTA*) - Alle Profildateien (*.g5e SGTA* PGTA*) - - - - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - QApplication - <h4>Welcome to %1!</h4>You want to configure %1 before you start using it? - <h4>Willkommen zu %1!</h4>Möchtest du %1 einstellen bevor du es nutzt? + + Font + Schrift + + + + Selected Font: %1 + Ausgewähle Schrift: %1 SavegameDialog - + Savegame Viewer Spielstandanzeiger - - <span style="font-weight:600">Savegame</span><br><br>%1 - <span style="font-weight:600">Spielstand</span><br><br>%1 + + <span style=" font-weight:600;">Savegame</span><br><br>%1 + <span style=" font-weight:600;">Spielstand</span><br><br>%1 - + &Export &Exportieren - + Cop&y + &Kopieren + + + &Close S&chließen - + Copy + Kopieren + + + Close + Schließen + + + Failed at %1 Fehlgeschlagen bei %1 @@ -1735,6 +1026,20 @@ Drücke 1 für Standardmodus Savegame Widget Spielstand Widget + + The Third Way (100%) - 00/00/00 00:00:00 + The Third Way (100%) - 00/00/00 00:00:00 + + + Savegame %1 +%2 + Spielstand %1 +%2 + + + SAVE - %1<br>%2 + SPIELSTAND - %1<br>%2 + View @@ -1742,10 +1047,13 @@ Drücke 1 für Standardmodus - Export Exportieren + + Copy + Kopieren + Delete @@ -1753,11 +1061,13 @@ Drücke 1 für Standardmodus + + Delete savegame Savegame löschen - + Export Savegame... Spielstand exportieren... @@ -1767,84 +1077,100 @@ Drücke 1 für Standardmodus SPIELSTAND %3 - %1<br>%2 - - + + WRONG FORMAT FALSCHES FORMAT - - + AUTO + AUTO + + + AUTOSAVE - %1 %2 AUTOSAVE - %1 %2 - - + SAVE %3 - %1 %2 SPIELSTAND %3 - %1 %2 - + UNKNOWN UNKNOWN - + Are you sure to delete %1 from your savegames? Bist du sicher %1 von deinen Spielständen zu löschen? - - - Delete Savegame - Savegame löschen - - - + Failed at deleting %1 from your savegames Fehlgeschlagen beim Löschen %1 von deinen Spielständen - + &View A&nsehen - - - + &Remove Entfe&rnen - - + + &Select Au&swählen - - + &Deselect A&bwählen - - + + Select &All &Alles auswählen - - + &Deselect All Alles a&bwählen + + Select + Auswählen + + + Deselect + Abwählen + + + Select all + Alles auswählen + + + Ctrl+S + Strg+S + + + Deselect all + Alles abwählen + + + Shift+S + Umschalt+S + View savegame @@ -1856,302 +1182,159 @@ Drücke 1 für Standardmodus Spielstand kopieren - - - + + &Export &Exportieren - + Savegame files (SGTA*) Spielstanddateien (SGTA*) - + All files (**) Alle Dateien (**) - - + + + - Export Savegame Spielstand exportieren - + Overwrite %1 with current Savegame? Überschreibe %1 mit aktuellen Spielstand? - + Failed to overwrite %1 with current Savegame Fehlgeschlagen beim Überschrieben von %1 mit aktuellen Spielstand - + Failed to export current Savegame Fehlgeschlagen beim Exportieren vom aktuellen Spielstand - + Failed to copy current Savegame + Fehlgeschlagen beim Kopieren vom aktuellen Spielstand + + + Overwrite %1 with current savegame? + Überschreibe %1 mit aktuellen Spielstand? + + + Failed to overwrite %1 with current savegame + Fehlgeschlagen beim Überschreiben von %1 mit aktuellen Spielstand + + + Failed to copy current savegame + Fehlgeschlagen beim Kopieren vom Spielstand + + + Failed to copy the savegame + Beim Kopieren vom Spielstand ist ein Fehler aufgetreten + + + No valid file is selected Keine gültige Datei wurde ausgewählt + + Are you sure to delete %1 from your Savegames? + Bist du sicher %1 von deinen Spielständen zu löschen? + + + Failed at deleting %1 from your Savegames + Fehlgeschlagen beim Löschen %1 von deinen Spielständen + SnapmaticEditor - - - - - - - - + + Snapmatic Properties Snapmatic Eigenschaften - + Snapmatic Type Snapmatic Typ - + + Editor Editor - + + Selfie Selbstporträt - + Regular Typisch - + + Mugshot - Polizeifoto + Fahndungsfoto - + Custom + Eigenes + + + Director Director - + Meme Meme - - - Snapmatic Title - Snapmatic Titel - - - - Snapmatic Values - Snapmatic Werte - - - - Crew: %1 (%2) - Crew: %1 (%2) - - - - Title: %1 (%2) - Titel: %1 (%2) - - - - Players: %1 (%2) - Multiple Player are inserted here - Spieler: %1 (%2) - - - - Player: %1 (%2) - One Player is inserted here - Spieler: %1 (%2) - - - - - Appropriate: %1 - Angemessen: %1 - - - + Extras Extras - + Qualify as Avatar automatically at apply - Beim Übernehmen als Avatar qualifizieren + Beim Übernehmen als Avatar qualifizieren - + Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture Das Qualifizieren als Avatar erlaubt dir dieses Snapmatic als Social Club Profilbild zu nutzen - - Apply changes - Änderungen übernehmen - - - + &Apply &Übernehmen - - Discard changes - Änderungen verwerfen - - - + &Cancel Abbre&chen - - - - Edit - Bearbeiten - - - - Yes - Yes, should work fine - Ja - - - - No - No, could lead to issues - Nein - - - - <h4>Unsaved changes detected</h4>You want to save the JSON content before you quit? - <h4>Ungespeicherte Änderungen erkannt</h4>Möchtest du den JSON Inhalt speichern bevor du verlässt? - - - - Patching of Snapmatic Properties failed because of %1 - Patchen von Snapmatic Eigenschaften fehlgeschlagen wegen %1 - - - - Patching of Snapmatic Properties failed because of JSON Error - Patchen von Snapmatic Eigenschaften fehlgeschlagen wegen JSON Fehler - - - - - - + Patching of Snapmatic Properties failed because of I/O Error Patchen von Snapmatic Eigenschaften fehlgeschlagen wegen I/O Fehler - - - - New Snapmatic title: - Neuer Snapmatic Titel: - - - - - Snapmatic Crew - Snapmatic Crew - - - - - New Snapmatic crew: - Neue Snapmatic Crew: - - - - SnapmaticPicture - - - PHOTO - %1 - FOTO - %1 - - - - open file %1 - Datei öffnen %1 - - - - header not exists - Header nicht existiert - - - - header is malformed - Header fehlerhaft ist - - - - picture not exists (%1) - Bild nicht existiert (%1) - - - - JSON not exists (%1) - JSON nicht existiert (%1) - - - - title not exists (%1) - Titel nicht existiert (%1) - - - - description not exists (%1) - Beschreibung nicht existiert (%1) - - - - reading file %1 because of %2 - Example for %2: JSON is malformed error - Datei lesen von %1 weil %2 - - - - - JSON is incomplete and malformed - JSON ist unvollständig und Fehlerhaft - - - - - JSON is incomplete - JSON ist unvollständig - - - - - JSON is malformed - JSON ist Fehlerhaft - SnapmaticWidget @@ -2161,409 +1344,530 @@ Drücke 1 für Standardmodus Snapmatic Widget - + PHOTO - 00/00/00 00:00:00 FOTO - 00/00/00 00:00:00 - + View Ansehen - + Copy Kopieren - + Export Exportieren - + Delete Löschen - - - + + + Delete picture Bild löschen - + Are you sure to delete %1 from your Snapmatic pictures? - Bist du sicher %1 von deine Snapmatic Bilder zu löschen? + Bist du sicher %1 von deinen Snapmatic Bilder zu löschen? - - Failed to hide %1 In-game from your Snapmatic pictures - Fehlgeschlagen beim Ausblenden von %1 im Spiel von deinen Snapmatic Bildern - - - - Failed to show %1 In-game from your Snapmatic pictures - Fehlgeschlagen beim Anzeigen von %1 im Spiel von deinen Snapmatic Bildern - - - - - + Edi&t Bearbei&ten - + Enable &In-game + &Im Spiel aktivieren + + + Disable &In-game + &Im Spiel deaktivieren + + + &Export &Exportieren - - - + Export as &JPG picture + Exportiere als &JPG Bild + + + Export as &GTA Snapmatic + Exportiere als &GTA Snapmatic + + + Show &In-game &Im Spiel anzeigen - - - + Hide &In-game &Im Spiel ausblenden - + &Edit Properties + &Eigenschaften bearbeiten + + + + &Edit Properties... + &Eigenschaften bearbeiten... + + + + Export as &JPG picture... + Exportiere als &JPG Bild... + + + + Export as &GTA Snapmatic... + Exportiere als &GTA Snapmatic... + + + &View A&nsehen - + &Remove Entfe&rnen - - + + &Select Au&swählen - - + &Deselect A&bwählen - - + + Select &All Alles &auswählen - - + &Deselect All Alles a&bwählen - + Select + Auswählen + + + Deselect + Abwählen + + + Select all + Alles auswählen + + + Ctrl+S + Strg+S + + + Deselect all + Alles abwählen + + + Shift+S + Umschalt+S + + + View picture Bild ansehen - + Copy picture Bild kopieren - + Export picture Bild exportieren - + You're sure to delete %1 from your Snapmatic pictures? + Bist du sicher %1 von deinen Snapmatic Bilder zu löschen? + + + Failed at deleting %1 from your Snapmatic pictures - Fehlgeschlagen beim Löschen von %1 von deinen Snapmatic Bildern - - - - TelemetryDialog - - - %1 User Statistics - %1 Benutzerstatistik - - - - You want help %1 to improve in the future by including personal usage data in your submission? - Sollen bei Einreichungen Persönliche Nutzungsdaten einbezogen werden um %1 in der Zukunft zu unterstützen? - - - - Yes, I want include personal usage data. - Ja, ich möchte Persönliche Nutzungsdaten einbeziehen. - - - - &OK - &OK + Fehlgeschlagen beim Löschen %1 von deinen Snapmatic Bildern UserInterface - + Grand Theft Auto V Sync + Grand Theft Auto V Sync + + + GTA V Sync + GTA V Sync + + + gta5sync - %1 + gta5sync - %1 + + + File + Datei + + + Help + Hilfe + + + Edit + Bearbeiten + + + Profile + Profil + + + About gta5sync + Über gta5sync + + + + Ctrl+A + Strg+A + + + Close + Schließen + + + Options + Optionen + + + + Ctrl+O + Strg+O + + + Select all + Alles auswählen + + + + Ctrl+S + Strg+S + + + Deselect all + Alles abwählen + + + Shift+S + Umschalt+S + + + Export selected + Auswahl exportieren + + + + Ctrl+E + Strg+E + + + Delete selected + Auswahl löschen + + + + Ctrl+D + Strg+D + + + Exit Beenden - + &Selection visibility Auswahl &Sichtbarkeit - + + &About gta5view + &Über gta5view + + + &Exit B&eenden + + + Ctrl+Q + Strg+Q + Select profile Profil auswählen + + + gta5view - %1 + gta5view - %1 + %1 %2 %1 %2 - - Reload profile overview - Übersicht der Profile neuladen - - - - Close %1 - Close %1 <- (gta5view/gta5sync) - %1 will be replaced automatically - Schließe %1 - - - + &File &Datei - + &Help &Hilfe - + &Edit Bearb&eiten - + &Profile &Profil - - Selection &mass tools - Auswahl &Massenwerkzeuge + Selection visibility + Auswahl Sichtbarkeit - - - - Change &Title... - &Titel ändern... + &About gta5sync + &Über gta5sync - - - - &Qualify as Avatar - Als Avatar &qualifizieren - - - - - - Change &Players... - S&pieler ändern... - - - - - - Change &Crew... - &Crew ändern... - - - + Close &Profile &Profil schließen - + + Ctrl+End + Strg+Ende + + + + Ctrl+Del + Strg+Entf + + + &Open File... Datei &öffnen... - - + + Select &GTA V Folder... Wähle &GTA V Ordner... - + + Ctrl+G + Strg+G + + + Show In-gam&e Im Spiel anzeig&en - + Hi&de In-game Im Spiel ausblen&den - - - - + Hid&e In-game + Im Spiel ausblen&den + + + &Enable In-game + Im Spiel aktivier&en + + + + Shift+E + Umschalt+E + + + &Disable In-game + Im Spiel &deaktivieren + + + + Shift+D + Umschalt+D + + + &Close S&chließen - + Select &Profile + &Profil auswählen + + + + Ctrl+P + Strg+P + + + &Options + &Optionen + + + &Settings Ein&stellungen - + Select &All &Alles auswählen - + &Deselect All Alles a&bwählen - + &Export selected... Auswahl &exportieren... - + &Remove selected Auswahl entfe&rnen - + Ctrl+R + Strg+R + + + &Import files... Dateien &importieren... - - - + + Ctrl+I + Strg+I + + + GTA V Folder not found! + GTA V Ordner nicht gefunden! + + + + Select Profile Profil auswählen - - - - + + + + Select GTA V Folder... Wähle GTA V Ordner... - + Select GTA V &Folder... + Wähle GTA V &Ordner... + + + Open File... Datei öffnen... - - + Import + Importieren + + + %2 - %1 %2 - %1 - - - - &About %1 - &Über %1 - - - - - &Donate - Spen&den - - - - Donate - Spenden - - - - Donation methods - Spendenmethoden - - - - &Copy - &Kopieren - - - View - Ansehen - - - Copy - Kopieren - - - - - - + + + + Open File Datei öffnen - + Can't open %1 because of not valid file format Kann nicht %1 öffnen weil Dateiformat nicht gültig ist - - %1 - Messages - %1 - Nachrichten + Change GTA V &Folder + GTA V &Ordner ändern - + gta5sync + gta5sync + + + Grand Theft Auto V Folder not found! + Grand Theft Auto V Ordner wurde nicht gefunden! + + + &Reload &Neuladen - - - - Show In-game - Im Spiel anzeigen + Reload + Neuladen - - - - Hide In-game - Im Spiel ausblenden + Reload profiles + Profile neuladen + + + Not able to reload profiles + Nicht fähig Profile neuzuladen diff --git a/res/gta5sync_en_US.qm b/res/gta5sync_en_US.qm deleted file mode 100644 index 502289e..0000000 Binary files a/res/gta5sync_en_US.qm and /dev/null differ diff --git a/res/gta5sync_en_US.ts b/res/gta5sync_en_US.ts deleted file mode 100644 index 1b4c531..0000000 --- a/res/gta5sync_en_US.ts +++ /dev/null @@ -1,2505 +0,0 @@ - - - - - AboutDialog - - - About %1 - - - - - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -Version %3<br/> -Created on %4<br/> -Built with Qt %5<br/> -Running with Qt %6<br/> -<br/> -%7 - - - - - &Close - - - - - Translated by %1 - Translated by translator, example Translated by Syping - - - - - TRANSLATOR - Insert your name here and profile here in following scheme, First Translator,First Profile\nSecond Translator\nThird Translator,Second Profile - Syping,g5e://about?U3lwaW5n:R2l0TGFiOiA8YSBocmVmPSJodHRwczovL2dpdGxhYi5jb20vU3lwaW5nIj5TeXBpbmc8L2E+PGJyLz5HaXRIdWI6IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9TeXBpbmciPlN5cGluZzwvYT48YnIvPlNvY2lhbCBDbHViOiA8YSBocmVmPSJodHRwczovL3NvY2lhbGNsdWIucm9ja3N0YXJnYW1lcy5jb20vbWVtYmVyL1N5cGluZy80NjMwMzA1NiI+U3lwaW5nPC9hPg== - - - - A project for viewing Grand Theft Auto V Snapmatic<br/> -Pictures and Savegames - - - - - Copyright &copy; <a href="%1">%2</a> %3 - - - - - %1 is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - - - - - Release - - - - - Release Candidate - - - - - Daily Build - - - - - Developer - - - - - Beta - - - - - Alpha - - - - - - Custom - - - - - CrewDatabase - - - - No Crew - - - - - ExportDialog - - - Dialog - - - - - Export Format - - - - - &JPEG/PNG format - - - - - GTA &Snapmatic format - - - - - Export Size - - - - - Default &Size - - - - - &Desktop Size - - - - - &Custom Size - - - - - Custom Size: - - - - - x - - - - - &Export - - - - - &Close - - - - - ImageEditorDialog - - - - - - Snapmatic Image Editor - - - - - Overwrite Image... - - - - - Apply changes - - - - - &Overwrite - - - - - Discard changes - - - - - &Close - - - - - - Patching of Snapmatic Image failed because of I/O Error - - - - - - Patching of Snapmatic Image failed because of Image Error - - - - - ImportDialog - - - Import... - - - - - Crop to Aspect Ratio - - - - - - - - Background Colour: <span style="color: %1">%1</span> - Background Color: <span style="color: %1">%1</span> - - - - Select background colour - Select background color - - - - Avatar - - - - - Picture - - - - - - Ignore Aspect Ratio - - - - - Watermark - - - - - Background - - - - - - Background Image: %1 - - - - - Select background image - - - - - Remove background image - - - - - Force Colour in Avatar Zone - Force Color in Avatar Zone - - - - Advanced - - - - - Resolution: - - - - - Snapmatic resolution - - - - - Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic - - - - - Unlimited Buffer - - - - - Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing - - - - - Import as-is - - - - - Import options - - - - - &Options - - - - - Import picture - - - - - &OK - - - - - Discard picture - - - - - &Cancel - - - - - - - - Background Image: - - - - - &Import new Picture... - - - - - &Crop Picture... - - - - - &Load Settings... - - - - - &Save Settings... - - - - - - Custom Avatar - Custom Avatar Description in SC, don't use Special Character! - - - - - - - Custom Picture - Custom Picture Description in SC, don't use Special Character! - - - - - Storage - Background Image: Storage - - - - - Crop Picture... - - - - - &Crop - - - - - Crop Picture - - - - - - Please import a new picture first - - - - - - Default - Default as Default Profile - - - - - - - - - - - - - - - - - - - - - - - - Profile %1 - Profile %1 as Profile 1 - - - - - - Load Settings... - - - - - - Please select your settings profile - - - - - - Save Settings... - - - - - - Snapmatic Avatar Zone - - - - - - Are you sure to use a square image outside of the Avatar Zone? -When you want to use it as Avatar the image will be detached! - - - - - Select Colour... - Select Color... - - - - File - Background Image: File - - - - - JsonEditorDialog - - - Snapmatic JSON Editor - - - - - Apply changes - - - - - &Save - - - - - Discard changes - - - - - &Close - - - - - JSON Error - - - - - MapLocationDialog - - - Snapmatic Map Viewer - - - - - Close viewer - - - - - &Close - - - - - Apply new position - - - - - &Apply - - - - - Revert old position - - - - - &Revert - - - - - Select new position - - - - - &Select - - - - - Quit select position - - - - - &Done - - - - - X: %1 -Y: %2 - X and Y position - - - - - OptionsDialog - - - %1 - Settings - - - - - Profiles - - - - - Content Open/Select Mode - - - - - Open with Doubleclick - - - - - Default Profile - - - - - Custom GTA V Folder - - - - - Force using Custom Folder - - - - - ... - - - - - Pictures - - - - - Export Size - - - - - Default: %1x%2 - - - - - Screen Resolution: %1x%2 - - - - - - Custom Size: - - - - - x - - - - - Ignore Aspect Ratio - - - - - Export Quality - - - - - Enable Custom Quality - - - - - Quality: - - - - - %1% - - - - - Picture Viewer - - - - - Enable Navigation Bar - - - - - Players - - - - - ID - - - - - Name - - - - - Game - - - - - Social Club Version - - - - - - - - - - - - Found: %1 - - - - - - - - - - - - - - Language: %1 - - - - - Steam Version - - - - - Feedback - - - - - - Participate in %1 User Statistics - - - - - Hardware, Application and OS Specification - - - - - Application Configuration - - - - - Other - - - - - - - Participation ID: %1 - - - - - &Copy - - - - - Language for Areas - - - - - Style - - - - - Style: - - - - - Font - - - - - Interface - - - - - Participation - - - - - Categories - - - - - System Language Configuration - - - - - Personal Usage Data - - - - - Language for Interface - - - - - - - - Current: %1 - - - - - Use Default Style (Restart) - - - - - Use Default Font (Restart) - - - - - Font: - - - - - Apply changes - - - - - &OK - OK, Cancel, Apply - - - - - Discard changes - - - - - &Cancel - OK, Cancel, Apply - - - - - System - System in context of System default - - - - - %1 (Game language) - Next closest language compared to the Game settings - - - - - - %1 (Closest to Interface) - Next closest language compared to the Interface - - - - - - - Auto - Automatic language choice. - - - - - %1 (Language priority) - First language a person can talk with a different person/application. "Native" or "Not Native". - - - - - %1 - %1 - - - - - The new Custom Folder will initialise after you restart %1. - The new Custom Folder will initialize after you restart %1. - - - - No Profile - No Profile, as default - - - - - - - Profile: %1 - - - - - View %1 User Statistics Online - - - - - Not registered - - - - - - - - Yes - - - - - - No - - - - - - OS defined - - - - - - Steam defined - - - - - PictureDialog - - - Snapmatic Picture Viewer - %1 - - - - - <span style="font-weight:600">Title: </span>%6<br/> -<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Created: </span>%8 - - - - - Manage picture - - - - - &Manage - - - - - Close viewer - - - - - &Close - - - - - - Export as &Picture... - - - - - - Export as &Snapmatic... - - - - - - &Overwrite Image... - - - - - - &Edit Properties... - - - - - - Open &Map Viewer... - - - - - Key 1 - Avatar Preview Mode -Key 2 - Toggle Overlay -Arrow Keys - Navigate - - - - - Snapmatic Picture Viewer - - - - - Failed at %1 - - - - - - - No Players - - - - - - No Crew - - - - - Unknown Location - - - - - Avatar Preview Mode -Press 1 for Default View - - - - - Export as Picture... - - - - - - Export - - - - - JPEG Graphics (*.jpg *.jpeg) - - - - - Portable Network Graphics (*.png) - - - - - - - - - - Export as Picture - - - - - - Overwrite %1 with current Snapmatic picture? - - - - - - Failed to export current Snapmatic picture - - - - - - No valid file is selected - - - - - Failed to export the picture because the system occurred a write failure - - - - - Failed to export the picture because the format detection failures - - - - - Failed to export the picture because the file can't be written - - - - - Failed to export the picture because of an unknown reason - - - - - Export as Snapmatic... - - - - - GTA V Export (*.g5e) - - - - - GTA V Raw Export (*.auto) - - - - - Snapmatic pictures (PGTA*) - - - - - - - - - Export as Snapmatic - - - - - Exported Snapmatic to "%1" because of using the .auto extension. - - - - - - Open &JSON Editor... - - - - - PlayerListDialog - - - Edit Players... - - - - - Available Players: - - - - - Selected Players: - - - - - &Apply - - - - - &Cancel - - - - - Add Players... - - - - - Failed to add more Players because the limit of Players are %1! - - - - - - Add Player... - - - - - Enter Social Club Player ID - - - - - Failed to add Player %1 because Player %1 is already added! - - - - - ProfileInterface - - - Profile Interface - - - - - Loading file %1 of %2 files - - - - - %1 %2 - - - - - Import file - - - - - &Import... - - - - - Close profile - - - - - &Close - - - - - - - Export file %1 of %2 files - - - - - Enabled pictures: %1 of %2 - - - - - Loading... - - - - - Snapmatic Loader - - - - - <h4>Following Snapmatic Pictures got repaired</h4>%1 - - - - - - - - - - - - - - - - - - - - - - - Import... - - - - - - - - - - Import - - - - - Importable files (%1) - - - - - - GTA V Export (*.g5e) - - - - - - Savegames files (SGTA*) - - - - - - Snapmatic pictures (PGTA*) - - - - - - - All image files (%1) - - - - - - - - All files (**) - - - - - - - No valid file is selected - - - - - - Import file %1 of %2 files - - - - - Import failed with... - -%1 - - - - - - Failed to read Snapmatic picture - - - - - - Failed to read Savegame file - - - - - - - Can't import %1 because file can't be open - - - - - - - Can't import %1 because file can't be parsed properly - - - - - Can't import %1 because file format can't be detected - - - - - Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e - - - - - Failed to import the Snapmatic picture, can't copy the file into profile - - - - - Failed to import the Savegame, can't copy the file into profile - - - - - Failed to import the Savegame, no Savegame slot is left - - - - - - JPG pictures and GTA Snapmatic - - - - - - JPG pictures only - - - - - - GTA Snapmatic only - - - - - %1Export Snapmatic pictures%2<br><br>JPG pictures make it possible to open the picture with a Image Viewer<br>GTA Snapmatic make it possible to import the picture into the game<br><br>Export as: - - - - - - - - - Export selected... - - - - - Initialising export... - Initializing export... - - - - Export failed with... - -%1 - - - - - - No Snapmatic pictures or Savegames files are selected - - - - - - - Remove selected - - - - - You really want remove the selected Snapmatic picutres and Savegame files? - - - - - - Qualify as Avatar - - - - - - - - - - No Snapmatic pictures are selected - - - - - - - - Patch selected... - - - - - - - - - - - - Patch file %1 of %2 files - - - - - - - - - - %1 failed with... - -%2 - Action failed with... - - - - - Failed to remove all selected Snapmatic pictures and/or Savegame files - - - - - Prepare Content for Import... - - - - - A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp? - - - - - Qualify - %1 failed with... - - - - - - Change Players... - - - - - Change Players - %1 failed with... - - - - - - - Change Crew... - - - - - Failed to enter a valid Snapmatic Crew ID - - - - - Change Crew - %1 failed with... - - - - - - - Change Title... - - - - - Failed to enter a valid Snapmatic title - - - - - Change Title - %1 failed with... - - - - - All profile files (*.g5e SGTA* PGTA*) - - - - - SavegameDialog - - - - Savegame Viewer - - - - - <span style="font-weight:600">Savegame</span><br><br>%1 - - - - - &Export - - - - - &Close - - - - - Failed at %1 - - - - - SavegameWidget - - - Savegame Widget - - - - - SAVE %3 - %1<br>%2 - - - - - View savegame - - - - - View - - - - - Copy savegame - - - - - - Export - - - - - Delete savegame - - - - - Delete - - - - - &View - - - - - - - &Export - - - - - - - &Remove - - - - - - &Select - - - - - - &Deselect - - - - - - Select &All - - - - - - &Deselect All - - - - - Savegame files (SGTA*) - - - - - All files (**) - - - - - - - - Export Savegame - - - - - Overwrite %1 with current Savegame? - - - - - Failed to overwrite %1 with current Savegame - - - - - Failed to export current Savegame - - - - - No valid file is selected - - - - - Export Savegame... - - - - - - AUTOSAVE - %1 -%2 - - - - - - SAVE %3 - %1 -%2 - - - - - - WRONG FORMAT - - - - - UNKNOWN - - - - - Are you sure to delete %1 from your savegames? - - - - - - Delete Savegame - - - - - Failed at deleting %1 from your savegames - - - - - SnapmaticEditor - - - - - - - - - - - Snapmatic Properties - - - - - Snapmatic Type - - - - - Editor - - - - - Selfie - - - - - Regular - - - - - Mugshot - - - - - Meme - - - - - Director - - - - - Snapmatic Values - - - - - Crew: %1 (%2) - - - - - Title: %1 (%2) - - - - - Players: %1 (%2) - Multiple Player are inserted here - - - - - Player: %1 (%2) - One Player is inserted here - - - - - - Appropriate: %1 - - - - - Extras - - - - - Qualify as Avatar automatically at apply - - - - - Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture - - - - - Apply changes - - - - - &Apply - - - - - Discard changes - - - - - &Cancel - - - - - - - Edit - - - - - Yes - Yes, should work fine - - - - - No - No, could lead to issues - - - - - <h4>Unsaved changes detected</h4>You want to save the JSON content before you quit? - - - - - Patching of Snapmatic Properties failed because of %1 - - - - - Patching of Snapmatic Properties failed because of JSON Error - - - - - - - - Patching of Snapmatic Properties failed because of I/O Error - - - - - - Snapmatic Title - - - - - - New Snapmatic title: - - - - - - Snapmatic Crew - - - - - - New Snapmatic crew: - - - - - SnapmaticPicture - - - PHOTO - %1 - - - - - open file %1 - - - - - header not exists - - - - - header is malformed - - - - - picture not exists (%1) - - - - - JSON not exists (%1) - - - - - title not exists (%1) - - - - - description not exists (%1) - - - - - reading file %1 because of %2 - Example for %2: JSON is malformed error - - - - - - JSON is incomplete and malformed - - - - - - JSON is incomplete - - - - - - JSON is malformed - - - - - SnapmaticWidget - - - Snapmatic Widget - - - - - PHOTO - 00/00/00 00:00:00 - - - - - View picture - - - - - View - - - - - Copy picture - - - - - Copy - - - - - Export picture - - - - - Export - - - - - - - Delete picture - - - - - Delete - - - - - - - Edi&t - - - - - - - Show &In-game - - - - - - - Hide &In-game - - - - - &Export - - - - - &View - - - - - &Remove - - - - - - &Select - - - - - - &Deselect - - - - - - Select &All - - - - - - &Deselect All - - - - - Are you sure to delete %1 from your Snapmatic pictures? - - - - - Failed at deleting %1 from your Snapmatic pictures - - - - - Failed to hide %1 In-game from your Snapmatic pictures - - - - - Failed to show %1 In-game from your Snapmatic pictures - - - - - TelemetryDialog - - - You want help %1 to improve in the future by including personal usage data in your submission? - - - - - %1 User Statistics - - - - - Yes, I want include personal usage data. - - - - - &OK - - - - - UserInterface - - - - %2 - %1 - - - - - Select profile - - - - - %1 %2 - - - - - Reload profile overview - - - - - &Reload - - - - - Close %1 - Close %1 <- (gta5view/gta5sync) - %1 will be replaced automatically - - - - - - - - &Close - - - - - &File - - - - - &Help - - - - - &Edit - - - - - &Profile - - - - - &Selection visibility - - - - - - - &About %1 - - - - - &Exit - - - - - Exit - - - - - Close &Profile - - - - - &Settings - - - - - Select &All - - - - - &Deselect All - - - - - &Export selected... - - - - - &Remove selected - - - - - &Import files... - - - - - &Open File... - - - - - - Select &GTA V Folder... - - - - - - - - Select GTA V Folder... - - - - - Show In-gam&e - - - - - Hi&de In-game - - - - - - - Change &Players... - - - - - Selection &mass tools - - - - - - - Change &Title... - - - - - - - Change &Crew... - - - - - - - &Qualify as Avatar - - - - - - - Select Profile - - - - - - &Donate - - - - - Donate - - - - - Donation methods - - - - - &Copy - - - - - Open File... - - - - - - - - Open File - - - - - Can't open %1 because of not valid file format - - - - - %1 - Messages - - - - - - - Show In-game - - - - - - - Hide In-game - - - - diff --git a/res/gta5sync_fr.qm b/res/gta5sync_fr.qm index 5b24a03..42bcebb 100644 Binary files a/res/gta5sync_fr.qm and b/res/gta5sync_fr.qm differ diff --git a/res/gta5sync_fr.ts b/res/gta5sync_fr.ts index 7e90ba6..d0a8cb7 100644 --- a/res/gta5sync_fr.ts +++ b/res/gta5sync_fr.ts @@ -3,114 +3,71 @@ AboutDialog + + About gta5sync + À propos de gta5sync + + + <span style=" font-weight:600;">gta5sync</span><br/> +<br/> +A project for viewing and sync Grand Theft Auto V Snapmatic<br/> +Pictures and Savegames<br/> +<br/> +Project version: %1<br/> +Project build: %4, %5<br/> +Compiled with Qt %2<br/> +Running with Qt %3<br/> +<br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5sync is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + <span style=" font-weight:600;">gta5sync</span><br/> +<br/> +Un outil pour gérer et synchroniser les photos Snapmatic<br/> +et les fichiers de sauvegarde de Grand Theft Auto V<br/> +<br/> +gta5sync v%1<br/> +Build %4, %5<br/> +Compilé avec Qt %2<br/> +Fonctionne avec Qt %3<br/> +<br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/> +gta5sync est distribué sous license <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + - About %1 - À propos de %1 + About gta5view + À propos de gta5view - <span style="font-weight:600">%1</span><br/> + <span style=" font-weight:600;">gta5view</span><br/> <br/> -%2<br/> +A project for viewing Grand Theft Auto V Snapmatic<br/> +Pictures and Savegames<br/> <br/> -Version %3<br/> -Created on %4<br/> -Built with Qt %5<br/> -Running with Qt %6<br/> +Project version: %1<br/> +Project build: %4, %5<br/> +Compiled with Qt %2<br/> +Running with Qt %3<br/> <br/> -%7 - <span style="font-weight:600">%1</span><br/> +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/>gta5view is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> + <span style=" font-weight:600;">gta5view</span><br/> <br/> -%2<br/> +Un outil pour gérer les photos Snapmatic<br/> +et les fichiers de sauvegarde de Grand Theft Auto V<br/> <br/> -Version %3<br/> -Publié le %4<br/> -Compilé avec Qt %5<br/> -Fonctionne avec Qt %6<br/> +gta5view v%1<br/> +Build %4, %5<br/> +Compilé avec Qt %2<br/> +Fonctionne avec Qt %3<br/> <br/> -%7 +Copyright &copy; <a href="https://github.com/Syping/">Syping</a> 2016<br/> +gta5view est distribué sous license <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - + &Close &Fermer - - - Translated by %1 - Translated by translator, example Translated by Syping - Traduit par %1 - - - - TRANSLATOR - Insert your name here and profile here in following scheme, First Translator,First Profile\nSecond Translator\nThird Translator,Second Profile - Ganjalo,https://github.com/Ganjalo/ -XeriosG,g5e://about?WGVyaW9zRw:RGlzY29yZDogWGVyaW9zRyM1MzIxPGJyLz5TdGVhbTogPGEgaHJlZj0iaHR0cHM6Ly9zdGVhbWNvbW11bml0eS5jb20vcHJvZmlsZXMvNzY1NjExOTg0MjU2NjU3MjQvIj5YZXJpb3NHPC9hPg - - - - A project for viewing Grand Theft Auto V Snapmatic<br/> -Pictures and Savegames - Un outil pour gérer les photos Snapmatic<br/> -et les fichiers de sauvegarde de Grand Theft Auto V - - - - Copyright &copy; <a href="%1">%2</a> %3 - Copyright &copy; <a href="%1">%2</a> %3 - - - - %1 is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - %1 est distribué sous license <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - - - - Release - Release - - - - Release Candidate - Release Candidate - - - - Daily Build - Daily Build - - - - Developer - Developer - - - - Beta - Beta - - - - Alpha - Alpha - - - - - Custom - Personnalisé - - - - CrewDatabase - - - - No Crew - Aucun crew - ExportDialog @@ -120,499 +77,61 @@ et les fichiers de sauvegarde de Grand Theft Auto V Exporter - + Export Format Format - + &JPEG/PNG format &JPEG/PNG - + GTA &Snapmatic format GTA &Snapmatic - + Export Size Dimensions - + Default &Size Par &défaut - + &Desktop Size Dimensions de l'&écran - + &Custom Size &Personnalisé - + Custom Size: Dimensions: - + x x - + &Export &Exporter - + &Close &Fermer - - ImageEditorDialog - - - - - - Snapmatic Image Editor - Éditeur d'images Snapmatic - - - - Overwrite Image... - Remplacer l'image... - - - - Apply changes - Appliquer les modifications - - - - &Overwrite - &Remplacer - - - - Discard changes - Annuler les modifications - - - - &Close - &Fermer - - - - - Patching of Snapmatic Image failed because of I/O Error - Échec du patch Snapmatic : I/O Error - - - - - Patching of Snapmatic Image failed because of Image Error - Échec du patch Snapmatic : Image Error - - - - ImportDialog - - - Import... - Importer... - - - - - Ignore Aspect Ratio - Déverrouiller le ratio d'aspect - - - - Avatar - Avatar - - - - Picture - Image - - - - Watermark - Filigrane - - - - Background - Fond - - - - - - - Background Colour: <span style="color: %1">%1</span> - Couleur de fond : <span style="color: %1">%1</span> - - - - Select background colour - Choisir la couleur de fond - - - ... - ... - - - - Select background image - Choisir l'image de fond - - - - Remove background image - Supprimer l'image de fond - - - - - Background Image: %1 - Image de fond : %1 - - - X - X - - - - Crop to Aspect Ratio - Recadrage au ratio d'aspect - - - - Force Colour in Avatar Zone - Forcer la couleur dans la zone d'avatar - - - - Advanced - Avancé - - - - Resolution: - Résolution : - - - - Snapmatic resolution - Résolution Snapmatic - - - - Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic - Éviter la compression et étendre la mémoire tampon à la place, améliore la qualité de l'image mais peut casser Snapmatic - - - - Unlimited Buffer - Mémoire tampon illimitée - - - - Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing - Importer tel quel,ne changez pas du tout l'image, garantie de casser Snapmatic à moins que vous ne sachiez ce que vous faites - - - - Import as-is - Importer tel quel - - - - Import options - Options d'importation - - - - &Options - &Options - - - - Import picture - Importer l'image - - - - &OK - &OK - - - - Discard picture - Supprimer l'image - - - - &Cancel - &Annuler - - - - - - - Background Image: - Image de fond : - - - - &Import new Picture... - &Importer une nouvelle image... - - - - &Crop Picture... - &Rogner l'image... - - - - &Load Settings... - &Charger les paramètres... - - - - &Save Settings... - &Sauvegarder les paramètres... - - - - - Custom Avatar - Custom Avatar Description in SC, don't use Special Character! - Avatar personnalisé - - - - - - Custom Picture - Custom Picture Description in SC, don't use Special Character! - Image personnalisé - - - - Storage - Background Image: Storage - Stockage - - - - Crop Picture... - Rogner l'image... - - - - &Crop - &Rogner - - - - Crop Picture - Rogner l'image - - - - - Please import a new picture first - Veuillez d'abord importer une nouvelle image - - - - - Default - Default as Default Profile - Défaut - - - - - - - - - - - - - - - - - - - - - - - Profile %1 - Profile %1 as Profile 1 - Profil %1 - - - - - Load Settings... - Charger les paramètres... - - - - - Please select your settings profile - Veuillez choisir votre profil de paramètres - - - - - Save Settings... - Sauvegarder les paramètres... - - - - - Are you sure to use a square image outside of the Avatar Zone? -When you want to use it as Avatar the image will be detached! - Êtes-vous sûr d'utiliser une image carrée en dehors de la Zone d'Avatar ? -Si vous l'utilisez comme Avatar, l'image sera détachée ! - - - - - Snapmatic Avatar Zone - Zone d'avatar Snapmatic - - - - Select Colour... - Choisir une couleur... - - - - File - Background Image: File - Fichier - - - - JsonEditorDialog - - - Snapmatic JSON Editor - Éditeur Snapmatic JSON - - - - Apply changes - Appliquer les modifications - - - - &Save - &Sauvegarder - - - - Discard changes - Annuler les modifications - - - - &Close - &Fermer - - - - JSON Error - Erreur JSON - - - - MapLocationDialog - - - Snapmatic Map Viewer - Visionneuse de carte Snapmatic - - - - Close viewer - Fermer la visionneuse - - - - &Close - &Fermer - - - - Apply new position - Appliquer la nouvelle position - - - - &Apply - &Appliquer - - - - Revert old position - Revenir à l'ancienne position - - - - &Revert - &Revenir - - - - Select new position - Sélectionner la nouvelle position - - - - &Select - &Sélectionner - - - - Quit select position - Quitter la sélection de position - - - - &Done - &Terminer - - - - X: %1 -Y: %2 - X and Y position - X : %1 -Y : %2 - - OptionsDialog @@ -631,17 +150,19 @@ Y : %2 Ouverture/Sélection du contenu + Open with Singleclick - Ouvrir avec un clic + Ouvrir avec un clic - + Open with Doubleclick Ouvrir avec un double-clic + Select with Singleclick - Sélectionner avec un clic + Sélectionner avec un clic @@ -746,272 +267,69 @@ Y : %2 - Game - Jeu - - - Social Club Version - Version du Social Club + Language + Langue - - - - - - - - - Found: %1 - Trouvé : %1 + Sync + Synchronisation - - - - - - - - - - - Language: %1 - Langue : %1 + Sync is not implemented at current time + La synchronisation n'est pas encore implémentée - - Steam Version - Version de Steam - - - - Feedback - Feedback - - - - Participation - Participation - - - - - Participate in %1 User Statistics - Participer aux statistiques d'usage %1 - - - - Categories - Catégories - - - - Hardware, Application and OS Specification - Matériel, applications et OS - - - - System Language Configuration - Langage système - - - - Application Configuration - Configuration de l'application - - - - Other - Autres - - - - - - Participation ID: %1 - ID de participation : %1 - - - - &Copy - &Copier - - - - Language for Areas - Langage des Zones - - - - Style - Style - - - - Style: - Style : - - - - Font - Police - - - Always use Message Font (Windows 2003 and earlier) - Toujours utiliser la police Message (Windows 2003 et précédent) - - - - Interface - Interface - - - - Personal Usage Data - Données d'utilisation - - - - Language for Interface - Langage de l'interface - - - - - - - Current: %1 - Actuel : %1 - - - - Use Default Style (Restart) - Utiliser le style par défaut (redémarrage requis) - - - - Use Default Font (Restart) - Utiliser la police par défaut (redémarrage requis) - - - - Font: - Police : - - - - Apply changes - Appliquer les changements - - - + &OK OK, Cancel, Apply &OK - - Discard changes - Annuler les changements - - - + &Cancel OK, Cancel, Apply &Annuler - + + %1 (%2 if available) + System like PC System = %1, System Language like Deutsch = %2 + %1 (%2 si disponible) + + + System - System in context of System default + System like PC System Système - - %1 (Game language) - Next closest language compared to the Game settings - %1 (Langue du jeu) - - - - - %1 (Closest to Interface) - Next closest language compared to the Interface - %1 (Langage proche de l'interface) - - - - - - Auto - Automatic language choice. - Automatique - - - - %1 (Language priority) - First language a person can talk with a different person/application. "Native" or "Not Native". - %1 (Priorité de la langue) - - - + + %1 %1 %1 - - The new Custom Folder will initialise after you restart %1. - Le nouveau Dossier personnalisé sera initialisé au redémarrage de %1. + + The new Custom Folder will initialize after you restart %1. + Le répertoire personnalisé sera actif au prochain lancement de %1. - - View %1 User Statistics Online - Voir les statistiques d'usage %1 en ligne + + The language change will take effect after you restart %1. + Le changement de langue sera actif au prochain lancement de %1. - - Not registered - Pas enregistré - - - - - - - Yes - Oui - - - - - No - Non - - - - - OS defined - Défini par le système d'exploitation - - - - - Steam defined - Défini par Steam - - - + No Profile No Profile, as default Aucun profil - - - + + + Profile: %1 Profil : %1 @@ -1020,277 +338,159 @@ Y : %2 PictureDialog - Snapmatic Picture Viewer - %1 - Visionneuse de photo Snapmatic - %1 + %1 - Snapmatic Picture Viewer + %1 - Visionneuse de photo Snapmatic - - <span style="font-weight:600">Title: </span>%6<br/> -<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Created: </span>%8 - <span style="font-weight:600">Titre : </span>%6<br/> -<span style="font-weight:600">Emplacement : </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Joueurs : </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Créé le : </span>%8 - - - - Manage picture - Gestion de l'image + + <span style=" font-weight:600;">Title: </span>%6<br/> +<span style=" font-weight:600;">Location: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Players: </span>%4 (Crew %5)<br/> +<span style=" font-weight:600;">Created: </span>%8 + <span style=" font-weight:600;">Titre: </span>%6<br/> +<span style=" font-weight:600;">Emplacement: </span>%7 (%1, %2, %3)<br/> +<span style=" font-weight:600;">Joueurs: </span>%4 (Crew %5)<br/> +<span style=" font-weight:600;">Créé le: </span>%8 - &Manage - &Gestion + Export picture + Exporter la photo - - Close viewer - Fermer la visionneuse + + + &Export + &Exporter + Close + Fermer la visionneuse + + + &Close &Fermer - - Failed to export the picture because the system occurred a write failure - Échec de l'export de l'image : erreur d'écriture - - - - Failed to export the picture because the format detection failures - Échec de l'export de l'image : erreur de détection du format - - - - Failed to export the picture because the file can't be written - Échec de l'export de l'image : impossible d'écrire dans le fichier - - - - Failed to export the picture because of an unknown reason - Échec de l'export de l'image : erreur inconnue - - - - Export as Snapmatic... + + Export as GTA Snapmatic... Exporter comme Snapmatic... - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - - - - GTA V Raw Export (*.auto) - GTA V Export Brut (*.g5e) - - - + Snapmatic pictures (PGTA*) Fichiers GTA Snapmatic (PGTA*) - - - - - - Export as Snapmatic - Exporter comme Snapmatic + + All files (**) + Tous les fichiers (**) - - Exported Snapmatic to "%1" because of using the .auto extension. - Exporté comme "%1" avec l'utilisation de l'extension .auto. + + + + + Export as GTA Snapmatic + Exporter comme GTA Snapmatic - - + + Overwrite %1 with current Snapmatic picture? %1 existe déjà. Vous-vous le remplacer ? - - Export as Picture... - Exporter comme image... + + + Failed to overwrite %1 with current Snapmatic picture + Echec du remplacement de %1 - - JPEG Graphics (*.jpg *.jpeg) - JPEG Graphics (*.jpg *.jpeg) + + Failed to copy current Snapmatic picture + Echec de la copie - - - - - - - Export as Picture - Exporter comme image - - - - + + No valid file is selected Fichier invalide - - - Export as &Picture... - Exporter comme &image... + + Export as &JPG picture... + Exporter comme image &JPG... - - - Export as &Snapmatic... - Exporter comme &Snapmatic... + + Export as &GTA Snapmatic... + Exporter comme &GTA Snapmatic... - - - &Overwrite Image... - &Remplacer l'image... - - - - - &Edit Properties... - Modifier les &propriétés... - - - - - Open &Map Viewer... - Ouvrir la &Visionneuse de Carte... - - - - Key 1 - Avatar Preview Mode -Key 2 - Toggle Overlay -Arrow Keys - Navigate - Touche 1 - Mode Aperçu Avatar -Touche 2 - Activer/désactiver l'overlay -Touches fléchées - Naviguer - - - + + Snapmatic Picture Viewer Visionneuse de photo Snapmatic - + + Failed at %1 Echec de %1 - - - No Crew + + + No player + Aucun joueur + + + + + No crew Aucun crew - - - - No Players - Aucun joueurs - - - - Avatar Preview Mode -Press 1 for Default View - Mode Aperçu Avatar -Appuyer sur 1 pour le mode par défaut - - - + Unknown Location Emplacement inconnu - - + + Export as JPG picture... + Exporter comme image JPG... + + + Export Exporter - + + JPEG picture (*.jpg) + Image JPEG (*.jpg) + + + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - - + + + + + Export as JPG picture + Exporter comme image JPG + + + Failed to export current Snapmatic picture Échec de l'export de la photo Snapmatic - - - - Open &JSON Editor... - Ouvrir l'éditeur &JSON... - - - - PlayerListDialog - - - Edit Players... - Modifier les joueurs... - - - - Available Players: - Joueurs disponibles : - - - - Selected Players: - Joueurs sélectionnés : - - - - &Apply - A&ppliquer - - - - &Cancel - A&nnuler - - - - Add Players... - Ajouter des joueurs... - - - - Failed to add more Players because the limit of Players are %1! - Échec de l'ajout de joueurs : la limite de %1 est atteinte ! - - - - - Add Player... - Ajouter un joueur... - - - - Enter Social Club Player ID - Entrer l'ID Social Club du joueur - - - - Failed to add Player %1 because Player %1 is already added! - Échec de l'ajout du joueur %1 car le joueur %1 est déjà ajouté ! - ProfileInterface @@ -1305,125 +505,94 @@ Appuyer sur 1 pour le mode par défaut Chargement du fichier %1 sur %2 - + %1 %2 %1 %2 - - Import file - Importer un fichier + + Import exported file + Importer un profil - + &Import... &Importer... - + Close profile Fermer - + &Close &Fermer - - - + + + Export file %1 of %2 files Copie du fichier %1 sur %2 - + Enabled pictures: %1 of %2 Photos activées : %1 sur %2 - + Loading... Chargement... - - Snapmatic Loader - Snapmatic Loader - - - - <h4>Following Snapmatic Pictures got repaired</h4>%1 - <h4>Les Snapmatic suivants ont été répaés</h4>%1 - - - - - - - - - - - - - - - - - - - - - + Import... Importer... - - - - - - + + + + + + + + + + + + Import Importer - - + + + All profile files (SGTA* PGTA*) + Fichiers de profil GTA (SGTA* PGTA*) + + + + Savegames files (SGTA*) Fichiers de sauvegarde GTA (SGTA*) - - + + Snapmatic pictures (PGTA*) Photos Snapmatic (PGTA*) - - - - All image files (%1) - Toutes les images (%1) - - - - - - + + All files (**) Tous les fichiers (**) - - - Import file %1 of %2 files - Importation du fichier %1 sur %2 - - - + Import failed with... %1 @@ -1432,227 +601,97 @@ Appuyer sur 1 pour le mode par défaut %1 - - - + + + No valid file is selected Fichier invalide - - Importable files (%1) - Fichiers importables (%1) - - - - + + Failed to read Snapmatic picture Impossible d'ouvrir la photo Snapmatic - - + + Failed to read Savegame file Impossible de lire le fichier de sauvegarde - - - - Can't import %1 because file can't be open - Impossible d'importer %1, le fichier ne peut pas être ouvert + + Can't import %1 because of not valid file format + Impossible d'importer %1, format invalide - - - - Can't import %1 because file can't be parsed properly - Impossible d'importer %1, le fichier ne peut pas être parsé correctement + + Failed to import the Snapmatic picture, file not begin with PGTA + Impossible d'importer la photo Snapmatic,nom de fichier incorrect (PGTA*) - - Can't import %1 because file format can't be detected - Impossible d'importer %1, le format du fichier n'est pas détecté + + Failed to import the Snapmatic picture, the picture is already in the game + Impossible d'importer la photo Snapmatic, un fichier du même nom existe déjà - - Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e - Impossible d'importer la photo Snapmatic,nom de fichier incorrect (PGTA*, *.g5e) - - - + Failed to import the Snapmatic picture, can't copy the file into profile Impossible d'importer la photo Snapmatic, impossible de copier le fichier dans le profil - + Failed to import the Savegame, can't copy the file into profile Impossible d'importer la sauvegarde, impossible de copier le fichier dans le profil - + Failed to import the Savegame, no Savegame slot is left Impossible d'importer la sauvegarde, aucun emplacement libre - - + + + + + Export selected + Exporter la sélection + + + + JPG pictures and GTA Snapmatic Images JPG et GTA Snapmatic - - + + JPG pictures only Images JPG seulement - - + + GTA Snapmatic only GTA Snapmatic seulement - + %1Export Snapmatic pictures%2<br><br>JPG pictures make it possible to open the picture with a Image Viewer<br>GTA Snapmatic make it possible to import the picture into the game<br><br>Export as: %1Exporter les photos Snapmatic%2<br><br>Les fichiers JPG permettent d'ouvrir les photos avec une visionneuse d'images<br>Les GTA Snapmatic permettent d'importer les photos dans le jeu<br><br>Exporter comme : - - - - - + Export selected... Exporter la sélection... - - Initialising export... + + Initializing export... Initialisation de l'export... - - - Qualify as Avatar - Qualifier comme Avatar - - - - - - - - - No Snapmatic pictures are selected - Aucun Snapmatic sélectionné - - - - - - - Patch selected... - Patcher la sélection... - - - - - - - - - - - Patch file %1 of %2 files - Patch du fichier %1 sur %2 - - - - - - - - - %1 failed with... - -%2 - Action failed with... - %1 a échoué avec... - -%2 - - - - Failed to remove all selected Snapmatic pictures and/or Savegame files - Échec de la supression des Snapmatic et/ou des fichiers de sauvegarde sélectionnés - - - - Prepare Content for Import... - Préparation du contenu pour l'import... - - - - A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp? - Un Snapmatic existe déjà avec le uid %1, voulez-vous assigner à votre import un nouvel uid et timestamp ? - - - - Qualify - %1 failed with... - Qualifier - - - - - Change Players... - Modifier les joueurs... - - - - Change Players - %1 failed with... - Modifier les joueurs - - - - - - Change Crew... - Modifier le Crew... - - - - Failed to enter a valid Snapmatic Crew ID - Snapmatic Crew ID invalide - - - - Change Crew - %1 failed with... - Changer le Crew - - - - - - Change Title... - Changer le titre... - - - - Failed to enter a valid Snapmatic title - Titre Snapmatic invalide - - - - Change Title - %1 failed with... - Changer le titre - - - + Export failed with... %1 @@ -1661,75 +700,67 @@ Appuyer sur 1 pour le mode par défaut %1 - - + + No Snapmatic pictures or Savegames files are selected Aucun fichier de sauvegarde ou photo Snapmatic sélectionné - - - + + + Remove selected Supprimer la sélection - + You really want remove the selected Snapmatic picutres and Savegame files? Supprimer la sélection ? - - All profile files (*.g5e SGTA* PGTA*) - Tous les fichiers de profil (*.g5e SGTA* PGTA*) - - - - - GTA V Export (*.g5e) - GTA V Export (*.g5e) + + Failed at remove the complete selected Snapmatic pictures and/or Savegame files + Impossible de supprimer la sélection QApplication + Font - Police + Police + Selected Font: %1 - Police sélectionnée : %1 - - - <h4>Welcome to %1!</h4>You want to configure %1 before you start using it? - <h4>Bienvenue sur %1!</h4>Voulez-vous configurer %1 avant de l'utiliser t? + Police sélectionnée : %1 SavegameDialog - + Savegame Viewer Gestionnaire de sauvegardes - - <span style="font-weight:600">Savegame</span><br><br>%1 - <span style="font-weight:600">Sauvegarde</span><br><br>%1 + + <span style=" font-weight:600;">Savegame</span><br><br>%1 + <span style=" font-weight:600;">Sauvegarde</span><br><br>%1 - + &Export &Exporter - + &Close &Fermer - + Failed at %1 Échec de %1 @@ -1763,12 +794,13 @@ Appuyer sur 1 pour le mode par défaut - Export Exporter + + Delete savegame Supprimer la sauvegarde @@ -1778,131 +810,118 @@ Appuyer sur 1 pour le mode par défaut Supprimer - - - + + &Export &Exporter - + Savegame files (SGTA*) Fichiers de sauvegarde GTA (SGTA*) - + All files (**) Tous les fichiers (**) - - + + + - Export Savegame Exporter la sauvegarde - + Overwrite %1 with current Savegame? Remplacer %1 ? - + Failed to overwrite %1 with current Savegame Impossible de remplacer %1 - + Failed to export current Savegame Impossible d'exporter la sauvegarde - + No valid file is selected Fichier invalide - + Export Savegame... Exporter la sauvegarde... - - + AUTOSAVE - %1 %2 SAUVEGARDE AUTO - %1 %2 - - + SAVE %3 - %1 %2 SAUVEGARDE %3 - %1 %2 - - + + WRONG FORMAT Format invalide - + UNKNOWN Inconnu - + Are you sure to delete %1 from your savegames? Supprimer %1 ? - - - Delete Savegame - Supprimer la sauvegarde - - - + Failed at deleting %1 from your savegames Impossible de supprimer %1 - + &View &Voir - - - + &Remove &Supprimer - - + + &Select &Sélectionner - - + &Deselect &Déselectionner - - + + Select &All Sélectionner to&ut - - + &Deselect All &Déselectionner tout @@ -1911,255 +930,83 @@ Appuyer sur 1 pour le mode par défaut SnapmaticEditor - - - - - - - - + + Snapmatic Properties Propriétés Snapmatic - + Snapmatic Type - Type + Type Snapmatic - + + Editor Éditeur - + + Selfie Selfie - + Regular Normal - + + Mugshot - Photo d'identité + Mugshot - + Custom + Personnalisé + + + Director Director - + Meme Meme - - - Snapmatic Title - Titre Snapmatic - - - - Snapmatic Values - Valeurs Snapmatic - - - - Crew: %1 (%2) - Crew : %1 (%2) - - - - Title: %1 (%2) - Titre : %1 (%2) - - - - Players: %1 (%2) - Multiple Player are inserted here - Joueurs : %1 (%2) - - - - Player: %1 (%2) - One Player is inserted here - Joueur : %1 (%2) - - - - - Appropriate: %1 - Valide : %1 - - - + Extras Extras - + Qualify as Avatar automatically at apply Qualifier comme Avatar - + Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture Qualifier comme Avatar permet d'utiliser cette image en tant que photo de profil sur le Social Club - - Apply changes - Appliquer les modifications - - - + &Apply - &Appliquer + A&ppliquer - - Discard changes - Annuler les modifications - - - + &Cancel A&nnuler - - - - Edit - Éditer - - - - Yes - Yes, should work fine - Oui, devrait fonctionner - Oui - - - - No - No, could lead to issues - Non, pourrait causer des erreurs - Non - - - - <h4>Unsaved changes detected</h4>You want to save the JSON content before you quit? - <h4>Modifications détectées</h4>Voulez-vous sauvegarder le contenu JSON avant de quitter ? - - - - Patching of Snapmatic Properties failed because of %1 - Patch des propriétés Snapmatic échoué : %1 - - - - Patching of Snapmatic Properties failed because of JSON Error - Patch des propriétés Snapmatic échoué : erreur JSON - - - - - - + Patching of Snapmatic Properties failed because of I/O Error La modification des propriétés Snapmatic a échoué : erreur d'entrée/sortie - - - - New Snapmatic title: - Nouveau titre Snapmatic : - - - - - Snapmatic Crew - Crew Snapmatic - - - - - New Snapmatic crew: - Nouveau crew Snapmatic : - - - - SnapmaticPicture - - - PHOTO - %1 - PHOTO - %1 - - - - open file %1 - ouverture du fichier %1 - - - - header not exists - les headers n'existent pas - - - - header is malformed - les headers sont incorrects - - - - picture not exists (%1) - l'image n'existe pas (%1) - - - - JSON not exists (%1) - le JSON n'existe pas (%1) - - - - title not exists (%1) - le titre n'existe pas (%1) - - - - description not exists (%1) - la description n'existe pas (%1) - - - - reading file %1 because of %2 - Example for %2: JSON is malformed error - lecture du fichier %1 : %2 - - - - - JSON is incomplete and malformed - JSON incomplet ou incorrect - - - - - JSON is incomplete - JSON incomplet - - - - - JSON is malformed - JSON incorrect - SnapmaticWidget @@ -2169,158 +1016,136 @@ Appuyer sur 1 pour le mode par défaut Snapmatic - + PHOTO - 00/00/00 00:00:00 Photo - 00/00/00 00:00:00 - + View picture Voir la photo - + View Voir - + Copy picture Copier la photo - + Copy Copier - + Export picture Exporter la photo - + Export Exporter - - - + + + Delete picture Supprimer la photo - + Delete Supprimer - + Are you sure to delete %1 from your Snapmatic pictures? Supprimer %1 ? - + Failed at deleting %1 from your Snapmatic pictures Impossible de supprimer %1 - - Failed to hide %1 In-game from your Snapmatic pictures - %1 n'a pas pu être rendu invisible en jeu - - - - Failed to show %1 In-game from your Snapmatic pictures - %1 n'a pas pu être rendu visible en jeu - - - - - + Edi&t Édi&ter - - - + Show &In-game &Visible en jeu - - - + Hide &In-game &Invisible en jeu - + + &Edit Properties... + Modifier les &propriétés... + + + &Export &Exporter - + + Export as &JPG picture... + Exporter comme image &JPG... + + + + Export as &GTA Snapmatic... + Exporter comme &GTA Snapmatic... + + + &View &Voir - + &Remove S&upprimer - - + + &Select &Sélectionner - - + &Deselect &Déselectionner - - + + Select &All Sélectionner &tout - - + &Deselect All &Déselectionner tout - - TelemetryDialog - - - You want help %1 to improve in the future by including personal usage data in your submission? - Voulez-vous aider au développement de %1 en transmettant vos données d'utilisation ? - - - - %1 User Statistics - Statistiques utilisateurs %1 - - - - Yes, I want include personal usage data. - Oui, je veux partager mes données d'utilisation. - - - - &OK - &OK - - UserInterface + + gta5sync - %1 + gta5sync - %1 + Select profile @@ -2333,245 +1158,220 @@ Appuyer sur 1 pour le mode par défaut - Reload profile overview - Recharger la vue du profil - - - &Reload &Rafraîchir - - Close %1 - Close %1 <- (gta5view/gta5sync) - %1 will be replaced automatically - Fermer %1 - - - - - - + &Close Fer&mer - + &File &Fichier - + &Help Ai&de - + &Edit &Éditer - + &Profile &Profil - + &About gta5sync + &À propos de gta5sync + + + + Ctrl+P + Ctrl+P + + + &Exit &Quitter - + Exit Quitter - + + Ctrl+Q + Ctrl+Q + + + Close &Profile Fermer le &profil - + + Ctrl+End + Ctrl + Fin + + + &Settings Paramètre&s - + + Ctrl+S + Ctrl+S + + + Select &All Sélectionner &tout - + + Ctrl+A + Ctrl+A + + + &Deselect All &Désélectionner tout - + + Ctrl+D + Ctrl+D + + + &Export selected... &Exporter la sélection... - + + Ctrl+E + Ctrl+E + + + &Remove selected &Supprimer la sélection - + + Ctrl+Del + Ctrl+Del + + + &Import files... &Importer... - + + Ctrl+I + Ctrl+I + + + &Open File... &Ouvrir... - - + + Ctrl+O + Ctrl+O + + + + Select &GTA V Folder... Modifier l'emplacement de &GTA V... - - - - + + + + Select GTA V Folder... Modifier l'emplacement de GTA V... - + + Ctrl+G + Ctrl+G + + + Show In-gam&e Rendre visible &en jeu - - - - Change &Players... - Modifier les &joueurs... + + Shift+E + Shift+E - - Selection &mass tools - Outils de sélectionne en &masse - - - - - - Change &Title... - Changer le &titre... - - - - - - Change &Crew... - Changer le &Crew... - - - - - - &Qualify as Avatar - &Qualifier comme Avatar - - - + &Selection visibility &Visibilité de la sélection - + + gta5view - %1 + gta5view - %1 + + + + &About gta5view + &À propos de gta5view + + + Hi&de In-game Ren&dre invisible en jeu - - + + Shift+D + Shift+D + + + %2 - %1 %2 - %1 - - - - &About %1 - &À propos de %1 - - - - - + + Select Profile Sélectionner un profil - - - &Donate - &Don - - - - Donate - Don - - - - Donation methods - Méthodes de don - - - View - Voir - - - Copy - Copier - - - - &Copy - &Copier - - - + Open File... Ouvrir... - - - - + + + + Open File Ouvrir - + Can't open %1 because of not valid file format Impossible d'ouvrir %1, format invalide - - - %1 - Messages - %1 - Nouvelles - - - - - - Show In-game - Visible en jeu - - - - - - Hide In-game - Invisible en jeu - diff --git a/res/gta5sync_ko.qm b/res/gta5sync_ko.qm deleted file mode 100644 index b100265..0000000 Binary files a/res/gta5sync_ko.qm and /dev/null differ diff --git a/res/gta5sync_ko.ts b/res/gta5sync_ko.ts deleted file mode 100644 index d2ebaa3..0000000 --- a/res/gta5sync_ko.ts +++ /dev/null @@ -1,2603 +0,0 @@ - - - - - AboutDialog - - - About %1 - %1 정보 - - - - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -Version %3<br/> -Created on %4<br/> -Built with Qt %5<br/> -Running with Qt %6<br/> -<br/> -%7 - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -버전 %3<br/> -생성됨 %4<br/> -Qt로 제작 %5<br/> -Qt로 실행 %6<br/> -<br/> -%7 - - - - &Close - 닫기(&C) - - - - Translated by %1 - Translated by translator, example Translated by Syping - 번역 %1 - - - - TRANSLATOR - Insert your name here and profile here in following scheme, First Translator,First Profile\nSecond Translator\nThird Translator,Second Profile - 앙시모사우루스,https://steamcommunity.com/profiles/76561198166105984/ - - - - A project for viewing Grand Theft Auto V Snapmatic<br/> -Pictures and Savegames - 이 프로그램은 GTA 5 스냅매틱을 수정하고 보기 위한 프로젝트입니다.<br/> -이미지 뷰어 및 세이브 파일 관리 지원 - - - - Copyright &copy; <a href="%1">%2</a> %3 - 저작권 &copy; <a href="%1">%2</a> %3 - - - - %1 is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - %1는 <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> 에 따라 라이센스가 부여됩니다 - - - - Release - 릴리즈 - - - - Release Candidate - 릴리즈 후보 - - - - Daily Build - 일일 빌드 - - - - Developer - 개발자 - - - - Beta - 베타 - - - - Alpha - 알파 - - - - - Custom - 사용자 지정 - - - - CrewDatabase - - - - No Crew - 조직 없음 - - - - ExportDialog - - - Dialog - 다이얼로그 - - - - Export Format - 내보낼 형식 - - - - &JPEG/PNG format - JPEG/PNG 형식(&J) - - - - GTA &Snapmatic format - GTA 스냅매틱 형식(&S) - - - - Export Size - 내보낼 크기 - - - - Default &Size - 기본 크기(&S) - - - - &Desktop Size - 바탕화면 크기(&D) - - - - &Custom Size - 사용자 정의 크기(&C) - - - - Custom Size: - 사용자 정의 크기: - - - - x - x - - - - &Export - 내보내기(&E) - - - - &Close - 닫기(&C) - - - - ImageEditorDialog - - - Overwrite Image... - 이미지 덮어쓰기 - - - - Apply changes - 변경 사항 적용 - - - - &Overwrite - 덮어쓰기(&O) - - - - Discard changes - 변경 사항 무시 - - - - &Close - 닫기(&C) - - - - - - - Snapmatic Image Editor - 스냅매틱 이미지 편집기 - - - - - Patching of Snapmatic Image failed because of I/O Error - I/O 오류로 인해 스냅매틱 이미지를 패치하지 못했습니다. - - - - - Patching of Snapmatic Image failed because of Image Error - 이미지 오류로 인해 스냅매틱 이미지를 패치하지 못했습니다. - - - - ImportDialog - - - Import... - 가져오기 - - - - Picture - 이미지 - - - - Avatar - 아바타 - - - - - Ignore Aspect Ratio - 화면 비율 무시 - - - - Watermark - 워터마크 - - - Force Borderless - 강제 테두리 없는 창 - - - - Background - 배경 - - - - - - - Background Colour: <span style="color: %1">%1</span> - 배경 색상: <span style="color: %1">%1</span> - - - - Select background colour - 배경 색상 선택 - - - ... - ... - - - - - - - Background Image: - 배경 이미지: - - - - Select background image - 배경 이미지 선택 - - - - Remove background image - 배경 이미지 제거 - - - X - X - - - - Crop to Aspect Ratio - 원본 비율로 자르기 - - - - Force Colour in Avatar Zone - 아바타 구역에 색상을 적용합니다 - - - - Advanced - 고급 - - - - Resolution: - 해상도: - - - - Snapmatic resolution - 스냅매틱 해상도 - - - - Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic - 압축하지 않고 버퍼를 확장하여 화질을 향상시키지만 스냅매틱이 손상될 수 있습니다. - - - - Unlimited Buffer - 버퍼 제한 없음 - - - - Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing - 원본 그대로 가져오기 기능은 이미지를 건들지 않지만 이 기능으로 인해 당신의 스냅매틱이 손상될 수 있습니다. - - - - Import as-is - 원본 그대로 가져오기 - - - - Import options - 가져오기 옵션 - - - - &Options - 옵션(&O) - - - - Import picture - 사진 가져오기 - - - - &OK - 확인(&O) - - - - Discard picture - 사진 삭제 - - - - &Cancel - 취소(&C) - - - - &Import new Picture... - 새로운 사진 가져오기(&I) - - - - &Crop Picture... - 사진 자르기(&C) - - - - &Load Settings... - 설정 불러오기(&L) - - - - &Save Settings... - 설정 저장(&S) - - - - - Custom Avatar - Custom Avatar Description in SC, don't use Special Character! - 소셜클럽의 사용자 지정 아바타 설명입니다. 특수 문자를 사용하지 마십시오! - 사용자 지정 아바타 - - - - - - Custom Picture - Custom Picture Description in SC, don't use Special Character! - 소셜클럽의 사용자 지정 그림 설명입니다. 특수 문자를 사용하지 마십시오! - 사용자 지정 사진 - - - - - Background Image: %1 - 배경 이미지: %1 - - - - Storage - Background Image: Storage - 배경 이미지: 저장됨 - 저장됨 - - - - Crop Picture... - 사진 자르기 - - - - &Crop - 자르기(&C) - - - - Crop Picture - 사진 자르기 - - - - - Load Settings... - 설정 불러오기 - - - - - Please import a new picture first - 먼저 새 이미지를 가져오세요 - - - - - Default - Default as Default Profile - 기본 프로필로 기본 설정 - 기본 - - - - - - - - - - - - - - - - - - - - - - - Profile %1 - Profile %1 as Profile 1 - %1을 프로필 1로 지정합니다. - 프로필 %1 - - - - - Please select your settings profile - 설정 프로필을 선택하세요 - - - - - Save Settings... - 설정 저장 - - - - - Snapmatic Avatar Zone - 스냅매틱 아바타 영역 - - - - - Are you sure to use a square image outside of the Avatar Zone? -When you want to use it as Avatar the image will be detached! - 아바타 구역 밖에서 네모난 이미지를 정말 사용합니까? -아바타로 사용하려는 경우 이미지가 분리됩니다! - - - - Select Colour... - 색상 선택 - - - - File - Background Image: File - 배경 이미지: 파일 - 파일 - - - - JsonEditorDialog - - - Snapmatic JSON Editor - 스냅매틱 JSON 편집기 - - - - Apply changes - 변경 사항 적용 - - - - &Save - 저장(&S) - - - - Discard changes - 변경 사항 무시 - - - - &Close - 닫기(&C) - - - - JSON Error - JSON 오류 - - - - MapLocationDialog - - - Snapmatic Map Viewer - 스냅매틱 지도 뷰어 - - - - Close viewer - 뷰어 닫기 - - - - &Close - 닫기(&C) - - - - Apply new position - 새 위치 적용 - - - - &Apply - 적용(&A) - - - - Revert old position - 이전 위치로 되돌리기 - - - - &Revert - 되돌리기(&R) - - - - Select new position - 새 위치 선택 - - - - &Select - 선택(&S) - - - - Quit select position - 선택 위치 종료 - - - - &Done - 완료(&D) - - - - X: %1 -Y: %2 - X and Y position - X 및 Y 위치 - X: %1 -Y: %2 - - - - OptionsDialog - - - %1 - Settings - %1 - 설정 - - - - Profiles - 프로필 - - - - Content Open/Select Mode - 컨텐츠 열기/선택 모드 - - - Open with Singleclick - 한 번 클릭으로 열기 - - - - Open with Doubleclick - 두 번 클릭으로 열기 - - - Select with Singleclick - 한 번 클릭으로 선택 - - - - Default Profile - 기본 프로필 - - - - Custom GTA V Folder - 사용자 지정 GTA 5 폴더 - - - - Force using Custom Folder - 사용자 지정 폴더를 강제로 사용합니다. - - - - ... - ... - - - - Pictures - 이미지 - - - - Export Size - 내보낼 크기 - - - - Default: %1x%2 - 기본: %1x%2 - - - - Screen Resolution: %1x%2 - 화면 해상도: %1x%2 - - - - - Custom Size: - 사용자 지정 크기: - - - - x - x - - - - Ignore Aspect Ratio - 화면 비율 무시 - - - - Export Quality - 내보낼 품질 - - - - Enable Custom Quality - 사용자 지정 품질 사용 - - - - Quality: - 품질: - - - - %1% - %1% - - - - Picture Viewer - 이미지 뷰어 - - - - Enable Navigation Bar - 탐색바 사용 - - - - Players - 플레이어 - - - - ID - 아이디 - - - - Name - 이름 - - - - Game - 게임 - - - - Social Club Version - 소셜 클럽 버전 - - - - - - - - - - - Found: %1 - 찾음: %1 - - - - - - - - - - - - - Language: %1 - 언어: %1 - - - - Steam Version - 스팀 버전 - - - - Feedback - 피드백 - - - - Participation - 참가 - - - - - Participate in %1 User Statistics - 사용자 통계 참가 %1 - - - - Categories - 카테고리 - - - - Hardware, Application and OS Specification - 하드웨어, 응용 프로그램 및 OS 사양 - - - - System Language Configuration - 시스템 언어 설정 - - - - Application Configuration - 응용 프로그램 설정 - - - - Personal Usage Data - 개인 사용 데이터 - - - - Other - 그 외 - - - - - - Participation ID: %1 - 참여 아이디: %1 - - - - &Copy - 복사(&C) - - - - Interface - 인터페이스 - - - - Language for Interface - 인터페이스 언어 - - - - - - - Current: %1 - 현재: %1 - - - - Language for Areas - 지역 언어 - - - - Style - 스타일 - - - - Use Default Style (Restart) - 기본 스타일을 사용합니다 (재시작 필요) - - - - Style: - 스타일: - - - - Font - 폰트 - - - - Use Default Font (Restart) - 기본 폰트 사용 (재시작 필요) - - - - Font: - 폰트: - - - Always use Message Font (Windows 2003 and earlier) - 항상 메시지 글꼴을 사용합니다.(Windows 2003 및 이전 버전) - - - - Apply changes - 변경 사항 적용 - - - - &OK - OK, Cancel, Apply - 확인, 취소, 적용 - 확인(&O) - - - - Discard changes - 변경 사항 취소 - - - - &Cancel - OK, Cancel, Apply - 확인, 취소, 적용 - 취소(&C) - - - - %1 (Language priority) - First language a person can talk with a different person/application. "Native" or "Not Native". - %1 (우선 순위) - - - - System - System in context of System default - 시스템 - - - - %1 (Game language) - Next closest language compared to the Game settings - 게임 설정과 가장 가까운 언어 - %1 (게임 언어) - - - - - - Auto - Automatic language choice. - 언어 자동 선택 - 자동 - - - - - %1 (Closest to Interface) - Next closest language compared to the Interface - 인터페이스와 가장 가까운 언어 - %1 (인터페이스와 가까운 언어) - - - - %1 - %1 - %1 - %1 - - - - The new Custom Folder will initialise after you restart %1. - 다시 시작한 후 새 사용자 지정 폴더가 초기화됩니다. %1. - - - - No Profile - No Profile, as default - 프로필 없음 (기본값) - 프로필 없음 - - - - - - Profile: %1 - 프로필: %1 - - - - View %1 User Statistics Online - 온라인 %1 사용자 통계 보기 - - - - Not registered - 등록되지 않았습니다. - - - - - - - Yes - - - - - - No - 아니요 - - - - - OS defined - OS 정의 - - - - - Steam defined - 스팀 정의 - - - - PictureDialog - - - Snapmatic Picture Viewer - %1 - 스냅매틱 이미지 뷰어 - %1 - - - - <span style="font-weight:600">Title: </span>%6<br/> -<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Created: </span>%8 - <span style="font-weight:600">제목: </span>%6<br/> -<span style="font-weight:600">위치: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">플레이어: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">생성 날짜: </span>%8 - - - - Manage picture - 이미지 관리 - - - - &Manage - 관리(&M) - - - - Close viewer - 뷰어 닫기 - - - - &Close - 닫기(&C) - - - - - Export as &Picture... - 내 PC에 이미지로 내보내기(&P) - - - - - Export as &Snapmatic... - 내 PC에 스냅매틱으로 내보내기(&S) - - - - - &Edit Properties... - 속성 편집(&E) - - - - - &Overwrite Image... - 이미지 덮어쓰기(&O) - - - - - Open &Map Viewer... - 지도 뷰어 열기(&M) - - - - - Open &JSON Editor... - JSON 편집기 열기(&J) - - - - Key 1 - Avatar Preview Mode -Key 2 - Toggle Overlay -Arrow Keys - Navigate - 숫자 1 - 아바타 미리보기 모드 -숫자 2 - 오버레이 전환 -화살표키 - 이동 - - - - Snapmatic Picture Viewer - 스냅매틱 이미지 뷰어 - - - - Failed at %1 - %1에서 실패했습니다. - - - - - - No Players - 플레이어 없음 - - - - - No Crew - 조직 없음 - - - - Unknown Location - 알 수 없는 위치 - - - - Avatar Preview Mode -Press 1 for Default View - 아바타 미리 보기 모드입니다. -돌아가려면 숫자 1을 누릅니다. - - - - Export as Picture... - 내 PC에 이미지로 내보내기 - - - - - Export - 내보내기 - - - - JPEG Graphics (*.jpg *.jpeg) - JPEG Graphics (*.jpg *.jpeg) - - - - Portable Network Graphics (*.png) - Portable Network Graphics (*.png) - - - - - - - - - Export as Picture - 내 PC에 이미지로 내보내기 - - - - - Overwrite %1 with current Snapmatic picture? - %1을 현재 스냅매틱 이미지로 덮어쓰시겠습니까? - - - - Failed to export the picture because the system occurred a write failure - 시스템에서 쓰기 오류가 발생하여 이미지를 내보내지 못했습니다. - - - - Failed to export the picture because the format detection failures - 확장자 감지에 실패하여 이미지를 내보내지 못했습니다. - - - - Failed to export the picture because the file can't be written - 파일을 쓸 수 없으므로 이미지를 내보내지 못했습니다. - - - - Failed to export the picture because of an unknown reason - 알 수 없는 이유로 이미지를 내보내지 못했습니다. - - - - - No valid file is selected - 올바른 파일이 선택되지 않았습니다. - - - - Export as Snapmatic... - 내 PC에 스냅매틱으로 내보내기 - - - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - - - - GTA V Raw Export (*.auto) - GTA V Raw Export (*.auto) - - - - Snapmatic pictures (PGTA*) - Snapmatic pictures (PGTA*) - - - - - - - - Export as Snapmatic - 내 PC에 스냅매틱으로 내보내기 - - - - - Failed to export current Snapmatic picture - 현재 스냅매틱 이미지를 내보내지 못했습니다. - - - - Exported Snapmatic to "%1" because of using the .auto extension. - .auto 확장자를 사용하기 때문에 스냅매틱을 "%1"로 내보냈습니다. - - - - PlayerListDialog - - - Edit Players... - 플레이어 편집 - - - - Available Players: - 사용 가능한 플레이어: - - - - Selected Players: - 선택된 플레이어: - - - - &Apply - 적용(&A) - - - - &Cancel - 취소(&C) - - - - Add Players... - 플레이어 추가 - - - - Failed to add more Players because the limit of Players are %1! - 플레이어의 제한이 %1이므로 플레이어를 추가하지 못했습니다! - - - - - Add Player... - 플레이어 추가 - - - - Enter Social Club Player ID - 소셜 클럽 플레이어 아이디 입력 - - - - Failed to add Player %1 because Player %1 is already added! - %1 플레이어가 이미 추가되어 %1 플레이어를 추가하지 못했습니다! - - - - ProfileInterface - - - Profile Interface - 프로필 인터페이스 - - - - Loading file %1 of %2 files - %2 파일의 %1 파일을 불러오는 중입니다. - - - - %1 %2 - %1 %2 - - - - Import file - 파일 가져오기 - - - - &Import... - 가져오기(&I) - - - - Close profile - 프로필 닫기 - - - - &Close - 닫기(&C) - - - - - - Export file %1 of %2 files - %2 파일 중 %1 파일을 내보냅니다. - - - - - - - - - - - - - - - - - - - - - - Import... - 가져오기 - - - - - - - - - Import - 가져오기 - - - - - - All image files (%1) - 모든 이미지 파일 (%1) - - - - - - - All files (**) - 모든 파일 (**) - - - - - - Can't import %1 because file can't be open - 파일을 열 수 없으므로 %1을 가져올 수 없습니다. - - - - - - Can't import %1 because file can't be parsed properly - 파일을 구문 분석할 수 없으므로 %1을 가져올 수 없습니다. - - - - Enabled pictures: %1 of %2 - 활성화된 이미지: %2의 %1 - - - - Loading... - 불러오는 중... - - - - Snapmatic Loader - 스냅매틱 불러오기 - - - - <h4>Following Snapmatic Pictures got repaired</h4>%1 - <h4>다음 스냅매틱 이미지를 복구했습니다. </h4>%1 - - - - Importable files (%1) - 가져올 수 있는 파일 (%1) - - - - - GTA V Export (*.g5e) - GTA V로 내보내기 (*.g5e) - - - - - Savegames files (SGTA*) - 세이브 파일 (SGTA*) - - - - - Snapmatic pictures (PGTA*) - 스냅매틱 이미지 (PGTA*) - - - - - - No valid file is selected - 올바른 파일이 선택되지 않았습니다. - - - - - Import file %1 of %2 files - %2 파일 중 %1 파일을 가져옵니다. - - - - Import failed with... - -%1 - 가져오기에 실패했습니다... - -%1 - - - - - Failed to read Snapmatic picture - 스냅매틱 이미지를 읽지 못했습니다. - - - - - Failed to read Savegame file - 세이브 파일을 읽지 못했습니다. - - - - Can't import %1 because file format can't be detected - 파일 형식을 검색할 수 없으므로 %1을 가져올 수 없습니다. - - - - Prepare Content for Import... - 가져올 컨텐츠를 준비합니다. - - - - Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e - 스냅매틱 이미지를 가져오지 못했습니다. 파일이 PGTA로 시작되거나 .g5e로 끝나지 않습니다. - - - - A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp? - uid %1이(가) 있는 스냅매틱 이미지가 이미 있습니다. 가져오기를 새 uid 및 타임스탬프를 할당하시겠습니까? - - - - Failed to import the Snapmatic picture, can't copy the file into profile - 스냅매틱 이미지를 가져오지 못했습니다. 파일을 프로필에 복사할 수 없습니다. - - - - Failed to import the Savegame, can't copy the file into profile - 게임 저장 파일을 가져오지 못했습니다. 파일을 프로필에 복사할 수 없습니다. - - - - Failed to import the Savegame, no Savegame slot is left - 게임 저장 파일을 가져오지 못했습니다. 게임 저장 슬롯이 남아 있지 않습니다. - - - - - - - - Export selected... - 내보내기를 선택했습니다. - - - - - JPG pictures and GTA Snapmatic - JPG 이미지 및 GTA 스냅매틱 - - - - - JPG pictures only - JPG 이미지만 - - - - - GTA Snapmatic only - GTA 스냅매틱만 - - - - %1Export Snapmatic pictures%2<br><br>JPG pictures make it possible to open the picture with a Image Viewer<br>GTA Snapmatic make it possible to import the picture into the game<br><br>Export as: - %1 스냅매틱 이미지 내보내기를 시작합니다.%2 <br><br>JPG 이미지를 사용하면 이미지 뷰어로 파일을 열 수 있습니다.<br>GTA 스냅매틱을 사용하면 다음과 같이 이미지를 게임으로 가져올 수 있습니다. - - - - Initialising export... - 내보내기를 초기화하는 중... - - - - Export failed with... - -%1 - 내보내지 못했습니다... - -%1 - - - - - No Snapmatic pictures or Savegames files are selected - 스냅매틱 이미지 또는 세이브 파일이 선택되지 않았습니다. - - - - - - Remove selected - 선택한 항목 삭제 - - - - You really want remove the selected Snapmatic picutres and Savegame files? - 선택한 스냅매틱 이미지 및 세이브 파일을 삭제하시겠습니까? - - - - Failed to remove all selected Snapmatic pictures and/or Savegame files - 선택한 모든 스냅매틱 이미지 및 세이브 파일을 삭제하지 못했습니다. - - - - - - - - - No Snapmatic pictures are selected - 스냅매틱 이미지가 선택되지 않았습니다. - - - - - - - - - %1 failed with... - -%2 - Action failed with... - 작업 실패... - %1이(가) 실패했습니다. - -%2 - - - - - Qualify as Avatar - 아바타 자격 부여 - - - - - - - Patch selected... - 패치가 선택됨... - - - - - - - - - - - Patch file %1 of %2 files - %2 파일의 %1 패치 파일입니다. - - - - Qualify - %1 failed with... - %1이(가) 실패한 경우... - 자격 부여 - - - - - Change Players... - 플레이어 변경 - - - - Change Players - %1 failed with... - %1이(가) 실패한 경우... - 플레이어 변경 - - - - - - Change Crew... - 조직 변경 - - - - Failed to enter a valid Snapmatic Crew ID - 올바른 스냅매틱 조직 아이디를 입력하지 못했습니다. - - - - Change Crew - %1 failed with... - %1이(가) 실패한 경우... - 조직 변경 - - - - - - Change Title... - 제목 변경 - - - - Failed to enter a valid Snapmatic title - 올바른 스냅매틱 제목을 입력하지 않았습니다. - - - - Change Title - %1 failed with... - %1이(가) 실패한 경우... - 제목 변경 - - - - All profile files (*.g5e SGTA* PGTA*) - 모든 프로필 파일 (*.g5e SGTA* PGTA*) - - - - QApplication - - Font - 폰트 - - - Selected Font: %1 - 선택된 폰트: %1 - - - <h4>Welcome to %1!</h4>You want to configure %1 before you start using it? - <h4>%1에 오신 것을 환영합니다!</h4>%1을 사용하기 전에 설정 창을 여시겠습니까? - - - - SavegameDialog - - - - Savegame Viewer - 세이브 파일 보기 - - - - <span style="font-weight:600">Savegame</span><br><br>%1 - <span style="font-weight:600">세이브 파일</span><br><br>%1 - - - - &Export - 내보내기(&E) - - - - &Close - 닫기(&C) - - - - Failed at %1 - 실패 %1 - - - - SavegameWidget - - - Savegame Widget - 세이브 파일 위젯 - - - - SAVE %3 - %1<br>%2 - 저장 %3 - %1<br>%2 - - - - View savegame - 세이브 파일 보기 - - - - View - 보기 - - - - Copy savegame - 세이브 파일 복사 - - - - - Export - 내보내기 - - - - Delete savegame - 세이브 파일 삭제 - - - - Delete - 삭제 - - - - &View - 보기(&V) - - - - - - &Export - 내보내기(&E) - - - - - - &Remove - 삭제(&R) - - - - - &Select - 선택(&S) - - - - - &Deselect - 선택 해제(&D) - - - - - Select &All - 모두 선택(&A) - - - - - &Deselect All - 모두 선택 해제(&D) - - - - Savegame files (SGTA*) - 세이브 파일 (SGTA*) - - - - All files (**) - 모든 파일 (**) - - - - - - - Export Savegame - 세이브 파일 내보내기 - - - - Overwrite %1 with current Savegame? - %1을 현재 세이브 파일로 덮어쓰시겠습니까? - - - - Failed to overwrite %1 with current Savegame - %1을 현재 세이브 파일로 덮어쓰지 못했습니다. - - - - Failed to export current Savegame - 현재 세이브 파일을 내보내지 못했습니다. - - - - No valid file is selected - 올바른 파일이 선택되지 않았습니다. - - - - Export Savegame... - 세이브 파일 내보내기 - - - - - AUTOSAVE - %1 -%2 - 자동 저장 - %1 -%2 - - - - - SAVE %3 - %1 -%2 - 저장 %3 - %1 -%2 - - - - - WRONG FORMAT - 잘못된 형식 - - - - UNKNOWN - 알 수 없음 - - - - - Delete Savegame - 세이브 파일 삭제 - - - - Are you sure to delete %1 from your savegames? - %1을(를) 세이브 파일에서 삭제하시겠습니까? - - - - Failed at deleting %1 from your savegames - %1을(를) 세이브 파일에서 삭제하지 못했습니다. - - - - SnapmaticEditor - - - - - - - - - - - Snapmatic Properties - 스냅매틱 속성 - - - - Snapmatic Type - 스냅매틱 형식 - - - - Editor - 편집기 - - - - Selfie - 셀피 - - - - Regular - 일반 - - - - Mugshot - 머그샷 - - - - Meme - - - - - Director - 감독 - - - - Snapmatic Values - 스냅매틱 값 - - - - Extras - 기타 - - - - Qualify as Avatar automatically at apply - 적용 시 자동으로 아바타 자격을 부여합니다. - - - - Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture - 이 스냅매틱을 소셜 클럽 프로필 이미지로 사용할 수 있습니다. - - - - Apply changes - 변경 사항 적용 - - - - &Apply - 적용(&A) - - - - Discard changes - 변경 사항 취소 - - - - &Cancel - 취소(&C) - - - - <h4>Unsaved changes detected</h4>You want to save the JSON content before you quit? - < h4>저장되지 않은 변경 내용이 감지되었습니다. </h4>그만두기 전에 JSON 콘텐츠를 저장하겠습니까? - - - - Patching of Snapmatic Properties failed because of %1 - %1로 인해 스냅매틱 속성을 패치하지 못했습니다. - - - - - - - Patching of Snapmatic Properties failed because of I/O Error - I/O 오류로 인해 스냅매틱 속성을 패치하지 못했습니다. - - - - Patching of Snapmatic Properties failed because of JSON Error - JSON 오류로 인해 스냅매틱 속성을 패치하지 못했습니다. - - - - - Snapmatic Crew - 조직 스냅매틱 - - - - - New Snapmatic crew: - 새로운 조직 스냅매틱: - - - - - Snapmatic Title - 스냅매틱 제목 - - - - - New Snapmatic title: - 새로운 스냅매틱 제목: - - - - - - Edit - 편집 - - - - Players: %1 (%2) - Multiple Player are inserted here - 여기에 여러 플레이어가 추가됩니다. - 플레이어: %1 (%2) - - - - Player: %1 (%2) - One Player is inserted here - 여기에 플레이어 하나가 추가됩니다. - 플레이어: %1 (%2) - - - - Title: %1 (%2) - 제목: %1 (%2) - - - - - Appropriate: %1 - 변경: %1 - - - - Yes - Yes, should work fine - 네, 잘 될 거예요. - - - - - No - No, could lead to issues - 아니요, 문제가 발생할 수 있습니다. - 아니요 - - - - Crew: %1 (%2) - 조직: %1 (%2) - - - - SnapmaticPicture - - - - JSON is incomplete and malformed - JSON 파일이 불안정하거나 형식이 잘못되었습니다. - - - - - JSON is incomplete - JSON 파일이 불안정합니다. - - - - - JSON is malformed - 잘못된 JSON 형식 - - - - PHOTO - %1 - 사진 - %1 - - - - open file %1 - 파일 열기 %1 - - - - header not exists - 헤더가 존재하지 않습니다. - - - - header is malformed - 헤더의 형식이 잘못되었습니다. - - - - picture not exists (%1) - 이미지가 존재하지 않습니다. (%1) - - - - JSON not exists (%1) - JSON 파일이 존재하지 않습니다. (%1) - - - - title not exists (%1) - 제목이 존재하지 않습니다. (%1) - - - - description not exists (%1) - 설명이 존재하지 않습니다. (%1) - - - - reading file %1 because of %2 - Example for %2: JSON is malformed error - %2의 예: JSON이 잘못된 형식입니다 - %2 때문에 %1 파일을 읽습니다. - - - - SnapmaticWidget - - - Snapmatic Widget - 스냅매틱 위젯 - - - - PHOTO - 00/00/00 00:00:00 - 이미지 - 00/00/00 00:00:00 - - - - View picture - 이미지 보기 - - - - View - 보기 - - - - Copy picture - 이미지 복사 - - - - Copy - 복사 - - - - Export picture - 이미지 내보내기 - - - - Export - 내보내기 - - - - - - Delete picture - 이미지 삭제 - - - - Delete - 삭제 - - - - - - Edi&t - 편집(&T) - - - - - - Show &In-game - 인게임에서 보이기(&I) - - - - - - Hide &In-game - 인게임에서 숨기기(&I) - - - - &Export - 내보내기(&E) - - - - &View - 보기(&V) - - - - &Remove - 삭제(&R) - - - - - &Select - 선택(&S) - - - - - &Deselect - 선택 해제(&D) - - - - - Select &All - 모두 선택(&A) - - - - - &Deselect All - 모두 선택 해제(&D) - - - - Are you sure to delete %1 from your Snapmatic pictures? - 스냅매틱 이미지에서 %1을 삭제하시겠습니까? - - - - Failed at deleting %1 from your Snapmatic pictures - 스냅매틱 이미지에서 %1을 삭제하지 못했습니다. - - - - Failed to hide %1 In-game from your Snapmatic pictures - 인게임 스냅매틱 이미지에서 %1 을 숨기지 못했습니다. - - - - Failed to show %1 In-game from your Snapmatic pictures - 인게임 스냅매틱 이미지에서 %1 을 표시하지 못했습니다. - - - - TelemetryDialog - - - You want help %1 to improve in the future by including personal usage data in your submission? - 개인 사용 데이터를 제출에 포함시켜 %1이(가) 개선되기를 원합니까? - - - - %1 User Statistics - %1 사용자 통계 - - - - Yes, I want include personal usage data. - 예, 개인 사용 데이터를 포함시키고 싶습니다. - - - - &OK - 확인(&O) - - - - UserInterface - - - - %2 - %1 - %2 - %1 - - - - Select profile - 프로필 선택 - - - - %1 %2 - %1 %2 - - - - Reload profile overview - 프로필 다시 불러오기 - - - - &Reload - 새로고침(&R) - - - - Close %1 - Close %1 <- (gta5view/gta5sync) - %1 will be replaced automatically - 닫기 %1 <- (gta5view/gta5sync) - %1 자동으로 교체됩니다. - 닫기 %1 - - - - - - - &Close - 닫기(&C) - - - - &File - 파일(&F) - - - - &Help - 도움말(&H) - - - - &Edit - 편집(&E) - - - - &Profile - 프로필(&P) - - - - &Selection visibility - 인게임 표시(&S) - - - - Selection &mass tools - 선택 작업(&M) - - - - - - &About %1 - %1 정보(&A) - - - - &Exit - 종료(&E) - - - - Exit - 종료 - - - - Close &Profile - 프로필 닫기(&P) - - - - &Settings - 설정(&S) - - - - Select &All - 모두 선택(&A) - - - - &Deselect All - 모두 선택 해제(&D) - - - - &Export selected... - 선택 내보내기(&E) - - - - &Remove selected - 선택 삭제(&R) - - - - &Import files... - 파일 불러오기(&I) - - - - &Open File... - 파일 열기(&O) - - - - - Select &GTA V Folder... - GTA V 폴더 선택(&G) - - - - - - - Select GTA V Folder... - GTA V 폴더 선택 - - - - Show In-gam&e - 인게임 보이기(&E) - - - - Hi&de In-game - 인게임 숨기기(&D) - - - - - - Change &Title... - 제목 변경(&T) - - - - - - Change &Crew... - &조직 상징 변경(&C) - - - - - - &Qualify as Avatar - 아바타 자격 부여(&Q) - - - - - - Change &Players... - 플레이어 변경(&P) - - - - - - Show In-game - 인게임 보이기 - - - - - - Hide In-game - 인게임 숨기기 - - - - - - Select Profile - 프로필 선택 - - - - - &Donate - 기부하기(&D) - - - - Donate - 기부하기 - - - - Donation methods - 기부 방법 - - - View - 보기 - - - Copy - 복사 - - - - &Copy - 복사(&C) - - - - Open File... - 파일 열기... - - - - - - - Open File - 파일 열기 - - - - Can't open %1 because of not valid file format - 올바른 파일 형식이 아니므로 %1을 열 수 없습니다. - - - - %1 - Messages - %1 - 뉴스 - - - diff --git a/res/gta5sync_ru.qm b/res/gta5sync_ru.qm deleted file mode 100644 index 214adf1..0000000 Binary files a/res/gta5sync_ru.qm and /dev/null differ diff --git a/res/gta5sync_ru.ts b/res/gta5sync_ru.ts deleted file mode 100644 index a05570c..0000000 --- a/res/gta5sync_ru.ts +++ /dev/null @@ -1,2584 +0,0 @@ - - - - - AboutDialog - - - About %1 - О программе %1 - - - - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -Version %3<br/> -Created on %4<br/> -Built with Qt %5<br/> -Running with Qt %6<br/> -<br/> -%7 - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -Версия %3<br/> -Сделано %4<br/> -Сделано с Qt %5<br/> -Выполняется на Qt %6<br/> -<br/> -%7 - - - - &Close - &Закрыть - - - - Translated by %1 - Translated by translator, example Translated by Syping - Перевёл %1 - - - - TRANSLATOR - Insert your name here and profile here in following scheme, First Translator,First Profile\nSecond Translator\nThird Translator,Second Profile - VADemon,https://github.com/VADemon/ - - - - A project for viewing Grand Theft Auto V Snapmatic<br/> -Pictures and Savegames - Проект для просмотра Grand Theft Auto V Snapmatic<br/> -картинок и сохранений - - - - Copyright &copy; <a href="%1">%2</a> %3 - Copyright &copy; <a href="%1">%2</a> %3 - - - - %1 is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - %1 под лицензией <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - - - - Release - Релиз - - - - Release Candidate - Предварительный выпуск - - - - Daily Build - Дневная сборка - - - - Developer - Разработчик - - - - Beta - Бета - - - - Alpha - Альфа - - - - - Custom - Не известен контекст - - Своя - - - - CrewDatabase - - - - No Crew - Вне банды - - - - ExportDialog - - - Dialog - Возможно не это имелось ввиду, немецкого перевода нету - - Диалоговое окно - - - - &JPEG/PNG format - Формат &JPEG/PNG - - - - GTA &Snapmatic format - Формат GTA &Snapmatic - - - - Export Format - Формат экспорта - - - - Export Size - Размер экспорта - - - - Default &Size - По &умолчанию - - - - &Desktop Size - Размер рабо&чего стола - - - - &Custom Size - &Другой размер - - - - Custom Size: - Размер: - - - - x - на - - - - &Export - &Экспортировать - - - - &Close - &Закрыть - - - - ImageEditorDialog - - - - - - Snapmatic Image Editor - Редактор картинок Snapmatic - - - - Overwrite Image... - Перезаписать картинку... - - - - Apply changes - Применить изменения - - - - &Overwrite - &Перезаписать - - - - Discard changes - Отменить изменения - - - - &Close - &Закрыть - - - - - Patching of Snapmatic Image failed because of I/O Error - Не удалось изменить картинку Snapmatic из-за ошибки ввода-вывода - - - - - Patching of Snapmatic Image failed because of Image Error - Не удалось изменить картинку Snapmatic из-за ошибки Image Error - - - - ImportDialog - - - Import... - Импортировать... - - - - - Ignore Aspect Ratio - Игнорировать соотн. сторон - - - - Avatar - Аватар - - - - Picture - Картинка - - - - Watermark - Водяной знак - - - Force Borderless - Обрезать рамки - - - - Background - Фон - - - - - - - Background Colour: <span style="color: %1">%1</span> - Цвет фона: <span style="color: %1">%1</span> - - - - Select background colour - Выберите цвет фона - - - ... - ... - - - - Select background image - Выбрать фоновое изображение - - - - Remove background image - Убрать фоновую картинку - - - - Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing - Импортировать как есть, не меняя картинку. Обязательно поломает Snapmatic, если не знаешь, что делаешь - - - - - Background Image: %1 - Фоновая картинка: %1 - - - X - latin X - - X - - - - Crop to Aspect Ratio - Обрезать до соотн. сторон - - - - Force Colour in Avatar Zone - Задать цвет в зоне аватарки - - - - Advanced - Расширенное - - - - Resolution: - Разрешение: - - - - Snapmatic resolution - Разрешение Snapmatic - - - - Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic - Не сжимать, а увеличить буфер. Улучшит качество картинки, но может поломать Snapmatic - - - - Unlimited Buffer - Неограниченный буфер - - - - Import as-is - Импортировать как есть - - - - Import options - Опции импорта - - - - &Options - &Опции - - - - Import picture - Импортировать картинку - - - - &OK - &ОК - - - - Discard picture - Отклонить картинку - - - - &Cancel - Я не уверен насчет горячих клавиш... - - От&мена - - - - - - - Background Image: - Фоновая картинка: - - - - &Import new Picture... - &Импортировать картинку... - - - - &Crop Picture... - Об&резать картинку... - - - - &Load Settings... - &Загрузить настройки... - - - - &Save Settings... - &Сохранить настройки... - - - - - Custom Avatar - Custom Avatar Description in SC, don't use Special Character! - Свой Аватар - - - - - - Custom Picture - Custom Picture Description in SC, don't use Special Character! - Своя Картинка - - - - Storage - Background Image: Storage - Хранилище - - - - Crop Picture... - Обрезать картинку... - - - - &Crop - Об&резать - - - - Crop Picture - Обрезать картинку - - - - - Please import a new picture first - Импортируй сначала новую картинку - - - - - Default - Default as Default Profile - По умолчанию - - - - - - - - - - - - - - - - - - - - - - - Profile %1 - Profile %1 as Profile 1 - Профиль %1 - - - - - Load Settings... - Загрузить настройки... - - - - - Please select your settings profile - Пожалуйста, выбери профиль для настроек - - - - - Save Settings... - Сохранить настройки... - - - - - Are you sure to use a square image outside of the Avatar Zone? -When you want to use it as Avatar the image will be detached! - Ты точно хочешь использовать квадратное изображение вне зоны аватарки? Если это аватар, то изображение будет обрезано! - - - - - Snapmatic Avatar Zone - Зона Snapmatic Аватарки - - - - Select Colour... - Выбрать цвет... - - - - File - Background Image: File - Файл - - - - JsonEditorDialog - - - Snapmatic JSON Editor - Редактор JSON для Snapmatic - - - - Apply changes - Применить изменения - - - - &Save - &Сохранить - - - - Discard changes - Отменить изменения - - - - &Close - &Закрыть - - - - JSON Error - Ошибка JSON - - - - MapLocationDialog - - - Snapmatic Map Viewer - Просмотрщик карты Snapmatic - - - - Close viewer - Закрыть просмотрщик - - - - &Close - &Закрыть - - - - Apply new position - Применить новую позицию - - - - &Apply - &Применить - - - - Revert old position - Вернуть старую позицию - - - - &Revert - &Откатить - - - - Select new position - Выбрать новую позицию - - - - &Select - &Выбрать - - - - Quit select position - Покинуть выбор позиции - - - - &Done - &Готово - - - - X: %1 -Y: %2 - X and Y position - X: %1 -Y: %2 - - - - OptionsDialog - - - Content Open/Select Mode - Открывать/выбирать содержимое - - - Open with Singleclick - Открывать одним щелчком - - - - Open with Doubleclick - Открывать двойным щелчком - - - Select with Singleclick - Выбирать одним щелчком - - - - Default Profile - Профиль по умолчанию - - - - Pictures - Картинки - - - - Export Size - Размер экспорта - - - - Screen Resolution: %1x%2 - Как разрешение экрана: %1x%2 - - - - Default: %1x%2 - По умолчанию: %1x%2 - - - - %1 - Settings - %1 - Настройки - - - - Profiles - Профили - - - - Custom GTA V Folder - Другая папка GTA V - - - - Force using Custom Folder - Использовать эту папку - - - - ... - ... - - - - - Custom Size: - Другой размер: - - - - x - x - - - - Ignore Aspect Ratio - Игнорировать соотношение сторон - - - - Export Quality - Качество экспорта - - - - Enable Custom Quality - Выставить другое качество - - - - Quality: - Качество: - - - - %1% - %1% - - - - Picture Viewer - Просмотрщик картинок - - - - Enable Navigation Bar - Вкл. навигационную панель - - - - Players - Игроки - - - - ID - ID - - - - Name - Имя - - - - Game - Игра - - - - Social Club Version - Версия Social Club - - - - - - - - - - - Found: %1 - Найдено: %1 - - - - - - - - - - - - - Language: %1 - Язык: %1 - - - - Steam Version - Версия Steam - - - - Feedback - Обратная связь - - - - Participation - Участие - - - - - Participate in %1 User Statistics - Участвовать в пользовательской статистике %1 - - - - Categories - Категории - - - - Hardware, Application and OS Specification - Application = gta5view - - Железо, выпуск программы, тип ОС - - - - System Language Configuration - Языковые настройки системы - - - - Application Configuration - Настройки программы - - - - Other - Другое - - - - - - Participation ID: %1 - Номер участника: %1 - - - - &Copy - &Копировать - - - - Language for Areas - Язык для местоположений? - - Язык перевода местоположений - - - - Style - Внешний вид - - - - Style: - Стиль: - - - - Font - Шрифт - - - Always use Message Font (Windows 2003 and earlier) - Всегда использовать шрифт сообщений (Windows 2003 и ранние) - - - - Interface - Интерфейс - - - - Personal Usage Data - Пользование программой - - - - Language for Interface - Язык интерфейса - - - - - - - Current: %1 - Сейчас: %1 - - - - Use Default Style (Restart) - Использовать стандартный стиль (Перезапуск) - - - - Use Default Font (Restart) - Использовать стандартный шрифт (Перезапуск) - - - - Font: - Шрифт: - - - - Apply changes - Применить изменения - - - - &OK - OK, Cancel, Apply - &ОК - - - - Discard changes - Отвергнуть изменения - - - - &Cancel - OK, Cancel, Apply - От&мена - - - - System - System in context of System default - Система - - - - %1 (Game language) - Next closest language compared to the Game settings - %1 (Язык игры) - - - - - %1 (Closest to Interface) - Next closest language compared to the Interface - %1 (Как язык интерфейса) - - - - - - Auto - Automatic language choice. - Автоматически - - - - %1 (Language priority) - First language a person can talk with a different person/application. "Native" or "Not Native". - %1 (Приоритетный язык) - - - - %1 - %1 - %1 - - - - The new Custom Folder will initialise after you restart %1. - Другая папка будет загружена после перезапуска %1. - - - - View %1 User Statistics Online - Посмотреть статистику %1 онлайн - - - - Not registered - Не зарегистрирован - - - - - - - Yes - Да - - - - - No - Нет - - - - - OS defined - Настройка от ОС - - - - - Steam defined - Настройка от Steam - - - - No Profile - No Profile, as default - Не выбран - - - - - - Profile: %1 - Профиль: %1 - - - - PictureDialog - - - <span style="font-weight:600">Title: </span>%6<br/> -<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Created: </span>%8 - <span style="font-weight:600">Заголовок: </span>%6<br/> -<span style="font-weight:600">Место: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Игроки: </span>%4 (Банда %5)<br/> -<span style="font-weight:600">Сделано: </span>%8 - - - - &Manage - &Управление - - - - Manage picture - Настройки картинки - - - - Snapmatic Picture Viewer - %1 - Просмотрщик фотографий Snapmatic - %1 - - - - Close viewer - Закрыть просмотрщик - - - - &Close - &Закрыть - - - - - Export - Экспортировать - - - - - Export as &Picture... - Экспортировать как &картинку... - - - - - Export as &Snapmatic... - Экспортировать как &Snapmatic... - - - - - &Overwrite Image... - &Перезаписать картинку... - - - - - &Edit Properties... - &Изменить свойства... - - - - - Open &Map Viewer... - Открыть &карту... - - - - Key 1 - Avatar Preview Mode -Key 2 - Toggle Overlay -Arrow Keys - Navigate - Клавиша 1 - Режим показа аватарки -Клавиша 2 - Вкл./выкл. оверлей -Стрелки - Навигация - - - - Snapmatic Picture Viewer - Просмотрщик фотографий Snapmatic - - - - Failed at %1 - Ошибка при %1 - - - - - No Crew - Вне банды - - - - - - No Players - Игроков нет - - - - Avatar Preview Mode -Press 1 for Default View - Режим просмотра аватарок -Нажмите 1 для стандартного просмотра - - - - Unknown Location - Неизвестное место - - - - Portable Network Graphics (*.png) - Картинка Portable Network Graphics (*.png) - - - - - Overwrite %1 with current Snapmatic picture? - Перезаписать %1 текущей картинкой Snapmatic? - - - - Export as Picture... - Экспорт как картинку... - - - - JPEG Graphics (*.jpg *.jpeg) - Картинка JPEG (*.jpg *.jpeg) - - - - - - - - - Export as Picture - Экспорт как картинку - - - - Failed to export the picture because the system occurred a write failure - Не удалось экспортировать картинку из-за ошибки системы при записи - - - - Failed to export the picture because the format detection failures - Не удалось экспортировать картинку, потому что произошла ошибка при распозновании формата - - - - Failed to export the picture because the file can't be written - Не удалось экспортировать картинку, так как файл не может быть записан - - - - Failed to export the picture because of an unknown reason - Не удалось экспортировать картинку по неизвестной причине - - - - - Failed to export current Snapmatic picture - Не удалось экспортировать текущую картинку Snapmatic - - - - Export as Snapmatic... - Экспортировать как Snapmatic... - - - - - - - - Export as Snapmatic - Экспортировать как Snapmatic - - - - Exported Snapmatic to "%1" because of using the .auto extension. - Snapmatic был экспортирован как "%1" из-за расширеня файла. - - - - - No valid file is selected - Выбранный файл неверен - - - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - - - - GTA V Raw Export (*.auto) - GTA V Экспорт Исходника (*.auto) - - - - Snapmatic pictures (PGTA*) - Картинки Snapmatic (PGTA*) - - - - - Open &JSON Editor... - Открыть &редактор JSON... - - - - PlayerListDialog - - - Edit Players... - Изменить игроков... - - - - Available Players: - Доступные игроки: - - - - Selected Players: - Выбранные игроки: - - - - &Apply - &Применить - - - - &Cancel - &Отмена - - - - Add Players... - Добавить игроков... - - - - Failed to add more Players because the limit of Players are %1! - Невозможно добавить больше игроков из-за ограничения в %1! - - - - - Add Player... - Добавить игрока... - - - - Enter Social Club Player ID - Введите идентификатор игрока из Social Club - - - - Failed to add Player %1 because Player %1 is already added! - Нельзя повторно добавить игрока %1, %1 уже добавлен! - - - - ProfileInterface - - - Profile Interface - Интерфейс профиля - - - - Loading file %1 of %2 files - Загружается файл %1 из %2 - - - - %1 %2 - %1 %2 - - - - Import file - Импортировать файл - - - - &Import... - &Импортировать... - - - - Close profile - Закрыть профиль - - - - &Close - &Закрыть - - - - Loading... - Загрузка... - - - - Snapmatic Loader - Загрузчик Snapmatic - - - - <h4>Following Snapmatic Pictures got repaired</h4>%1 - Change wording if the %1 is not a multiline beginning at new line - - <h4>Нижеследующие картинки Snapmatic были восстановлены</h4>%1 - - - - - - - - - - - - - - - - - - - - - - Import... - Импортировать... - - - - - - - - - Import - Импортировать - - - - - Savegames files (SGTA*) - Файлы сохранения (SGTA*) - - - - - Snapmatic pictures (PGTA*) - Картинка Snapmatic (PGTA*) - - - - - - - All files (**) - Все файлы (**) - - - - - Import file %1 of %2 files - Импортируются файлы %1 из %2 - - - - Import failed with... - -%1 - Ошибка при импорте... - -%1 - - - - - Failed to read Snapmatic picture - Не удалось загрузить картинку Snapmatic - - - - - Failed to read Savegame file - Не удалось загрузить файл сохранения - - - - - - No valid file is selected - Выбранный файл неверен - - - - Enabled pictures: %1 of %2 - Включенные картинки: %1 из %2 - - - - Importable files (%1) - Файлы для импорта (%1) - - - - - - All image files (%1) - Все файлы изображений (%1) - - - - - - Can't import %1 because file can't be open - Не удалось открыть %1, файл не может быть открыт - - - - - - Can't import %1 because file can't be parsed properly - Не получилось импортировать %1, файл не может быть правильно обработан - - - - Can't import %1 because file format can't be detected - Не получилось импортировать %1, не удалось определить формат файла - - - - Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e - Не удалось импортировать картинку Snapmatic, название не начинается с PGTA или не заканчивается с .g5e - - - - Failed to import the Snapmatic picture, can't copy the file into profile - Не удалось импортировать картинку Snapmatic, не получилось скопировать файл в профиль - - - - Failed to import the Savegame, can't copy the file into profile - Не удалось импортировать сохранение, не получилось скопировать файл в профиль - - - - Failed to import the Savegame, no Savegame slot is left - Не удалось импортировать сохранение, нет пустых ячеек под сохранения - - - - - JPG pictures and GTA Snapmatic - Картинки JPG и GTA Snapmatic - - - - - JPG pictures only - Только картинки JPG - - - - - GTA Snapmatic only - Только GTA Snapmatic - - - - Initialising export... - Подготовка к экспорту... - - - - - No Snapmatic pictures or Savegames files are selected - Не выделен ни один Snapmatic или сохранение - - - - - - Remove selected - Снять выделение - - - - You really want remove the selected Snapmatic picutres and Savegame files? - Точно ли хочешь удалить выбранные картинки Snapmatic и файлы сохранений? - - - - Prepare Content for Import... - Подготовка данных к импорту... - - - - - Qualify as Avatar - Пометить как Аватар - - - - - - - - - No Snapmatic pictures are selected - Не выделена ни одна картинка Snapmatic - - - - - - - Patch selected... - Пропатчить выделенные... - - - - - - - - - - - Patch file %1 of %2 files - Изменяется файл %1 из %2 - - - - - - - - - %1 failed with... - -%2 - Action failed with... - %1 завершился с ошибкой... - -%2 - - - - A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp? - Можно использовать слово "приписать" - - - - - Failed to remove all selected Snapmatic pictures and/or Savegame files - Не удалось удалить все выделенные картинки Snapmatic и/или сохранения - - - - Qualify - %1 failed with... - Помечание - - - - - Change Players... - Изменить игроков... - - - - Change Players - %1 failed with... - Измение игроков - - - - - - Change Crew... - Изменить банду... - - - - Failed to enter a valid Snapmatic Crew ID - Введённый идентификатор банды не верен - - - - Change Crew - %1 failed with... - Изменение банды - - - - - - Change Title... - Изменить заголовок... - - - - Failed to enter a valid Snapmatic title - Введённый заголовок не верен - - - - Change Title - %1 failed with... - Изменение заголовка - - - - %1Export Snapmatic pictures%2<br><br>JPG pictures make it possible to open the picture with a Image Viewer<br>GTA Snapmatic make it possible to import the picture into the game<br><br>Export as: - %1Эскпортировать картинки Snapmatic%2<br><br>Картинки JPG можно открыть любым просмотрщиком<br>Картинки формата GTA Snapmatic можно снова импортировать в игру<br><br>Экспортировать как: - - - - - - - - Export selected... - Экпортировать выделенное... - - - - Export failed with... - -%1 - Экспорт провалился на... - -%1 - - - - - - Export file %1 of %2 files - Экспортируется файл %1 из %2 - - - - All profile files (*.g5e SGTA* PGTA*) - Все файлы профиля (*.g5e SGTA* PGTA*) - - - - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - - - - QApplication - - <h4>Welcome to %1!</h4>You want to configure %1 before you start using it? - <h4>Добро пожаловать в %1!</h4>Хочешь изменить настройки %1 перед использованием? - - - - SavegameDialog - - - - Savegame Viewer - Просмотрщик сохранений - - - - <span style="font-weight:600">Savegame</span><br><br>%1 - <span style="font-weight:600">Сохранение</span><br><br>%1 - - - - &Export - &Экспорт - - - - &Close - &Закрыть - - - - Failed at %1 - Ошибка при %1 - - - - SavegameWidget - - - Savegame Widget - Виджет сохранений - - - - View savegame - Просмотреть сохранение - - - - View - Просмотр - - - - - Export - Экспорт - - - - Delete - Удалить - - - - Delete savegame - Удалить сохранение - - - - Export Savegame... - Экспортировать сохранение... - - - - SAVE %3 - %1<br>%2 - СОХРАНЕНИЕ %3 - %1<br>%2 - - - - - WRONG FORMAT - НЕВЕРНЫЙ ФОРМАТ - - - - - AUTOSAVE - %1 -%2 - АВТОСОХРАНЕНИЕ - %1 -%2 - - - - - SAVE %3 - %1 -%2 - СОХРАНЕНИЕ %3 - %1 -%2 - - - - UNKNOWN - НЕИЗВЕСТНО - - - - Are you sure to delete %1 from your savegames? - Вы уверены, что хотите удалить сохранение %1? - - - - - Delete Savegame - Удалить сохранение - - - - Failed at deleting %1 from your savegames - Не удалось удалить сохранение %1 - - - - &View - &Просмотр - - - - - - &Remove - &Удалить - - - - - &Select - &Выбрать - - - - - &Deselect - Сн&ять выбор - - - - - Select &All - В&ыбрать все - - - - - &Deselect All - Снять выбо&р со всех - - - - Copy savegame - Копировать сохранение - - - - - - &Export - &Экспортировать - - - - Savegame files (SGTA*) - Файлы сохранений (SGTA*) - - - - All files (**) - Все файлы (**) - - - - - - - Export Savegame - Экспортировать сохранение - - - - Overwrite %1 with current Savegame? - Перезаписать %1 текущим сохранением? - - - - Failed to overwrite %1 with current Savegame - Не удалось переписать %1 текущим сохранением - - - - Failed to export current Savegame - Не удалось экспортировать текущее сохранение - - - - No valid file is selected - Выбранный файл неверен - - - - SnapmaticEditor - - - - - - - - - - - Snapmatic Properties - Свойства Snapmatic - - - - Snapmatic Type - Тип Snapmatic - - - - Editor - Редактор - - - - Selfie - Автопортрет - - - - Regular - Обычный - - - - Mugshot - Под арестом - - - - Director - Director - - - - Snapmatic Values - Значения в Snapmatic - - - - Crew: %1 (%2) - Банда: %1 (%2) - - - - Meme - Meme - - - - - Snapmatic Title - Заголовок Snapmatic - - - - Title: %1 (%2) - Заголовок: %1 (%2) - - - - Players: %1 (%2) - Multiple Player are inserted here - Игроки: %1 (%2) - - - - Player: %1 (%2) - One Player is inserted here - Игрок: %1 (%2) - - - - - Appropriate: %1 - Подходит: %1 - - - - Extras - Дополнительно - - - - Qualify as Avatar automatically at apply - Пометить как аватарку - - - - Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture - C меткой аватара можно загрузить эту картинку Snapmatic в профиль на Social Club - - - - Apply changes - Применить изменения - - - - &Apply - &Применить - - - - Discard changes - - - - - &Cancel - &Отмена - - - - - - Edit - Правка - - - - Yes - Yes, should work fine - Да - - - - No - No, could lead to issues - Нет - - - - <h4>Unsaved changes detected</h4>You want to save the JSON content before you quit? - <h4>Несохранённые изменения</h4>Сохранить изменения в JSON перед выходом? - - - - Patching of Snapmatic Properties failed because of %1 - Не удалось изменить свойства Snapmatic из-за %1 - - - - Patching of Snapmatic Properties failed because of JSON Error - Не удалось измененить свойства Snapmatic из-за ошибки JSON - - - - - - - Patching of Snapmatic Properties failed because of I/O Error - Не удалось измененить свойства Snapmatic из-за проблемы ввода/вывода - - - - - New Snapmatic title: - Новый заголовок Snapmatic: - - - - - Snapmatic Crew - Банда на Snapmatic - - - - - New Snapmatic crew: - Новая банда на Snapmatic: - - - - SnapmaticPicture - - - PHOTO - %1 - ФОТО - %1 - - - - open file %1 - Открыть файл %1 - - - - header not exists - Отсутствует шапка (header) - - - - header is malformed - Шапка (header) повреждена - - - - picture not exists (%1) - Картинки не существует (%1) - - - - JSON not exists (%1) - JSON не существует (%1) - - - - title not exists (%1) - Заголовок отсутствует (%1) - - - - description not exists (%1) - Описание отсутствует (%1) - - - - reading file %1 because of %2 - Example for %2: JSON is malformed error - Чтение из файла %1 из-за %2 - - - - - JSON is incomplete and malformed - JSON не полный и повреждён - - - - - JSON is incomplete - JSON частично отсутствует - - - - - JSON is malformed - JSON повреждён - - - - SnapmaticWidget - - - Snapmatic Widget - Виджет Snapmatic - - - - PHOTO - 00/00/00 00:00:00 - ФОТО - 00/00/00 00:00:00 - - - - View picture - Просмотр картинки - - - - View - Просмотр - - - - Copy - Копировать - - - - Export - Экспорт - - - - Delete - Удалить - - - - - - Delete picture - Удалить картинку - - - - Are you sure to delete %1 from your Snapmatic pictures? - Уверены, что хотите удалить %1 из коллекции картинок Snapmatic? - - - - Failed at deleting %1 from your Snapmatic pictures - Не удалось удалить %1 из колелкции картинок Snapmatic - - - - Failed to hide %1 In-game from your Snapmatic pictures - Не удалось скрыть %1 из списка картинок Snapmatic в игре - - - - Failed to show %1 In-game from your Snapmatic pictures - Не удалось показать %1 в списке картинок Snapmatic в игре - - - - - - Edi&t - &Правка - - - - - - Show &In-game - Показывать в &игре - - - - - - Hide &In-game - Ск&рыть в игре - - - - &Export - &Экспорт - - - - &View - По&казать - - - - &Remove - У&далить - - - - - &Select - &Выделить - - - - - &Deselect - Сн&ять выделение - - - - - Select &All - В&ыбрать все - - - - - &Deselect All - Снять выбо&р со всех - - - - Copy picture - Скопировать картинку - - - - Export picture - Экспорт картинки - - - - TelemetryDialog - - - You want help %1 to improve in the future by including personal usage data in your submission? - Разрешишь нам собирать статистику о пользовании тобой %1? Это поможет нам в разработке. - - - - %1 User Statistics - %1 Пользовательская статистика - - - - Yes, I want include personal usage data. - Да, передавать данные о пользовании программой. - - - - &OK - &ОК - - - - UserInterface - - - Select profile - Выбор профиля - - - - %1 %2 - %1 %2 - - - - Reload profile overview - Перезагрузить обзор профилей - - - - Close %1 - Close %1 <- (gta5view/gta5sync) - %1 will be replaced automatically - Закрыть %1 - - - - &File - &Файл - - - - &Help - &Справка - - - - &Edit - &Правка - - - - &Profile - П&рофиль - - - - &Exit - В&ыход - - - - Exit - Выход - - - - Close &Profile - Закрыть п&рофиль - - - - &Settings - &Настройки - - - - &Import files... - &Импортировать файлы... - - - - - Select &GTA V Folder... - Выбрать &папку GTA V... - - - - Show In-gam&e - Показывать в и&гре - - - - Hi&de In-game - Скры&ть в игре - - - - - - Change &Players... - &Изменить игрока... - - - - - - Change &Title... - Изменить &Заголовок... - - - - - - Change &Crew... - Изменить &банду... - - - - - - &Qualify as Avatar - &Пометить как Аватар - - - - - - - &Close - &Закрыть - - - - &Selection visibility - В&идимость выделенного - - - - Selection &mass tools - Инструменты &массовой выборки - - - - Select &All - В&ыбрать все - - - - &Deselect All - Снять выбо&р со всех - - - - &Export selected... - &Экпортировать выделенное... - - - - &Remove selected - &Удалить выделенное - - - - &Open File... - &Открыть файл... - - - - - - Select Profile - Выбор профиля - - - - - - - Select GTA V Folder... - Выбрать папку GTA V... - - - - - %2 - %1 - %2 - %1 - - - - - - &About %1 - &О программе %1 - - - - - &Donate - По&жертвовать - - - - Donate - Пожертвовать - - - - Donation methods - Способы для взноса - - - - &Copy - &Копировать - - - View - Просмотр - - - Copy - Копировать - - - - Open File... - Открыть файл... - - - - - - - Open File - Открыть файл - - - - Can't open %1 because of not valid file format - Не удалось открыть %1 из-за неверного формата файла - - - - %1 - Messages - %1 - Новости - - - - &Reload - Пере&загрузить - - - - - - Show In-game - Показывать в игре - - - - - - Hide In-game - Скрыть в игре - - - diff --git a/res/gta5sync_uk.qm b/res/gta5sync_uk.qm deleted file mode 100644 index 07fed50..0000000 Binary files a/res/gta5sync_uk.qm and /dev/null differ diff --git a/res/gta5sync_uk.ts b/res/gta5sync_uk.ts deleted file mode 100644 index c49c9ce..0000000 --- a/res/gta5sync_uk.ts +++ /dev/null @@ -1,2583 +0,0 @@ - - - - - AboutDialog - - - About %1 - Про %1 - - - - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -Version %3<br/> -Created on %4<br/> -Built with Qt %5<br/> -Running with Qt %6<br/> -<br/> -%7 - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -Версія %3<br/> -Створено %4<br/> -Побудовано з Qt %5<br/> -Виконується на Qt %6<br/> -<br/> -%7 - - - - &Close - &Закрити - - - - Translated by %1 - Translated by translator, example Translated by Syping - Переклад %1 - - - - TRANSLATOR - Insert your name here and profile here in following scheme, First Translator,First Profile\nSecond Translator\nThird Translator,Second Profile - PROFessoR 'AppleSOft',https://steamcommunity.com/id/AppleSOft -VenJam1n,https://socialclub.rockstargames.com/member/--VenJam1n-- -twitter,https://twitter.com/_VenJam1n - VenJam1n,g5e://about?VmVuSmFtMW4:U3RlYW06IDxhIGhyZWY9Imh0dHBzOi8vc3RlYW1jb21tdW5pdHkuY29tL3Byb2ZpbGVzLzc2NTYxMTk3OTg0NjM1ODE2LyI+UFJPRmVzc29SICdBcHBsZVNPZnQnPC9hPjxici8+U29jaWFsIENsdWI6IDxhIGhyZWY9Imh0dHBzOi8vc29jaWFsY2x1Yi5yb2Nrc3RhcmdhbWVzLmNvbS9tZW1iZXIvLS1WZW5KYW0xbi0tLzU2Mzc1NjkiPlZlbkphbTFuPC9hPjxici8+VHdpdHRlcjogPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9fVmVuSmFtMW4iPlZlbkphbTFuPC9hPjxici8+PGJyLz7Qn9C+0LbQtdGA0YLQstGD0LLQsNC90L3Rjzxici8+PGEgaHJlZj0iaHR0cHM6Ly9zdGVhbWNvbW11bml0eS5jb20vdHJhZGVvZmZlci9uZXc/cGFydG5lcj0yNDM3MDA4OCZ0b2tlbj1HSW16XzhRSyI+U3RlYW0gVHJhZGU8L2E - - - - A project for viewing Grand Theft Auto V Snapmatic<br/> -Pictures and Savegames - Проект для перегляду Grand Theft Auto V Snapmatic<br/> -зображень та сейвів - - - - Copyright &copy; <a href="%1">%2</a> %3 - Авторське право &copy; <a href="%1">%2</a> %3 - - - - %1 is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - %1 ліцензовано під <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - - - - Release - Реліз - - - - Release Candidate - Реліз-Кандидат - - - - Daily Build - Щоденна Збірка - - - - Developer - Розробник - - - - Beta - Бета - - - - Alpha - Альфа - - - - - Custom - Custom - - - - CrewDatabase - - - - No Crew - Без банди - - - - ExportDialog - - - Dialog - Діалог - - - - Export Format - Формат експорту - - - - &JPEG/PNG format - &JPEG/PNG формат - - - - GTA &Snapmatic format - GTA &Snapmatic формат - - - - Export Size - Експортувати розміром - - - - Default &Size - Стандартний &розмір - - - - &Desktop Size - &Розмір робочого столу - - - - &Custom Size - &Користувацький розмір - - - - Custom Size: - Користувацький розмір: - - - - x - x - - - - &Export - &Експорт - - - - &Close - &Закрити - - - - ImageEditorDialog - - - Overwrite Image... - Перезаписати зображення... - - - - Apply changes - Застосувати зміни - - - - &Overwrite - &Перезаписати - - - - Discard changes - Скасувати зміни - - - - &Close - &Закрити - - - - - - - Snapmatic Image Editor - Редактор Snapmatic зображень - - - - - Patching of Snapmatic Image failed because of I/O Error - Виправлення Snapmatic зображення не вдалося через I/O Error - - - - - Patching of Snapmatic Image failed because of Image Error - Виправлення Snapmatic зображення не вдалося через помилку картинки - - - - ImportDialog - - - Import... - Імпорт... - - - - Picture - Зображення - - - - Avatar - Аватар - - - - - Ignore Aspect Ratio - Ігнорувати співвідношення сторін - - - - Watermark - Водяний знак - - - Force Borderless - Примусово без рамок - - - - Background - Фон - - - - - - - Background Colour: <span style="color: %1">%1</span> - Фоновий колір: <span style="color: %1">%1</span> - - - - Select background colour - Виберіть колір фону - - - ... - ... - - - - - - - Background Image: - Фонове зображення: - - - - Select background image - Виберіть фонове зображення - - - - Remove background image - Видалити фонове зображення - - - X - Х - - - - Crop to Aspect Ratio - Обрізати під співвідношення сторін - - - - Force Colour in Avatar Zone - Примусовий колір в зоні Аватару - - - - Advanced - Додатково - - - - Resolution: - Розширення: - - - - Snapmatic resolution - Розширення Snapmatic - - - - Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic - Не стискати, а збільшити буфер. Поліпшить якість картинки, але може поламати Snapmatic - - - - Unlimited Buffer - Необмежений буфер - - - - Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing - Імпортуати як є, взагалі не змінюється зображення, гарантовано зламається Snapmatic, тільки якщо не знаєте, що робите - - - - Import as-is - Імпортувати як є - - - - Import options - Параметри імпорту - - - - &Options - &Параметри - - - - Import picture - Імпортувати зображення - - - - &OK - &OK - - - - Discard picture - Відхилити зображення - - - - &Cancel - &Скасувати - - - - &Import new Picture... - &Імпортувати нове зображення... - - - - &Crop Picture... - &Обрізати зображення... - - - - &Load Settings... - &Завантажити параметри... - - - - &Save Settings... - &Зберегти параметри... - - - - - Custom Avatar - Custom Avatar Description in SC, don't use Special Character! - Користувацький Аватар - - - - - - Custom Picture - Custom Picture Description in SC, don't use Special Character! - Користувацьке Зображення - - - - Storage - Background Image: Storage - Зберігання - - - - Crop Picture... - Обрізати зображення... - - - - &Crop - &Обрізати - - - - Crop Picture - Обрізати зображення - - - - - Please import a new picture first - Спершу імпортуйте нове зображення - - - - - Default - Default as Default Profile - Стандартний - - - - - - - - - - - - - - - - - - - - - - - Profile %1 - Profile %1 as Profile 1 - Профіль %1 - - - - - Load Settings... - Завантажити параметри... - - - - - Save Settings... - Зберегти параметри... - - - - - Snapmatic Avatar Zone - Зона Snapmatic Аватару - - - - - Are you sure to use a square image outside of the Avatar Zone? -When you want to use it as Avatar the image will be detached! - Ви впевнені, що будете використовувати квадратне зображення поза зоною аватара? -Якщо ви хочете використовувати його як Аватар, зображення буде відокремлено! - - - - Select Colour... - Вибір кольору... - - - - - Background Image: %1 - Фонове зображення: %1 - - - - - Please select your settings profile - Будь ласка, виберіть свій профіль налаштувань - - - - File - Background Image: File - Файл - - - - JsonEditorDialog - - - Snapmatic JSON Editor - JSON редактор Snapmatic - - - - Apply changes - Застосувати зміни - - - - &Save - &Зберегти - - - - Discard changes - Скасувати зміни - - - - &Close - &Закрити - - - - JSON Error - JSON помилка - - - - MapLocationDialog - - - Snapmatic Map Viewer - Перегляд карти Snapmatic - - - - Close viewer - Закрити переглядач - - - - &Close - &Закрити - - - - Apply new position - Застосувати нову позицію - - - - &Apply - &Застосувати - - - - Revert old position - Повернути стару позицію - - - - &Revert - &Повернути - - - - Select new position - Виберіть нову позицію - - - - &Select - &Виділення - - - - Quit select position - Вийти з вибору позиції - - - - &Done - &Готово - - - - X: %1 -Y: %2 - X and Y position - X: %1 -Y: %2 - - - - OptionsDialog - - - %1 - Settings - %1 - Налаштування - - - - Profiles - Профілі - - - - Content Open/Select Mode - Відкривати/обирати вміст - - - Open with Singleclick - Відкривати одиночним кліком - - - - Open with Doubleclick - Відкривати подвійним кліком - - - Select with Singleclick - Обирати одиночним кліком - - - - Default Profile - Типовий профіль - - - - Custom GTA V Folder - Користувацька GTA V тека - - - - Force using Custom Folder - Використовувати цю теку GTA V - - - - ... - ... - - - - Pictures - Зображення - - - - Export Size - Розмір при експорті - - - - Default: %1x%2 - Стандартно: %1x%2 - - - - Screen Resolution: %1x%2 - Розширення дисплея: %1x%2 - - - - - Custom Size: - Користувацький розмір: - - - - x - x - - - - Ignore Aspect Ratio - Ігнорувати співвідношення сторін - - - - Export Quality - Якість при експорті - - - - Enable Custom Quality - Увімкнути користувацьку якість - - - - Quality: - Якість: - - - - %1% - %1% - - - - Picture Viewer - Переглядач зображень - - - - Enable Navigation Bar - Увімкнути навігаціїйну панель - - - - Players - Гравці - - - - ID - ID - - - - Name - Ім'я - - - - Game - Гра - - - - Social Club Version - Social Club версія - - - - - - - - - - - Found: %1 - Знайдено:%1 - - - - - - - - - - - - - Language: %1 - Мова: %1 - - - - Steam Version - Steam версія - Steam Version - - - - Feedback - Опитування - - - - Participation - Участь - - - - - Participate in %1 User Statistics - Опитування %1 про устаткування ПК - - - - Categories - Категорії - - - - Hardware, Application and OS Specification - Обладнання, випуск програми, специфікації ОС - - - - System Language Configuration - Мовні налаштування системи - - - - Application Configuration - Налаштування програми - - - - Personal Usage Data - Особисті дані використання - - - - Other - Інше - - - - - - Participation ID: %1 - ID учасника : %1 - - - - &Copy - &Копіювати - - - - Interface - Інтерфейс - - - - Language for Interface - Мова інтерфейсу - - - - - - - Current: %1 - Зараз: %1 - - - - Language for Areas - Мова перекладу розташування - - - - Style - Стиль - - - - Use Default Style (Restart) - Використовувати стандартний стиль (Перезапуск) - - - - Style: - Стиль: - - - - Font - Шрифт - - - - Use Default Font (Restart) - Використовувати стандартний шрифт (Перезапуск) - - - - Font: - Шрифт: - - - Always use Message Font (Windows 2003 and earlier) - Завжди використовуйте шрифт повідомлень (Windows 2003 і раніше) - - - - Apply changes - Застосувати зміни - - - - &OK - OK, Cancel, Apply - &OK - - - - Discard changes - Скасувати зміни - - - - &Cancel - OK, Cancel, Apply - &Скасувати - - - - System - System in context of System default - Як у системи - - - - %1 (Game language) - Next closest language compared to the Game settings - %1 (Мова гри) - - - - - %1 (Closest to Interface) - Next closest language compared to the Interface - %1 (Співпадає з інтерфейсом) - - - - - - Auto - Automatic language choice. - Автоматично - - - - %1 (Language priority) - First language a person can talk with a different person/application. "Native" or "Not Native". - %1 (пріоритет мови) - - - - %1 - %1 - %1 - - - - The new Custom Folder will initialise after you restart %1. - Нова користувацька папка буде ініціалізована після перезапуску %1. - - - - No Profile - No Profile, as default - Жодного - - - - - - Profile: %1 - Профіль: %1 - - - - View %1 User Statistics Online - Переглянути користувацьку статистику %1 онлайн - - - - Not registered - Не зареєстрований - - - - - - - Yes - Так - - - - - No - Ні - - - - - OS defined - Визначається ОС - - - - - Steam defined - Визначається Steam - - - - PictureDialog - - - Snapmatic Picture Viewer - %1 - Переглядач зображень Snapmatic - %1 - - - - <span style="font-weight:600">Title: </span>%6<br/> -<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Created: </span>%8 - <span style="font-weight:600">Назва: </span>%6<br/> -<span style="font-weight:600">Розташування: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Гравці: </span>%4 (Банда %5)<br/> -<span style="font-weight:600">Створено: </span>%8 - - - - Manage picture - Керування зображенням - - - - &Manage - &Керувати - - - - Close viewer - Закрити переглядач - - - - &Close - &Закрити - - - - - Export as &Picture... - Експортувати як &зображення... - - - - - Export as &Snapmatic... - Експортувати як &Snapmatic... - - - - - &Edit Properties... - &Змінити властивості... - - - - - &Overwrite Image... - &Перезаписати зображення... - - - - - Open &Map Viewer... - Відкрити &карту... - - - - - Open &JSON Editor... - Відкрити редактор &JSON... - - - - Key 1 - Avatar Preview Mode -Key 2 - Toggle Overlay -Arrow Keys - Navigate - Клавіша 1 - Режим показу аватарки -Клавіша 2 - Вкл./Викл. Оверлей -Стрілки - Навігація - - - - Snapmatic Picture Viewer - Переглядач фотографій Snapmatic - - - - Failed at %1 - Помилка на%1 - - - - - - No Players - Гравців немає - - - - - No Crew - Банди немає - - - - Unknown Location - Невідома локація - - - - Avatar Preview Mode -Press 1 for Default View - Режим для аватарок -Натисніть 1 для стандартного перегляду - - - - Export as Picture... - Експортувати як зображення... - - - - - Export - Експорт - - - - JPEG Graphics (*.jpg *.jpeg) - JPEG Graphics (*.jpg *.jpeg) - - - - Portable Network Graphics (*.png) - Portable Network Graphics (*.png) - - - - - - - - - Export as Picture - Експортувати як зображення - - - - - Overwrite %1 with current Snapmatic picture? - Перезаписати %1 поточним Snapmatic зображенням? - - - - Failed to export the picture because the system occurred a write failure - Не вдалося експортувати зображення, оскільки в системі виникла помилка запису - - - - Failed to export the picture because the format detection failures - Не вдалося експортувати зображення через помилки виявлення формату - - - - Failed to export the picture because the file can't be written - Не вдалося експортувати зображення, оскільки файл не може бути записаний - - - - Failed to export the picture because of an unknown reason - Не вдалося експортувати зображення через невідому причину - - - - - No valid file is selected - Вибрано невірний файл - - - - Export as Snapmatic... - Експортувати як Snapmatic... - - - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - - - - GTA V Raw Export (*.auto) - GTA V RAW-експорт (*.auto) - - - - Snapmatic pictures (PGTA*) - Snapmatic картинки (PGTA*) - - - - - - - - Export as Snapmatic - Експортувати як Snapmatic - - - - - Failed to export current Snapmatic picture - Не вдалося експортувати поточну фотографію Snapmatic - - - - Exported Snapmatic to "%1" because of using the .auto extension. - Експортується Snapmatic до "%1" через використання .auto розширення. - - - - PlayerListDialog - - - Edit Players... - Редагувати гравців... - - - - Available Players: - Доступні гравці: - - - - Selected Players: - Вибрані гравці: - - - - &Apply - &Застосувати - - - - &Cancel - &Скасувати - - - - Add Players... - Додати гравців... - - - - Failed to add more Players because the limit of Players are %1! - Не вдалося додати більше гравців, бо ліміт %1! - - - - - Add Player... - Додати гравця... - - - - Enter Social Club Player ID - Введіть ID гравця Social Club - - - - Failed to add Player %1 because Player %1 is already added! - Не вдалося додати гравця %1, оскільки %1 вже доданий! - - - - ProfileInterface - - - Profile Interface - Інтерфейс профілю - - - - Loading file %1 of %2 files - Завантаження файлу %1 з %2 файлів - - - - %1 %2 - %1 %2 - - - - Import file - Імпортувати файл - - - - &Import... - &Імпортувати... - - - - Close profile - Закрити профіль - - - - &Close - &Закрити - - - - - - Export file %1 of %2 files - Експортується файл %1 з %2 файлів - - - - - - - - - - - - - - - - - - - - - - Import... - Імпортування... - - - - - - - - - Import - Імпорт - - - - - - All image files (%1) - Файли зображень (%1) - - - - - - - All files (**) - Усі файли (**) - - - - - - Can't import %1 because file can't be open - Неможливо імпортувати %1, оскільки файл не може бути відкритий - - - - - - Can't import %1 because file can't be parsed properly - Неможливо імпортувати %1, оскільки файл неможливо розібрати правильно - - - - Enabled pictures: %1 of %2 - Увімкнено фотографії:%1 з%2 - - - - Loading... - Завантаження... - - - - Snapmatic Loader - Snapmatic Loader - - - - <h4>Following Snapmatic Pictures got repaired</h4>%1 - <h4>Наступні Snapmatic зображення були відновлені</h4>%1 - - - - Importable files (%1) - Імпортуються файли (%1) - - - - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - - - - - Savegames files (SGTA*) - Файли збереження гри (SGTA*) - - - - - Snapmatic pictures (PGTA*) - Snapmatic зображення (PGTA*) - - - - - - No valid file is selected - Вибрані недійсні файли - - - - - Import file %1 of %2 files - Імпортується файл %1 з %2 файлів - - - - Import failed with... - -%1 - Не вдалося імпортувати тому що... - -%1 - - - - - Failed to read Snapmatic picture - Не вдалося прочитати Snapmatic картинку - - - - - Failed to read Savegame file - Не вдалося прочитати файл збереження гри - - - - Can't import %1 because file format can't be detected - Неможливо імпортувати%1, оскільки формат файлу не може бути виявлений - - - - Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e - Не вдалося імпортувати зображення Snapmatic, файл не починається з PGTA або закінчується .g5e - - - - Failed to import the Snapmatic picture, can't copy the file into profile - Не вдалося імпортувати зображення Snapmatic, не можна скопіювати файл у профіль - - - - Failed to import the Savegame, can't copy the file into profile - Не вдалося імпортувати Сейв, не можна скопіювати файл у профіль - - - - Failed to import the Savegame, no Savegame slot is left - Не вдалося імпортувати Сейв, немає вільного слота - - - - - - - - Export selected... - Експорт обраних... - - - - - JPG pictures and GTA Snapmatic - JPG картинки і GTA Snapmatic - - - - - JPG pictures only - Тільки JPG картинки - - - - - GTA Snapmatic only - Тільки GTA Snapmatic - - - - %1Export Snapmatic pictures%2<br><br>JPG pictures make it possible to open the picture with a Image Viewer<br>GTA Snapmatic make it possible to import the picture into the game<br><br>Export as: - %1 Експортувати Snapmatic фотографії %2 <br><br> Фотографії JPG дозволяють відкривати зображення за допомогою засобу перегляду зображень<br>GTA Snapmatic дає змогу імпортувати зображення в гру<br><br>Експортувати як: - - - - Initialising export... - Ініціалізація експорту... - - - - Export failed with... - -%1 - Експортувати не вдалося тому що... - -%1 - - - - - No Snapmatic pictures or Savegames files are selected - Не вибрано жодного Snapmatic зображення або файлу збереження - - - - - - Remove selected - Видалити вибрані - - - - You really want remove the selected Snapmatic picutres and Savegame files? - Ви дійсно хочете видалити вибрані Snapmatic фотографії та файли збереження гри? - - - - Failed to remove all selected Snapmatic pictures and/or Savegame files - Не вдалося видалити всі обрані Snapmatic фотографії та/або Сейви - - - - - - - - - No Snapmatic pictures are selected - Не вибрано жодного Snapmatic зображення - - - - - - - - - %1 failed with... - -%2 - Action failed with... - %1 не вдалося з... - -%2 - - - - Prepare Content for Import... - Підготувати контент для імпорту ... - - - - A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp? - Snapmatic зображення з uid %1 вже існує, ви хочете призначити для імпорту новий uid та мітку часу? - - - - - Qualify as Avatar - Позначити як Аватар - - - - - - - Patch selected... - Вибір патчу... - - - - - - - - - - - Patch file %1 of %2 files - Патч файлу %1 з %2 файлів - - - - Qualify - %1 failed with... - Якість - - - - - Change Players... - Зміна гравців... - - - - Change Players - %1 failed with... - Змінити гравців - - - - - - Change Crew... - Зміна банди... - - - - Failed to enter a valid Snapmatic Crew ID - Не вдалося ввести дійсний ID Банди Snapmatic - - - - Change Crew - %1 failed with... - Змінити банду - - - - - - Change Title... - Зміна назви... - - - - Failed to enter a valid Snapmatic title - Не вдалося ввести дійсний заголовок Snapmatic - - - - Change Title - %1 failed with... - Змінити назву - - - - All profile files (*.g5e SGTA* PGTA*) - Усі файли зображень (*.g5e SGTA* PGTA*) - - - - QApplication - - Font - Шрифт - - - Selected Font: %1 - Вибраний шрифт:%1 - - - <h4>Welcome to %1!</h4>You want to configure %1 before you start using it? - <h4>Ласкаво просимо до %1!</h4>Ви хочете налаштувати %1 перед використанням? - - - - SavegameDialog - - - - Savegame Viewer - Перегляд файлів збереження гри - - - - <span style="font-weight:600">Savegame</span><br><br>%1 - <span style="font-weight:600">Ігрове збереження</span><br><br>%1 - - - - &Export - &Експорт - - - - &Close - &Закрити - - - - Failed at %1 - Помилка на %1 - - - - SavegameWidget - - - Savegame Widget - Віджет збереження гри - - - - SAVE %3 - %1<br>%2 - ЗБЕРЕЖЕННЯ %3 - %1<br>%2 - - - - View savegame - Переглянути ігрове збереження - - - - View - Перегляд - - - - Copy savegame - Скопіювати файл збереження - - - - - Export - Експорт - - - - Delete savegame - Видалити сейв - - - - Delete - Видалити - - - - &View - &Перегляд - - - - - - &Export - &Експорт - - - - - - &Remove - &Видалення - - - - - &Select - &Виділення - - - - - &Deselect - &Зняти виділення - - - - - Select &All - Вибрати &усі - - - - - &Deselect All - &Зняти виділення усіх - - - - Savegame files (SGTA*) - Файли збереження гри (SGTA*) - - - - All files (**) - Усі файли (**) - - - - - - - Export Savegame - Експорт файлу збереження - - - - Overwrite %1 with current Savegame? - Перезаписати %1 поточним ігровим збереженням? - - - - Failed to overwrite %1 with current Savegame - Не вдалося перезаписати %1 поточним збереженням гри - - - - Failed to export current Savegame - Не вдалося експортувати поточне ігрове збереження - - - - No valid file is selected - Вибрано невірний файл - - - - Export Savegame... - Експортування файлу збереження... - - - - - AUTOSAVE - %1 -%2 - АВТОМАТИЧНЕ ЗБЕРЕЖЕННЯ - %1 -%2 - - - - - SAVE %3 - %1 -%2 - ЗБЕРЕЖЕННЯ %3 - %1 -%2 - - - - - WRONG FORMAT - НЕПРАВИЛЬНИЙ ФОРМАТ - - - - UNKNOWN - НЕВІДОМИЙ - - - - - Delete Savegame - Видалити файл збереження - - - - Are you sure to delete %1 from your savegames? - Ви впевнені, що хочете видалити %1 зі своїх сейвів? - - - - Failed at deleting %1 from your savegames - Не вдалося видалити %1 із ваших збережених ігор - - - - SnapmaticEditor - - - - - - - - - - - Snapmatic Properties - Властивості Snapmatic - - - - Snapmatic Type - Тип Snapmatic - - - - Editor - Редактор - - - - Selfie - Автопортрет - - - - Regular - Звичайний - - - - Mugshot - Кухоль постріл - - - - Meme - Мем - - - - Director - Режисер - - - - Snapmatic Values - Значення в Snapmatic - - - - Extras - Додатково - - - - Qualify as Avatar automatically at apply - При застосуванні налаштувань помітити як Аватар - - - - Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture - З міткою як Аватар можливо завантажити це зображення Snapmatic в профіль Social Club - - - - Apply changes - Застосувати зміни - - - - &Apply - &Застосувати - - - - Discard changes - Скасувати зміни - - - - &Cancel - &Скасувати - - - - <h4>Unsaved changes detected</h4>You want to save the JSON content before you quit? - <h4> Виявлені незбережені зміни </h4> Ви хочете зберегти вміст JSON перед тим, як вийти? - - - - Patching of Snapmatic Properties failed because of %1 - Змінити властивості Snapmatic не вдалося тому що%1 - - - - - - - Patching of Snapmatic Properties failed because of I/O Error - Змінити властивості Snapmatic не вдалося через I/O Помилку - - - - Patching of Snapmatic Properties failed because of JSON Error - Змінити властивості Snapmatic не вдалося через JSON Помилку - - - - - Snapmatic Crew - Snapmatic банда - - - - - New Snapmatic crew: - Нова Snapmatic банда: - - - - - Snapmatic Title - Snapmatic назва - - - - - New Snapmatic title: - Новий Snapmatic заголовок: - - - - - - Edit - Правка - - - - Players: %1 (%2) - Multiple Player are inserted here - Гравці: %1 (%2) - - - - Player: %1 (%2) - One Player is inserted here - Гравець: %1 (%2) - - - - Title: %1 (%2) - Назва: %1 (%2) - - - - - Appropriate: %1 - Підходить: %1 - - - - Yes - Yes, should work fine - Так - - - - No - No, could lead to issues - Ні - - - - Crew: %1 (%2) - Банда: %1 (%2) - - - - SnapmaticPicture - - - - JSON is incomplete and malformed - JSON неповний та неправильний - - - - - JSON is incomplete - JSON неповний - - - - - JSON is malformed - JSON неправильний - - - - PHOTO - %1 - ФОТО - %1 - - - - open file %1 - відкрити файл%1 - - - - header not exists - заголовок не існує - - - - header is malformed - заголовок неправильний - - - - picture not exists (%1) - зображення не існує (%1) - - - - JSON not exists (%1) - JSON не існує (%1) - - - - title not exists (%1) - заголовок не існує (%1) - - - - description not exists (%1) - опис не існує (%1) - - - - reading file %1 because of %2 - Example for %2: JSON is malformed error - читання файлу %1 тому що %2 - - - - SnapmaticWidget - - - Snapmatic Widget - Віджет Snapmatic - - - - PHOTO - 00/00/00 00:00:00 - ФОТО - 00/00/00 00:00:00 - - - - View picture - Переглянути зображення - - - - View - Перегляд - - - - Copy picture - Копіювати фото - - - - Copy - Копіювати - - - - Export picture - Експорт фото - - - - Export - Експорт - - - - - - Delete picture - Видалити фото - - - - Delete - Видалити - - - - - - Edi&t - Редагува&ти - - - - - - Show &In-game - Показати &у грі - - - - - - Hide &In-game - Сховати &у грі - - - - &Export - &Експортувати - - - - &View - &Переглянути - - - - &Remove - &Видалити - - - - - &Select - &Виділення - - - - - &Deselect - &Зняти виділення - - - - - Select &All - Вибрати &усі - - - - - &Deselect All - &Зняти виділення усіх - - - - Are you sure to delete %1 from your Snapmatic pictures? - Ви дійсно бажаєте видалити %1 з ваших Snapmatic фотографій? - - - - Failed at deleting %1 from your Snapmatic pictures - Не вдалося видалити%1 з ваших Snapmatic фотографій - - - - Failed to hide %1 In-game from your Snapmatic pictures - Не вдалося сховати %1 Snapmatic у грі - - - - Failed to show %1 In-game from your Snapmatic pictures - Не вдалося показати %1 Snapmatic у грі - - - - TelemetryDialog - - - You want help %1 to improve in the future by including personal usage data in your submission? - Ви хочете допомогти %1 покращитись у майбутньому, включивши дані особистого користування? - - - - %1 User Statistics - %1 Статистика користувачів - - - - Yes, I want include personal usage data. - Так, я хочу включити дані особистого користування. - - - - &OK - &OK - &OK - - - - UserInterface - - - - %2 - %1 - %2 - %1 - - - - Select profile - Виберіть профіль - - - - %1 %2 - %1 %2 - - - - Reload profile overview - Перезавантажити огляд профілю - - - - &Reload - &Перезавантажити - - - - Close %1 - Close %1 <- (gta5view/gta5sync) - %1 will be replaced automatically - Закрити %1 - - - - - - - &Close - &Закрити - - - - &File - &Файл - - - - &Help - &Справка - - - - &Edit - &Правка - - - - &Profile - &Профіль - - - - &Selection visibility - &Вибір видимості - - - - Selection &mass tools - Інструменти &масової вибірки - - - - - - &About %1 - &Про %1 - - - - &Exit - &Вихід - - - - Exit - Вихід - - - - Close &Profile - Закрити &профіль - - - - &Settings - &Налаштування - - - - Select &All - Вибрати &все - - - - &Deselect All - &Скасувати вибір усіх - - - - &Export selected... - &Експорт вибраного... - - - - &Remove selected - &Видалити вибране - - - - &Import files... - &Імпорт файлів... - - - - &Open File... - &Відкрити файл... - - - - - Select &GTA V Folder... - Вибрати &GTA V теку... - - - - - - - Select GTA V Folder... - Вибрати GTA V теку... - - - - Show In-gam&e - &Показати у грі - - - - Hi&de In-game - &Приховати у грі - - - - - - Change &Title... - Змінити &заголовок... - - - - - - Change &Crew... - Змінити &банду... - - - - - - &Qualify as Avatar - Позначити як &аватар - - - - - - Change &Players... - Змінити &гравців... - - - - - - Show In-game - Показати у грі - - - - - - Hide In-game - Сховати у грі - - - - - - Select Profile - Вибрати профіль - - - - - &Donate - &Пожертвування - - - - Donate - Пожертвування - - - - Donation methods - Метод пожертвування - - - View - Перегляд - - - Copy - Копіювати - - - - &Copy - &Копіювати - - - - Open File... - Відкрити файл... - - - - - - - Open File - Відкрити файл - - - - Can't open %1 because of not valid file format - Неможливо відкрити %1 через невідомий формат файлу - - - - %1 - Messages - %1 - Новини - - - diff --git a/res/gta5sync_zh_TW.qm b/res/gta5sync_zh_TW.qm deleted file mode 100644 index d4eb70d..0000000 Binary files a/res/gta5sync_zh_TW.qm and /dev/null differ diff --git a/res/gta5sync_zh_TW.ts b/res/gta5sync_zh_TW.ts deleted file mode 100644 index fb4d4bc..0000000 --- a/res/gta5sync_zh_TW.ts +++ /dev/null @@ -1,2564 +0,0 @@ - - - - - AboutDialog - - - About %1 - 關於 %1 - - - - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -Version %3<br/> -Created on %4<br/> -Built with Qt %5<br/> -Running with Qt %6<br/> -<br/> -%7 - <span style="font-weight:600">%1</span><br/> -<br/> -%2<br/> -<br/> -版本:%3<br/> -建置於 %4<br/> -使用 Qt %5 建置<br/> -使用 Qt %6 執行<br/> -<br/> -%7 - - - - &Close - 關閉(&C) - - - - Translated by %1 - Translated by translator, example Translated by Syping - 繁體中文化: %1 - - - - TRANSLATOR - Insert your name here and profile here in following scheme, First Translator,First Profile\nSecond Translator\nThird Translator,Second Profile - Ray,https://steamcommunity.com/profiles/76561198282701714/ - - - - A project for viewing Grand Theft Auto V Snapmatic<br/> -Pictures and Savegames - 一個 Grand Theft Auto V Snapmatic 圖片、遊戲存檔檢視專案 - - - - Copyright &copy; <a href="%1">%2</a> %3 - 版權 &copy; <a href="%1">%2</a> %3 - - - - %1 is licensed under <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> - %1 使用 <a href="https://www.gnu.org/licenses/gpl-3.0.html#content">GNU GPLv3</a> 授權條款發布 - - - - Release - 正式版本 - - - - Release Candidate - 最終測試版本 - - - - Daily Build - 每日建置版本 - - - - Developer - 開發版本 - - - - Beta - Beta 版本 - - - - Alpha - Alpha 版本 - - - - - Custom - 自訂 - - - - CrewDatabase - - - - No Crew - - - - - ExportDialog - - - Dialog - 對話 - - - - Export Format - 匯出格式 - - - - &JPEG/PNG format - JPEG/PNG 格式(&J) - - - - GTA &Snapmatic format - GTA Snapmatic 格式(&S) - - - - Export Size - 匯出尺寸 - - - - Default &Size - 預設(&S) - - - - &Desktop Size - 桌面尺寸(&D) - - - - &Custom Size - 自訂尺寸(&C) - - - - Custom Size: - 自訂尺寸: - - - - x - x - - - - &Export - 匯出(&E) - - - - &Close - 關閉(&C) - - - - ImageEditorDialog - - - Overwrite Image... - 修改圖片... - - - - Apply changes - 套用變更 - - - - &Overwrite - 修改(&O) - - - - Discard changes - 捨棄變更 - - - - &Close - 關閉(&C) - - - - - - - Snapmatic Image Editor - Snapmatic 圖片編輯器 - - - - - Patching of Snapmatic Image failed because of I/O Error - I/O 錯誤,Snapmatic 圖片更新失敗 - - - - - Patching of Snapmatic Image failed because of Image Error - 圖片錯誤,Snapmatic 圖片更新失敗 - - - - ImportDialog - - - Import... - 匯入... - - - - Picture - 圖片 - - - - Avatar - 大頭貼 - - - - - Ignore Aspect Ratio - 忽略長寬比 - - - - Watermark - 浮水印 - - - Force Borderless - 強制無邊框 - - - - Background - 背景 - - - - - - - Background Colour: <span style="color: %1">%1</span> - 背景顏色: <span style="color: %1">%1</span> - - - - Select background colour - 選擇背景顏色 - - - ... - ... - - - - - - - Background Image: - 背景圖片: - - - - Select background image - 選擇背景圖片 - - - - Remove background image - 移除背景圖片 - - - X - X - - - - Crop to Aspect Ratio - 裁剪長寬比 - - - - Force Colour in Avatar Zone - 強制在大頭貼區域使用顏色 - - - - Advanced - 進階 - - - - Resolution: - 解析度: - - - - Snapmatic resolution - Snapmatic 解析度 - - - - Avoid compression and expand buffer instead, improves picture quality, but may break Snapmatic - 避免壓縮來提高圖片品質,但可能會破壞 Snapmatic 運作 - - - - Unlimited Buffer - 無限緩衝 - - - - Import as-is, don't change the picture at all, guaranteed to break Snapmatic unless you know what you doing - 除非你知道自己在幹什麼,否則修改圖片將使 Snapmatic 故障 - - - - Import as-is - 照原樣匯入 - - - - Import options - 匯入選項 - - - - &Options - 選項(&O) - - - - Import picture - 匯入圖片 - - - - &OK - 確定(&O) - - - - Discard picture - 捨棄圖片 - - - - &Cancel - 取消(&C) - - - - &Import new Picture... - 匯入新圖片(&I)... - - - - &Crop Picture... - 裁剪圖片(&C)... - - - - &Load Settings... - 載入設定(&L)... - - - - &Save Settings... - 儲存設定(&S)... - - - - - Custom Avatar - Custom Avatar Description in SC, don't use Special Character! - 自訂大頭貼 - - - - - - Custom Picture - Custom Picture Description in SC, don't use Special Character! - 自訂圖片 - - - - Storage - Background Image: Storage - 儲存 - - - - Crop Picture... - 裁剪圖片... - - - - &Crop - 裁剪(&C) - - - - Crop Picture - 裁剪圖片 - - - - - Please import a new picture first - 請先匯入新圖片 - - - - - Default - Default as Default Profile - 預設 - - - - - - - - - - - - - - - - - - - - - - - Profile %1 - Profile %1 as Profile 1 - 設定檔 %1 - - - - - Load Settings... - 載入設定... - - - - - Save Settings... - 儲存設定... - - - - - Snapmatic Avatar Zone - Snapmatic 大頭貼區域 - - - - - Are you sure to use a square image outside of the Avatar Zone? -When you want to use it as Avatar the image will be detached! - 你確定要在大頭貼區域以外的地方使用方形圖片嗎? 作為大頭貼的圖片將被分離! - - - - Select Colour... - 選擇顏色... - - - - - Background Image: %1 - 背景圖片: %1 - - - - - Please select your settings profile - 請選擇設定檔 - - - - File - Background Image: File - 文件 - - - - JsonEditorDialog - - - Snapmatic JSON Editor - Snapmatic JSON 編輯器 - - - - Apply changes - 套用變更 - - - - &Save - 保存(&S) - - - - Discard changes - 捨棄變更 - - - - &Close - 關閉(&C) - - - - JSON Error - JSON 錯誤 - - - - MapLocationDialog - - - Snapmatic Map Viewer - Snapmatic 地圖檢視器 - - - - Close viewer - 關閉檢視器 - - - - &Close - 關閉(&C) - - - - Apply new position - 套用新位置 - - - - &Apply - 套用(&A) - - - - Revert old position - 還原舊位置 - - - - &Revert - 還原(&R) - - - - Select new position - 選擇新位置 - - - - &Select - 選擇(&S) - - - - Quit select position - 離開位置選擇 - - - - &Done - 完成(&D) - - - - X: %1 -Y: %2 - X and Y position - X: %1 -Y: %2 - - - - OptionsDialog - - - %1 - Settings - %1 - 設定 - - - - Profiles - 設定檔 - - - - Content Open/Select Mode - 開啟/選擇模式 - - - Open with Singleclick - 點一次開啟 - - - - Open with Doubleclick - 點兩次開啟 - - - Select with Singleclick - 點一次選取 - - - - Default Profile - 預設設定檔 - - - - Custom GTA V Folder - 自訂 GTA V 資料夾 - - - - Force using Custom Folder - 強制使用自訂資料夾 - - - - ... - ... - - - - Pictures - 圖片 - - - - Export Size - 匯出尺寸 - - - - Default: %1x%2 - 預設: %1x%2 - - - - Screen Resolution: %1x%2 - 螢幕解析度: %1x%2 - - - - - Custom Size: - 自訂尺寸: - - - - x - x - - - - Ignore Aspect Ratio - 忽略長寬比 - - - - Export Quality - 匯出品質 - - - - Enable Custom Quality - 啟用自訂品質 - - - - Quality: - 品質: - - - - %1% - %1% - - - - Picture Viewer - 圖片檢視器 - - - - Enable Navigation Bar - 啟用導航欄 - - - - Players - 玩家 - - - - ID - ID - - - - Name - 名稱 - - - - Game - 遊戲 - - - - Social Club Version - Social Club 版 - - - - - - - - - - - Found: %1 - 找到: %1 - - - - - - - - - - - - - Language: %1 - 語言: %1 - - - - Steam Version - Steam 版 - - - - Feedback - 反饋 - - - - Participation - 參與 - - - - - Participate in %1 User Statistics - 參與 %1 使用者統計 - - - - Categories - 分類 - - - - Hardware, Application and OS Specification - 硬體、軟體和 OS 規格 - - - - System Language Configuration - 系統語言設定 - - - - Application Configuration - 應用程式設定 - - - - Personal Usage Data - 個人使用數據 - - - - Other - 其他 - - - - - - Participation ID: %1 - 參與 ID: %1 - - - - &Copy - 複製(&C) - - - - Interface - 介面 - - - - Language for Interface - 介面語言 - - - - - - - Current: %1 - 目前: %1 - - - - Language for Areas - 區域語言 - - - - Style - 樣式 - - - - Use Default Style (Restart) - 使用預設樣式 (需重新啟動) - - - - Style: - 樣式: - - - - Font - 字體 - - - - Use Default Font (Restart) - 使用預設字體 (需重新啟動) - - - - Font: - 字體: - - - Always use Message Font (Windows 2003 and earlier) - 總是使用訊息字體 (Windows 2003 和更早版本) - - - - Apply changes - 套用變更 - - - - &OK - OK, Cancel, Apply - 確定(&O) - - - - Discard changes - 捨棄變更 - - - - &Cancel - OK, Cancel, Apply - 取消(&C) - - - - System - System in context of System default - 系統 - - - - - %1 (Closest to Interface) - Next closest language compared to the Interface - %1 (與介面接近的語言) - - - - - - Auto - Automatic language choice. - 自動 - - - - %1 (Language priority) - First language a person can talk with a different person/application. "Native" or "Not Native". - %1 (語言優先) - - - - %1 (Game language) - Next closest language compared to the Game settings - %1 (遊戲語言) - - - - %1 - %1 - %1 - - - - The new Custom Folder will initialise after you restart %1. - 自訂資料夾將在 %1 重新啟動後初始化. - - - - No Profile - No Profile, as default - - - - - - - Profile: %1 - 設定檔: %1 - - - - View %1 User Statistics Online - 檢視 %1 使用者統計資訊 - - - - Not registered - 未註冊參與 - - - - - - - Yes - - - - - - No - - - - - - OS defined - 系統定義 - - - - - Steam defined - Steam 定義 - - - - PictureDialog - - - Snapmatic Picture Viewer - %1 - Snapmatic 圖片檢視器 - %1 - - - - <span style="font-weight:600">Title: </span>%6<br/> -<span style="font-weight:600">Location: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">Players: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">Created: </span>%8 - <span style="font-weight:600">標題: </span>%6<br/> -<span style="font-weight:600">地點: </span>%7 (%1, %2, %3)<br/> -<span style="font-weight:600">玩家: </span>%4 (Crew %5)<br/> -<span style="font-weight:600">建立於: </span>%8 - - - - Manage picture - 管理圖片 - - - - &Manage - 管理(&M) - - - - Close viewer - 關閉檢視器 - - - - &Close - 關閉(&C) - - - - - Export as &Picture... - 匯出成圖片(&P)... - - - - - Export as &Snapmatic... - 匯出成 Snapmatic(&S)... - - - - - &Edit Properties... - 編輯屬性(&E) ... - - - - - &Overwrite Image... - 修改圖片(&O)... - - - - - Open &Map Viewer... - 開啟地圖檢視器(&M)... - - - - - Open &JSON Editor... - 開啟 JSON 編輯器(&J)... - - - - Key 1 - Avatar Preview Mode -Key 2 - Toggle Overlay -Arrow Keys - Navigate - 數字鍵 1 - 大頭接預覽模式 -數字鍵 2 - 開關重疊層 -方向鍵 - 導覽 - - - - Snapmatic Picture Viewer - Snapmatic 圖片檢視器 - - - - Failed at %1 - 失敗: %1 - - - - - - No Players - - - - - - No Crew - - - - - Unknown Location - 未知地點 - - - - Avatar Preview Mode -Press 1 for Default View - 大頭貼預覽模式 -按 1 切換格預設檢視 - - - - Export as Picture... - 匯出成圖片... - - - - - Export - 匯出 - - - - JPEG Graphics (*.jpg *.jpeg) - JPEG 圖形格式 (*.jpg *.jpeg) - - - - Portable Network Graphics (*.png) - 可攜式網路圖形 (*.png) - - - - - - - - - Export as Picture - 匯出成圖片 - - - - - Overwrite %1 with current Snapmatic picture? - 確定修改目前的 Snapmatic 圖片 %1 ? - - - - Failed to export the picture because the system occurred a write failure - 系統寫入失敗,無法匯出圖片 - - - - Failed to export the picture because the format detection failures - 格式檢測失敗,無法匯出圖片 - - - - Failed to export the picture because the file can't be written - 文件無法寫入,匯出圖片失敗 - - - - Failed to export the picture because of an unknown reason - 未知的錯誤,無法匯出圖片 - - - - - No valid file is selected - 未選擇有效的檔案 - - - - Export as Snapmatic... - 匯出成 Snapmatic... - - - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - - - - GTA V Raw Export (*.auto) - GTA V Raw Export (*.auto) - - - - Snapmatic pictures (PGTA*) - Snapmatic 圖片 (PGTA*) - - - - - - - - Export as Snapmatic - 匯出成 Snapmatic - - - - - Failed to export current Snapmatic picture - 匯出目前的 Snapmatic 圖片失敗 - - - - Exported Snapmatic to "%1" because of using the .auto extension. - 因為使用 .auto 格式,將 Snapmatic 匯出到 "%1". - - - - PlayerListDialog - - - Edit Players... - 編輯玩家... - - - - Available Players: - 可用的玩家: - - - - Selected Players: - 已選擇玩家: - - - - &Apply - 套用(&A) - - - - &Cancel - 取消(&C) - - - - Add Players... - 新增玩家... - - - - Failed to add more Players because the limit of Players are %1! - 因為數量限制 %1,無法新增更多玩家! - - - - - Add Player... - 新增玩家... - - - - Enter Social Club Player ID - 輸入玩家的 Social Club ID - - - - Failed to add Player %1 because Player %1 is already added! - 新增 %1 失敗,因為 %1 已被新增! - - - - ProfileInterface - - - Profile Interface - 設定檔界面 - - - - Loading file %1 of %2 files - 載入檔案中 %1 共 %2 個檔案 - - - - %1 %2 - %1 %2 - - - - Import file - 匯入檔案 - - - - &Import... - 匯入(&I)... - - - - Close profile - 關閉設定檔 - - - - &Close - 關閉(&C) - - - - - - Export file %1 of %2 files - 匯出檔案中 %1 共 %2 個檔案 - - - - - - - - - - - - - - - - - - - - - - Import... - 匯入... - - - - - - - - - Import - 匯入 - - - - - - All image files (%1) - 所有圖片 (%1) - - - - - - - All files (**) - 所有檔案 (**) - - - - - - Can't import %1 because file can't be open - 無法匯入 %1,因為檔案無法開啟 - - - - - - Can't import %1 because file can't be parsed properly - 無法匯入 %1,因為檔案無法正確解析 - - - - Enabled pictures: %1 of %2 - 開啟圖片 %1 共 %2 - - - - Loading... - 載入中... - - - - Snapmatic Loader - Snapmatic 載入器 - - - - <h4>Following Snapmatic Pictures got repaired</h4>%1 - <h4>下列的 Snapmatic 圖片已被更新</h4>%1 - - - - Importable files (%1) - 可匯入的檔案 (%1) - - - - - GTA V Export (*.g5e) - GTA V Export (*.g5e) - - - - - Savegames files (SGTA*) - 遊戲存檔 (SGTA*) - - - - - Snapmatic pictures (PGTA*) - Snapmatic 圖片 (PGTA*) - - - - - - No valid file is selected - 沒有選擇有效的檔案 - - - - - Import file %1 of %2 files - 匯入檔案 %1 共 %2 個 - - - - Import failed with... - -%1 - %1 匯入失敗 - - - - - Failed to read Snapmatic picture - 無法讀取 Snapmatic 圖片 - - - - - Failed to read Savegame file - 無法讀取遊戲存檔 - - - - Can't import %1 because file format can't be detected - 無法匯入 %1,因為無法檢測該檔案格式 - - - - Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e - 匯入 Snapmatic 圖片失敗,檔案不是 PGTA 開頭或附檔名不是 .g5e - - - - Failed to import the Snapmatic picture, can't copy the file into profile - 匯入 Snapmatic 圖片失敗,無法將該檔案複製到設定檔中 - - - - Failed to import the Savegame, can't copy the file into profile - 匯入遊戲存檔失敗,無法將該檔案複製到設定檔中 - - - - Failed to import the Savegame, no Savegame slot is left - 匯入遊戲存檔失敗,沒有遊戲存檔欄位 - - - - - - - - Export selected... - 匯出所選... - - - - - JPG pictures and GTA Snapmatic - JPG 圖片和 GTA Snapmatic - - - - - JPG pictures only - 只有 JPG 圖片 - - - - - GTA Snapmatic only - 只有 GTA Snapmatic - - - - %1Export Snapmatic pictures%2<br><br>JPG pictures make it possible to open the picture with a Image Viewer<br>GTA Snapmatic make it possible to import the picture into the game<br><br>Export as: - %1 匯出 Snapmatic 圖片 %2<br><br>JPG 圖片可使用圖片檢視器開啟<br>GTA Snapmatic 可以匯入到遊戲中<br><br>匯出成: - - - - Initialising export... - 初始化... - - - - Export failed with... - -%1 - %1 匯出失敗 - - - - - No Snapmatic pictures or Savegames files are selected - 未選擇 Snapmatic 圖片或遊戲存檔 - - - - - - Remove selected - 移除所選 - - - - You really want remove the selected Snapmatic picutres and Savegame files? - 你想移除所選的 Snapmatic 圖片/存檔嗎? - - - - Failed to remove all selected Snapmatic pictures and/or Savegame files - 無法移除所選擇的 Snapmatic 圖片/遊戲存檔 - - - - - - - - - No Snapmatic pictures are selected - 未選擇 Snapmatic 圖片 - - - - - - - - - %1 failed with... - -%2 - Action failed with... - %1 失敗... - -%2 - - - - Prepare Content for Import... - 準備匯入內容... - - - - A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp? - 已有與 uid %1 相同的 Snapmatic 圖片,你想要匯入新的 uid 和時間戳嗎? - - - - - Qualify as Avatar - 合格大頭貼 - - - - - - - Patch selected... - 修改所選... - - - - - - - - - - - Patch file %1 of %2 files - 修改檔案 %1 共 %2 個檔案 - - - - Qualify - %1 failed with... - 合格 - - - - - Change Players... - 更改玩家... - - - - Change Players - %1 failed with... - 更改玩家 - - - - - - Change Crew... - 更改幫會... - - - - Failed to enter a valid Snapmatic Crew ID - 輸入了無效的幫會 ID - - - - Change Crew - %1 failed with... - 更改幫會 - - - - - - Change Title... - 更改標題... - - - - Failed to enter a valid Snapmatic title - 輸入了無效的標題 - - - - Change Title - %1 failed with... - 更改標題 - - - - All profile files (*.g5e SGTA* PGTA*) - 所有設定檔檔案 (*.g5e SGTA* PGTA*) - - - - QApplication - - <h4>Welcome to %1!</h4>You want to configure %1 before you start using it? - <h4>歡迎使用 %1!</h4> 你想在開始前先設定 %1 嗎? - - - - SavegameDialog - - - - Savegame Viewer - 遊戲存檔檢視器 - - - - <span style="font-weight:600">Savegame</span><br><br>%1 - <span style="font-weight:600">遊戲存檔</span><br><br>%1 - - - - &Export - 匯出(&E) - - - - &Close - 關閉(&C) - - - - Failed at %1 - 失敗 %1 - - - - SavegameWidget - - - Savegame Widget - 遊戲存檔小工具 - - - - SAVE %3 - %1<br>%2 - 存檔 %3 - %1<br>%2 - - - - View savegame - 檢視存檔 - - - - View - 檢視 - - - - Copy savegame - 複製存檔 - - - - - Export - 匯出 - - - - Delete savegame - 刪除存檔 - - - - Delete - 刪除 - - - - &View - 檢視(&V) - - - - - - &Export - 匯出(&E) - - - - - - &Remove - 移除(&R) - - - - - &Select - 選擇(&S) - - - - - &Deselect - 取消選擇(&D) - - - - - Select &All - 選擇全部(&A) - - - - - &Deselect All - 取消選擇全部(&D) - - - - Savegame files (SGTA*) - 遊戲存檔 (SGTA*) - - - - All files (**) - 所有檔案 (**) - - - - - - - Export Savegame - 匯出存檔 - - - - Overwrite %1 with current Savegame? - 是否修改目前的存檔 %1? - - - - Failed to overwrite %1 with current Savegame - 遊戲存檔 %1 修改失敗 - - - - Failed to export current Savegame - 匯出目前的存檔失敗 - - - - No valid file is selected - 沒有選擇有效的檔案 - - - - Export Savegame... - 匯出遊戲存檔... - - - - - AUTOSAVE - %1 -%2 - 自動存檔 - %1 -%2 - - - - - SAVE %3 - %1 -%2 - 存檔 %3 - %1 -%2 - - - - - WRONG FORMAT - 格式錯誤 - - - - UNKNOWN - 未知 - - - - - Delete Savegame - 刪除存檔 - - - - Are you sure to delete %1 from your savegames? - 你確定要刪除存檔 %1? - - - - Failed at deleting %1 from your savegames - 刪除存檔 %1 失敗 - - - - SnapmaticEditor - - - - - - - - - - - Snapmatic Properties - Snapmatic 屬性 - - - - Snapmatic Type - Snapmatic 類型 - - - - Editor - 編輯 - - - - Selfie - 自拍 - - - - Regular - 正常 - - - - Mugshot - 犯罪照片 - - - - Meme - Meme - - - - Director - 導演 - - - - Snapmatic Values - Snapmatic 信息 - - - - Extras - 附加功能 - - - - Qualify as Avatar automatically at apply - 自動設定成符合資格的圖片 - - - - Qualify as Avatar allows you to use this Snapmatic as a Social Club profile picture - 符合資格的圖片將可以設定為 Social Club 大頭貼 - - - - Apply changes - 套用變更 - - - - &Apply - 套用(&A) - - - - Discard changes - 捨棄變更 - - - - &Cancel - 取消(&C) - - - - <h4>Unsaved changes detected</h4>You want to save the JSON content before you quit? - <h4>目前的變更未儲存</h4> 你想要在退出之前儲存 JSON 嗎? - - - - Patching of Snapmatic Properties failed because of %1 - 更新 Snapmatic 屬性失敗,因為 %1 - - - - - - - Patching of Snapmatic Properties failed because of I/O Error - 讀寫錯誤,未能更新 Snapmatic 屬性 - - - - Patching of Snapmatic Properties failed because of JSON Error - JSON 錯誤,未能更新 Snapmatic 屬性 - - - - - Snapmatic Crew - 幫會 - - - - - New Snapmatic crew: - 輸入新的幫會: - - - - - Snapmatic Title - 標題 - - - - - New Snapmatic title: - 輸入新的標題: - - - - - - Edit - 編輯 - - - - Players: %1 (%2) - Multiple Player are inserted here - 玩家: %1 (%2) - - - - Player: %1 (%2) - One Player is inserted here - 玩家: %1 (%2) - - - - Title: %1 (%2) - 標題: %1 (%2) - - - - - Appropriate: %1 - 可使用: %1 - - - - Yes - Yes, should work fine - - - - - No - No, could lead to issues - - - - - Crew: %1 (%2) - 幫會: %1 (%2) - - - - SnapmaticPicture - - - - JSON is incomplete and malformed - JSON 不完整和異常 - - - - - JSON is incomplete - JSON 不完整 - - - - - JSON is malformed - JSON 異常 - - - - PHOTO - %1 - 照片 - %1 - - - - open file %1 - 開啟檔案 - %1 - - - - header not exists - 標頭不存在 - - - - header is malformed - 標頭異常 - - - - picture not exists (%1) - 圖片不存在 (%1) - - - - JSON not exists (%1) - JSON 不存在 (%1) - - - - title not exists (%1) - 標題不存在 (%1) - - - - description not exists (%1) - 描述不存在 (%1) - - - - reading file %1 because of %2 - Example for %2: JSON is malformed error - 讀取檔案 %1 失敗,因為 %2 - - - - SnapmaticWidget - - - Snapmatic Widget - Snapmatic 小工具 - - - - PHOTO - 00/00/00 00:00:00 - 照片 - 00/00/00 00:00:00 - - - - View picture - 檢視圖片 - - - - View - 檢視 - - - - Copy picture - 複製圖片 - - - - Copy - 複製 - - - - Export picture - 匯出圖片 - - - - Export - 匯出 - - - - - - Delete picture - 刪除圖片 - - - - Delete - 刪除 - - - - - - Edi&t - 編輯(&E) - - - - - - Show &In-game - 在遊戲中顯示(&I) - - - - - - Hide &In-game - 在遊戲中隱藏(&I) - - - - &Export - 匯出(&E) - - - - &View - 檢視(&V) - - - - &Remove - 移除(&R) - - - - - &Select - 選擇(&S) - - - - - &Deselect - 取消選擇(&D) - - - - - Select &All - 選擇全部(&A) - - - - - &Deselect All - 取消選擇全部(&D) - - - - Are you sure to delete %1 from your Snapmatic pictures? - 你確定要刪除Snapmatic 圖片 %1 嗎? - - - - Failed at deleting %1 from your Snapmatic pictures - 刪除 Snapmatic 圖片 %1 失敗 - - - - Failed to hide %1 In-game from your Snapmatic pictures - 在遊戲中隱藏圖片 %1 失敗 - - - - Failed to show %1 In-game from your Snapmatic pictures - 在遊戲中顯示圖片 %1 失敗 - - - - TelemetryDialog - - - You want help %1 to improve in the future by including personal usage data in your submission? - 你希望通過收集資料來幫助改善 %1 嗎? - - - - %1 User Statistics - %1 使用者統計 - - - - Yes, I want include personal usage data. - 是的,我想幫忙. - - - - &OK - 確定(&O) - - - - UserInterface - - - - %2 - %1 - %2 - %1 - - - - Select profile - 選擇設定檔 - - - - %1 %2 - %1 %2 - - - - Reload profile overview - 重新載入設定檔概述 - - - - &Reload - 重新載入(&R) - - - - Close %1 - Close %1 <- (gta5view/gta5sync) - %1 will be replaced automatically - 關閉 %1 - - - - - - - &Close - 關閉(&C) - - - - &File - 檔案(&F) - - - - &Help - 幫助(&H) - - - - &Edit - 編輯(&E) - - - - &Profile - 設定檔(&P) - - - - &Selection visibility - 選擇可見度(&S) - - - - Selection &mass tools - 工具(&M) - - - - - - &About %1 - 關於 %1(&A) - - - - &Exit - 離開(&E) - - - - Exit - 離開 - - - - Close &Profile - 關閉設定檔(&P) - - - - &Settings - 設定(&S) - - - - Select &All - 選擇全部(&A) - - - - &Deselect All - 取消選擇全部(&D) - - - - &Export selected... - 匯出所選(&E)... - - - - &Remove selected - 移除所選(&R) - - - - &Import files... - 匯入檔案(&I)... - - - - &Open File... - 開啟檔案(&O)... - - - - - Select &GTA V Folder... - 選擇 GTA V 資料夾(&G)... - - - - - - - Select GTA V Folder... - 選擇 GTA V 資料夾... - - - - Show In-gam&e - 在遊戲中顯示(&E) - - - - Hi&de In-game - 在遊戲中隱藏(&D) - - - - - - Change &Title... - 更改標題(&T)... - - - - - - Change &Crew... - 更改幫會(&C)... - - - - - - &Qualify as Avatar - 符合大頭貼資格(&Q) - - - - - - Change &Players... - 更改玩家(&P)... - - - - - - Show In-game - 在遊戲中顯示 - - - - - - Hide In-game - 在遊戲中隱藏 - - - - - - Select Profile - 選擇設定檔 - - - - - &Donate - 贊助(&D) - - - - Donate - 贊助 - - - - Donation methods - 贊助方式 - - - View - 檢視 - - - Copy - 複製 - - - - &Copy - 複製(&C) - - - - Open File... - 開啟檔案... - - - - - - - Open File - 開啟檔案 - - - - Can't open %1 because of not valid file format - 格式無效,無法開啟 %1 - - - - %1 - Messages - %1 - 新聞 - - - diff --git a/res/gta5view-128.png b/res/gta5view-128.png deleted file mode 100644 index fc3d97a..0000000 Binary files a/res/gta5view-128.png and /dev/null differ diff --git a/res/gta5view-16.png b/res/gta5view-16.png deleted file mode 100644 index 662b09d..0000000 Binary files a/res/gta5view-16.png and /dev/null differ diff --git a/res/gta5view-24.png b/res/gta5view-24.png deleted file mode 100644 index 3b2797b..0000000 Binary files a/res/gta5view-24.png and /dev/null differ diff --git a/res/gta5view-256.png b/res/gta5view-256.png deleted file mode 100644 index e728fb4..0000000 Binary files a/res/gta5view-256.png and /dev/null differ diff --git a/res/gta5view-32.png b/res/gta5view-32.png deleted file mode 100644 index b0f64cd..0000000 Binary files a/res/gta5view-32.png and /dev/null differ diff --git a/res/gta5view-40.png b/res/gta5view-40.png deleted file mode 100644 index 27a6988..0000000 Binary files a/res/gta5view-40.png and /dev/null differ diff --git a/res/gta5view-48.png b/res/gta5view-48.png deleted file mode 100644 index 3f32f7e..0000000 Binary files a/res/gta5view-48.png and /dev/null differ diff --git a/res/gta5view-512.png b/res/gta5view-512.png deleted file mode 100644 index cb29d15..0000000 Binary files a/res/gta5view-512.png and /dev/null differ diff --git a/res/gta5view-64.png b/res/gta5view-64.png deleted file mode 100644 index e48fb58..0000000 Binary files a/res/gta5view-64.png and /dev/null differ diff --git a/res/gta5view-96.png b/res/gta5view-96.png deleted file mode 100644 index 975157d..0000000 Binary files a/res/gta5view-96.png and /dev/null differ diff --git a/res/gta5view.desktop b/res/gta5view.desktop new file mode 100644 index 0000000..168bfd0 --- /dev/null +++ b/res/gta5view.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Version=1.0 +Encoding=UTF-8 +Type=Application +Name=gta5view +Comment=gta5view +Categories=Qt;Application;Utility; +Exec=gta5view +Icon=gta5view +Terminal=false +StartupNotify=false diff --git a/res/gta5view.exe.manifest b/res/gta5view.exe.manifest deleted file mode 100644 index 3f57eaf..0000000 --- a/res/gta5view.exe.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/res/gta5view.icns b/res/gta5view.icns deleted file mode 100644 index 12f8c6f..0000000 Binary files a/res/gta5view.icns and /dev/null differ diff --git a/res/gta5view.xpm b/res/gta5view.xpm new file mode 100644 index 0000000..f1ee97b --- /dev/null +++ b/res/gta5view.xpm @@ -0,0 +1,135 @@ +/* XPM */ +static char * C:\Users\Rafael\Documents\Projects\gta5view\res\gta5view_xpm[] = { +"128 128 4 1", +" c None", +". c #000000", +"+ c #FE0000", +"@ c #FF0000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ...................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ............. ", +" ............. ", +" ............. ", +" .............. ", +" ............. ", +" ............. ", +" ............. ", +" .............. ", +" .............. ", +" ............. ", +" ............. ", +" ............. ", +" .............. ", +" ............. ", +" ............. ", +" ............. ", +" ............. ", +" .............. ", +" ............. ", +" ............. ", +" ............. ", +" ............. ", +" .............. ", +" ............. ", +" ............. ", +" ............. ", +" .............. ", +" .............. ", +" ............. .. ", +" ................................ ", +" .................................... ", +" ........................................ ", +" .......................................... ", +" ............................................ ", +" ............................................. ", +" .............................................. ", +" ................................................. ", +" ................................................. ", +" .................................................. ", +" ..... ............................. ", +" ......................... ", +" ...................... ", +" ..................... ", +" ................... ", +" ................... ", +" .................. ", +" ................. ", +" ................ ", +" ............... ", +" ................ ", +" ................ ", +" ............... ", +" ............... ", +" ............... ", +" ............... ", +" .............. ", +" ++ .............. ", +" +@@@+ .............. ", +" @@@@@ .............. ", +" +@@@@@ .............. ", +" @@@@+ ............... ", +" @@@+ .............. ", +" .............. ", +" ", +" ", +" ", +" ", +" @@@@ @@@@ @@@ +++@@++ ++++ ++++ @@@@@ ", +" @@@@+ +@@@@ @@@@+ ++@@@@@@@@@+ @@@@+ +@@@@+ +@@@@+ ", +" @@@@+ @@@@+ @@@@+ +@@@@@@@@@@@@@ @@@@+ @@@@@@ @@@@@ ", +" +@@@+ +@@@@ +@@@@ +@@@@@@@@@@@@@@+ @@@@+ +@@@@@@ @@@@+ ", +" +@@@@ +@@@@+ +@@@@ @@@@@++ +@@@@@ @@@@+ @@@@@@@ +@@@@ ", +" +@@@@ +@@@+ +@@@+ +@@@@+ +@@@@+ @@@@+ +@@@+@@@ @@@@+ ", +" +@@@@ +@@@@+ @@@@+ +@@@@+ @@@@+ @@@@+ @@@++@@@ +@@@@ ", +" +@@@@ +@@@+ @@@@+ +@@@@+ +@@@+ @@@@+ @@@@ +@@@ @@@@+ ", +" @@@@ +@@@@+ +@@@@ +@@@@ @@@@+ @@@@@ @@@+ +@@@ +@@@@ ", +" @@@@+ @@@@+ +@@@@ +@@@@+ +@@@@+ +@@@+ +@@@ +@@@ +@@@+ ", +" @@@@+ +@@@@ +@@@+ +@@@@ @@@@+ @@@@+ @@@+ +@@@ +@@@@+ ", +" @@@@+ @@@@+ @@@@+ @@@@+ ++@@@@+ +@@@+ +@@@+ +@@@+ @@@@@ ", +" +@@@+ +@@@@ @@@@ +@@@@ ++@@@@@+ +@@@+ +@@@ +@@@+ @@@@+ ", +" +@@@+ @@@@+ +@@@@ +@@@@+++++++@@@@@@@+ +@@@+ +@@@+ +@@@+ +@@@@ ", +" +@@@@ +@@@@ +@@@+ @@@@@@@@@@@@@@@@@++ +@@@+ +@@@ +@@@+ @@@@+ ", +" +@@@@ @@@@+ @@@@+ @@@@@@@@@@@@@@@++ +@@@+ @@@+ @@@+ +@@@@ ", +" @@@@ +@@@+ @@@@+ +@@@@@@@@@@@+++ +@@@+ +@@@ @@@+ @@@@+ ", +" @@@@ +@@@@@ +@@@@ +@@@@++ +@@@+ @@@+ @@@+ +@@@@ ", +" @@@@ +@@@+ +@@@@ +@@@@ +@@@@ +@@@ @@@+ +@@@+ ", +" @@@@+ +@@@@+ +@@@+ +@@@@ +@@@@ @@@+ @@@+ @@@@ ", +" +@@@+ +@@@+ @@@@+ +@@@@ @@@@+ +@@@ @@@+ @@@@+ ", +" +@@@+ @@@@@ @@@@+ +@@@@ @@@+ @@@+ @@@+ @@@@ ", +" +@@@+ +@@@+ +@@@@ @@@@+ @@@+ +@@@+ @@@+ +@@@+ ", +" +@@@+ @@@@ +@@@@ @@@@+ @@@+ +@@+ @@@+ +@@@+ ", +" +@@@+ +@@@+ +@@@+ +@@@@+ @@@+ @@@+ @@@+ @@@+ ", +" @@@+ @@@@ @@@@+ +@@@@@ ++ @@@++@@+ +@@++@@@+ ", +" @@@++@@@+ @@@@+ +@@@@@+ ++@@@ @@@+@@@+ +@@++@@@ ", +" @@@@@@@@ +@@@@ @@@@@@@@@@@@@@@@@ @@@@@@@ +@@@@@@+ ", +" @@@@@@@+ +@@@@ +@@@@@@@@@@@@@@@ @@@@@@+ +@@@@@@ ", +" +@@@@@+ +@@@+ +@@@@@@@@@@@++ @@@@@@ +@@@@@+ ", +" @@@@@ @@@@ ++++@++++ @@@@@ @@@@@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/res/img.cmake b/res/img.cmake deleted file mode 100644 index 7a51a90..0000000 --- a/res/img.cmake +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 3.7) - -set(GTA5VIEW_IMGFILES - res/add.svgz - res/avatararea.png - res/avatarareaimport.png - res/back.svgz - res/flag-de.png - res/flag-fr.png - res/flag-gb.png - res/flag-kr.png - res/flag-ru.png - res/flag-tw.png - res/flag-ua.png - res/flag-us.png - res/mapcayoperico.jpg - res/mappreview.jpg - res/next.svgz - res/pointmaker-8.png - res/pointmaker-16.png - res/pointmaker-24.png - res/pointmaker-32.png - res/savegame.svgz - res/watermark_1b.png - res/watermark_2b.png - res/watermark_2r.png -) diff --git a/res/img.qrc b/res/img.qrc deleted file mode 100644 index 4fe80f2..0000000 --- a/res/img.qrc +++ /dev/null @@ -1,36 +0,0 @@ - - - add.svgz - avatararea.png - avatarareaimport.png - back.svgz - flag-de.png - flag-fr.png - flag-gb.png - flag-kr.png - flag-ru.png - flag-tw.png - flag-ua.png - flag-us.png - gta5view-16.png - gta5view-24.png - gta5view-32.png - gta5view-40.png - gta5view-48.png - gta5view-64.png - gta5view-96.png - gta5view-128.png - gta5view-256.png - mapcayoperico.jpg - mappreview.jpg - next.svgz - pointmaker-8.png - pointmaker-16.png - pointmaker-24.png - pointmaker-32.png - savegame.svgz - watermark_1b.png - watermark_2b.png - watermark_2r.png - - diff --git a/res/ltc.str b/res/ltc.str deleted file mode 100644 index 865862c..0000000 --- a/res/ltc.str +++ /dev/null @@ -1 +0,0 @@ -Litecoin \ No newline at end of file diff --git a/res/ltc.svgz b/res/ltc.svgz deleted file mode 100644 index ae954e1..0000000 Binary files a/res/ltc.svgz and /dev/null differ diff --git a/res/mapcayoperico.jpg b/res/mapcayoperico.jpg deleted file mode 100644 index a9cdab1..0000000 Binary files a/res/mapcayoperico.jpg and /dev/null differ diff --git a/res/mappreview.jpg b/res/mappreview.jpg deleted file mode 100644 index 0049692..0000000 Binary files a/res/mappreview.jpg and /dev/null differ diff --git a/res/next.png b/res/next.png new file mode 100644 index 0000000..4a36bc2 Binary files /dev/null and b/res/next.png differ diff --git a/res/next.svgz b/res/next.svgz deleted file mode 100644 index bdf7ee9..0000000 Binary files a/res/next.svgz and /dev/null differ diff --git a/res/pointmaker-16.png b/res/pointmaker-16.png deleted file mode 100644 index f038879..0000000 Binary files a/res/pointmaker-16.png and /dev/null differ diff --git a/res/pointmaker-24.png b/res/pointmaker-24.png deleted file mode 100644 index 87e9669..0000000 Binary files a/res/pointmaker-24.png and /dev/null differ diff --git a/res/pointmaker-32.png b/res/pointmaker-32.png deleted file mode 100644 index de591b1..0000000 Binary files a/res/pointmaker-32.png and /dev/null differ diff --git a/res/pointmaker-8.png b/res/pointmaker-8.png deleted file mode 100644 index 5c0e653..0000000 Binary files a/res/pointmaker-8.png and /dev/null differ diff --git a/res/qt4/qt_ko.qm b/res/qt4/qt_ko.qm deleted file mode 100644 index e3d1231..0000000 Binary files a/res/qt4/qt_ko.qm and /dev/null differ diff --git a/res/qt4/qt_uk.qm b/res/qt4/qt_uk.qm deleted file mode 100644 index 112ca5c..0000000 Binary files a/res/qt4/qt_uk.qm and /dev/null differ diff --git a/res/qt4/qt_zh_TW.qm b/res/qt4/qt_zh_TW.qm deleted file mode 100644 index a9a25b2..0000000 Binary files a/res/qt4/qt_zh_TW.qm and /dev/null differ diff --git a/res/qt4/tr_qt.qrc b/res/qt4/tr_qt.qrc deleted file mode 100644 index 0b79a15..0000000 --- a/res/qt4/tr_qt.qrc +++ /dev/null @@ -1,10 +0,0 @@ - - - qt_de.qm - qt_fr.qm - qt_ko.qm - qt_ru.qm - qt_uk.qm - qt_zh_TW.qm - - diff --git a/res/qt5/qtbase_de.qm b/res/qt5/qtbase_de.qm deleted file mode 100644 index 4a4c988..0000000 Binary files a/res/qt5/qtbase_de.qm and /dev/null differ diff --git a/res/qt5/qtbase_en_GB.qm b/res/qt5/qtbase_en_GB.qm deleted file mode 100644 index 8a7e376..0000000 Binary files a/res/qt5/qtbase_en_GB.qm and /dev/null differ diff --git a/res/qt5/qtbase_en_GB.ts b/res/qt5/qtbase_en_GB.ts deleted file mode 100644 index 0fbfffd..0000000 --- a/res/qt5/qtbase_en_GB.ts +++ /dev/null @@ -1,65 +0,0 @@ - - - - - QColorDialog - - Hu&e: - - - - &Sat: - - - - &Val: - - - - &Red: - - - - &Green: - - - - Bl&ue: - - - - A&lpha channel: - - - - &HTML: - - - - Cursor at %1, %2 -Press ESC to cancel - Cursour at %1, %2 -Press ESC to cancel - - - Select Color - Select Colour - - - &Basic colors - &Basic colours - - - &Custom colors - &Custom colours - - - &Add to Custom Colors - &Add to Custom Colours - - - &Pick Screen Color - &Pick Screen Colour - - - diff --git a/res/qt5/qtbase_fr.qm b/res/qt5/qtbase_fr.qm deleted file mode 100644 index 009fb5a..0000000 Binary files a/res/qt5/qtbase_fr.qm and /dev/null differ diff --git a/res/qt5/qtbase_ko.qm b/res/qt5/qtbase_ko.qm deleted file mode 100644 index 20e4661..0000000 Binary files a/res/qt5/qtbase_ko.qm and /dev/null differ diff --git a/res/qt5/qtbase_ru.qm b/res/qt5/qtbase_ru.qm deleted file mode 100644 index c1a2286..0000000 Binary files a/res/qt5/qtbase_ru.qm and /dev/null differ diff --git a/res/qt5/qtbase_uk.qm b/res/qt5/qtbase_uk.qm deleted file mode 100644 index 21a3038..0000000 Binary files a/res/qt5/qtbase_uk.qm and /dev/null differ diff --git a/res/qt5/qtbase_zh_TW.qm b/res/qt5/qtbase_zh_TW.qm deleted file mode 100644 index 6205298..0000000 Binary files a/res/qt5/qtbase_zh_TW.qm and /dev/null differ diff --git a/res/qt5/tr_qt.qrc b/res/qt5/tr_qt.qrc deleted file mode 100644 index 7bfe7cc..0000000 --- a/res/qt5/tr_qt.qrc +++ /dev/null @@ -1,11 +0,0 @@ - - - qtbase_en_GB.qm - qtbase_de.qm - qtbase_fr.qm - qtbase_ko.qm - qtbase_ru.qm - qtbase_uk.qm - qtbase_zh_TW.qm - - diff --git a/res/qt6/qtbase_de.qm b/res/qt6/qtbase_de.qm deleted file mode 100644 index a0d2672..0000000 Binary files a/res/qt6/qtbase_de.qm and /dev/null differ diff --git a/res/qt6/qtbase_en_GB.qm b/res/qt6/qtbase_en_GB.qm deleted file mode 100644 index 8a7e376..0000000 Binary files a/res/qt6/qtbase_en_GB.qm and /dev/null differ diff --git a/res/qt6/qtbase_en_GB.ts b/res/qt6/qtbase_en_GB.ts deleted file mode 100644 index 0fbfffd..0000000 --- a/res/qt6/qtbase_en_GB.ts +++ /dev/null @@ -1,65 +0,0 @@ - - - - - QColorDialog - - Hu&e: - - - - &Sat: - - - - &Val: - - - - &Red: - - - - &Green: - - - - Bl&ue: - - - - A&lpha channel: - - - - &HTML: - - - - Cursor at %1, %2 -Press ESC to cancel - Cursour at %1, %2 -Press ESC to cancel - - - Select Color - Select Colour - - - &Basic colors - &Basic colours - - - &Custom colors - &Custom colours - - - &Add to Custom Colors - &Add to Custom Colours - - - &Pick Screen Color - &Pick Screen Colour - - - diff --git a/res/qt6/qtbase_ko.qm b/res/qt6/qtbase_ko.qm deleted file mode 100644 index 20e4661..0000000 Binary files a/res/qt6/qtbase_ko.qm and /dev/null differ diff --git a/res/qt6/qtbase_ru.qm b/res/qt6/qtbase_ru.qm deleted file mode 100644 index c1a2286..0000000 Binary files a/res/qt6/qtbase_ru.qm and /dev/null differ diff --git a/res/qt6/qtbase_uk.qm b/res/qt6/qtbase_uk.qm deleted file mode 100644 index 21a3038..0000000 Binary files a/res/qt6/qtbase_uk.qm and /dev/null differ diff --git a/res/qt6/qtbase_zh_TW.qm b/res/qt6/qtbase_zh_TW.qm deleted file mode 100644 index f32a72f..0000000 Binary files a/res/qt6/qtbase_zh_TW.qm and /dev/null differ diff --git a/res/qt6/tr_qt.qrc b/res/qt6/tr_qt.qrc deleted file mode 100644 index 7bfe7cc..0000000 --- a/res/qt6/tr_qt.qrc +++ /dev/null @@ -1,11 +0,0 @@ - - - qtbase_en_GB.qm - qtbase_de.qm - qtbase_fr.qm - qtbase_ko.qm - qtbase_ru.qm - qtbase_uk.qm - qtbase_zh_TW.qm - - diff --git a/res/qt4/qt_de.qm b/res/qt_de.qm old mode 100644 new mode 100755 similarity index 100% rename from res/qt4/qt_de.qm rename to res/qt_de.qm diff --git a/res/qt4/qt_fr.qm b/res/qt_fr.qm similarity index 100% rename from res/qt4/qt_fr.qm rename to res/qt_fr.qm diff --git a/res/qtbase_de.qm b/res/qtbase_de.qm new file mode 100755 index 0000000..ed026f9 Binary files /dev/null and b/res/qtbase_de.qm differ diff --git a/res/qt6/qtbase_fr.qm b/res/qtbase_fr.qm similarity index 99% rename from res/qt6/qtbase_fr.qm rename to res/qtbase_fr.qm index 009fb5a..8353f0a 100644 Binary files a/res/qt6/qtbase_fr.qm and b/res/qtbase_fr.qm differ diff --git a/res/savegame.png b/res/savegame.png new file mode 100755 index 0000000..a2c61b0 Binary files /dev/null and b/res/savegame.png differ diff --git a/res/savegame.svgz b/res/savegame.svgz deleted file mode 100644 index a1c8247..0000000 Binary files a/res/savegame.svgz and /dev/null differ diff --git a/res/src/AvatarAreaProject.xcf b/res/src/AvatarAreaProject.xcf deleted file mode 100644 index 98c204e..0000000 Binary files a/res/src/AvatarAreaProject.xcf and /dev/null differ diff --git a/res/src/mainui.png b/res/src/mainui.png deleted file mode 100644 index 211e3cc..0000000 Binary files a/res/src/mainui.png and /dev/null differ diff --git a/res/src/picture.png b/res/src/picture.png deleted file mode 100644 index 94d46a5..0000000 Binary files a/res/src/picture.png and /dev/null differ diff --git a/res/src/prop.png b/res/src/prop.png deleted file mode 100644 index 7acd21c..0000000 Binary files a/res/src/prop.png and /dev/null differ diff --git a/res/template.g5e b/res/template.g5e deleted file mode 100644 index c74ba7f..0000000 Binary files a/res/template.g5e and /dev/null differ diff --git a/res/template.qrc b/res/template.qrc deleted file mode 100644 index 06dcf5a..0000000 --- a/res/template.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - template.g5e - - diff --git a/res/tr_g5p.qrc b/res/tr_g5p.qrc deleted file mode 100644 index b51e8fd..0000000 --- a/res/tr_g5p.qrc +++ /dev/null @@ -1,11 +0,0 @@ - - - gta5sync_en_US.qm - gta5sync_de.qm - gta5sync_fr.qm - gta5sync_ko.qm - gta5sync_ru.qm - gta5sync_uk.qm - gta5sync_zh_TW.qm - - diff --git a/res/watermark_1b.png b/res/watermark_1b.png deleted file mode 100644 index c0a8adc..0000000 Binary files a/res/watermark_1b.png and /dev/null differ diff --git a/res/watermark_2b.png b/res/watermark_2b.png deleted file mode 100644 index 0cf74b9..0000000 Binary files a/res/watermark_2b.png and /dev/null differ diff --git a/res/watermark_2r.png b/res/watermark_2r.png deleted file mode 100644 index 51aa4b2..0000000 Binary files a/res/watermark_2r.png and /dev/null differ diff --git a/res/xmr.str b/res/xmr.str deleted file mode 100644 index 131342e..0000000 --- a/res/xmr.str +++ /dev/null @@ -1 +0,0 @@ -Monero \ No newline at end of file diff --git a/res/xmr.svgz b/res/xmr.svgz deleted file mode 100644 index 55c269a..0000000 Binary files a/res/xmr.svgz and /dev/null differ diff --git a/tmext/TelemetryClassAuthenticator.cpp b/tmext/TelemetryClassAuthenticator.cpp deleted file mode 100644 index fc523f7..0000000 --- a/tmext/TelemetryClassAuthenticator.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2018 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "TelemetryClassAuthenticator.h" -#include -#include - -#ifndef GTA5SYNC_TELEMETRY_PUSHURL -#define GTA5SYNC_TELEMETRY_PUSHURL "" -#endif - -#ifndef GTA5SYNC_TELEMETRY_REGURL -#define GTA5SYNC_TELEMETRY_REGURL "" -#endif - -#ifndef GTA5SYNC_TELEMETRY_AUTHID -#define GTA5SYNC_TELEMETRY_AUTHID "" -#endif - -#ifndef GTA5SYNC_TELEMETRY_AUTHPW -#define GTA5SYNC_TELEMETRY_AUTHPW "" -#endif - -const QUrl TelemetryClassAuthenticator::getTrackingPushURL() -{ - if (haveAccessData()) - { - QUrl pushUrl(GTA5SYNC_TELEMETRY_PUSHURL); - QUrlQuery pushQuery(pushUrl); - if (!getTrackingAuthID().isEmpty()) { pushQuery.addQueryItem("tid", getTrackingAuthID()); } - if (!getTrackingAuthPW().isEmpty()) { pushQuery.addQueryItem("tpw", getTrackingAuthPW()); } - pushUrl.setQuery(pushQuery.query(QUrl::FullyEncoded)); - return pushUrl; - } - else - { - QUrl pushUrl(GTA5SYNC_TELEMETRY_PUSHURL); - return pushUrl; - } -} - -const QUrl TelemetryClassAuthenticator::getTrackingRegURL() -{ - if (haveAccessData()) - { - QUrl regUrl(GTA5SYNC_TELEMETRY_REGURL); - QUrlQuery regQuery(regUrl); - if (!getTrackingAuthID().isEmpty()) { regQuery.addQueryItem("tid", getTrackingAuthID()); } - if (!getTrackingAuthPW().isEmpty()) { regQuery.addQueryItem("tpw", getTrackingAuthPW()); } - regUrl.setQuery(regQuery.query(QUrl::FullyEncoded)); - return regUrl; - } - else - { - QUrl regUrl(GTA5SYNC_TELEMETRY_REGURL); - return regUrl; - } -} - -const QString TelemetryClassAuthenticator::getTrackingAuthID() -{ - return QString(GTA5SYNC_TELEMETRY_AUTHID); -} - -const QString TelemetryClassAuthenticator::getTrackingAuthPW() -{ - return QString(GTA5SYNC_TELEMETRY_AUTHPW); -} - -bool TelemetryClassAuthenticator::havePushURL() -{ - return !getTrackingPushURL().isEmpty(); -} - -bool TelemetryClassAuthenticator::haveRegURL() -{ - return !getTrackingRegURL().isEmpty(); -} - -bool TelemetryClassAuthenticator::haveAccessData() -{ - if (getTrackingAuthID().isEmpty() && getTrackingAuthPW().isEmpty()) { return false; } - return true; -} diff --git a/tmext/TelemetryClassAuthenticator.h b/tmext/TelemetryClassAuthenticator.h deleted file mode 100644 index 4180029..0000000 --- a/tmext/TelemetryClassAuthenticator.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2018 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef TELEMETRYCLASSAUTHENTICATOR_H -#define TELEMETRYCLASSAUTHENTICATOR_H - -#include -#include -#include -#include - -class TelemetryClassAuthenticator : public QObject -{ - Q_OBJECT -public: - static const QUrl getTrackingPushURL(); - static const QUrl getTrackingRegURL(); - static const QString getTrackingAuthID(); - static const QString getTrackingAuthPW(); - static bool havePushURL(); - static bool haveRegURL(); - static bool haveAccessData(); -}; - - -#endif // TELEMETRYCLASSAUTHENTICATOR_H diff --git a/uimod/JSHighlighter.cpp b/uimod/JSHighlighter.cpp deleted file mode 100644 index 42a988c..0000000 --- a/uimod/JSHighlighter.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017-2020 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "JSHighlighter.h" - -JSHighlighter::JSHighlighter(QTextDocument *parent) : - QSyntaxHighlighter(parent) -{ - HighlightingRule rule; - - QBrush keywordBrush(QColor::fromRgb(66, 137, 244)); - keywordFormat.setForeground(keywordBrush); - keywordFormat.setFontItalic(true); - QStringList keywordPatterns; - keywordPatterns << "\\btrue\\b" << "\\bfalse\\b"; - for (QString pattern : keywordPatterns) - { -#if QT_VERSION >= 0x050000 - rule.pattern = QRegularExpression(pattern); -#else - rule.pattern = QRegExp(pattern); -#endif - rule.format = keywordFormat; - highlightingRules.append(rule); - } - - QBrush doubleBrush(QColor::fromRgb(66, 137, 244)); - doubleFormat.setForeground(doubleBrush); -#if QT_VERSION >= 0x050000 - rule.pattern = QRegularExpression("[+-]?\\d*\\.?\\d+"); -#else - rule.pattern = QRegExp("[+-]?\\d*\\.?\\d+"); -#endif - rule.format = doubleFormat; - highlightingRules.append(rule); - - QBrush quotationBrush(QColor::fromRgb(66, 244, 104)); - quotationFormat.setForeground(quotationBrush); -#if QT_VERSION >= 0x050000 - rule.pattern = QRegularExpression("\"[^\"]*\""); -#else - rule.pattern = QRegExp("\"[^\"]*\""); -#endif - rule.format = quotationFormat; - highlightingRules.append(rule); - - QBrush objectBrush(QColor::fromRgb(255, 80, 80)); - objectFormat.setForeground(objectBrush); -#if QT_VERSION >= 0x050000 - rule.pattern = QRegularExpression("\"[^\"]*\"(?=:)"); -#else - rule.pattern = QRegExp("\"[^\"]*\"(?=:)"); -#endif - rule.format = objectFormat; - highlightingRules.append(rule); -} - -void JSHighlighter::highlightBlock(const QString &text) -{ -#if QT_VERSION >= 0x050000 - for (const HighlightingRule &rule : qAsConst(highlightingRules)) -#else - for (const HighlightingRule &rule : highlightingRules) -#endif - { -#if QT_VERSION >= 0x050000 - QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); - while (matchIterator.hasNext()) { - QRegularExpressionMatch match = matchIterator.next(); - setFormat(match.capturedStart(), match.capturedLength(), rule.format); - } -#else - QRegExp expression(rule.pattern); - int index = expression.indexIn(text); - while (index >= 0) - { - int length = expression.matchedLength(); - setFormat(index, length, rule.format); - index = expression.indexIn(text, index + length); - } -#endif - } - setCurrentBlockState(0); -} diff --git a/uimod/JSHighlighter.h b/uimod/JSHighlighter.h deleted file mode 100644 index d93bfa9..0000000 --- a/uimod/JSHighlighter.h +++ /dev/null @@ -1,65 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017-2020 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef JSHIGHLIGHTER_H -#define JSHIGHLIGHTER_H - -#include -#include -#include -#include -#include -#include -#include - -#if QT_VERSION >= 0x050000 -#include -#else -#include -#endif - -class QTextDocument; - -class JSHighlighter : public QSyntaxHighlighter -{ - Q_OBJECT - -public: - struct HighlightingRule - { -#if QT_VERSION >= 0x050000 - QRegularExpression pattern; -#else - QRegExp pattern; -#endif - QTextCharFormat format; - }; - QVector highlightingRules; - - QTextCharFormat keywordFormat; - QTextCharFormat doubleFormat; - QTextCharFormat quotationFormat; - QTextCharFormat objectFormat; - - JSHighlighter(QTextDocument *parent = 0); - -protected: - void highlightBlock(const QString &text) override; -}; - -#endif // JSHIGHLIGHTER_H diff --git a/uimod/UiModLabel.cpp b/uimod/UiModLabel.cpp old mode 100644 new mode 100755 index 4a2c2d4..f069fa5 --- a/uimod/UiModLabel.cpp +++ b/uimod/UiModLabel.cpp @@ -1,75 +1,68 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "UiModLabel.h" -#include -#include - -UiModLabel::UiModLabel(const QString &text, QWidget *parent) : QLabel(parent) -{ - setText(text); -} - -UiModLabel::UiModLabel(QWidget *parent, const QString &text) : QLabel(parent) -{ - setText(text); -} - -UiModLabel::UiModLabel(QWidget *parent) : QLabel(parent) -{ -} - -UiModLabel::~UiModLabel() -{ -} - -void UiModLabel::paintEvent(QPaintEvent *ev) -{ - QLabel::paintEvent(ev); - emit labelPainted(); -} - -void UiModLabel::mouseMoveEvent(QMouseEvent *ev) -{ - QLabel::mouseMoveEvent(ev); - emit mouseMoved(); -} - -void UiModLabel::mousePressEvent(QMouseEvent *ev) -{ - QLabel::mousePressEvent(ev); - emit mousePressed(ev->button()); -} - -void UiModLabel::mouseReleaseEvent(QMouseEvent *ev) -{ - QLabel::mouseReleaseEvent(ev); - emit mouseReleased(ev->button()); -} - -void UiModLabel::mouseDoubleClickEvent(QMouseEvent *ev) -{ - QLabel::mouseDoubleClickEvent(ev); - emit mouseDoubleClicked(ev->button()); -} - -void UiModLabel::resizeEvent(QResizeEvent *ev) -{ - QLabel::resizeEvent(ev); - emit resized(ev->size()); -} +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "UiModLabel.h" +#include + +UiModLabel::UiModLabel(const QString &text, QWidget *parent) : QLabel(parent) +{ + setText(text); +} + +UiModLabel::UiModLabel(QWidget *parent, const QString &text) : QLabel(parent) +{ + setText(text); +} + +UiModLabel::UiModLabel(QWidget *parent) : QLabel(parent) +{ +} + +UiModLabel::~UiModLabel() +{ +} + +void UiModLabel::mouseMoveEvent(QMouseEvent *ev) +{ + QLabel::mouseMoveEvent(ev); + emit mouseMoved(); +} + +void UiModLabel::mousePressEvent(QMouseEvent *ev) +{ + QLabel::mousePressEvent(ev); + emit mousePressed(ev->button()); +} + +void UiModLabel::mouseReleaseEvent(QMouseEvent *ev) +{ + QLabel::mouseReleaseEvent(ev); + emit mouseReleased(ev->button()); +} + +void UiModLabel::mouseDoubleClickEvent(QMouseEvent *ev) +{ + QLabel::mouseDoubleClickEvent(ev); + emit mouseDoubleClicked(ev->button()); +} + +void UiModLabel::resizeEvent(QResizeEvent *ev) +{ + QLabel::resizeEvent(ev); + emit resized(ev->size()); +} diff --git a/uimod/UiModLabel.h b/uimod/UiModLabel.h old mode 100644 new mode 100755 index 0988a4e..8d63f9d --- a/uimod/UiModLabel.h +++ b/uimod/UiModLabel.h @@ -1,53 +1,51 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef UIMODLABEL_H -#define UIMODLABEL_H - -#include -#include -#include -#include - -class UiModLabel : public QLabel -{ - Q_OBJECT -public: - UiModLabel(const QString &text, QWidget *parent = 0); - UiModLabel(QWidget *parent, const QString &text); - UiModLabel(QWidget *parent = 0); - ~UiModLabel(); - -protected: - void mouseMoveEvent(QMouseEvent *ev); - void mousePressEvent(QMouseEvent *ev); - void mouseReleaseEvent(QMouseEvent *ev); - void mouseDoubleClickEvent(QMouseEvent *ev); - void paintEvent(QPaintEvent *ev); - void resizeEvent(QResizeEvent *ev); - -signals: - void mouseMoved(); - void mousePressed(Qt::MouseButton button); - void mouseReleased(Qt::MouseButton button); - void mouseDoubleClicked(Qt::MouseButton button); - void labelPainted(); - void resized(QSize newSize); -}; - -#endif // UIMODLABEL_H +/***************************************************************************** +* gta5sync GRAND THEFT AUTO V SYNC +* Copyright (C) 2016 Syping +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef UIMODLABEL_H +#define UIMODLABEL_H + +#include +#include +#include +#include + +class UiModLabel : public QLabel +{ + Q_OBJECT +public: + UiModLabel(const QString &text, QWidget *parent = 0); + UiModLabel(QWidget *parent, const QString &text); + UiModLabel(QWidget *parent = 0); + ~UiModLabel(); + +protected: + void mouseMoveEvent(QMouseEvent *ev); + void mousePressEvent(QMouseEvent *ev); + void mouseReleaseEvent(QMouseEvent *ev); + void mouseDoubleClickEvent(QMouseEvent *ev); + void resizeEvent(QResizeEvent *ev); + +signals: + void mouseMoved(); + void mousePressed(Qt::MouseButton button); + void mouseReleased(Qt::MouseButton button); + void mouseDoubleClicked(Qt::MouseButton button); + void resized(QSize newSize); +}; + +#endif // UIMODLABEL_H diff --git a/uimod/UiModWidget.cpp b/uimod/UiModWidget.cpp deleted file mode 100644 index 990ce7f..0000000 --- a/uimod/UiModWidget.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "UiModWidget.h" -#include -#include -#include -#include -#include -#include - -UiModWidget::UiModWidget(QWidget *parent) : QWidget(parent) -{ - filesDropEnabled = false; - imageDropEnabled = false; -} - -UiModWidget::~UiModWidget() -{ -} - -void UiModWidget::setFilesDropEnabled(bool enabled) -{ - filesDropEnabled = enabled; -} - -void UiModWidget::setImageDropEnabled(bool enabled) -{ - imageDropEnabled = enabled; -} - -void UiModWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent) -{ - if (filesDropEnabled && dragEnterEvent->mimeData()->hasUrls()) { - QVector pathList; - const QList urlList = dragEnterEvent->mimeData()->urls(); - - for (const QUrl ¤tUrl : urlList) { - if (currentUrl.isLocalFile()) { - pathList.append(currentUrl.toLocalFile()); - } - } - - if (!pathList.isEmpty()) { - dragEnterEvent->acceptProposedAction(); - } - } - else if (imageDropEnabled && dragEnterEvent->mimeData()->hasImage()) { - dragEnterEvent->acceptProposedAction(); - } -} - -void UiModWidget::dropEvent(QDropEvent *dropEvent) -{ - dropEvent->acceptProposedAction(); - emit dropped(dropEvent->mimeData()); -} - -void UiModWidget::paintEvent(QPaintEvent *paintEvent) -{ - Q_UNUSED(paintEvent) - QStyleOption opt; - opt.initFrom(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} diff --git a/uimod/UiModWidget.h b/uimod/UiModWidget.h deleted file mode 100644 index 469c000..0000000 --- a/uimod/UiModWidget.h +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************************** -* gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2017 Syping -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef UIMODWIDGET_H -#define UIMODWIDGET_H - -#include -#include -#include -#include - -class UiModWidget : public QWidget -{ - Q_OBJECT -public: - UiModWidget(QWidget *parent = 0); - void setFilesDropEnabled(bool enabled); - void setImageDropEnabled(bool enabled); - ~UiModWidget(); - -protected: - void dragEnterEvent(QDragEnterEvent *dragEnterEvent); - void dropEvent(QDropEvent *dropEvent); - void paintEvent(QPaintEvent *paintEvent); - -private: - bool filesDropEnabled; - bool imageDropEnabled; - -signals: - void dropped(const QMimeData *mimeData); -}; - -#endif // UIMODWIDGET_H